ETH Price: $3,027.87 (+4.31%)

Token

FreeBitcoins Token (FBTC)
 

Overview

Max Total Supply

1,000,000,000 FBTC

Holders

7

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 8 Decimals)

Balance
30,010,000 FBTC

Value
$0.00
0x2d38f017ec55858583d0db5f6088acbfe0a39808
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
FBTC

Compiler Version
v0.5.13+commit.5b0b510c

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 8 : FBTC.sol
pragma solidity ^0.5.13;

import "./StakeableToken.sol";
import "openzeppelin-solidity/contracts/access/Roles.sol";

contract FBTC is StakeableToken {
    using Roles for Roles.Role;
    Roles.Role private _minters;

     constructor()
        public
    {
         globals.shareRate = uint40(1 * SHARE_RATE_SCALE);
        _minters.add(ORIGIN_ADDR);

        _mint(FAUCET_ADDR, FAUCET_MINT);
        _mint(LLC_ADDR, LLC_MINT);
        _mint(XP_ADDR, XP_MINT);
        _mint(BAC_ADDR, BAY_MINT);
    }

    function mint(address to, uint256 amount) public {
        // Only minters can mint
        require(_minters.has(msg.sender), "DOES_NOT_HAVE_MINTER_ROLE");

        _mint(to, amount);
    }
}

File 2 of 8 : StakeableToken.sol
pragma solidity ^0.5.13;

import "./GlobalsAndUtility.sol";


contract StakeableToken is GlobalsAndUtility {
    /**
     * @dev PUBLIC FACING: Open a stake.
     * @param newStakedHearts Number of Hearts to stake
     * @param newStakedDays Number of days to stake
     */
    function stakeStart(uint256 newStakedHearts, uint256 newStakedDays)
        external
    {
        GlobalsCache memory g;
        GlobalsCache memory gSnapshot;
        _globalsLoad(g, gSnapshot);

        /* Enforce the minimum stake time */
        require(newStakedDays >= MIN_STAKE_DAYS, "FREE: newStakedDays lower than minimum");

        /* Check if log data needs to be updated */
        _dailyDataUpdateAuto(g);

        _stakeStart(g, newStakedHearts, newStakedDays);

        /* Remove staked Hearts from balance of staker */
        _burn(msg.sender, newStakedHearts);

        _globalsSync(g, gSnapshot);
    }

    /**
     * @dev PUBLIC FACING: Unlocks a completed stake, distributing the proceeds of any penalty
     * immediately. The staker must still call stakeEnd() to retrieve their stake return (if any).
     * @param stakerAddr Address of staker
     * @param stakeIndex Index of stake within stake list
     * @param stakeIdParam The stake's id
     */
    function stakeGoodAccounting(address stakerAddr, uint256 stakeIndex, uint40 stakeIdParam)
        external
    {
        GlobalsCache memory g;
        GlobalsCache memory gSnapshot;
        _globalsLoad(g, gSnapshot);

        /* require() is more informative than the default assert() */
        require(stakeLists[stakerAddr].length != 0, "FREE: Empty stake list");
        require(stakeIndex < stakeLists[stakerAddr].length, "FREE: stakeIndex invalid");

        StakeStore storage stRef = stakeLists[stakerAddr][stakeIndex];

        /* Get stake copy */
        StakeCache memory st;
        _stakeLoad(stRef, stakeIdParam, st);

        /* Stake must have served full term */
        require(g._currentDay >= st._lockedDay + st._stakedDays, "FREE: Stake not fully served");

        /* Stake must still be locked */
        require(st._unlockedDay == 0, "FREE: Stake already unlocked");

        /* Check if log data needs to be updated */
        _dailyDataUpdateAuto(g);

        /* Unlock the completed stake */
        _stakeUnlock(g, st);

        /* stakeReturn value is unused here */
        (, uint256 payout, uint256 penalty, uint256 cappedPenalty) = _stakePerformance(
            g,
            st,
            st._stakedDays
        );

        _emitStakeGoodAccounting(
            stakerAddr,
            stakeIdParam,
            st._stakedHearts,
            st._stakeShares,
            payout,
            penalty
        );

        if (cappedPenalty != 0) {
            _splitPenaltyProceeds(g, cappedPenalty);
        }

        /* st._unlockedDay has changed */
        _stakeUpdate(stRef, st);

        _globalsSync(g, gSnapshot);
    }

    /**
     * @dev PUBLIC FACING: Closes a stake. The order of the stake list can change so
     * a stake id is used to reject stale indexes.
     * @param stakeIndex Index of stake within stake list
     * @param stakeIdParam The stake's id
     */
    function stakeEnd(uint256 stakeIndex, uint40 stakeIdParam)
        external
    {
        GlobalsCache memory g;
        GlobalsCache memory gSnapshot;
        _globalsLoad(g, gSnapshot);

        StakeStore[] storage stakeListRef = stakeLists[msg.sender];

        /* require() is more informative than the default assert() */
        require(stakeListRef.length != 0, "FREE: Empty stake list");
        require(stakeIndex < stakeListRef.length, "FREE: stakeIndex invalid");

        /* Get stake copy */
        StakeCache memory st;
        _stakeLoad(stakeListRef[stakeIndex], stakeIdParam, st);

        /* Check if log data needs to be updated */
        _dailyDataUpdateAuto(g);

        uint256 servedDays = 0;

        bool prevUnlocked = (st._unlockedDay != 0);
        uint256 stakeReturn;
        uint256 payout = 0;
        uint256 penalty = 0;
        uint256 cappedPenalty = 0;

        if (g._currentDay >= st._lockedDay) {
            if (prevUnlocked) {
                /* Previously unlocked in stakeGoodAccounting(), so must have served full term */
                servedDays = st._stakedDays;
            } else {
                _stakeUnlock(g, st);

                servedDays = g._currentDay - st._lockedDay;
                if (servedDays > st._stakedDays) {
                    servedDays = st._stakedDays;
                }
            }

            (stakeReturn, payout, penalty, cappedPenalty) = _stakePerformance(g, st, servedDays);
        } else {
            /* Stake hasn't been added to the total yet, so no penalties or rewards apply */
            g._nextStakeSharesTotal -= st._stakeShares;

            stakeReturn = st._stakedHearts;
        }

        _emitStakeEnd(
            stakeIdParam,
            st._stakedHearts,
            st._stakeShares,
            payout,
            penalty,
            servedDays,
            prevUnlocked
        );

        if (cappedPenalty != 0 && !prevUnlocked) {
            /* Split penalty proceeds only if not previously unlocked by stakeGoodAccounting() */
            _splitPenaltyProceeds(g, cappedPenalty);
        }

        /* Pay the stake return, if any, to the staker */
        if (stakeReturn != 0) {
            _mint(msg.sender, stakeReturn);

            /* Update the share rate if necessary */
            _shareRateUpdate(g, st, stakeReturn);
        }
        g._lockedHeartsTotal -= st._stakedHearts;

        _stakeRemove(stakeListRef, stakeIndex);

        _globalsSync(g, gSnapshot);
    }

    /**
     * @dev PUBLIC FACING: Return the current stake count for a staker address
     * @param stakerAddr Address of staker
     */
    function stakeCount(address stakerAddr)
        external
        view
        returns (uint256)
    {
        return stakeLists[stakerAddr].length;
    }

    /**
     * @dev Open a stake.
     * @param g Cache of stored globals
     * @param newStakedHearts Number of Hearts to stake
     * @param newStakedDays Number of days to stake
     */
    function _stakeStart(
        GlobalsCache memory g,
        uint256 newStakedHearts,
        uint256 newStakedDays
    )
        internal
    {
        /* Enforce the maximum stake time */
        require(newStakedDays <= MAX_STAKE_DAYS, "FREE: newStakedDays higher than maximum");

        uint256 bonusHearts = _stakeStartBonusHearts(newStakedHearts, newStakedDays);
        uint256 newStakeShares = (newStakedHearts + bonusHearts) * SHARE_RATE_SCALE / g._shareRate;

        /* Ensure newStakedHearts is enough for at least one stake share */
        require(newStakeShares != 0, "FREE: newStakedHearts must be at least minimum shareRate");

        /*
            The stakeStart timestamp will always be part-way through the current
            day, so it needs to be rounded-up to the next day to ensure all
            stakes align with the same fixed calendar days. The current day is
            already rounded-down, so rounded-up is current day + 1.
        */
        uint256 newLockedDay = g._currentDay + 1;

        /* Create Stake */
        uint40 newStakeId = ++g._latestStakeId;
        _stakeAdd(
            stakeLists[msg.sender],
            newStakeId,
            newStakedHearts,
            newStakeShares,
            newLockedDay,
            newStakedDays
        );

        _emitStakeStart(newStakeId, newStakedHearts, newStakeShares, newStakedDays);

        /* Stake is added to total in the next round, not the current round */
        g._nextStakeSharesTotal += newStakeShares;

        /* Track total staked Hearts for inflation calculations */
        g._lockedHeartsTotal += newStakedHearts;
    }

    /**
     * @dev Calculates total stake payout including rewards for a multi-day range
     * @param stakeSharesParam Param from stake to calculate bonuses for
     * @param beginDay First day to calculate bonuses for
     * @param endDay Last day (non-inclusive) of range to calculate bonuses for
     * @return Payout in Hearts
     */
    function _calcPayoutRewards(
        uint256 stakeSharesParam,
        uint256 beginDay,
        uint256 endDay
    )
        private
        view
        returns (uint256 payout)
    {
        for (uint256 day = beginDay; day < endDay; day++) {
            payout += dailyData[day].dayPayoutTotal * stakeSharesParam
                / dailyData[day].dayStakeSharesTotal;
        }

        return payout;
    }

    /**
     * @dev Calculate bonus Hearts for a new stake, if any
     * @param newStakedHearts Number of Hearts to stake
     * @param newStakedDays Number of days to stake
     */
    function _stakeStartBonusHearts(uint256 newStakedHearts, uint256 newStakedDays)
        private
        pure
        returns (uint256 bonusHearts)
    {
        /*
            LONGER PAYS BETTER:

            If longer than 1 day stake is committed to, each extra day
            gives bonus shares of approximately 0.0548%, which is approximately 20%
            extra per year of increased stake length committed to, but capped to a
            maximum of 200% extra.

            extraDays       =  stakedDays - 1

            longerBonus%    = (extraDays / 364) * 20%
                            = (extraDays / 364) / 5
                            =  extraDays / 1820
                            =  extraDays / LPB

            extraDays       =  longerBonus% * 1820
            extraDaysMax    =  longerBonusMax% * 1820
                            =  200% * 1820
                            =  3640
                            =  LPB_MAX_DAYS

            BIGGER PAYS BETTER:

            Bonus percentage scaled 0% to 10% for the first 150M FREE of stake.

            biggerBonus%    = (cappedHearts /  BPB_MAX_HEARTS) * 10%
                            = (cappedHearts /  BPB_MAX_HEARTS) / 10
                            =  cappedHearts / (BPB_MAX_HEARTS * 10)
                            =  cappedHearts /  BPB

            COMBINED:

            combinedBonus%  =            longerBonus%  +  biggerBonus%

                                      cappedExtraDays     cappedHearts
                            =         ---------------  +  ------------
                                            LPB               BPB

                                cappedExtraDays * BPB     cappedHearts * LPB
                            =   ---------------------  +  ------------------
                                      LPB * BPB               LPB * BPB

                                cappedExtraDays * BPB  +  cappedHearts * LPB
                            =   --------------------------------------------
                                                  LPB  *  BPB

            bonusHearts     = hearts * combinedBonus%
                            = hearts * (cappedExtraDays * BPB  +  cappedHearts * LPB) / (LPB * BPB)
        */
        uint256 cappedExtraDays = 0;

        /* Must be more than 1 day for Longer-Pays-Better */
        if (newStakedDays > 1) {
            cappedExtraDays = newStakedDays <= LPB_MAX_DAYS ? newStakedDays - 1 : LPB_MAX_DAYS;
        }

        uint256 cappedStakedHearts = newStakedHearts <= BPB_MAX_HEARTS
            ? newStakedHearts
            : BPB_MAX_HEARTS;

        bonusHearts = cappedExtraDays * BPB + cappedStakedHearts * LPB;
        bonusHearts = newStakedHearts * bonusHearts / (LPB * BPB);

        return bonusHearts;
    }

    function _stakeUnlock(GlobalsCache memory g, StakeCache memory st)
        private
        pure
    {
        g._stakeSharesTotal -= st._stakeShares;
        st._unlockedDay = g._currentDay;
    }

    function _stakePerformance(GlobalsCache memory g, StakeCache memory st, uint256 servedDays)
        private
        view
        returns (uint256 stakeReturn, uint256 payout, uint256 penalty, uint256 cappedPenalty)
    {
        if (servedDays < st._stakedDays) {
            (payout, penalty) = _calcPayoutAndEarlyPenalty(
                g,
                st._lockedDay,
                st._stakedDays,
                servedDays,
                st._stakeShares
            );
            stakeReturn = st._stakedHearts + payout;
        } else {
            // servedDays must == stakedDays here
            payout = _calcPayoutRewards(
                st._stakeShares,
                st._lockedDay,
                st._lockedDay + servedDays
            );
            stakeReturn = st._stakedHearts + payout;

            penalty = _calcLatePenalty(st._lockedDay, st._stakedDays, st._unlockedDay, stakeReturn);
        }
        if (penalty != 0) {
            if (penalty > stakeReturn) {
                /* Cannot have a negative stake return */
                cappedPenalty = stakeReturn;
                stakeReturn = 0;
            } else {
                /* Remove penalty from the stake return */
                cappedPenalty = penalty;
                stakeReturn -= cappedPenalty;
            }
        }
        return (stakeReturn, payout, penalty, cappedPenalty);
    }

    function _calcPayoutAndEarlyPenalty(
        GlobalsCache memory g,
        uint256 lockedDayParam,
        uint256 stakedDaysParam,
        uint256 servedDays,
        uint256 stakeSharesParam
    )
        private
        view
        returns (uint256 payout, uint256 penalty)
    {
        uint256 servedEndDay = lockedDayParam + servedDays;

        /* 50% of stakedDays (rounded up) with a minimum applied */
        uint256 penaltyDays = (stakedDaysParam + 1) / 2;
        if (penaltyDays < EARLY_PENALTY_MIN_DAYS) {
            penaltyDays = EARLY_PENALTY_MIN_DAYS;
        }

        if (servedDays == 0) {
            /* Fill penalty days with the estimated average payout */
            uint256 expected = _estimatePayoutRewardsDay(g, stakeSharesParam);
            penalty = expected * penaltyDays;
            return (payout, penalty); // Actual payout was 0
        }

        if (penaltyDays < servedDays) {
            /*
                Simplified explanation of intervals where end-day is non-inclusive:

                penalty:    [lockedDay  ...  penaltyEndDay)
                delta:                      [penaltyEndDay  ...  servedEndDay)
                payout:     [lockedDay  .......................  servedEndDay)
            */
            uint256 penaltyEndDay = lockedDayParam + penaltyDays;
            penalty = _calcPayoutRewards(stakeSharesParam, lockedDayParam, penaltyEndDay);

            uint256 delta = _calcPayoutRewards(stakeSharesParam, penaltyEndDay, servedEndDay);
            payout = penalty + delta;
            return (payout, penalty);
        }

        /* penaltyDays >= servedDays  */
        payout = _calcPayoutRewards(stakeSharesParam, lockedDayParam, servedEndDay);

        if (penaltyDays == servedDays) {
            penalty = payout;
        } else {
            /*
                (penaltyDays > servedDays) means not enough days served, so fill the
                penalty days with the average payout from only the days that were served.
            */
            penalty = payout * penaltyDays / servedDays;
        }
        return (payout, penalty);
    }

    function _calcLatePenalty(
        uint256 lockedDayParam,
        uint256 stakedDaysParam,
        uint256 unlockedDayParam,
        uint256 rawStakeReturn
    )
        private
        pure
        returns (uint256)
    {
        /* Allow grace time before penalties accrue */
        uint256 maxUnlockedDay = lockedDayParam + stakedDaysParam + LATE_PENALTY_GRACE_DAYS;
        if (unlockedDayParam <= maxUnlockedDay) {
            return 0;
        }

        /* Calculate penalty as a percentage of stake return based on time */
        return rawStakeReturn * (unlockedDayParam - maxUnlockedDay) / LATE_PENALTY_SCALE_DAYS;
    }

    function _splitPenaltyProceeds(GlobalsCache memory g, uint256 penalty)
        private
    {
        /* Split a penalty 50:50 between Origin and stakePenaltyTotal */
        uint256 splitPenalty = penalty / 2;

        if (splitPenalty != 0) {
            _mint(ORIGIN_ADDR, splitPenalty);
        }

        /* Use the other half of the penalty to account for an odd-numbered penalty */
        splitPenalty = penalty - splitPenalty;
        g._stakePenaltyTotal += splitPenalty;
    }

    function _shareRateUpdate(GlobalsCache memory g, StakeCache memory st, uint256 stakeReturn)
        private
    {
        if (stakeReturn > st._stakedHearts) {
            /*
                Calculate the new shareRate that would yield the same number of shares if
                the user re-staked this stakeReturn, factoring in any bonuses they would
                receive in stakeStart().
            */
            uint256 bonusHearts = _stakeStartBonusHearts(stakeReturn, st._stakedDays);
            uint256 newShareRate = (stakeReturn + bonusHearts) * SHARE_RATE_SCALE / st._stakeShares;

            if (newShareRate > SHARE_RATE_MAX) {
                /*
                    Realistically this can't happen, but there are contrived theoretical
                    scenarios that can lead to extreme values of newShareRate, so it is
                    capped to prevent them anyway.
                */
                newShareRate = SHARE_RATE_MAX;
            }

            if (newShareRate > g._shareRate) {
                g._shareRate = newShareRate;

                _emitShareRateChange(newShareRate, st._stakeId);
            }
        }
    }

    function _emitStakeStart(
        uint40 stakeId,
        uint256 stakedHearts,
        uint256 stakeShares,
        uint256 stakedDays
    )
        private
    {
        emit StakeStart( // (auto-generated event)
            uint256(uint40(block.timestamp))
                | (uint256(uint72(stakedHearts)) << 40)
                | (uint256(uint72(stakeShares)) << 112)
                | (uint256(uint16(stakedDays)) << 184),
            msg.sender,
            stakeId
        );
    }

    function _emitStakeGoodAccounting(
        address stakerAddr,
        uint40 stakeId,
        uint256 stakedHearts,
        uint256 stakeShares,
        uint256 payout,
        uint256 penalty
    )
        private
    {
        emit StakeGoodAccounting( // (auto-generated event)
            uint256(uint40(block.timestamp))
                | (uint256(uint72(stakedHearts)) << 40)
                | (uint256(uint72(stakeShares)) << 112)
                | (uint256(uint72(payout)) << 184),
            uint256(uint72(penalty)),
            stakerAddr,
            stakeId,
            msg.sender
        );
    }

    function _emitStakeEnd(
        uint40 stakeId,
        uint256 stakedHearts,
        uint256 stakeShares,
        uint256 payout,
        uint256 penalty,
        uint256 servedDays,
        bool prevUnlocked
    )
        private
    {
        emit StakeEnd( // (auto-generated event)
            uint256(uint40(block.timestamp))
                | (uint256(uint72(stakedHearts)) << 40)
                | (uint256(uint72(stakeShares)) << 112)
                | (uint256(uint72(payout)) << 184),
            uint256(uint72(penalty))
                | (uint256(uint16(servedDays)) << 72)
                | (prevUnlocked ? (1 << 88) : 0),
            msg.sender,
            stakeId
        );
    }

    function _emitShareRateChange(uint256 shareRate, uint40 stakeId)
        private
    {
        emit ShareRateChange( // (auto-generated event)
            uint256(uint40(block.timestamp))
                | (uint256(uint40(shareRate)) << 40),
            stakeId
        );
    }
}

File 3 of 8 : Roles.sol
pragma solidity ^0.5.0;

/**
 * @title Roles
 * @dev Library for managing addresses assigned to a Role.
 */
library Roles {
    struct Role {
        mapping (address => bool) bearer;
    }

    /**
     * @dev Give an account access to this role.
     */
    function add(Role storage role, address account) internal {
        require(!has(role, account), "Roles: account already has role");
        role.bearer[account] = true;
    }

    /**
     * @dev Remove an account's access to this role.
     */
    function remove(Role storage role, address account) internal {
        require(has(role, account), "Roles: account does not have role");
        role.bearer[account] = false;
    }

    /**
     * @dev Check if an account has this role.
     * @return bool
     */
    function has(Role storage role, address account) internal view returns (bool) {
        require(account != address(0), "Roles: account is the zero address");
        return role.bearer[account];
    }
}

File 4 of 8 : GlobalsAndUtility.sol
pragma solidity ^0.5.13;

import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";


contract GlobalsAndUtility is ERC20 {
    /* Define events */
    /*  DailyDataUpdate   (auto-generated event)

        uint40            timestamp       -->  data0 [ 39:  0]
        uint16            beginDay        -->  data0 [ 55: 40]
        uint16            endDay          -->  data0 [ 71: 56]
        bool              isAutoUpdate    -->  data0 [ 79: 72]
        address  indexed  updaterAddr
    */
    event DailyDataUpdate(
        uint256 data0,
        address indexed updaterAddr
    );


    /*  StakeStart        (auto-generated event)

        uint40            timestamp       -->  data0 [ 39:  0]
        address  indexed  stakerAddr
        uint40   indexed  stakeId
        uint72            stakedHearts    -->  data0 [111: 40]
        uint72            stakeShares     -->  data0 [183:112]
        uint16            stakedDays      -->  data0 [199:184]
    */
    event StakeStart(
        uint256 data0,
        address indexed stakerAddr,
        uint40 indexed stakeId
    );

    /*  StakeGoodAccounting(auto-generated event)

        uint40            timestamp       -->  data0 [ 39:  0]
        address  indexed  stakerAddr
        uint40   indexed  stakeId
        uint72            stakedHearts    -->  data0 [111: 40]
        uint72            stakeShares     -->  data0 [183:112]
        uint72            payout          -->  data0 [255:184]
        uint72            penalty         -->  data1 [ 71:  0]
        address  indexed  senderAddr
    */
    event StakeGoodAccounting(
        uint256 data0,
        uint256 data1,
        address indexed stakerAddr,
        uint40 indexed stakeId,
        address indexed senderAddr
    );

    /*  StakeEnd          (auto-generated event)

        uint40            timestamp       -->  data0 [ 39:  0]
        address  indexed  stakerAddr
        uint40   indexed  stakeId
        uint72            stakedHearts    -->  data0 [111: 40]
        uint72            stakeShares     -->  data0 [183:112]
        uint72            payout          -->  data0 [255:184]
        uint72            penalty         -->  data1 [ 71:  0]
        uint16            servedDays      -->  data1 [ 87: 72]
        bool              prevUnlocked    -->  data1 [ 95: 88]
    */
    event StakeEnd(
        uint256 data0,
        uint256 data1,
        address indexed stakerAddr,
        uint40 indexed stakeId
    );

    /*  ShareRateChange   (auto-generated event)

        uint40            timestamp       -->  data0 [ 39:  0]
        uint40            shareRate       -->  data0 [ 79: 40]
        uint40   indexed  stakeId
    */
    event ShareRateChange(
        uint256 data0,
        uint40 indexed stakeId
    );

    /* Origin address */
    address internal constant ORIGIN_ADDR = 0xB8cF11B8De281560884b4A23Efd69D9aACBf3f4d;

    /* DIST addresses */
    address internal constant FAUCET_ADDR = 0xc3D6E20cC4D492c4B0b84312Fb5d730D03278222; /* 50% */
    address internal constant LLC_ADDR = 0xAef2989e6A23982D93d83F91378d17ec31662bd1;  /* 40% */
    address internal constant XP_ADDR = 0xB8cF11B8De281560884b4A23Efd69D9aACBf3f4d;  /* 5% */
    address internal constant BAC_ADDR = 0x2D38F017eC55858583d0dB5f6088acbfE0a39808;  /* 5% */

    /* 1B total initial distrubution */
    uint256 internal constant FAUCET_MINT = 50000000000000000;
    uint256 internal constant LLC_MINT = 40000000000000000;
    uint256 internal constant XP_MINT = 5000000000000000;
    uint256 internal constant BAY_MINT = 5000000000000000;

    /* ERC20 constants */
    string public constant name = "FreeBitcoins Token";
    string public constant symbol = "FBTC";
    uint8 public constant decimals = 8;

    /* Hearts per Satoshi = 10,000 * 1e8 / 1e8 = 1e4 */
    uint256 private constant HEARTS_PER_FBTC = 10 ** uint256(decimals); // 1e8

    /* Time of contract launch (2019-03-04T00:00:00Z) */
    uint256 internal constant LAUNCH_TIME = 1627603200000;
                                            
    /* Size of a Hearts or Shares uint */
    uint256 internal constant HEART_UINT_SIZE = 72;

     /* Stake timing parameters */
    uint256 internal constant MIN_STAKE_DAYS = 1;

    uint256 internal constant MAX_STAKE_DAYS = 5555; // Approx 15 years
    uint256 internal constant EARLY_PENALTY_MIN_DAYS = 90;

    uint256 private constant LATE_PENALTY_GRACE_WEEKS = 2;
    uint256 internal constant LATE_PENALTY_GRACE_DAYS = LATE_PENALTY_GRACE_WEEKS * 7;

    uint256 private constant LATE_PENALTY_SCALE_WEEKS = 100;
    uint256 internal constant LATE_PENALTY_SCALE_DAYS = LATE_PENALTY_SCALE_WEEKS * 7;

    /* Stake shares Longer Pays Better bonus constants used by _stakeStartBonusHearts() */
    uint256 private constant LPB_BONUS_PERCENT = 20;
    uint256 private constant LPB_BONUS_MAX_PERCENT = 200;
    uint256 internal constant LPB = 364 * 100 / LPB_BONUS_PERCENT;
    uint256 internal constant LPB_MAX_DAYS = LPB * LPB_BONUS_MAX_PERCENT / 100;

    /* Stake shares Bigger Pays Better bonus constants used by _stakeStartBonusHearts() */
    uint256 private constant BPB_BONUS_PERCENT = 10;
    uint256 private constant BPB_MAX_FBTC = 150 * 1e6;
    uint256 internal constant BPB_MAX_HEARTS = BPB_MAX_FBTC * HEARTS_PER_FBTC;
    uint256 internal constant BPB = BPB_MAX_HEARTS * 100 / BPB_BONUS_PERCENT;

    /* Share rate is scaled to increase precision */
    uint256 internal constant SHARE_RATE_SCALE = 1e5;

    /* Share rate max (after scaling) */
    uint256 internal constant SHARE_RATE_UINT_SIZE = 40;
    uint256 internal constant SHARE_RATE_MAX = (1 << SHARE_RATE_UINT_SIZE) - 1;

    /* Globals expanded for memory (except _latestStakeId) and compact for storage */
    struct GlobalsCache {
        // 1
        uint256 _lockedHeartsTotal;
        uint256 _nextStakeSharesTotal;
        uint256 _shareRate;
        uint256 _stakePenaltyTotal;
        // 2
        uint256 _dailyDataCount;
        uint256 _stakeSharesTotal;
        uint40 _latestStakeId;
        //
        uint256 _currentDay;
    }

    struct GlobalsStore {
        // 1
        uint72 lockedHeartsTotal;
        uint72 nextStakeSharesTotal;
        uint40 shareRate;
        uint72 stakePenaltyTotal;
        // 2
        uint16 dailyDataCount;
        uint72 stakeSharesTotal;
        uint40 latestStakeId;
    }
    GlobalsStore public globals;

    /* Daily data */
    struct DailyDataStore {
        uint72 dayPayoutTotal;
        uint72 dayStakeSharesTotal;
    }

    mapping(uint256 => DailyDataStore) public dailyData;

    /* Stake expanded for memory (except _stakeId) and compact for storage */
    struct StakeCache {
        uint40 _stakeId;
        uint256 _stakedHearts;
        uint256 _stakeShares;
        uint256 _lockedDay;
        uint256 _stakedDays;
        uint256 _unlockedDay;
    }

    struct StakeStore {
        uint40 stakeId;
        uint72 stakedHearts;
        uint72 stakeShares;
        uint16 lockedDay;
        uint16 stakedDays;
        uint16 unlockedDay;
    }

    mapping(address => StakeStore[]) public stakeLists;

     /* Temporary state for calculating daily rounds */
    struct DailyRoundState {
        uint256 _allocSupplyCached;
        uint256 _payoutTotal;
    }

   /**
     * @dev PUBLIC FACING: Optionally update daily data for a smaller
     * range to reduce gas cost for a subsequent operation
     * @param beforeDay Only update days before this day number (optional; 0 for current day)
     */
    function dailyDataUpdate(uint256 beforeDay)
        external
    {
        GlobalsCache memory g;
        GlobalsCache memory gSnapshot;
        _globalsLoad(g, gSnapshot);

        if (beforeDay != 0) {
            require(beforeDay <= g._currentDay, "FBTC: beforeDay cannot be in the future");

            _dailyDataUpdate(g, beforeDay, false);
        } else {
            /* Default to updating before current day */
            _dailyDataUpdate(g, g._currentDay, false);
        }

        _globalsSync(g, gSnapshot);
    }


     /**
     * @dev PUBLIC FACING: External helper to return multiple values of daily data with
     * a single call. Ugly implementation due to limitations of the standard ABI encoder.
     * @param beginDay First day of data range
     * @param endDay Last day (non-inclusive) of data range
     * @return Fixed array of packed values
     */
    function dailyDataRange(uint256 beginDay, uint256 endDay)
        external
        view
        returns (uint256[] memory list)
    {
        require(beginDay < endDay && endDay <= globals.dailyDataCount, "FBTC: range invalid");

        list = new uint256[](endDay - beginDay);

        uint256 src = beginDay;
        uint256 dst = 0;
        uint256 v;
        do {
            v = uint256(dailyData[src].dayStakeSharesTotal) << HEART_UINT_SIZE;
            v |= uint256(dailyData[src].dayPayoutTotal);

            list[dst++] = v;
        } while (++src < endDay);

        return list;
    }

     /**
     * @dev PUBLIC FACING: External helper to return most global info with a single call.
     * Ugly implementation due to limitations of the standard ABI encoder.
     * @return Fixed array of values
     */
    function globalInfo()
        external
        view
        returns (uint256[9] memory)
    {
        return [
            // 1
            globals.lockedHeartsTotal,
            globals.nextStakeSharesTotal,
            globals.shareRate,
            globals.stakePenaltyTotal,
            // 2
            globals.dailyDataCount,
            globals.stakeSharesTotal,
            globals.latestStakeId,
            //
            block.timestamp,
            totalSupply()
        ];
    }

    /**
     * @dev PUBLIC FACING: ERC20 totalSupply() is the circulating supply and does not include any
     * staked Hearts. allocatedSupply() includes both.
     * @return Allocated Supply in Hearts
     */
    function allocatedSupply()
        external
        view
        returns (uint256)
    {
        return totalSupply() + globals.lockedHeartsTotal;
    }

    /**
     * @dev PUBLIC FACING: External helper for the current day number since launch time
     * @return Current day number (zero-based)
     */
    function getCurrentDay()
        external
        view
        returns (uint256)
    {
        return _getCurrentDay();
    }

    function _getCurrentDay()
        internal
        view
        returns (uint256)
    {
        return (block.timestamp - LAUNCH_TIME) / 1 days;
    }

    function _dailyDataUpdateAuto(GlobalsCache memory g)
        internal
    {
        _dailyDataUpdate(g, g._currentDay, true);
    }

    function _globalsLoad(GlobalsCache memory g, GlobalsCache memory gSnapshot)
        internal
        view
    {
        // 1
        g._lockedHeartsTotal = globals.lockedHeartsTotal;
        g._nextStakeSharesTotal = globals.nextStakeSharesTotal;
        g._shareRate = globals.shareRate;
        g._stakePenaltyTotal = globals.stakePenaltyTotal;
        // 2
        g._dailyDataCount = globals.dailyDataCount;
        g._stakeSharesTotal = globals.stakeSharesTotal;
        g._latestStakeId = globals.latestStakeId;
        //
        g._currentDay = _currentDay();

        _globalsCacheSnapshot(g, gSnapshot);
    }

        function _globalsCacheSnapshot(GlobalsCache memory g, GlobalsCache memory gSnapshot)
        internal
        pure
    {
        // 1
        gSnapshot._lockedHeartsTotal = g._lockedHeartsTotal;
        gSnapshot._nextStakeSharesTotal = g._nextStakeSharesTotal;
        gSnapshot._shareRate = g._shareRate;
        gSnapshot._stakePenaltyTotal = g._stakePenaltyTotal;
        // 2
        gSnapshot._dailyDataCount = g._dailyDataCount;
        gSnapshot._stakeSharesTotal = g._stakeSharesTotal;
        gSnapshot._latestStakeId = g._latestStakeId;
    }

    function _globalsSync(GlobalsCache memory g, GlobalsCache memory gSnapshot)
        internal
    {
        if (g._lockedHeartsTotal != gSnapshot._lockedHeartsTotal
            || g._nextStakeSharesTotal != gSnapshot._nextStakeSharesTotal
            || g._shareRate != gSnapshot._shareRate
            || g._stakePenaltyTotal != gSnapshot._stakePenaltyTotal) {
            // 1
            globals.lockedHeartsTotal = uint72(g._lockedHeartsTotal);
            globals.nextStakeSharesTotal = uint72(g._nextStakeSharesTotal);
            globals.shareRate = uint40(g._shareRate);
            globals.stakePenaltyTotal = uint72(g._stakePenaltyTotal);
        }
        if (g._dailyDataCount != gSnapshot._dailyDataCount
            || g._stakeSharesTotal != gSnapshot._stakeSharesTotal
            || g._latestStakeId != gSnapshot._latestStakeId) {
            // 2
            globals.dailyDataCount = uint16(g._dailyDataCount);
            globals.stakeSharesTotal = uint72(g._stakeSharesTotal);
            globals.latestStakeId = g._latestStakeId;
        }
    }

    function _stakeLoad(StakeStore storage stRef, uint40 stakeIdParam, StakeCache memory st)
        internal
        view
    {
        /* Ensure caller's stakeIndex is still current */
        require(stakeIdParam == stRef.stakeId, "FBTC: stakeIdParam not in stake");

        st._stakeId = stRef.stakeId;
        st._stakedHearts = stRef.stakedHearts;
        st._stakeShares = stRef.stakeShares;
        st._lockedDay = stRef.lockedDay;
        st._stakedDays = stRef.stakedDays;
        st._unlockedDay = stRef.unlockedDay;
    }

     function _stakeUpdate(StakeStore storage stRef, StakeCache memory st)
        internal
    {
        stRef.stakeId = st._stakeId;
        stRef.stakedHearts = uint72(st._stakedHearts);
        stRef.stakeShares = uint72(st._stakeShares);
        stRef.lockedDay = uint16(st._lockedDay);
        stRef.stakedDays = uint16(st._stakedDays);
        stRef.unlockedDay = uint16(st._unlockedDay);
    }

    function _stakeAdd(
        StakeStore[] storage stakeListRef,
        uint40 newStakeId,
        uint256 newStakedHearts,
        uint256 newStakeShares,
        uint256 newLockedDay,
        uint256 newStakedDays
    )
        internal
    {
        stakeListRef.push(
            StakeStore(
                newStakeId,
                uint72(newStakedHearts),
                uint72(newStakeShares),
                uint16(newLockedDay),
                uint16(newStakedDays),
                uint16(0) // unlockedDay
            )
        );
    }

   /**
     * @dev Efficiently delete from an unordered array by moving the last element
     * to the "hole" and reducing the array length. Can change the order of the list
     * and invalidate previously held indexes.
     * @notice stakeListRef length and stakeIndex are already ensured valid in stakeEnd()
     * @param stakeListRef Reference to stakeLists[stakerAddr] array in storage
     * @param stakeIndex Index of the element to delete
     */
    function _stakeRemove(StakeStore[] storage stakeListRef, uint256 stakeIndex)
        internal
    {
        uint256 lastIndex = stakeListRef.length - 1;

        /* Skip the copy if element to be removed is already the last element */
        if (stakeIndex != lastIndex) {
            /* Copy last element to the requested element's "hole" */
            stakeListRef[stakeIndex] = stakeListRef[lastIndex];
        }

        /*
            Reduce the array length now that the array is contiguous.
            Surprisingly, 'pop()' uses less gas than 'stakeListRef.length = lastIndex'
        */
        stakeListRef.pop();
    }

    /**
     * @dev Estimate the stake payout for an incomplete day
     * @param g Cache of stored globals
     * @param stakeSharesParam Param from stake to calculate bonuses for
     * @return Payout in Hearts
     */
    function _estimatePayoutRewardsDay(GlobalsCache memory g, uint256 stakeSharesParam)
        internal
        view
        returns (uint256 payout)
    {
        /* Prevent updating state for this estimation */
        GlobalsCache memory gTmp;
        _globalsCacheSnapshot(g, gTmp);

        DailyRoundState memory rs;
        rs._allocSupplyCached = totalSupply() + g._lockedHeartsTotal;

        _dailyRoundCalc(gTmp, rs);

        /* Stake is no longer locked so it must be added to total as if it were */
        gTmp._stakeSharesTotal += stakeSharesParam;
        payout = rs._payoutTotal * stakeSharesParam / gTmp._stakeSharesTotal;

        return payout;
    }


    function _dailyRoundCalc(GlobalsCache memory g, DailyRoundState memory rs)
        private
        pure
    {
        /*
            Calculate payout round

            Inflation of 10% inflation per 364 days             (approx 1 year)
            dailyInterestRate   = exp(log(1 + 10%)  / 364) - 1
                                = exp(log(1 + 0.1) / 364) - 1
                                = exp(log(1.1) / 364) - 1
                                = 0.000261875            (approx)

            payout  = allocSupply * dailyInterestRate
                    = allocSupply / (1 / dailyInterestRate)
                    = allocSupply / (1 / 0.000261875)
                                     

                    = allocSupply / 3818.61575179            (approx)
                    = allocSupply * 10000 / 38186157             (* 10000/10000 for int precision)
        */
        rs._payoutTotal = rs._allocSupplyCached * 10000 / 38186157;
        if (g._stakePenaltyTotal != 0) {
            rs._payoutTotal += g._stakePenaltyTotal;
            g._stakePenaltyTotal = 0;
        }
    }

    function _dailyRoundCalcAndStore(GlobalsCache memory g, DailyRoundState memory rs, uint256 day)
        private
    {
        _dailyRoundCalc(g, rs);

        dailyData[day].dayPayoutTotal = uint72(rs._payoutTotal);
        dailyData[day].dayStakeSharesTotal = uint72(g._stakeSharesTotal);
    }

     /**
     * @dev PUBLIC FACING: External helper for the current day number since launch time
     * @return Current day number (zero-based)
     */
    function currentDay()
        external
        view
        returns (uint256)
    {
        return _currentDay();
    }

    function _currentDay() 
        internal
        view
        returns (uint256)
    {
        return (block.timestamp - LAUNCH_TIME) / 1 days;
    }


    function _dailyDataUpdate(GlobalsCache memory g, uint256 beforeDay, bool isAutoUpdate)
        private
    {
        if (g._dailyDataCount >= beforeDay) {
            /* Already up-to-date */
            return;
        }

        DailyRoundState memory rs;
        rs._allocSupplyCached = totalSupply() + g._lockedHeartsTotal;

        uint256 day = g._dailyDataCount;

        _dailyRoundCalcAndStore(g, rs, day);

        /* Stakes started during this day are added to the total the next day */
        if (g._nextStakeSharesTotal != 0) {
            g._stakeSharesTotal += g._nextStakeSharesTotal;
            g._nextStakeSharesTotal = 0;
        }

        while (++day < beforeDay) {
            _dailyRoundCalcAndStore(g, rs, day);
        }

        _emitDailyDataUpdate(g._dailyDataCount, day, isAutoUpdate);
        g._dailyDataCount = day;

    }

    function _emitDailyDataUpdate(uint256 beginDay, uint256 endDay, bool isAutoUpdate)
        private
    {
        emit DailyDataUpdate( // (auto-generated event)
            uint256(uint40(block.timestamp))
                | (uint256(uint16(beginDay)) << 40)
                | (uint256(uint16(endDay)) << 56)
                | (isAutoUpdate ? (1 << 72) : 0),
            msg.sender
        );
    }
}

File 5 of 8 : ERC20.sol
pragma solidity ^0.5.0;

import "../../GSN/Context.sol";
import "./IERC20.sol";
import "../../math/SafeMath.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20Mintable}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20 {
    using SafeMath for uint256;

    mapping (address => uint256) private _balances;

    mapping (address => mapping (address => uint256)) private _allowances;

    uint256 private _totalSupply;

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20};
     *
     * Requirements:
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for `sender`'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal {
        require(account != address(0), "ERC20: mint to the zero address");

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal {
        require(account != address(0), "ERC20: burn from the zero address");

        _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.
     *
     * This is internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`.`amount` is then deducted
     * from the caller's allowance.
     *
     * See {_burn} and {_approve}.
     */
    function _burnFrom(address account, uint256 amount) internal {
        _burn(account, amount);
        _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "ERC20: burn amount exceeds allowance"));
    }
}

File 6 of 8 : Context.sol
pragma solidity ^0.5.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
contract Context {
    // Empty internal constructor, to prevent people from mistakenly deploying
    // an instance of this contract, which should be used via inheritance.
    constructor () internal { }
    // solhint-disable-previous-line no-empty-blocks

    function _msgSender() internal view returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

File 7 of 8 : IERC20.sol
pragma solidity ^0.5.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
 * the optional functions; to access them see {ERC20Detailed}.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 8 of 8 : SafeMath.sol
pragma solidity ^0.5.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     *
     * _Available since v2.4.0._
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"data0","type":"uint256"},{"indexed":true,"internalType":"address","name":"updaterAddr","type":"address"}],"name":"DailyDataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"data0","type":"uint256"},{"indexed":true,"internalType":"uint40","name":"stakeId","type":"uint40"}],"name":"ShareRateChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"data0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"data1","type":"uint256"},{"indexed":true,"internalType":"address","name":"stakerAddr","type":"address"},{"indexed":true,"internalType":"uint40","name":"stakeId","type":"uint40"}],"name":"StakeEnd","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"data0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"data1","type":"uint256"},{"indexed":true,"internalType":"address","name":"stakerAddr","type":"address"},{"indexed":true,"internalType":"uint40","name":"stakeId","type":"uint40"},{"indexed":true,"internalType":"address","name":"senderAddr","type":"address"}],"name":"StakeGoodAccounting","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"data0","type":"uint256"},{"indexed":true,"internalType":"address","name":"stakerAddr","type":"address"},{"indexed":true,"internalType":"uint40","name":"stakeId","type":"uint40"}],"name":"StakeStart","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":true,"inputs":[],"name":"allocatedSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentDay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dailyData","outputs":[{"internalType":"uint72","name":"dayPayoutTotal","type":"uint72"},{"internalType":"uint72","name":"dayStakeSharesTotal","type":"uint72"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"beginDay","type":"uint256"},{"internalType":"uint256","name":"endDay","type":"uint256"}],"name":"dailyDataRange","outputs":[{"internalType":"uint256[]","name":"list","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"beforeDay","type":"uint256"}],"name":"dailyDataUpdate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentDay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"globalInfo","outputs":[{"internalType":"uint256[9]","name":"","type":"uint256[9]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"globals","outputs":[{"internalType":"uint72","name":"lockedHeartsTotal","type":"uint72"},{"internalType":"uint72","name":"nextStakeSharesTotal","type":"uint72"},{"internalType":"uint40","name":"shareRate","type":"uint40"},{"internalType":"uint72","name":"stakePenaltyTotal","type":"uint72"},{"internalType":"uint16","name":"dailyDataCount","type":"uint16"},{"internalType":"uint72","name":"stakeSharesTotal","type":"uint72"},{"internalType":"uint40","name":"latestStakeId","type":"uint40"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"stakerAddr","type":"address"}],"name":"stakeCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"stakeIndex","type":"uint256"},{"internalType":"uint40","name":"stakeIdParam","type":"uint40"}],"name":"stakeEnd","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"stakerAddr","type":"address"},{"internalType":"uint256","name":"stakeIndex","type":"uint256"},{"internalType":"uint40","name":"stakeIdParam","type":"uint40"}],"name":"stakeGoodAccounting","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakeLists","outputs":[{"internalType":"uint40","name":"stakeId","type":"uint40"},{"internalType":"uint72","name":"stakedHearts","type":"uint72"},{"internalType":"uint72","name":"stakeShares","type":"uint72"},{"internalType":"uint16","name":"lockedDay","type":"uint16"},{"internalType":"uint16","name":"stakedDays","type":"uint16"},{"internalType":"uint16","name":"unlockedDay","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newStakedHearts","type":"uint256"},{"internalType":"uint256","name":"newStakedDays","type":"uint256"}],"name":"stakeStart","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b506003805464ffffffffff60901b1916740186a000000000000000000000000000000000000017905562000067600773b8cf11b8de281560884b4a23efd69d9aacbf3f4d6200012d602090811b6200260d17901c565b6200009773c3d6e20cc4d492c4b0b84312fb5d730d0327822266b1a2bc2ec500006001600160e01b03620001d416565b620000c773aef2989e6a23982d93d83f91378d17ec31662bd1668e1bc9bf0400006001600160e01b03620001d416565b620000f773b8cf11b8de281560884b4a23efd69d9aacbf3f4d6611c37937e080006001600160e01b03620001d416565b62000127732d38f017ec55858583d0db5f6088acbfe0a398086611c37937e080006001600160e01b03620001d416565b620003ee565b6200014282826001600160e01b03620002ef16565b15620001af57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6001600160a01b0382166200024a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b62000266816002546200037260201b62001b3b1790919060201c565b6002556001600160a01b038216600090815260208181526040909120546200029991839062001b3b62000372821b17901c565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b60006001600160a01b03821662000352576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018062002cd36022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b600082820183811015620003e757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6128d580620003fe6000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c806352a438b8116100de57806390de687111610097578063a9059cbb11610071578063a9059cbb1461055f578063c31245251461058b578063dd62ed3e146105e7578063f04b5fa01461061557610173565b806390de6871146104e857806395d89b411461052b578063a457c2d71461053357610173565b806352a438b8146103d65780635c9302c9146103a257806365cf71b2146103f95780636a210a0e1461043257806370a08231146104a55780638f1c65c0146104cb57610173565b806333060d901161013057806333060d901461031c578063343009a214610342578063395093511461036e5780633a70a5ca1461039a5780633e6968b6146103a257806340c10f19146103aa57610173565b806306fdde0314610178578063095ea7b3146101f557806318160ddd1461023557806323b872dd1461024f5780632607443b14610285578063313ce567146102fe575b600080fd5b610180610656565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101ba5781810151838201526020016101a2565b50505050905090810190601f1680156101e75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102216004803603604081101561020b57600080fd5b506001600160a01b038135169060200135610684565b604080519115158252519081900360200190f35b61023d6106a1565b60408051918252519081900360200190f35b6102216004803603606081101561026557600080fd5b506001600160a01b038135811691602081013590911690604001356106a7565b6102b16004803603604081101561029b57600080fd5b506001600160a01b038135169060200135610734565b6040805164ffffffffff90971687526001600160481b039586166020880152939094168584015261ffff9182166060860152811660808501529190911660a0830152519081900360c00190f35b6103066107a2565b6040805160ff9092168252519081900360200190f35b61023d6004803603602081101561033257600080fd5b50356001600160a01b03166107a7565b61036c6004803603604081101561035857600080fd5b508035906020013564ffffffffff166107c2565b005b6102216004803603604081101561038457600080fd5b506001600160a01b0381351690602001356109c4565b61023d610a18565b61023d610a35565b61036c600480360360408110156103c057600080fd5b506001600160a01b038135169060200135610a44565b61036c600480360360408110156103ec57600080fd5b5080359060200135610ab4565b61036c6004803603606081101561040f57600080fd5b5080356001600160a01b0316906020810135906040013564ffffffffff16610b3c565b6104556004803603604081101561044857600080fd5b5080359060200135610d91565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610491578181015183820152602001610479565b505050509050019250505060405180910390f35b61023d600480360360208110156104bb57600080fd5b50356001600160a01b0316610e97565b61036c600480360360208110156104e157600080fd5b5035610eb2565b610505600480360360208110156104fe57600080fd5b5035610f45565b604080516001600160481b03938416815291909216602082015281519081900390910190f35b610180610f6b565b6102216004803603604081101561054957600080fd5b506001600160a01b038135169060200135610f8b565b6102216004803603604081101561057557600080fd5b506001600160a01b038135169060200135610ff9565b61059361100d565b604080516001600160481b039889168152968816602088015264ffffffffff95861687820152938716606087015261ffff909216608086015290941660a0840152921660c082015290519081900360e00190f35b61023d600480360360408110156105fd57600080fd5b506001600160a01b0381358116916020013516611060565b61061d61108b565b604051808261012080838360005b8381101561064357818101518382015260200161062b565b5050505090500191505060405180910390f35b60405180604001604052806012815260200171233932b2a134ba31b7b4b739902a37b5b2b760711b81525081565b6000610698610691611125565b8484611129565b50600192915050565b60025490565b60006106b4848484611215565b61072a846106c0611125565b610725856040518060600160405280602881526020016127c8602891396001600160a01b038a166000908152600160205260408120906106fe611125565b6001600160a01b03168152602081019190915260400160002054919063ffffffff61137116565b611129565b5060019392505050565b6006602052816000526040600020818154811061074d57fe5b60009182526020909120015464ffffffffff811692506001600160481b03600160281b820481169250600160701b8204169061ffff600160b81b8204811691600160c81b8104821691600160d81b9091041686565b600881565b6001600160a01b031660009081526006602052604090205490565b6107ca61254b565b6107d261254b565b6107dc8282611408565b3360009081526006602052604090208054610837576040805162461bcd60e51b8152602060048201526016602482015275119491514e88115b5c1d1e481cdd185ad9481b1a5cdd60521b604482015290519081900360640190fd5b80548510610887576040805162461bcd60e51b8152602060048201526018602482015277119491514e881cdd185ad9525b99195e081a5b9d985b1a5960421b604482015290519081900360640190fd5b61088f612597565b6108af82878154811061089e57fe5b906000526020600020018683611488565b6108b88461154a565b60a0810151606082015160e08601516000921515918391829182918291116109315784156108ec5786608001519550610917565b6108f68a8861155d565b86606001518a60e00151039550866080015186111561091757866080015195505b6109228a888861157b565b9296509094509250905061094a565b60408701516020808c0180519290920390915287015193505b6109618b8860200151896040015186868b8b61161e565b801580159061096e575084155b1561097d5761097d8a826116e0565b83156109985761098d338561171b565b6109988a888661180b565b60208701518a51038a526109ac888d61187e565b6109b68a8a6119be565b505050505050505050505050565b60006106986109d1611125565b8461072585600160006109e2611125565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff611b3b16565b6003546000906001600160481b0316610a2f6106a1565b01905090565b6000610a3f611b9c565b905090565b610a5560073363ffffffff611bae16565b610aa6576040805162461bcd60e51b815260206004820152601960248201527f444f45535f4e4f545f484156455f4d494e5445525f524f4c4500000000000000604482015290519081900360640190fd5b610ab0828261171b565b5050565b610abc61254b565b610ac461254b565b610ace8282611408565b6001831015610b0e5760405162461bcd60e51b81526004018080602001828103825260268152602001806127a26026913960400191505060405180910390fd5b610b178261154a565b610b22828585611c15565b610b2c3385611d16565b610b3682826119be565b50505050565b610b4461254b565b610b4c61254b565b610b568282611408565b6001600160a01b038516600090815260066020526040902054610bb9576040805162461bcd60e51b8152602060048201526016602482015275119491514e88115b5c1d1e481cdd185ad9481b1a5cdd60521b604482015290519081900360640190fd5b6001600160a01b0385166000908152600660205260409020548410610c20576040805162461bcd60e51b8152602060048201526018602482015277119491514e881cdd185ad9525b99195e081a5b9d985b1a5960421b604482015290519081900360640190fd5b6001600160a01b0385166000908152600660205260408120805486908110610c4457fe5b906000526020600020019050610c58612597565b610c63828683611488565b80608001518160600151018460e001511015610cc6576040805162461bcd60e51b815260206004820152601c60248201527f465245453a205374616b65206e6f742066756c6c792073657276656400000000604482015290519081900360640190fd5b60a081015115610d1d576040805162461bcd60e51b815260206004820152601c60248201527f465245453a205374616b6520616c726561647920756e6c6f636b656400000000604482015290519081900360640190fd5b610d268461154a565b610d30848261155d565b6000806000610d448785866080015161157b565b93509350935050610d618a89866020015187604001518787611e12565b8015610d7157610d7187826116e0565b610d7b8585611eaf565b610d8587876119be565b50505050505050505050565b60608183108015610da8575060045461ffff168211155b610def576040805162461bcd60e51b815260206004820152601360248201527211909510ce881c985b99d9481a5b9d985b1a59606a1b604482015290519081900360640190fd5b828203604051908082528060200260200182016040528015610e1b578160200160208202803883390190505b509050826000805b5060008281526005602052604090205483516001830192600160481b830460481b71ffffffffffffffffff000000000000000000166001600160481b03909316929092179182918691908110610e7557fe5b602002602001018181525050848360010193508310610e235750505092915050565b6001600160a01b031660009081526020819052604090205490565b610eba61254b565b610ec261254b565b610ecc8282611408565b8215610f26578160e00151831115610f155760405162461bcd60e51b815260040180806020018281038252602781526020018061277b6027913960400191505060405180910390fd5b610f2182846000611f68565b610f36565b610f36828360e001516000611f68565b610f4082826119be565b505050565b6005602052600090815260409020546001600160481b0380821691600160481b90041682565b604051806040016040528060048152602001634642544360e01b81525081565b6000610698610f98611125565b846107258560405180606001604052806025815260200161287c6025913960016000610fc2611125565b6001600160a01b03908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff61137116565b6000610698611006611125565b8484611215565b6003546004546001600160481b0380831692600160481b810482169264ffffffffff600160901b8304811693600160b81b90930483169261ffff83169262010000810490911691600160581b9091041687565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6110936125d4565b60408051610120810182526003546001600160481b038082168352600160481b82048116602084015264ffffffffff600160901b8304811694840194909452600160b81b9091048116606083015260045461ffff8116608084015262010000810490911660a0830152600160581b900490911660c08201524260e0820152610100810161111e6106a1565b9052905090565b3390565b6001600160a01b03831661116e5760405162461bcd60e51b81526004018080602001828103825260248152602001806128586024913960400191505060405180910390fd5b6001600160a01b0382166111b35760405162461bcd60e51b81526004018080602001828103825260228152602001806126fb6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661125a5760405162461bcd60e51b81526004018080602001828103825260258152602001806128336025913960400191505060405180910390fd5b6001600160a01b03821661129f5760405162461bcd60e51b815260040180806020018281038252602381526020018061268f6023913960400191505060405180910390fd5b6112e28160405180606001604052806026815260200161271d602691396001600160a01b038616600090815260208190526040902054919063ffffffff61137116565b6001600160a01b038085166000908152602081905260408082209390935590841681522054611317908263ffffffff611b3b16565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600081848411156114005760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156113c55781810151838201526020016113ad565b50505050905090810190601f1680156113f25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6003546001600160481b038082168452600160481b82048116602085015264ffffffffff600160901b830481166040860152600160b81b9092048116606085015260045461ffff8116608086015262010000810490911660a0850152600160581b90041660c0830152611479611b9c565b60e0830152610ab08282611ff2565b825464ffffffffff8381169116146114e7576040805162461bcd60e51b815260206004820152601f60248201527f464254433a207374616b654964506172616d206e6f7420696e207374616b6500604482015290519081900360640190fd5b915464ffffffffff811683526001600160481b03600160281b820481166020850152600160701b820416604084015261ffff600160b81b820481166060850152600160c81b820481166080850152600160d81b9091041660a09092019190915250565b61155a818260e001516001611f68565b50565b604081015160a080840180519290920390915260e090920151910152565b60008060008085608001518510156115b9576115a68787606001518860800151888a6040015161203a565b60208801518201955090935091506115f6565b604086015160608701516115d091908781016120df565b92508286602001510193506115f3866060015187608001518860a001518761212c565b91505b8115611615578382111561160d5750600092611615565b509182900391805b93509350935093565b8664ffffffffff16336001600160a01b03167f72d9c5a7ab13846e08d9c838f9e866a1bb4a66a2fd3ba3c9e7da3cf9e394dfd760b8876001600160481b0316901b6070896001600160481b0316901b60288b6001600160481b0316901b4264ffffffffff1617171784611692576000611698565b600160581b5b6bffffffffffffffffffffffff1660488761ffff16901b886001600160481b03161717604051808381526020018281526020019250505060405180910390a350505050505050565b6002810480156117085761170873b8cf11b8de281560884b4a23efd69d9aacbf3f4d8261171b565b6060909201805192909103919091019052565b6001600160a01b038216611776576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b600254611789908263ffffffff611b3b16565b6002556001600160a01b0382166000908152602081905260409020546117b5908263ffffffff611b3b16565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b8160200151811115610f40576000611827828460800151612159565b905060008360400151620186a0838501028161183f57fe5b04905064ffffffffff811115611857575064ffffffffff5b8460400151811115611877576040850181905283516118779082906121cc565b5050505050565b81546000190181811461198d5782818154811061189757fe5b906000526020600020018383815481106118ad57fe5b6000918252602090912082549101805464ffffffffff191664ffffffffff9092169190911780825582546001600160481b03600160281b9182900481169091026dffffffffffffffffff000000000019909216919091178083558354600160701b9081900490921690910268ffffffffffffffffff60701b1990911617808255825461ffff600160b81b91829004811690910261ffff60b81b19909216919091178083558354600160c81b9081900483160261ffff60c81b19909116178083559254600160d81b908190049091160261ffff60d81b199092169190911790555b8280548061199757fe5b600082815260209020810160001990810180546001600160e81b0319169055019055505050565b805182511415806119d757508060200151826020015114155b806119ea57508060400151826040015114155b806119fd57508060600151826060015114155b15611a8b5781516003805460208501516040860151606087015168ffffffffffffffffff199093166001600160481b039586161768ffffffffffffffffff60481b1916600160481b928616929092029190911764ffffffffff60901b1916600160901b64ffffffffff90921691909102176001600160b81b0316600160b81b93909116929092029190911790555b80608001518260800151141580611aaa57508060a001518260a0015114155b80611acb57508060c0015164ffffffffff168260c0015164ffffffffff1614155b15610ab05760808201516004805460a085015160c086015164ffffffffff16600160581b0264ffffffffff60581b196001600160481b0390921662010000026affffffffffffffffff00001961ffff90961661ffff19909416939093179490941691909117169190911790555050565b600082820183811015611b95576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b620151804265017af4b5e7ff19010490565b60006001600160a01b038216611bf55760405162461bcd60e51b81526004018080602001828103825260228152602001806127f06022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b6115b3811115611c565760405162461bcd60e51b81526004018080602001828103825260278152602001806126b26027913960400191505060405180910390fd5b6000611c628383612159565b905060008460400151620186a08386010281611c7a57fe5b04905080611cb95760405162461bcd60e51b81526004018080602001828103825260388152602001806127436038913960400191505060405180910390fd5b60e085015160c08601805164ffffffffff60019182011691829052336000908152600660205260409020920191611cf490828886868a612223565b611d008187858861232e565b5050602085018051909101905250508151019052565b6001600160a01b038216611d5b5760405162461bcd60e51b81526004018080602001828103825260218152602001806128126021913960400191505060405180910390fd5b611d9e816040518060600160405280602281526020016126d9602291396001600160a01b038516600090815260208190526040902054919063ffffffff61137116565b6001600160a01b038316600090815260208190526040902055600254611dca908263ffffffff6123ac16565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b604080514264ffffffffff9081166dffffffffffffffffff0000000000602889901b161768ffffffffffffffffff60701b607088901b16176001600160b81b031960b887901b161782526001600160481b038416602083015282513393918916926001600160a01b038b16927fd824970a2cf19cc2b630c87ce5b00f67301cac3ac60513d027c7a39129f93b4692918290030190a4505050505050565b80518254602083015160408401516060850151608086015160a09096015164ffffffffff1990941664ffffffffff909516949094176dffffffffffffffffff00000000001916600160281b6001600160481b03938416021768ffffffffffffffffff60701b1916600160701b92909116919091021761ffff60b81b1916600160b81b61ffff938416021761ffff60c81b1916600160c81b938316939093029290921761ffff60d81b1916600160d81b9190921602179055565b81836080015110611f7857610f40565b611f806125f3565b8351611f8a6106a1565b0181526080840151611f9d8583836123ee565b602085015115611fbd5760208501805160a0870180519091019052600090525b60010183811015611fd857611fd38583836123ee565b611fbd565b611fe785608001518285612452565b608085015250505050565b815181526020808301519082015260408083015190820152606080830151908201526080808301519082015260a0808301519082015260c09182015164ffffffffff16910152565b60008083860160026001870104605a8110156120545750605a5b856120735760006120658a876124c9565b9190910292506120d5915050565b858110156120a657878101612089868a836120df565b935060006120988783866120df565b850195506120d59350505050565b6120b18589846120df565b9350858114156120c3578392506120d2565b85818502816120ce57fe5b0492505b50505b9550959350505050565b6000825b82811015612124576000818152600560205260409020546001600160481b03600160481b82048116911686028161211657fe5b0491909101906001016120e3565b509392505050565b6000848401600e01808411612145576000915050612151565b6102bc90840383020490505b949350505050565b600080600183111561217f57610e3883111561217757610e3861217c565b600183035b90505b600066354a6ba7a1800085111561219d5766354a6ba7a1800061219f565b845b670214e8348c4f0000830261071c82020193509050680ecca2d59581a400008584025b0495945050505050565b8064ffffffffff167f9861fa0ed101659f7a59b4583fcc798dfa4f3b419bea371c8ee2ad0ffe13a31e60288464ffffffffff16901b4264ffffffffff16176040518082815260200191505060405180910390a25050565b6040805160c08101825264ffffffffff96871681526001600160481b03958616602080830191825295871692820192835261ffff9485166060830190815293851660808301908152600060a084018181528b54600181018d559b825297902092519290990180549151935194519951965164ffffffffff1990921692909816919091176dffffffffffffffffff00000000001916600160281b928716929092029190911768ffffffffffffffffff60701b1916600160701b92909516919091029390931761ffff60b81b1916600160b81b958216959095029490941761ffff60c81b1916600160c81b918516919091021761ffff60d81b1916600160d81b9190931602919091179055565b8364ffffffffff16336001600160a01b03167f14872dc760f33532684e68e1b6d5fd3f71ba7b07dee76bdb2b084f28b74233ef60b88461ffff16901b6070866001600160481b0316901b6028886001600160481b0316901b4264ffffffffff161717176040518082815260200191505060405180910390a350505050565b6000611b9583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611371565b6123f88383612516565b6020918201516000918252600590925260409020805460a0909301516001600160481b03908116600160481b0268ffffffffffffffffff60481b199190931668ffffffffffffffffff199094169390931792909216179055565b337fb8d6eb541ded1720cc657b719f57abcb1fe4711cb7ead82751b135f5d94bc94482612480576000612486565b600160481b5b69ffffffffffffffffffff1660388561ffff16901b60288761ffff16901b4264ffffffffff161717176040518082815260200191505060405180910390a2505050565b60006124d361254b565b6124dd8482611ff2565b6124e56125f3565b84516124ef6106a1565b0181526124fc8282612516565b60a08201805185019081905260208201518502816121c257fe5b8051630246acad9061271002046020820152606082015115610ab0576060820180516020830180519091019052600090525050565b604051806101000160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600064ffffffffff168152602001600081525090565b6040518060c00160405280600064ffffffffff16815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518061012001604052806009906020820280388339509192915050565b604051806040016040528060008152602001600081525090565b6126178282611bae565b15612669576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff1916600117905556fe45524332303a207472616e7366657220746f20746865207a65726f2061646472657373465245453a206e65775374616b65644461797320686967686572207468616e206d6178696d756d45524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365465245453a206e65775374616b6564486561727473206d757374206265206174206c65617374206d696e696d756d20736861726552617465464254433a206265666f72654461792063616e6e6f7420626520696e2074686520667574757265465245453a206e65775374616b656444617973206c6f776572207468616e206d696e696d756d45524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365526f6c65733a206163636f756e7420697320746865207a65726f206164647265737345524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa265627a7a72315820ec5bb25716b7bd4a6e835180afd65fbfbee6a2ff787e8440126e8e2dbbab556164736f6c634300050d0032526f6c65733a206163636f756e7420697320746865207a65726f2061646472657373

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101735760003560e01c806352a438b8116100de57806390de687111610097578063a9059cbb11610071578063a9059cbb1461055f578063c31245251461058b578063dd62ed3e146105e7578063f04b5fa01461061557610173565b806390de6871146104e857806395d89b411461052b578063a457c2d71461053357610173565b806352a438b8146103d65780635c9302c9146103a257806365cf71b2146103f95780636a210a0e1461043257806370a08231146104a55780638f1c65c0146104cb57610173565b806333060d901161013057806333060d901461031c578063343009a214610342578063395093511461036e5780633a70a5ca1461039a5780633e6968b6146103a257806340c10f19146103aa57610173565b806306fdde0314610178578063095ea7b3146101f557806318160ddd1461023557806323b872dd1461024f5780632607443b14610285578063313ce567146102fe575b600080fd5b610180610656565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101ba5781810151838201526020016101a2565b50505050905090810190601f1680156101e75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102216004803603604081101561020b57600080fd5b506001600160a01b038135169060200135610684565b604080519115158252519081900360200190f35b61023d6106a1565b60408051918252519081900360200190f35b6102216004803603606081101561026557600080fd5b506001600160a01b038135811691602081013590911690604001356106a7565b6102b16004803603604081101561029b57600080fd5b506001600160a01b038135169060200135610734565b6040805164ffffffffff90971687526001600160481b039586166020880152939094168584015261ffff9182166060860152811660808501529190911660a0830152519081900360c00190f35b6103066107a2565b6040805160ff9092168252519081900360200190f35b61023d6004803603602081101561033257600080fd5b50356001600160a01b03166107a7565b61036c6004803603604081101561035857600080fd5b508035906020013564ffffffffff166107c2565b005b6102216004803603604081101561038457600080fd5b506001600160a01b0381351690602001356109c4565b61023d610a18565b61023d610a35565b61036c600480360360408110156103c057600080fd5b506001600160a01b038135169060200135610a44565b61036c600480360360408110156103ec57600080fd5b5080359060200135610ab4565b61036c6004803603606081101561040f57600080fd5b5080356001600160a01b0316906020810135906040013564ffffffffff16610b3c565b6104556004803603604081101561044857600080fd5b5080359060200135610d91565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610491578181015183820152602001610479565b505050509050019250505060405180910390f35b61023d600480360360208110156104bb57600080fd5b50356001600160a01b0316610e97565b61036c600480360360208110156104e157600080fd5b5035610eb2565b610505600480360360208110156104fe57600080fd5b5035610f45565b604080516001600160481b03938416815291909216602082015281519081900390910190f35b610180610f6b565b6102216004803603604081101561054957600080fd5b506001600160a01b038135169060200135610f8b565b6102216004803603604081101561057557600080fd5b506001600160a01b038135169060200135610ff9565b61059361100d565b604080516001600160481b039889168152968816602088015264ffffffffff95861687820152938716606087015261ffff909216608086015290941660a0840152921660c082015290519081900360e00190f35b61023d600480360360408110156105fd57600080fd5b506001600160a01b0381358116916020013516611060565b61061d61108b565b604051808261012080838360005b8381101561064357818101518382015260200161062b565b5050505090500191505060405180910390f35b60405180604001604052806012815260200171233932b2a134ba31b7b4b739902a37b5b2b760711b81525081565b6000610698610691611125565b8484611129565b50600192915050565b60025490565b60006106b4848484611215565b61072a846106c0611125565b610725856040518060600160405280602881526020016127c8602891396001600160a01b038a166000908152600160205260408120906106fe611125565b6001600160a01b03168152602081019190915260400160002054919063ffffffff61137116565b611129565b5060019392505050565b6006602052816000526040600020818154811061074d57fe5b60009182526020909120015464ffffffffff811692506001600160481b03600160281b820481169250600160701b8204169061ffff600160b81b8204811691600160c81b8104821691600160d81b9091041686565b600881565b6001600160a01b031660009081526006602052604090205490565b6107ca61254b565b6107d261254b565b6107dc8282611408565b3360009081526006602052604090208054610837576040805162461bcd60e51b8152602060048201526016602482015275119491514e88115b5c1d1e481cdd185ad9481b1a5cdd60521b604482015290519081900360640190fd5b80548510610887576040805162461bcd60e51b8152602060048201526018602482015277119491514e881cdd185ad9525b99195e081a5b9d985b1a5960421b604482015290519081900360640190fd5b61088f612597565b6108af82878154811061089e57fe5b906000526020600020018683611488565b6108b88461154a565b60a0810151606082015160e08601516000921515918391829182918291116109315784156108ec5786608001519550610917565b6108f68a8861155d565b86606001518a60e00151039550866080015186111561091757866080015195505b6109228a888861157b565b9296509094509250905061094a565b60408701516020808c0180519290920390915287015193505b6109618b8860200151896040015186868b8b61161e565b801580159061096e575084155b1561097d5761097d8a826116e0565b83156109985761098d338561171b565b6109988a888661180b565b60208701518a51038a526109ac888d61187e565b6109b68a8a6119be565b505050505050505050505050565b60006106986109d1611125565b8461072585600160006109e2611125565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff611b3b16565b6003546000906001600160481b0316610a2f6106a1565b01905090565b6000610a3f611b9c565b905090565b610a5560073363ffffffff611bae16565b610aa6576040805162461bcd60e51b815260206004820152601960248201527f444f45535f4e4f545f484156455f4d494e5445525f524f4c4500000000000000604482015290519081900360640190fd5b610ab0828261171b565b5050565b610abc61254b565b610ac461254b565b610ace8282611408565b6001831015610b0e5760405162461bcd60e51b81526004018080602001828103825260268152602001806127a26026913960400191505060405180910390fd5b610b178261154a565b610b22828585611c15565b610b2c3385611d16565b610b3682826119be565b50505050565b610b4461254b565b610b4c61254b565b610b568282611408565b6001600160a01b038516600090815260066020526040902054610bb9576040805162461bcd60e51b8152602060048201526016602482015275119491514e88115b5c1d1e481cdd185ad9481b1a5cdd60521b604482015290519081900360640190fd5b6001600160a01b0385166000908152600660205260409020548410610c20576040805162461bcd60e51b8152602060048201526018602482015277119491514e881cdd185ad9525b99195e081a5b9d985b1a5960421b604482015290519081900360640190fd5b6001600160a01b0385166000908152600660205260408120805486908110610c4457fe5b906000526020600020019050610c58612597565b610c63828683611488565b80608001518160600151018460e001511015610cc6576040805162461bcd60e51b815260206004820152601c60248201527f465245453a205374616b65206e6f742066756c6c792073657276656400000000604482015290519081900360640190fd5b60a081015115610d1d576040805162461bcd60e51b815260206004820152601c60248201527f465245453a205374616b6520616c726561647920756e6c6f636b656400000000604482015290519081900360640190fd5b610d268461154a565b610d30848261155d565b6000806000610d448785866080015161157b565b93509350935050610d618a89866020015187604001518787611e12565b8015610d7157610d7187826116e0565b610d7b8585611eaf565b610d8587876119be565b50505050505050505050565b60608183108015610da8575060045461ffff168211155b610def576040805162461bcd60e51b815260206004820152601360248201527211909510ce881c985b99d9481a5b9d985b1a59606a1b604482015290519081900360640190fd5b828203604051908082528060200260200182016040528015610e1b578160200160208202803883390190505b509050826000805b5060008281526005602052604090205483516001830192600160481b830460481b71ffffffffffffffffff000000000000000000166001600160481b03909316929092179182918691908110610e7557fe5b602002602001018181525050848360010193508310610e235750505092915050565b6001600160a01b031660009081526020819052604090205490565b610eba61254b565b610ec261254b565b610ecc8282611408565b8215610f26578160e00151831115610f155760405162461bcd60e51b815260040180806020018281038252602781526020018061277b6027913960400191505060405180910390fd5b610f2182846000611f68565b610f36565b610f36828360e001516000611f68565b610f4082826119be565b505050565b6005602052600090815260409020546001600160481b0380821691600160481b90041682565b604051806040016040528060048152602001634642544360e01b81525081565b6000610698610f98611125565b846107258560405180606001604052806025815260200161287c6025913960016000610fc2611125565b6001600160a01b03908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff61137116565b6000610698611006611125565b8484611215565b6003546004546001600160481b0380831692600160481b810482169264ffffffffff600160901b8304811693600160b81b90930483169261ffff83169262010000810490911691600160581b9091041687565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6110936125d4565b60408051610120810182526003546001600160481b038082168352600160481b82048116602084015264ffffffffff600160901b8304811694840194909452600160b81b9091048116606083015260045461ffff8116608084015262010000810490911660a0830152600160581b900490911660c08201524260e0820152610100810161111e6106a1565b9052905090565b3390565b6001600160a01b03831661116e5760405162461bcd60e51b81526004018080602001828103825260248152602001806128586024913960400191505060405180910390fd5b6001600160a01b0382166111b35760405162461bcd60e51b81526004018080602001828103825260228152602001806126fb6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661125a5760405162461bcd60e51b81526004018080602001828103825260258152602001806128336025913960400191505060405180910390fd5b6001600160a01b03821661129f5760405162461bcd60e51b815260040180806020018281038252602381526020018061268f6023913960400191505060405180910390fd5b6112e28160405180606001604052806026815260200161271d602691396001600160a01b038616600090815260208190526040902054919063ffffffff61137116565b6001600160a01b038085166000908152602081905260408082209390935590841681522054611317908263ffffffff611b3b16565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600081848411156114005760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156113c55781810151838201526020016113ad565b50505050905090810190601f1680156113f25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6003546001600160481b038082168452600160481b82048116602085015264ffffffffff600160901b830481166040860152600160b81b9092048116606085015260045461ffff8116608086015262010000810490911660a0850152600160581b90041660c0830152611479611b9c565b60e0830152610ab08282611ff2565b825464ffffffffff8381169116146114e7576040805162461bcd60e51b815260206004820152601f60248201527f464254433a207374616b654964506172616d206e6f7420696e207374616b6500604482015290519081900360640190fd5b915464ffffffffff811683526001600160481b03600160281b820481166020850152600160701b820416604084015261ffff600160b81b820481166060850152600160c81b820481166080850152600160d81b9091041660a09092019190915250565b61155a818260e001516001611f68565b50565b604081015160a080840180519290920390915260e090920151910152565b60008060008085608001518510156115b9576115a68787606001518860800151888a6040015161203a565b60208801518201955090935091506115f6565b604086015160608701516115d091908781016120df565b92508286602001510193506115f3866060015187608001518860a001518761212c565b91505b8115611615578382111561160d5750600092611615565b509182900391805b93509350935093565b8664ffffffffff16336001600160a01b03167f72d9c5a7ab13846e08d9c838f9e866a1bb4a66a2fd3ba3c9e7da3cf9e394dfd760b8876001600160481b0316901b6070896001600160481b0316901b60288b6001600160481b0316901b4264ffffffffff1617171784611692576000611698565b600160581b5b6bffffffffffffffffffffffff1660488761ffff16901b886001600160481b03161717604051808381526020018281526020019250505060405180910390a350505050505050565b6002810480156117085761170873b8cf11b8de281560884b4a23efd69d9aacbf3f4d8261171b565b6060909201805192909103919091019052565b6001600160a01b038216611776576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b600254611789908263ffffffff611b3b16565b6002556001600160a01b0382166000908152602081905260409020546117b5908263ffffffff611b3b16565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b8160200151811115610f40576000611827828460800151612159565b905060008360400151620186a0838501028161183f57fe5b04905064ffffffffff811115611857575064ffffffffff5b8460400151811115611877576040850181905283516118779082906121cc565b5050505050565b81546000190181811461198d5782818154811061189757fe5b906000526020600020018383815481106118ad57fe5b6000918252602090912082549101805464ffffffffff191664ffffffffff9092169190911780825582546001600160481b03600160281b9182900481169091026dffffffffffffffffff000000000019909216919091178083558354600160701b9081900490921690910268ffffffffffffffffff60701b1990911617808255825461ffff600160b81b91829004811690910261ffff60b81b19909216919091178083558354600160c81b9081900483160261ffff60c81b19909116178083559254600160d81b908190049091160261ffff60d81b199092169190911790555b8280548061199757fe5b600082815260209020810160001990810180546001600160e81b0319169055019055505050565b805182511415806119d757508060200151826020015114155b806119ea57508060400151826040015114155b806119fd57508060600151826060015114155b15611a8b5781516003805460208501516040860151606087015168ffffffffffffffffff199093166001600160481b039586161768ffffffffffffffffff60481b1916600160481b928616929092029190911764ffffffffff60901b1916600160901b64ffffffffff90921691909102176001600160b81b0316600160b81b93909116929092029190911790555b80608001518260800151141580611aaa57508060a001518260a0015114155b80611acb57508060c0015164ffffffffff168260c0015164ffffffffff1614155b15610ab05760808201516004805460a085015160c086015164ffffffffff16600160581b0264ffffffffff60581b196001600160481b0390921662010000026affffffffffffffffff00001961ffff90961661ffff19909416939093179490941691909117169190911790555050565b600082820183811015611b95576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b620151804265017af4b5e7ff19010490565b60006001600160a01b038216611bf55760405162461bcd60e51b81526004018080602001828103825260228152602001806127f06022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b6115b3811115611c565760405162461bcd60e51b81526004018080602001828103825260278152602001806126b26027913960400191505060405180910390fd5b6000611c628383612159565b905060008460400151620186a08386010281611c7a57fe5b04905080611cb95760405162461bcd60e51b81526004018080602001828103825260388152602001806127436038913960400191505060405180910390fd5b60e085015160c08601805164ffffffffff60019182011691829052336000908152600660205260409020920191611cf490828886868a612223565b611d008187858861232e565b5050602085018051909101905250508151019052565b6001600160a01b038216611d5b5760405162461bcd60e51b81526004018080602001828103825260218152602001806128126021913960400191505060405180910390fd5b611d9e816040518060600160405280602281526020016126d9602291396001600160a01b038516600090815260208190526040902054919063ffffffff61137116565b6001600160a01b038316600090815260208190526040902055600254611dca908263ffffffff6123ac16565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b604080514264ffffffffff9081166dffffffffffffffffff0000000000602889901b161768ffffffffffffffffff60701b607088901b16176001600160b81b031960b887901b161782526001600160481b038416602083015282513393918916926001600160a01b038b16927fd824970a2cf19cc2b630c87ce5b00f67301cac3ac60513d027c7a39129f93b4692918290030190a4505050505050565b80518254602083015160408401516060850151608086015160a09096015164ffffffffff1990941664ffffffffff909516949094176dffffffffffffffffff00000000001916600160281b6001600160481b03938416021768ffffffffffffffffff60701b1916600160701b92909116919091021761ffff60b81b1916600160b81b61ffff938416021761ffff60c81b1916600160c81b938316939093029290921761ffff60d81b1916600160d81b9190921602179055565b81836080015110611f7857610f40565b611f806125f3565b8351611f8a6106a1565b0181526080840151611f9d8583836123ee565b602085015115611fbd5760208501805160a0870180519091019052600090525b60010183811015611fd857611fd38583836123ee565b611fbd565b611fe785608001518285612452565b608085015250505050565b815181526020808301519082015260408083015190820152606080830151908201526080808301519082015260a0808301519082015260c09182015164ffffffffff16910152565b60008083860160026001870104605a8110156120545750605a5b856120735760006120658a876124c9565b9190910292506120d5915050565b858110156120a657878101612089868a836120df565b935060006120988783866120df565b850195506120d59350505050565b6120b18589846120df565b9350858114156120c3578392506120d2565b85818502816120ce57fe5b0492505b50505b9550959350505050565b6000825b82811015612124576000818152600560205260409020546001600160481b03600160481b82048116911686028161211657fe5b0491909101906001016120e3565b509392505050565b6000848401600e01808411612145576000915050612151565b6102bc90840383020490505b949350505050565b600080600183111561217f57610e3883111561217757610e3861217c565b600183035b90505b600066354a6ba7a1800085111561219d5766354a6ba7a1800061219f565b845b670214e8348c4f0000830261071c82020193509050680ecca2d59581a400008584025b0495945050505050565b8064ffffffffff167f9861fa0ed101659f7a59b4583fcc798dfa4f3b419bea371c8ee2ad0ffe13a31e60288464ffffffffff16901b4264ffffffffff16176040518082815260200191505060405180910390a25050565b6040805160c08101825264ffffffffff96871681526001600160481b03958616602080830191825295871692820192835261ffff9485166060830190815293851660808301908152600060a084018181528b54600181018d559b825297902092519290990180549151935194519951965164ffffffffff1990921692909816919091176dffffffffffffffffff00000000001916600160281b928716929092029190911768ffffffffffffffffff60701b1916600160701b92909516919091029390931761ffff60b81b1916600160b81b958216959095029490941761ffff60c81b1916600160c81b918516919091021761ffff60d81b1916600160d81b9190931602919091179055565b8364ffffffffff16336001600160a01b03167f14872dc760f33532684e68e1b6d5fd3f71ba7b07dee76bdb2b084f28b74233ef60b88461ffff16901b6070866001600160481b0316901b6028886001600160481b0316901b4264ffffffffff161717176040518082815260200191505060405180910390a350505050565b6000611b9583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611371565b6123f88383612516565b6020918201516000918252600590925260409020805460a0909301516001600160481b03908116600160481b0268ffffffffffffffffff60481b199190931668ffffffffffffffffff199094169390931792909216179055565b337fb8d6eb541ded1720cc657b719f57abcb1fe4711cb7ead82751b135f5d94bc94482612480576000612486565b600160481b5b69ffffffffffffffffffff1660388561ffff16901b60288761ffff16901b4264ffffffffff161717176040518082815260200191505060405180910390a2505050565b60006124d361254b565b6124dd8482611ff2565b6124e56125f3565b84516124ef6106a1565b0181526124fc8282612516565b60a08201805185019081905260208201518502816121c257fe5b8051630246acad9061271002046020820152606082015115610ab0576060820180516020830180519091019052600090525050565b604051806101000160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600064ffffffffff168152602001600081525090565b6040518060c00160405280600064ffffffffff16815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518061012001604052806009906020820280388339509192915050565b604051806040016040528060008152602001600081525090565b6126178282611bae565b15612669576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff1916600117905556fe45524332303a207472616e7366657220746f20746865207a65726f2061646472657373465245453a206e65775374616b65644461797320686967686572207468616e206d6178696d756d45524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365465245453a206e65775374616b6564486561727473206d757374206265206174206c65617374206d696e696d756d20736861726552617465464254433a206265666f72654461792063616e6e6f7420626520696e2074686520667574757265465245453a206e65775374616b656444617973206c6f776572207468616e206d696e696d756d45524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365526f6c65733a206163636f756e7420697320746865207a65726f206164647265737345524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa265627a7a72315820ec5bb25716b7bd4a6e835180afd65fbfbee6a2ff787e8440126e8e2dbbab556164736f6c634300050d0032

Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.