ETH Price: $3,344.18 (-8.06%)

Contract

0x488933457E89656D7eF7E69C10F2f80C7acA19b5
 
Transaction Hash
Method
Block
From
To
Reward Claim214209022024-12-17 7:56:113 days ago1734422171IN
0x48893345...C7acA19b5
0 ETH0.000746088.46050478
Withdraw214208962024-12-17 7:54:593 days ago1734422099IN
0x48893345...C7acA19b5
0 ETH0.000830458.41452718
Withdraw210915312024-11-01 8:14:2349 days ago1730448863IN
0x48893345...C7acA19b5
0 ETH0.000657387.1
Withdraw205216572024-08-13 19:00:47128 days ago1723575647IN
0x48893345...C7acA19b5
0 ETH0.000311293.19680464
Withdraw204618722024-08-05 10:49:23137 days ago1722854963IN
0x48893345...C7acA19b5
0 ETH0.0027005327.73245622
Reward Claim204618642024-08-05 10:47:47137 days ago1722854867IN
0x48893345...C7acA19b5
0 ETH0.00289730.97573099
Withdraw199491822024-05-25 20:09:11208 days ago1716667751IN
0x48893345...C7acA19b5
0 ETH0.000371534.92238696
Reward Claim199490902024-05-25 19:50:47208 days ago1716666647IN
0x48893345...C7acA19b5
0 ETH0.000465844.98095352
Withdraw197611202024-04-29 12:58:11235 days ago1714395491IN
0x48893345...C7acA19b5
0 ETH0.0010028910.83018776
Deposit195251302024-03-27 10:40:23268 days ago1711536023IN
0x48893345...C7acA19b5
0 ETH0.0025712523.60487386
Reward Claim192808332024-02-22 4:38:47302 days ago1708576727IN
0x48893345...C7acA19b5
0 ETH0.0030758334.87935705
Withdraw192808312024-02-22 4:38:23302 days ago1708576703IN
0x48893345...C7acA19b5
0 ETH0.0026170734.66783109
Withdraw192808222024-02-22 4:36:35302 days ago1708576595IN
0x48893345...C7acA19b5
0 ETH0.0036412435.19576086
Withdraw191315142024-02-01 5:30:23323 days ago1706765423IN
0x48893345...C7acA19b5
0 ETH0.0011959215.84462831
Reward Claim188464402023-12-23 5:29:35363 days ago1703309375IN
0x48893345...C7acA19b5
0 ETH0.0018841620.66266201
Reward Claim184195492023-10-24 10:33:23423 days ago1698143603IN
0x48893345...C7acA19b5
0 ETH0.0018664421.1651047
Withdraw184195462023-10-24 10:32:47423 days ago1698143567IN
0x48893345...C7acA19b5
0 ETH0.0023648120.42699242
Reward Claim184110942023-10-23 6:08:35424 days ago1698041315IN
0x48893345...C7acA19b5
0 ETH0.000705197.99673801
Withdraw184110912023-10-23 6:07:59424 days ago1698041279IN
0x48893345...C7acA19b5
0 ETH0.000836498.47677108
Reward Claim181366962023-09-14 19:51:23462 days ago1694721083IN
0x48893345...C7acA19b5
0 ETH0.002058422.5734012
Reward Claim179255372023-08-16 6:14:47492 days ago1692166487IN
0x48893345...C7acA19b5
0 ETH0.0018527421.00969669
Withdraw179255352023-08-16 6:14:23492 days ago1692166463IN
0x48893345...C7acA19b5
0 ETH0.0020370120.64742282
Reward Claim179253482023-08-16 5:36:35492 days ago1692164195IN
0x48893345...C7acA19b5
0 ETH0.0013199618.56878807
Withdraw179253462023-08-16 5:36:11492 days ago1692164171IN
0x48893345...C7acA19b5
0 ETH0.0021349718.44165887
Withdraw179248782023-08-16 4:02:11492 days ago1692158531IN
0x48893345...C7acA19b5
0 ETH0.0014982519.85657039
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
BFCModel

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, BSD-3-Clause license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-01-22
*/

// File: contracts/module/safeMath.sol

// SPDX-License-Identifier: BSD-3-Clause
pragma solidity 0.6.12;

// from: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/SafeMath.sol
// Subject to the MIT license.

/**
 * @title BiFi's safe-math Contract
 * @author BiFi(seinmyung25, Miller-kk, tlatkdgus1, dongchangYoo)
 */
contract safeMathModule {
    uint256 constant one = 1 ether;

    function expDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        return safeDiv( safeMul(a, one), b);
    }
    function expMul(uint256 a, uint256 b) internal pure returns (uint256) {
        return safeDiv( safeMul(a, b), one);
    }
    function safeAdd(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addtion overflow");
        return c;
    }
    function safeSub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(a >= b, "SafeMath: subtraction overflow");
        return a - b;
    }
    function safeMul(uint256 a, uint256 b) internal pure returns (uint256) {
        if(a == 0) { return 0;}
        uint256 c = a * b;
        require( (c/a) == b, "SafeMath: multiplication overflow");
        return c;
    }
    function safeDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return (a/b);
    }
}

// File: contracts/ERC20.sol

/**
 * @title BiFi's ERC20 Mockup Contract
 * @author BiFi(seinmyung25, Miller-kk, tlatkdgus1, dongchangYoo)
 */
contract ERC20 {
    string symbol;
    string name;
    uint8 decimals = 18;
    uint256 totalSupply = 1000 * 1e9 * 1e18; // token amount: 1000 Bilions

    // Owner of this contract
    address public owner;

    // Balances for each account
    mapping(address => uint256) balances;

    // Owner of account approves the transfer of an amount to another account
    mapping(address => mapping (address => uint256)) allowed;

    // Functions with this modifier can only be executed by the owner
    modifier onlyOwner() {
        require(msg.sender == owner, "only owner");
        _;
    }

    event Transfer(address, address, uint256);
    event Approval(address, address, uint256);

    // Constructor
    constructor (string memory _name, string memory _symbol) public {

        owner = msg.sender;

        name = _name;
        symbol = _symbol;
        balances[msg.sender] = totalSupply;
    }

    // What is the balance of a particular account?
    function balanceOf(address _owner) public view returns (uint256 balance) {
        return balances[_owner];
    }

    // Transfer the balance from owner's account to another account
    function transfer(address _to, uint256 _amount) public returns (bool success) {

        require(balances[msg.sender] >= _amount, "insuficient sender's balance");
        require(_amount > 0, "requested amount must be positive");
        require(balances[_to] + _amount > balances[_to], "receiver's balance overflows");

        balances[msg.sender] -= _amount;
        balances[_to] += _amount;
        emit Transfer(msg.sender, _to, _amount);
        return true;
    }

    // Send _value amount of tokens from address _from to address _to
    // The transferFrom method is used for a withdraw workflow, allowing contracts to send
    // tokens on your behalf, for example to "deposit" to a contract address and/or to charge
    // fees in sub-currencies; the command should fail unless the _from account has
    // deliberately authorized the sender of the message via some mechanism; we propose
    // these standardized APIs for approval:
    function transferFrom(address _from, address _to,uint256 _amount) public returns (bool success) {

        require(balances[_from] >= _amount, "insuficient sender's balance");
        require(allowed[_from][msg.sender] >= _amount, "not allowed transfer");
        require(_amount > 0, "requested amount must be positive");
        require(balances[_to] + _amount > balances[_to], "receiver's balance overflows");

        balances[_from] -= _amount;
        allowed[_from][msg.sender] -= _amount;
        balances[_to] += _amount;
        emit Transfer(_from, _to, _amount);

        return true;
    }

    // Allow _spender to withdraw from your account, multiple times, up to the _value amount.
    // If this function is called again it overwrites the current allowance with _value.
    function approve(address _spender, uint256 _amount) public returns (bool success) {
        allowed[msg.sender][_spender] = _amount;
        emit Approval(msg.sender, _spender, _amount);
        return true;
    }

    function allowance(address _owner, address _spender) public view returns (uint256 remaining) {
        return allowed[_owner][_spender];
    }
}

contract BFCtoken is ERC20 {
    constructor() public ERC20 ("Bifrost", "BFC") {}
}

contract LPtoken is ERC20 {
    constructor() public ERC20 ("BFC-ETH", "LP") {}
}

contract BiFitoken is ERC20 {
    constructor() public ERC20 ("BiFi", "BiFi") {}
}

// File: contracts/module/storageModule.sol


/**
 * @title BiFi's Reward Distribution Storage Contract
 * @notice Define the basic Contract State
 * @author BiFi(seinmyung25, Miller-kk, tlatkdgus1, dongchangYoo)
 */
contract storageModule {
    address public owner;

    bool public claimLock;
    bool public withdrawLock;

    uint256 public rewardPerBlock;
    uint256 public decrementUnitPerBlock;
    uint256 public rewardLane;

    uint256 public lastBlockNum;
    uint256 public totalDeposited;

    ERC20 public lpErc; ERC20 public rewardErc;

    mapping(address => Account) public accounts;

    uint256 public passedPoint;
    RewardVelocityPoint[] public registeredPoints;

    struct Account {
        uint256 deposited;
        uint256 pointOnLane;
        uint256 rewardAmount;
    }

    struct RewardVelocityPoint {
        uint256 blockNumber;
        uint256 rewardPerBlock;
        uint256 decrementUnitPerBlock;
    }

    struct UpdateRewardLaneModel {
        uint256 len; uint256 tmpBlockDelta;

        uint256 memPassedPoint; uint256 tmpPassedPoint;

        uint256 memThisBlockNum;
        uint256 memLastBlockNum; uint256 tmpLastBlockNum;

        uint256 memTotalDeposit;

        uint256 memRewardLane; uint256 tmpRewardLane;
        uint256 memRewardPerBlock; uint256 tmpRewardPerBlock;

        uint256 memDecrementUnitPerBlock; uint256 tmpDecrementUnitPerBlock;
    }
}

// File: contracts/module/eventModule.sol

/**
 * @title BiFi's Reward Distribution Event Contract
 * @notice Define the service Events
 * @author BiFi(seinmyung25, Miller-kk, tlatkdgus1, dongchangYoo)
 */
contract eventModule {
    /// @dev Events for user actions
    event Deposit(address userAddr, uint256 amount, uint256 userDeposit, uint256 totalDeposit);
    event Withdraw(address userAddr, uint256 amount, uint256 userDeposit, uint256 totalDeposit);
    event Claim(address userAddr, uint256 amount);
    event UpdateRewardParams(uint256 atBlockNumber, uint256 rewardPerBlock, uint256 decrementUnitPerBlock);

    /// @dev Events for admin actions below

    /// @dev Contracts Access Control
    event ClaimLock(bool lock);
    event WithdrawLock(bool lock);
    event OwnershipTransfer(address from, address to);

    /// @dev Distribution Model Parameter editer
    event SetRewardParams(uint256 rewardPerBlock, uint256 decrementUnitPerBlock);
    event RegisterRewardParams(uint256 atBlockNumber, uint256 rewardPerBlock, uint256 decrementUnitPerBlock);
    event DeleteRegisterRewardParams(uint256 index, uint256 atBlockNumber, uint256 rewardPerBlock, uint256 decrementUnitPerBlock, uint256 arrayLen);
}

// File: contracts/module/internalModule.sol




/**
 * @title BiFi's Reward Distribution Internal Contract
 * @notice Implement the basic functions for staking and reward distribution
 * @dev All functions are internal.
 * @author BiFi(seinmyung25, Miller-kk, tlatkdgus1, dongchangYoo)
 */
contract internalModule is storageModule, eventModule, safeMathModule {
    /**
     * @notice Deposit the Contribution Tokens
     * @param userAddr The user address of the Contribution Tokens
     * @param amount The amount of the Contribution Tokens
     */
    function _deposit(address userAddr, uint256 amount) internal {
        Account memory user = accounts[userAddr];
        uint256 totalDeposit = totalDeposited;

        user.deposited = safeAdd(user.deposited, amount);
        accounts[userAddr].deposited = user.deposited;
        totalDeposit = safeAdd(totalDeposited, amount);
        totalDeposited = totalDeposit;

        if(amount > 0) {
            /// @dev transfer the Contribution Toknes to this contract.
            emit Deposit(userAddr, amount, user.deposited, totalDeposit);
            require( lpErc.transferFrom(msg.sender, address(this), amount), "token error" );
        }
    }

    /**
     * @notice Withdraw the Contribution Tokens
     * @param userAddr The user address of the Contribution Tokens
     * @param amount The amount of the Contribution Tokens
     */
    function _withdraw(address userAddr, uint256 amount) internal {
        Account memory user = accounts[userAddr];
        uint256 totalDeposit = totalDeposited;
        require(user.deposited >= amount, "not enough user Deposit");

        user.deposited = safeSub(user.deposited, amount);
        accounts[userAddr].deposited = user.deposited;
        totalDeposit = safeSub(totalDeposited, amount);
        totalDeposited = totalDeposit;

        if(amount > 0) {
            /// @dev transfer the Contribution Tokens from this contact.
            emit Withdraw(userAddr, amount, user.deposited, totalDeposit);
            require( lpErc.transfer(userAddr, amount), "token error" );
        }
    }

    /**
     * @notice Calculate current reward
     * @dev This function is called whenever the balance of the Contribution
       Tokens of the user.
     * @param userAddr The user address of the Contribution and Reward Tokens
     */
    function _redeemAll(address userAddr) internal {
        Account memory user = accounts[userAddr];

        uint256 newRewardLane = _updateRewardLane();

        uint256 distance = safeSub(newRewardLane, user.pointOnLane);
        uint256 rewardAmount = expMul(user.deposited, distance);

        if(user.pointOnLane != newRewardLane) accounts[userAddr].pointOnLane = newRewardLane;
        if(rewardAmount != 0) accounts[userAddr].rewardAmount = safeAdd(user.rewardAmount, rewardAmount);
    }

    /**
     * @notice Claim the Reward Tokens
     * @dev Transfer all reward the user has earned at once.
     * @param userAddr The user address of the Reward Tokens
     */
    function _rewardClaim(address userAddr) internal {
        Account memory user = accounts[userAddr];

        if(user.rewardAmount != 0) {
            uint256 amount = user.rewardAmount;
            accounts[userAddr].rewardAmount = 0;

            /// @dev transfer the Reward Tokens from this contract.
            emit Claim(userAddr, amount);
            require(rewardErc.transfer(userAddr, amount), "token error" );
        }
    }

    /**
     * @notice Update the reward lane value upto ths currnet moment (block)
     * @dev This function should care the "reward velocity points," at which the
       parameters of reward distribution are changed.
     * @return The current (calculated) reward lane value
     */
    function _updateRewardLane() internal returns (uint256) {
        /// @dev Set up memory variables used for calculation temporarily.
        UpdateRewardLaneModel memory vars;

        vars.len = registeredPoints.length;
        vars.memTotalDeposit = totalDeposited;

        vars.tmpPassedPoint = vars.memPassedPoint = passedPoint;

        vars.memThisBlockNum = block.number;
        vars.tmpLastBlockNum = vars.memLastBlockNum = lastBlockNum;

        vars.tmpRewardLane = vars.memRewardLane = rewardLane;
        vars.tmpRewardPerBlock = vars.memRewardPerBlock = rewardPerBlock;
        vars.tmpDecrementUnitPerBlock = vars.memDecrementUnitPerBlock = decrementUnitPerBlock;

        for(uint256 i=vars.memPassedPoint; i<vars.len; i++) {
            RewardVelocityPoint memory point = registeredPoints[i];

            /**
             * @dev Check whether this reward velocity point is valid and has
               not applied yet.
             */
            if(vars.tmpLastBlockNum < point.blockNumber && point.blockNumber <= vars.memThisBlockNum) {
                vars.tmpPassedPoint = i+1;
                /// @dev Update the reward lane with the tmp variables
                vars.tmpBlockDelta = safeSub(point.blockNumber, vars.tmpLastBlockNum);
                (vars.tmpRewardLane, vars.tmpRewardPerBlock) =
                _calcNewRewardLane(
                    vars.tmpRewardLane,
                    vars.memTotalDeposit,
                    vars.tmpRewardPerBlock,
                    vars.tmpDecrementUnitPerBlock,
                    vars.tmpBlockDelta);

                /// @dev Update the tmp variables with this reward velocity point.
                vars.tmpLastBlockNum = point.blockNumber;
                vars.tmpRewardPerBlock = point.rewardPerBlock;
                vars.tmpDecrementUnitPerBlock = point.decrementUnitPerBlock;
                /**
                 * @dev Notify the update of the parameters (by passing the
                   reward velocity points)
                 */
                emit UpdateRewardParams(point.blockNumber, point.rewardPerBlock, point.decrementUnitPerBlock);
            } else {
                /// @dev sorted array, exit eariler without accessing future points.
                break;
            }
        }

        /**
         * @dev Update the reward lane for the remained period between the
           latest velocity point and this moment (block)
         */
        if( vars.tmpLastBlockNum < vars.memThisBlockNum ) {
            vars.tmpBlockDelta = safeSub(vars.memThisBlockNum, vars.tmpLastBlockNum);
            vars.tmpLastBlockNum = vars.memThisBlockNum;
            (vars.tmpRewardLane, vars.tmpRewardPerBlock) =
            _calcNewRewardLane(
                vars.tmpRewardLane,
                vars.memTotalDeposit,
                vars.tmpRewardPerBlock,
                vars.tmpDecrementUnitPerBlock,
                vars.tmpBlockDelta);
        }

        /**
         * @dev Update the reward lane parameters with the tmp variables.
         */
        if(vars.memLastBlockNum != vars.tmpLastBlockNum) lastBlockNum = vars.tmpLastBlockNum;
        if(vars.memPassedPoint != vars.tmpPassedPoint) passedPoint = vars.tmpPassedPoint;
        if(vars.memRewardLane != vars.tmpRewardLane) rewardLane = vars.tmpRewardLane;
        if(vars.memRewardPerBlock != vars.tmpRewardPerBlock) rewardPerBlock = vars.tmpRewardPerBlock;
        if(vars.memDecrementUnitPerBlock != vars.tmpDecrementUnitPerBlock) decrementUnitPerBlock = vars.tmpDecrementUnitPerBlock;

        return vars.tmpRewardLane;
    }

    /**
     * @notice Calculate a new reward lane value with the given parameters
     * @param _rewardLane The previous reward lane value
     * @param _totalDeposit Thte total deposit amount of the Contribution Tokens
     * @param _rewardPerBlock The reward token amount per a block
     * @param _decrementUnitPerBlock The decerement amount of the reward token per a block
     */
    function _calcNewRewardLane(
        uint256 _rewardLane,
        uint256 _totalDeposit,
        uint256 _rewardPerBlock,
        uint256 _decrementUnitPerBlock,
        uint256 delta) internal pure returns (uint256, uint256) {
            uint256 executableDelta;
            if(_decrementUnitPerBlock != 0) {
                executableDelta = safeDiv(_rewardPerBlock, _decrementUnitPerBlock);
                if(delta > executableDelta) delta = executableDelta;
                else executableDelta = 0;
            }

            uint256 distance;
            if(_totalDeposit != 0) {
                distance = expMul( _sequencePartialSumAverage(_rewardPerBlock, delta, _decrementUnitPerBlock), safeMul( expDiv(one, _totalDeposit), delta) );
                _rewardLane = safeAdd(_rewardLane, distance);
            }

            if(executableDelta != 0) _rewardPerBlock = 0;
            else _rewardPerBlock = _getNewRewardPerBlock(_rewardPerBlock, _decrementUnitPerBlock, delta);

            return (_rewardLane, _rewardPerBlock);
    }

    /**
     * @notice Register a new reward velocity point
     * @dev We assume that reward velocity points are stored in order of block
       number. Namely, registerPoints is always a sorted array.
     * @param _blockNumber The block number for the point.
     * @param _rewardPerBlock The reward token amount per a block
     * @param _decrementUnitPerBlock The decerement amount of the reward token per a block
     */
    function _registerRewardVelocity(uint256 _blockNumber, uint256 _rewardPerBlock, uint256 _decrementUnitPerBlock) internal {
        RewardVelocityPoint memory varPoint = RewardVelocityPoint(_blockNumber, _rewardPerBlock, _decrementUnitPerBlock);
        emit RegisterRewardParams(_blockNumber, _rewardPerBlock, _decrementUnitPerBlock);
        registeredPoints.push(varPoint);
    }

    /**
     * @notice Delete a existing reward velocity point
     * @dev We assume that reward velocity points are stored in order of block
       number. Namely, registerPoints is always a sorted array.
     * @param _index The index number of deleting point in state array.
     */
    function _deleteRegisteredRewardVelocity(uint256 _index) internal {
        uint256 len = registeredPoints.length;
        require(len != 0 && _index < len, "error: no elements in registeredPoints");

        RewardVelocityPoint memory point = registeredPoints[_index];
        emit DeleteRegisterRewardParams(_index, point.blockNumber, point.rewardPerBlock, point.decrementUnitPerBlock, len-1);
        for(uint256 i=_index; i<len-1; i++) {
            registeredPoints[i] = registeredPoints[i+1];
        }
        registeredPoints.pop();
     }

    /**
     * @notice Set paramaters for the reward distribution
     * @param _rewardPerBlock The reward token amount per a block
     * @param _decrementUnitPerBlock The decerement amount of the reward token per a block
     */
    function _setParams(uint256 _rewardPerBlock, uint256 _decrementUnitPerBlock) internal {
        emit SetRewardParams(_rewardPerBlock, _decrementUnitPerBlock);
        rewardPerBlock = _rewardPerBlock;
        decrementUnitPerBlock = _decrementUnitPerBlock;
    }

    /**
     * @return the avaerage of the RewardLance of the inactive (i.e., no-action)
       periods.
    */
    function _sequencePartialSumAverage(uint256 a, uint256 n, uint256 d) internal pure returns (uint256) {
        /**
        @dev return Sn / n,
                where Sn = ( (n{2*a + (n-1)d}) / 2 )
            == ( (2na + (n-1)d) / 2 ) / n
            caveat: use safeSub() to avoid the case that d is negative
        */
        if (n > 0)
            return safeDiv(safeSub( safeMul(2,a), safeMul( safeSub(n,1), d) ), 2);
        else
            return 0;
    }

    function _getNewRewardPerBlock(uint256 before, uint256 dec, uint256 delta) internal pure returns (uint256) {
        return safeSub(before, safeMul(dec, delta));
    }

    function _setClaimLock(bool lock) internal {
        emit ClaimLock(lock);
        claimLock = lock;
    }

    function _setWithdrawLock(bool lock) internal {
        emit WithdrawLock(lock);
        withdrawLock = lock;
    }

    function _ownershipTransfer(address to) internal {
        emit OwnershipTransfer(msg.sender, to);
        owner = to;
    }
}

// File: contracts/module/viewModule.sol


/**
 * @title BiFi's Reward Distribution View Contract
 * @notice Implements the view functions for support front-end
 * @author BiFi(seinmyung25, Miller-kk, tlatkdgus1, dongchangYoo)
 */
contract viewModule is internalModule {
    function marketInformation(uint256 _fromBlockNumber, uint256 _toBlockNumber) external view returns (
        uint256 rewardStartBlockNumber,
        uint256 distributedAmount,
        uint256 totalDeposit,
        uint256 poolRate
        )
    {
        if(rewardPerBlock == 0) rewardStartBlockNumber = registeredPoints[0].blockNumber;
        else rewardStartBlockNumber = registeredPoints[0].blockNumber;

        distributedAmount = _redeemAllView(address(0));

        totalDeposit = totalDeposited;

        poolRate = getPoolRate(address(0), _fromBlockNumber, _toBlockNumber);

        return (
            rewardStartBlockNumber,
            distributedAmount,
            totalDeposit,
            poolRate
        );
    }

    function userInformation(address userAddr, uint256 _fromBlockNumber, uint256 _toBlockNumber) external view returns (
        uint256 stakedTokenAmount,
        uint256 rewardStartBlockNumber,
        uint256 claimStartBlockNumber,
        uint256 earnedTokenAmount,
        uint256 poolRate
        )
    {
        Account memory user = accounts[userAddr];

        stakedTokenAmount = user.deposited;

        if(rewardPerBlock == 0) rewardStartBlockNumber = registeredPoints[0].blockNumber;
        else rewardStartBlockNumber = registeredPoints[0].blockNumber;

        earnedTokenAmount = _redeemAllView(userAddr);

        poolRate = getPoolRate(userAddr, _fromBlockNumber, _toBlockNumber);

        return (stakedTokenAmount, rewardStartBlockNumber, claimStartBlockNumber, earnedTokenAmount, poolRate);
    }

    function modelInfo() external view returns (uint256, uint256, uint256, uint256, uint256) {
        return (rewardPerBlock, decrementUnitPerBlock, rewardLane, lastBlockNum, totalDeposited);
    }

    function getParams() external view returns (uint256, uint256, uint256, uint256) {
        return (rewardPerBlock, rewardLane, lastBlockNum, totalDeposited);
    }

    function getRegisteredPointLength() external view returns (uint256) {
        return registeredPoints.length;
    }

    function getRegisteredPoint(uint256 index) external view returns (uint256, uint256, uint256) {
        RewardVelocityPoint memory point = registeredPoints[index];
        return (point.blockNumber, point.rewardPerBlock, point.decrementUnitPerBlock);
    }

    function userInfo(address userAddr) external view returns (uint256, uint256, uint256) {
        Account memory user = accounts[userAddr];
        uint256 earnedRewardAmount = _redeemAllView(userAddr);

        return (user.deposited, user.pointOnLane, earnedRewardAmount);
    }

    function distributionInfo() external view returns (uint256, uint256, uint256) {
        uint256 totalDistributedRewardAmount_now = _distributedRewardAmountView();
        return (rewardPerBlock, decrementUnitPerBlock, totalDistributedRewardAmount_now);
    }

    function _distributedRewardAmountView() internal view returns (uint256) {
        return _redeemAllView( address(0) );
    }

    function _redeemAllView(address userAddr) internal view returns (uint256) {
        Account memory user;
        uint256 newRewardLane;
        if( userAddr != address(0) ) {
            user = accounts[userAddr];
            newRewardLane = _updateRewardLaneView(lastBlockNum);
        } else {
            user = Account(totalDeposited, 0, 0);
            newRewardLane = _updateRewardLaneView(0);
        }

        uint256 distance = safeSub(newRewardLane, user.pointOnLane);
        uint256 rewardAmount = expMul(user.deposited, distance);

        return safeAdd(user.rewardAmount, rewardAmount);
    }

    function _updateRewardLaneView(uint256 fromBlockNumber) internal view returns (uint256) {
        /// @dev Set up memory variables used for calculation temporarily.
        UpdateRewardLaneModel memory vars;

        vars.len = registeredPoints.length;
        vars.memTotalDeposit = totalDeposited;

        if(fromBlockNumber == 0){
            vars.tmpPassedPoint = vars.memPassedPoint = 0;

            vars.memThisBlockNum = block.number;
            vars.tmpLastBlockNum = vars.memLastBlockNum = 0;
            vars.tmpRewardLane = vars.memRewardLane = 0;
            vars.tmpRewardPerBlock = vars.memRewardPerBlock = 0;
            vars.tmpDecrementUnitPerBlock = vars.memDecrementUnitPerBlock = 0;
        } else {
            vars.tmpPassedPoint = vars.memPassedPoint = passedPoint;
            vars.memThisBlockNum = block.number;
            vars.tmpLastBlockNum = vars.memLastBlockNum = fromBlockNumber;

            vars.tmpRewardLane = vars.memRewardLane = rewardLane;
            vars.tmpRewardPerBlock = vars.memRewardPerBlock = rewardPerBlock;
            vars.tmpDecrementUnitPerBlock = vars.memDecrementUnitPerBlock = decrementUnitPerBlock;
        }

        for(uint256 i=vars.memPassedPoint; i<vars.len; i++) {
            RewardVelocityPoint memory point = registeredPoints[i];
            /**
             * @dev Check whether this reward velocity point is valid and has
               not applied yet.
             */
            if(vars.tmpLastBlockNum < point.blockNumber && point.blockNumber <= vars.memThisBlockNum) {
                vars.tmpPassedPoint = i+1;
                /// @dev Update the reward lane with the tmp variables
                vars.tmpBlockDelta = safeSub(point.blockNumber, vars.tmpLastBlockNum);
                (vars.tmpRewardLane, vars.tmpRewardPerBlock) =
                _calcNewRewardLane(
                    vars.tmpRewardLane,
                    vars.memTotalDeposit,
                    vars.tmpRewardPerBlock,
                    vars.tmpDecrementUnitPerBlock,
                    vars.tmpBlockDelta);

                /// @dev Update the tmp variables with this reward velocity point.
                vars.tmpLastBlockNum = point.blockNumber;
                vars.tmpRewardPerBlock = point.rewardPerBlock;
                vars.tmpDecrementUnitPerBlock = point.decrementUnitPerBlock;
                /**
                 * @dev Notify the update of the parameters (by passing the
                   reward velocity points)
                 */
            } else {
                /// @dev sorted array, exit eariler without accessing future points.
                break;
            }
        }

        /**
         * @dev Update the reward lane for the remained period between the
           latest velocity point and this moment (block)
         */
        if(vars.memThisBlockNum > vars.tmpLastBlockNum) {
            vars.tmpBlockDelta = safeSub(vars.memThisBlockNum, vars.tmpLastBlockNum);
            vars.tmpLastBlockNum = vars.memThisBlockNum;
            (vars.tmpRewardLane, vars.tmpRewardPerBlock) =
            _calcNewRewardLane(
                vars.tmpRewardLane,
                vars.memTotalDeposit,
                vars.tmpRewardPerBlock,
                vars.tmpDecrementUnitPerBlock,
                vars.tmpBlockDelta);
        }
        return vars.tmpRewardLane;
    }
    /**
     * @notice Get The rewardPerBlock of user in suggested period(see params)
     * @param userAddr The Address of user, 0 for total
     * @param fromBlockNumber calculation start block number
     * @param toBlockNumber calculation end block number
     * @notice this function calculate based on current contract state
     */
    function getPoolRate(address userAddr, uint256 fromBlockNumber, uint256 toBlockNumber) internal view returns (uint256) {
        UpdateRewardLaneModel memory vars;

        vars.len = registeredPoints.length;
        vars.memTotalDeposit = totalDeposited;

        vars.tmpLastBlockNum = vars.memLastBlockNum = fromBlockNumber;
        (vars.memPassedPoint, vars.memRewardPerBlock, vars.memDecrementUnitPerBlock) = getParamsByBlockNumber(fromBlockNumber);
        vars.tmpPassedPoint = vars.memPassedPoint;
        vars.tmpRewardPerBlock = vars.memRewardPerBlock;
        vars.tmpDecrementUnitPerBlock = vars.memDecrementUnitPerBlock;

        vars.memThisBlockNum = toBlockNumber;
        vars.tmpRewardLane = vars.memRewardLane = 0;

        for(uint256 i=vars.memPassedPoint; i<vars.len; i++) {
            RewardVelocityPoint memory point = registeredPoints[i];

            if(vars.tmpLastBlockNum < point.blockNumber && point.blockNumber <= vars.memThisBlockNum) {
                vars.tmpPassedPoint = i+1;
                vars.tmpBlockDelta = safeSub(point.blockNumber, vars.tmpLastBlockNum);
                (vars.tmpRewardLane, vars.tmpRewardPerBlock) =
                _calcNewRewardLane(
                    vars.tmpRewardLane,
                    vars.memTotalDeposit,
                    vars.tmpRewardPerBlock,
                    vars.tmpDecrementUnitPerBlock,
                    vars.tmpBlockDelta);

                vars.tmpLastBlockNum = point.blockNumber;
                vars.tmpRewardPerBlock = point.rewardPerBlock;
                vars.tmpDecrementUnitPerBlock = point.decrementUnitPerBlock;

            } else {
                break;
            }
        }

        if(vars.memThisBlockNum > vars.tmpLastBlockNum) {
            vars.tmpBlockDelta = safeSub(vars.memThisBlockNum, vars.tmpLastBlockNum);
            vars.tmpLastBlockNum = vars.memThisBlockNum;
            (vars.tmpRewardLane, vars.tmpRewardPerBlock) =
            _calcNewRewardLane(
                vars.tmpRewardLane,
                vars.memTotalDeposit,
                vars.tmpRewardPerBlock,
                vars.tmpDecrementUnitPerBlock,
                vars.tmpBlockDelta);
        }

        Account memory user;
        if( userAddr != address(0) ) user = accounts[userAddr];
        else user = Account(vars.memTotalDeposit, 0, 0);

        return safeDiv(expMul(user.deposited, vars.tmpRewardLane), safeSub(toBlockNumber, fromBlockNumber));
    }

    function getParamsByBlockNumber(uint256 _blockNumber) internal view returns (uint256, uint256, uint256) {
        uint256 _rewardPerBlock; uint256 _decrement;
        uint256 i;

        uint256 tmpthisPoint;

        uint256 pointLength = registeredPoints.length;
        if( pointLength > 0 ) {
            for(i = 0; i < pointLength; i++) {
                RewardVelocityPoint memory point = registeredPoints[i];
                if(_blockNumber >= point.blockNumber && 0 != point.blockNumber) {
                    tmpthisPoint = i;
                    _rewardPerBlock = point.rewardPerBlock;
                    _decrement = point.decrementUnitPerBlock;
                } else if( 0 == point.blockNumber ) continue;
                else break;
            }
        }
        RewardVelocityPoint memory point = registeredPoints[tmpthisPoint];
        _rewardPerBlock = point.rewardPerBlock;
        _decrement = point.decrementUnitPerBlock;
        if(_blockNumber > point.blockNumber) {
            _rewardPerBlock = safeSub(_rewardPerBlock, safeMul(_decrement, safeSub(_blockNumber, point.blockNumber) ) );
        }
        return (i, _rewardPerBlock, _decrement);
    }

    function getUserPoolRate(address userAddr, uint256 fromBlockNumber, uint256 toBlockNumber) external view returns (uint256) {
        return getPoolRate(userAddr, fromBlockNumber, toBlockNumber);
    }

    function getModelPoolRate(uint256 fromBlockNumber, uint256 toBlockNumber) external view returns (uint256) {
        return getPoolRate(address(0), fromBlockNumber, toBlockNumber);
    }
}

// File: contracts/module/externalModule.sol


/**
 * @title BiFi's Reward Distribution External Contract
 * @notice Implements the service actions.
 * @author BiFi(seinmyung25, Miller-kk, tlatkdgus1, dongchangYoo)
 */
contract externalModule is viewModule {
    modifier onlyOwner() {
        require(msg.sender == owner, "onlyOwner: external function access control!");
        _;
    }
    modifier checkClaimLocked() {
        require(!claimLock, "error: claim Locked");
        _;
    }
    modifier checkWithdrawLocked() {
        require(!withdrawLock, "error: withdraw Locked");
        _;
    }

    /**
     * @notice Set the Deposit-Token address
     * @param erc20Addr The address of Deposit Token
     */
    function setERC(address erc20Addr) external onlyOwner {
        lpErc = ERC20(erc20Addr);
    }

    /**
     * @notice Set the Contribution-Token address
     * @param erc20Addr The address of Contribution Token
     */
    function setRE(address erc20Addr) external onlyOwner {
        rewardErc = ERC20(erc20Addr);
    }

    /**
     * @notice Set the reward distribution parameters instantly
     */
    function setParam(uint256 _rewardPerBlock, uint256 _decrementUnitPerBlock) onlyOwner external {
        _setParams(_rewardPerBlock, _decrementUnitPerBlock);
    }

    /**
     * @notice Terminate Contract Distribution
     */
    function modelFinish(uint256 amount) external onlyOwner {
        if( amount != 0) {
            require( rewardErc.transfer(owner, amount), "token error" );
        }
        else {
            require( rewardErc.transfer(owner, rewardErc.balanceOf(address(this))), "token error" );
        }
        delete totalDeposited;
        delete rewardPerBlock;
        delete decrementUnitPerBlock;
        delete rewardLane;
        delete totalDeposited;
        delete registeredPoints;
    }

    /**
     * @notice Transfer the Remaining Contribution Tokens
     */
    function retrieveRewardAmount(uint256 amount) external onlyOwner {
        if( amount != 0) {
            require( rewardErc.transfer(owner, amount), "token error");
        }
        else {
            require( rewardErc.transfer(owner, rewardErc.balanceOf(address(this))), "token error");
        }
    }

    /**
     * @notice Deposit the Contribution Tokens
     * @param amount The amount of the Contribution Tokens
     */
    function deposit(uint256 amount) external {
        address userAddr = msg.sender;
        _redeemAll(userAddr);
        _deposit(userAddr, amount);
    }

    /**
     * @notice Deposit the Contribution Tokens to target user
     * @param userAddr The target user
     * @param amount The amount of the Contribution Tokens
     */
    function depositTo(address userAddr, uint256 amount) external {
        _redeemAll(userAddr);
        _deposit(userAddr, amount);
    }

    /**
     * @notice Withdraw the Contribution Tokens
     * @param amount The amount of the Contribution Tokens
     */
    function withdraw(uint256 amount) checkWithdrawLocked external {
        address userAddr = msg.sender;
        _redeemAll(userAddr);
        _withdraw(userAddr, amount);
    }

    /**
     * @notice Claim the Reward Tokens
     * @dev Transfer all reward the user has earned at once.
     */
    function rewardClaim() checkClaimLocked external {
        address userAddr = msg.sender;
        _redeemAll(userAddr);
        _rewardClaim(userAddr);
    }
    /**
     * @notice Claim the Reward Tokens
     * @param userAddr The targetUser
     * @dev Transfer all reward the target user has earned at once.
     */
    function rewardClaimTo(address userAddr) checkClaimLocked external {
        _redeemAll(userAddr);
        _rewardClaim(userAddr);
    }

    /// @dev Set locks & access control
    function setClaimLock(bool lock) onlyOwner external {
        _setClaimLock(lock);
    }
    function setWithdrawLock(bool lock) onlyOwner external {
        _setWithdrawLock(lock);
    }
    function ownershipTransfer(address to) onlyOwner external {
        _ownershipTransfer(to);
    }

    /**
     * @notice Register a new future reward velocity point
     */
    function registerRewardVelocity(uint256 _blockNumber, uint256 _rewardPerBlock, uint256 _decrementUnitPerBlock) onlyOwner public {
        require(_blockNumber > block.number, "new Reward params should register earlier");
        require(registeredPoints.length == 0 || _blockNumber > registeredPoints[registeredPoints.length-1].blockNumber, "Earilier velocity points are already set.");
        _registerRewardVelocity(_blockNumber, _rewardPerBlock, _decrementUnitPerBlock);
    }
    function deleteRegisteredRewardVelocity(uint256 _index) onlyOwner external {
        require(_index >= passedPoint, "Reward velocity point already passed.");
        _deleteRegisteredRewardVelocity(_index);
    }

    /**
     * @notice Set the reward distribution parameters
     */
    function setRewardVelocity(uint256 _rewardPerBlock, uint256 _decrementUnitPerBlock) onlyOwner external {
        _updateRewardLane();
        _setParams(_rewardPerBlock, _decrementUnitPerBlock);
    }
}

// File: contracts/DistributionModelV3.sol


/**
 * @title BiFi's Reward Distribution Contract
 * @notice Implements voting process along with vote delegation
 * @author BiFi(seinmyung25, Miller-kk, tlatkdgus1, dongchangYoo)
 */
contract DistributionModelV3 is externalModule {
    constructor(address _owner, address _lpErc, address _rewardErc) public {
        owner = _owner;
        lpErc = ERC20(_lpErc);
        rewardErc = ERC20(_rewardErc);
        lastBlockNum = block.number;
    }
}

contract BFCModel is DistributionModelV3 {
    constructor(address _owner, address _lpErc, address _rewardErc, uint256 _start)
    DistributionModelV3(_owner, _lpErc, _rewardErc) public {
        /*
        _start: parameter start block nubmer
        0x3935413a1cdd90ff: fixed point(1e18) reward per blocks
        0x62e9bea75f: fixed point(1e18) decrement per blocks
        */
        _registerRewardVelocity(_start, 0x3935413a1cdd90ff, 0x62e9bea75f);
    }
}

contract BFCETHModel is DistributionModelV3 {
    constructor(address _owner, address _lpErc, address _rewardErc, uint256 _start)
    DistributionModelV3(_owner, _lpErc, _rewardErc) public {
        /*
        _start: parameter start block nubmer
        0xe4d505786b744b3f: fixed point(1e18) reward per blocks
        0x18ba6fb966b: fixed point(1e18) decrement per blocks
        */
        _registerRewardVelocity(_start, 0xe4d505786b744b3f, 0x18ba6fb966b);
    }
}

contract BiFiETHModel is DistributionModelV3 {
    constructor(address _owner, address _lpErc, address _rewardErc, uint256 _start)
    DistributionModelV3(_owner, _lpErc, _rewardErc) public {
        /*
        _start: parameter start block nubmer
        0x11e0a46e285a68955: fixed point(1e18) reward per blocks
        0x1ee90ba90c4: fixed point(1e18) decrement per blocks
        */
        _registerRewardVelocity(_start, 0x11e0a46e285a68955, 0x1ee90ba90c4);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_lpErc","type":"address"},{"internalType":"address","name":"_rewardErc","type":"address"},{"internalType":"uint256","name":"_start","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"userAddr","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"lock","type":"bool"}],"name":"ClaimLock","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"atBlockNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardPerBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"decrementUnitPerBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"arrayLen","type":"uint256"}],"name":"DeleteRegisterRewardParams","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"userAddr","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userDeposit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalDeposit","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"atBlockNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardPerBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"decrementUnitPerBlock","type":"uint256"}],"name":"RegisterRewardParams","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"rewardPerBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"decrementUnitPerBlock","type":"uint256"}],"name":"SetRewardParams","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"atBlockNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardPerBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"decrementUnitPerBlock","type":"uint256"}],"name":"UpdateRewardParams","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"userAddr","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userDeposit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalDeposit","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"lock","type":"bool"}],"name":"WithdrawLock","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"accounts","outputs":[{"internalType":"uint256","name":"deposited","type":"uint256"},{"internalType":"uint256","name":"pointOnLane","type":"uint256"},{"internalType":"uint256","name":"rewardAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimLock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decrementUnitPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"deleteRegisteredRewardVelocity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddr","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distributionInfo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"fromBlockNumber","type":"uint256"},{"internalType":"uint256","name":"toBlockNumber","type":"uint256"}],"name":"getModelPoolRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getParams","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRegisteredPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRegisteredPointLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddr","type":"address"},{"internalType":"uint256","name":"fromBlockNumber","type":"uint256"},{"internalType":"uint256","name":"toBlockNumber","type":"uint256"}],"name":"getUserPoolRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastBlockNum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpErc","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fromBlockNumber","type":"uint256"},{"internalType":"uint256","name":"_toBlockNumber","type":"uint256"}],"name":"marketInformation","outputs":[{"internalType":"uint256","name":"rewardStartBlockNumber","type":"uint256"},{"internalType":"uint256","name":"distributedAmount","type":"uint256"},{"internalType":"uint256","name":"totalDeposit","type":"uint256"},{"internalType":"uint256","name":"poolRate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"modelFinish","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"modelInfo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"ownershipTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"passedPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockNumber","type":"uint256"},{"internalType":"uint256","name":"_rewardPerBlock","type":"uint256"},{"internalType":"uint256","name":"_decrementUnitPerBlock","type":"uint256"}],"name":"registerRewardVelocity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"registeredPoints","outputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint256","name":"rewardPerBlock","type":"uint256"},{"internalType":"uint256","name":"decrementUnitPerBlock","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"retrieveRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddr","type":"address"}],"name":"rewardClaimTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardErc","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardLane","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"lock","type":"bool"}],"name":"setClaimLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc20Addr","type":"address"}],"name":"setERC","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewardPerBlock","type":"uint256"},{"internalType":"uint256","name":"_decrementUnitPerBlock","type":"uint256"}],"name":"setParam","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc20Addr","type":"address"}],"name":"setRE","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewardPerBlock","type":"uint256"},{"internalType":"uint256","name":"_decrementUnitPerBlock","type":"uint256"}],"name":"setRewardVelocity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"lock","type":"bool"}],"name":"setWithdrawLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalDeposited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddr","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddr","type":"address"},{"internalType":"uint256","name":"_fromBlockNumber","type":"uint256"},{"internalType":"uint256","name":"_toBlockNumber","type":"uint256"}],"name":"userInformation","outputs":[{"internalType":"uint256","name":"stakedTokenAmount","type":"uint256"},{"internalType":"uint256","name":"rewardStartBlockNumber","type":"uint256"},{"internalType":"uint256","name":"claimStartBlockNumber","type":"uint256"},{"internalType":"uint256","name":"earnedTokenAmount","type":"uint256"},{"internalType":"uint256","name":"poolRate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawLock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b5060405162002d9e38038062002d9e833981810160405260808110156200003757600080fd5b50805160208201516040830151606090930151600080546001600160a01b038086166001600160a01b0319928316179092556006805483861690831617905560078054928716929091169190911790554360045591929091620000a981673935413a1cdd90ff6462e9bea75f620000b3565b50505050620001d7565b620000bd620001b6565b60405180606001604052808581526020018481526020018381525090507f1fdf2820867a17742112aebea1dc9d50d73c902c1e5e2ac7f03b0b11e697adb384848460405180848152602001838152602001828152602001935050505060405180910390a1600a805460018101825560009190915281517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a860039092029182015560208201517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a98201556040909101517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2aa90910155505050565b60405180606001604052806000815260200160008152602001600081525090565b612bb780620001e76000396000f3fe608060405234801561001057600080fd5b506004361061023d5760003560e01c80635c388ca61161013b578063b8b1bf99116100b8578063e04bfd811161007c578063e04bfd811461062f578063f4bb1b2114610637578063f71a161314610654578063ff50abdc14610673578063ffaad6a51461067b5761023d565b8063b8b1bf99146105d4578063ca6702cc146105dc578063cabac91c146105e4578063d3a417a214610601578063d48ab308146106275761023d565b8063744f31d7116100ff578063744f31d7146105675780638ae39cac1461058a5780638da5cb5b146105925780639091038a1461059a578063b6b55f25146105b75761023d565b80635c388ca6146104c65780635e5c06e2146104e25780635e615a6b146105085780636409f9211461053657806369cddfe51461053e5761023d565b80633011113a116101c957806336f2fa681161018d57806336f2fa68146104445780634959e729146104675780634f7f399b1461046f578063534caae51461048c57806359f2ea07146104945761023d565b80633011113a146103c95780633237a68e146103e8578063327bc7b11461040e57806334a5519114610416578063368990421461043c5761023d565b806315d0c2841161021057806315d0c2841461031f5780631959a002146103275780631eb804db1461036b57806323c6a502146103885780632e1a7d4d146103ac5761023d565b8063046a360e1461024257806309ce91ad146102775780630e8f7f311461029f57806310dc7f47146102fc575b600080fd5b6102656004803603604081101561025857600080fd5b50803590602001356106a7565b60408051918252519081900360200190f35b61029d6004803603602081101561028d57600080fd5b50356001600160a01b03166106be565b005b6102d1600480360360608110156102b557600080fd5b506001600160a01b038135169060208101359060400135610729565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b61029d6004803603604081101561031257600080fd5b50803590602001356107f4565b610265610854565b61034d6004803603602081101561033d57600080fd5b50356001600160a01b031661085a565b60408051938452602084019290925282820152519081900360600190f35b61029d6004803603602081101561038157600080fd5b50356108c3565b610390610959565b604080516001600160a01b039092168252519081900360200190f35b61029d600480360360208110156103c257600080fd5b5035610968565b61029d600480360360208110156103df57600080fd5b503515156109d4565b61029d600480360360208110156103fe57600080fd5b50356001600160a01b0316610a26565b610265610a8d565b61029d6004803603602081101561042c57600080fd5b50356001600160a01b0316610a93565b610265610afe565b61029d6004803603604081101561045a57600080fd5b5080359060200135610b04565b6102d1610b57565b61029d6004803603602081101561048557600080fd5b5035610b6d565b610265610de9565b610265600480360360608110156104aa57600080fd5b506001600160a01b038135169060208101359060400135610def565b6104ce610e06565b604080519115158252519081900360200190f35b61034d600480360360208110156104f857600080fd5b50356001600160a01b0316610e16565b610510610e37565b604080519485526020850193909352838301919091526060830152519081900360800190f35b61029d610e49565b61029d6004803603606081101561055457600080fd5b5080359060208101359060400135610ea8565b6105106004803603604081101561057d57600080fd5b5080359060200135610fab565b61026561102e565b610390611034565b61029d600480360360208110156105b057600080fd5b5035611043565b61029d600480360360208110156105cd57600080fd5b503561129d565b6104ce6112b1565b6102656112c1565b61034d600480360360208110156105fa57600080fd5b50356112c7565b61029d6004803603602081101561061757600080fd5b50356001600160a01b03166112f7565b61034d611349565b61039061136a565b61034d6004803603602081101561064d57600080fd5b5035611379565b61029d6004803603602081101561066a57600080fd5b503515156113da565b61026561142c565b61029d6004803603604081101561069157600080fd5b506001600160a01b038135169060200135611432565b60006106b560008484611445565b90505b92915050565b6000546001600160a01b031633146107075760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b600680546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006107396129c0565b506001600160a01b03881660009081526008602090815260409182902082516060810184528154808252600180840154948301949094526002909201549381019390935290549096506107ad57600a60008154811061079457fe5b90600052602060002090600302016000015494506107d0565b600a6000815481106107bb57fe5b90600052602060002090600302016000015494505b6107d9896116bf565b92506107e6898989611445565b915050939792965093509350565b6000546001600160a01b0316331461083d5760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b61084561179c565b506108508282611a36565b5050565b60035481565b60008060006108676129c0565b506001600160a01b03841660009081526008602090815260408083208151606081018352815481526001820154938101939093526002015490820152906108ad866116bf565b8251602090930151929792965094509092505050565b6000546001600160a01b0316331461090c5760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b60095481101561094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180612b086025913960400191505060405180910390fd5b61095681611a7c565b50565b6007546001600160a01b031681565b600054600160a81b900460ff16156109c0576040805162461bcd60e51b8152602060048201526016602482015275195c9c9bdc8e881dda5d1a191c985dc8131bd8dad95960521b604482015290519081900360640190fd5b336109ca81611c0b565b6108508183611ce0565b6000546001600160a01b03163314610a1d5760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b61095681611ede565b600054600160a01b900460ff1615610a7b576040805162461bcd60e51b8152602060048201526013602482015272195c9c9bdc8e8818db185a5b48131bd8dad959606a1b604482015290519081900360640190fd5b610a8481611c0b565b61095681611f31565b60095481565b6000546001600160a01b03163314610adc5760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b600780546001600160a01b0319166001600160a01b0392909216919091179055565b60045481565b6000546001600160a01b03163314610b4d5760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b6108508282611a36565b6001546002546003546004546005549091929394565b6000546001600160a01b03163314610bb65760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b8015610c8957600754600080546040805163a9059cbb60e01b81526001600160a01b039283166004820152602481018690529051919093169263a9059cbb9260448083019360209390929083900390910190829087803b158015610c1957600080fd5b505af1158015610c2d573d6000803e3d6000fd5b505050506040513d6020811015610c4357600080fd5b5051610c84576040805162461bcd60e51b815260206004820152600b60248201526a3a37b5b2b71032b93937b960a91b604482015290519081900360640190fd5b610dc7565b600754600054604080516370a0823160e01b815230600482015290516001600160a01b039384169363a9059cbb93169184916370a0823191602480820192602092909190829003018186803b158015610ce157600080fd5b505afa158015610cf5573d6000803e3d6000fd5b505050506040513d6020811015610d0b57600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b158015610d5c57600080fd5b505af1158015610d70573d6000803e3d6000fd5b505050506040513d6020811015610d8657600080fd5b5051610dc7576040805162461bcd60e51b815260206004820152600b60248201526a3a37b5b2b71032b93937b960a91b604482015290519081900360640190fd5b6000600581905560018190556002819055600381905561095690600a906129e1565b60025481565b6000610dfc848484611445565b90505b9392505050565b600054600160a81b900460ff1681565b60086020526000908152604090208054600182015460029092015490919083565b60015460035460045460055490919293565b600054600160a01b900460ff1615610e9e576040805162461bcd60e51b8152602060048201526013602482015272195c9c9bdc8e8818db185a5b48131bd8dad959606a1b604482015290519081900360640190fd5b33610a8481611c0b565b6000546001600160a01b03163314610ef15760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b438311610f2f5760405162461bcd60e51b8152600401808060200182810382526029815260200180612a986029913960400191505060405180910390fd5b600a541580610f605750600a80546000198101908110610f4b57fe5b90600052602060002090600302016000015483115b610f9b5760405162461bcd60e51b8152600401808060200182810382526029815260200180612b2d6029913960400191505060405180910390fd5b610fa683838361209c565b505050565b60008060008060015460001415610fe357600a600081548110610fca57fe5b9060005260206000209060030201600001549350611006565b600a600081548110610ff157fe5b90600052602060002090600302016000015493505b61101060006116bf565b9250600554915061102360008787611445565b905092959194509250565b60015481565b6000546001600160a01b031681565b6000546001600160a01b0316331461108c5760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b801561115f57600754600080546040805163a9059cbb60e01b81526001600160a01b039283166004820152602481018690529051919093169263a9059cbb9260448083019360209390929083900390910190829087803b1580156110ef57600080fd5b505af1158015611103573d6000803e3d6000fd5b505050506040513d602081101561111957600080fd5b505161115a576040805162461bcd60e51b815260206004820152600b60248201526a3a37b5b2b71032b93937b960a91b604482015290519081900360640190fd5b610956565b600754600054604080516370a0823160e01b815230600482015290516001600160a01b039384169363a9059cbb93169184916370a0823191602480820192602092909190829003018186803b1580156111b757600080fd5b505afa1580156111cb573d6000803e3d6000fd5b505050506040513d60208110156111e157600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b15801561123257600080fd5b505af1158015611246573d6000803e3d6000fd5b505050506040513d602081101561125c57600080fd5b5051610956576040805162461bcd60e51b815260206004820152600b60248201526a3a37b5b2b71032b93937b960a91b604482015290519081900360640190fd5b336112a781611c0b565b610850818361219d565b600054600160a01b900460ff1681565b600a5490565b600a81815481106112d457fe5b600091825260209091206003909102018054600182015460029092015490925083565b6000546001600160a01b031633146113405760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b610956816122d8565b60008060008061135761233d565b6001546002549095509350915050909192565b6006546001600160a01b031681565b60008060006113866129c0565b600a858154811061139357fe5b600091825260209182902060408051606081018252600393909302909101805480845260018201549484018590526002909101549290910182905297919650945092505050565b6000546001600160a01b031633146114235760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b6109568161234e565b60055481565b61143b82611c0b565b610850828261219d565b600061144f612a02565b600a54815260055460e082015260a0810184905260c08101849052611473846123a1565b6101808401819052610140840182905260408401839052606084018390526101608401919091526101a083015260808201849052600061010083018190526101208301525b81518110156115af576114c96129c0565b600a82815481106114d657fe5b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905080600001518360c0015110801561152b57506080830151815111155b156115a057600182016060840152805160c084015161154a91906124f2565b6020840181905261012084015160e08501516101608601516101a08701516115719461254f565b6101608501908152610120850191909152815160c08501526020820151905260408101516101a08401526115a6565b506115af565b506001016114b8565b508060c0015181608001511115611610576115d281608001518260c001516124f2565b60208201819052608082015160c083015261012082015160e08301516101608401516101a08501516116039461254f565b6101608301526101208201525b6116186129c0565b6001600160a01b0386161561166c57506001600160a01b0385166000908152600860209081526040918290208251606081018452815481526001820154928101929092526002015491810191909152611690565b60405180606001604052808360e00151815260200160008152602001600081525090505b6116b56116a682600001518461012001516125ea565b6116b086886124f2565b612603565b9695505050505050565b60006116c96129c0565b60006001600160a01b0384161561173c5760086000856001600160a01b03166001600160a01b031681526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050915061173560045461266a565b905061176a565b604051806060016040528060055481526020016000815260200160008152509150611767600061266a565b90505b600061177a8284602001516124f2565b9050600061178c8460000151836125ea565b90506116b584604001518261289d565b60006117a6612a02565b600a54815260055460e0820152600954604082018190526060820181905243608083015260045460a0830181905260c08301526003546101008301819052610120830152600154610140830181905261016083015260025461018083018190526101a08301525b815181101561194a5761181e6129c0565b600a828154811061182b57fe5b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905080600001518360c0015110801561188057506080830151815111155b1561193b57600182016060840152805160c084015161189f91906124f2565b6020840181905261012084015160e08501516101608601516101a08701516118c69461254f565b6101608501908152610120850191909152815160c085015260208083018051909252604083810180516101a088015284519351905182519485529284015282810191909152517fc2d5f9e666d2dd7e740ece9acaf1b93ce48894cbc0336d693410badb7c40aead9181900360600190a1611941565b5061194a565b5060010161180d565b5080608001518160c0015110156119ab5761196d81608001518260c001516124f2565b60208201819052608082015160c083015261012082015160e08301516101608401516101a085015161199e9461254f565b6101608301526101208201525b8060c001518160a00151146119c35760c08101516004555b80606001518160400151146119db5760608101516009555b806101200151816101000151146119f6576101208101516003555b80610160015181610140015114611a11576101608101516001555b806101a0015181610180015114611a2c576101a08101516002555b6101200151905090565b604080518381526020810183905281517fbfc739097487a2d01d113d21aef3ef3d22331f56d3273bc4907d61407e5b0856929181900390910190a1600191909155600255565b600a548015801590611a8d57508082105b611ac85760405162461bcd60e51b8152600401808060200182810382526026815260200180612ac16026913960400191505060405180910390fd5b611ad06129c0565b600a8381548110611add57fe5b6000918252602091829020604080516060808201835260039094029092018054808452600182015484870181905260029092015484840181905283518a81529687019190915285830191909152928401929092526000198501608084015290519092507f543ba8eaac0e28f58eb335897e63175861579bc16306e05ab5936084c1f074919181900360a00190a1825b60018303811015611bd557600a8160010181548110611b8757fe5b9060005260206000209060030201600a8281548110611ba257fe5b60009182526020909120825460039092020190815560018083015481830155600292830154929091019190915501611b6c565b50600a805480611be157fe5b60008281526020812060036000199093019283020181815560018101829055600201559055505050565b611c136129c0565b506001600160a01b0381166000908152600860209081526040808320815160608101835281548152600182015493810193909352600201549082015290611c5861179c565b90506000611c6a8284602001516124f2565b90506000611c7c8460000151836125ea565b905082846020015114611ca8576001600160a01b03851660009081526008602052604090206001018390555b8015611cd957611cbc84604001518261289d565b6001600160a01b0386166000908152600860205260409020600201555b5050505050565b611ce86129c0565b506001600160a01b038216600090815260086020908152604091829020825160608101845281548082526001830154938201939093526002909101549281019290925260055490831115611d83576040805162461bcd60e51b815260206004820152601760248201527f6e6f7420656e6f7567682075736572204465706f736974000000000000000000604482015290519081900360640190fd5b8151611d8f90846124f2565b8083526001600160a01b038516600090815260086020526040902055600554611db890846124f2565b600581905590508215611ed8578151604080516001600160a01b0387168152602081018690528082019290925260608201839052517f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca949181900360800190a16006546040805163a9059cbb60e01b81526001600160a01b038781166004830152602482018790529151919092169163a9059cbb9160448083019260209291908290030181600087803b158015611e6d57600080fd5b505af1158015611e81573d6000803e3d6000fd5b505050506040513d6020811015611e9757600080fd5b5051611ed8576040805162461bcd60e51b815260206004820152600b60248201526a3a37b5b2b71032b93937b960a91b604482015290519081900360640190fd5b50505050565b60408051821515815290517f24e8043bbab505bf23b3d9b569ad2dc34a6a563516daca26e3ad818b40c14f659181900360200190a160008054911515600160a81b0260ff60a81b19909216919091179055565b611f396129c0565b506001600160a01b038116600090815260086020908152604091829020825160608101845281548152600182015492810192909252600201549181018290529015610850576040808201516001600160a01b0384166000818152600860209081528482206002019190915583519182528101829052825191927f47cee97cb7acd717b3c0aa1435d004cd5b3c8c57d70dbceb4e4458bbd60e39d492918290030190a16007546040805163a9059cbb60e01b81526001600160a01b038681166004830152602482018590529151919092169163a9059cbb9160448083019260209291908290030181600087803b15801561203157600080fd5b505af1158015612045573d6000803e3d6000fd5b505050506040513d602081101561205b57600080fd5b5051610fa6576040805162461bcd60e51b815260206004820152600b60248201526a3a37b5b2b71032b93937b960a91b604482015290519081900360640190fd5b6120a46129c0565b60405180606001604052808581526020018481526020018381525090507f1fdf2820867a17742112aebea1dc9d50d73c902c1e5e2ac7f03b0b11e697adb384848460405180848152602001838152602001828152602001935050505060405180910390a1600a805460018101825560009190915281517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a860039092029182015560208201517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a98201556040909101517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2aa90910155505050565b6121a56129c0565b506001600160a01b0382166000908152600860209081526040918290208251606081018452815480825260018301549382019390935260029091015492810192909252600554906121f6908461289d565b8083526001600160a01b03851660009081526008602052604090205560055461221f908461289d565b600581905590508215611ed8578151604080516001600160a01b0387168152602081018690528082019290925260608201839052517f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e9181900360800190a1600654604080516323b872dd60e01b81523360048201523060248201526044810186905290516001600160a01b03909216916323b872dd916064808201926020929091908290030181600087803b158015611e6d57600080fd5b604080513381526001600160a01b038316602082015281517f22500af037c600dd7b720644ab6e358635085601d9ac508ad83eb2d6b2d729ca929181900390910190a1600080546001600160a01b0319166001600160a01b0392909216919091179055565b600061234960006116bf565b905090565b60408051821515815290517f4d23c25ea752bd74a0dfa4a88c011a2c7bf8713a06a6b1028feb1fd277746c4f9181900360200190a160008054911515600160a01b0260ff60a01b19909216919091179055565b600a54600090819081908190819081908190801561246257600092505b80831015612462576123ce6129c0565b600a84815481106123db57fe5b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905080600001518a101580156124285750805115155b15612443578392508060200151955080604001519450612455565b805161244f5750612457565b50612462565b505b6001909201916123be565b61246a6129c0565b600a838154811061247757fe5b600091825260209182902060408051606081018252600390930290910180548084526001820154948401859052600290910154918301829052929850965091508a11156124e1576124de866124d9876124d48e86600001516124f2565b6128f7565b6124f2565b95505b509198939750919550919350505050565b600081831015612549576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600080808415612579576125638686612603565b90508084111561257557809350612579565b5060005b600087156125be576125af61258f888789612950565b6125aa6125a4670de0b6b3a76400008c612993565b886128f7565b6125ea565b90506125bb898261289d565b98505b81156125cd57600096506125db565b6125d88787876129b0565b96505b50969794965093945050505050565b60006106b56125f984846128f7565b670de0b6b3a76400005b6000808211612659576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161266257fe5b049392505050565b6000612674612a02565b600a54815260055460e0820152826126dd576000604082018190526060820181905243608083015260a0820181905260c08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a0820152612734565b60095460408201819052606082015243608082015260a0810183905260c081018390526003546101008201819052610120820152600154610140820181905261016082015260025461018082018190526101a08201525b60408101515b81518110156128315761274b6129c0565b600a828154811061275857fe5b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905080600001518360c001511080156127ad57506080830151815111155b1561282257600182016060840152805160c08401516127cc91906124f2565b6020840181905261012084015160e08501516101608601516101a08701516127f39461254f565b6101608501908152610120850191909152815160c08501526020820151905260408101516101a0840152612828565b50612831565b5060010161273a565b508060c00151816080015111156128925761285481608001518260c001516124f2565b60208201819052608082015160c083015261012082015160e08301516101608401516101a08501516128859461254f565b6101608301526101208201525b610120015192915050565b6000828201838110156106b5576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a2061646474696f6e206f766572666c6f77000000000000604482015290519081900360640190fd5b600082612906575060006106b8565b8282028284828161291357fe5b04146106b55760405162461bcd60e51b8152600401808060200182810382526021815260200180612ae76021913960400191505060405180910390fd5b6000821561298b5761298461297d6129696002876128f7565b6124d96129778760016124f2565b866128f7565b6002612603565b9050610dff565b506000610dff565b60006106b56129aa84670de0b6b3a76400006128f7565b83612603565b6000610dfc846124d985856128f7565b60405180606001604052806000815260200160008152602001600081525090565b50805460008255600302906000526020600020908101906109569190612a71565b604051806101c0016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b80821115612a93576000808255600182018190556002820155600301612a72565b509056fe6e65772052657761726420706172616d732073686f756c64207265676973746572206561726c6965726572726f723a206e6f20656c656d656e747320696e2072656769737465726564506f696e7473536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775265776172642076656c6f6369747920706f696e7420616c7265616479207061737365642e456172696c6965722076656c6f6369747920706f696e74732061726520616c7265616479207365742e6f6e6c794f776e65723a2065787465726e616c2066756e6374696f6e2061636365737320636f6e74726f6c21a2646970667358221220c4a83c86d0f7ef3050ab249a43e9a049c0888eb6032b03d57b942652efa27fd964736f6c634300060c0033000000000000000000000000359903041de93c69828f911aeb0be29cc9ccc58b0000000000000000000000000c7d5ae016f806603cb1782bea29ac69471cab9c000000000000000000000000db7bb52ac3f9e2f6153a3f9dcdd4d67f9f8360340000000000000000000000000000000000000000000000000000000000b09d48

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061023d5760003560e01c80635c388ca61161013b578063b8b1bf99116100b8578063e04bfd811161007c578063e04bfd811461062f578063f4bb1b2114610637578063f71a161314610654578063ff50abdc14610673578063ffaad6a51461067b5761023d565b8063b8b1bf99146105d4578063ca6702cc146105dc578063cabac91c146105e4578063d3a417a214610601578063d48ab308146106275761023d565b8063744f31d7116100ff578063744f31d7146105675780638ae39cac1461058a5780638da5cb5b146105925780639091038a1461059a578063b6b55f25146105b75761023d565b80635c388ca6146104c65780635e5c06e2146104e25780635e615a6b146105085780636409f9211461053657806369cddfe51461053e5761023d565b80633011113a116101c957806336f2fa681161018d57806336f2fa68146104445780634959e729146104675780634f7f399b1461046f578063534caae51461048c57806359f2ea07146104945761023d565b80633011113a146103c95780633237a68e146103e8578063327bc7b11461040e57806334a5519114610416578063368990421461043c5761023d565b806315d0c2841161021057806315d0c2841461031f5780631959a002146103275780631eb804db1461036b57806323c6a502146103885780632e1a7d4d146103ac5761023d565b8063046a360e1461024257806309ce91ad146102775780630e8f7f311461029f57806310dc7f47146102fc575b600080fd5b6102656004803603604081101561025857600080fd5b50803590602001356106a7565b60408051918252519081900360200190f35b61029d6004803603602081101561028d57600080fd5b50356001600160a01b03166106be565b005b6102d1600480360360608110156102b557600080fd5b506001600160a01b038135169060208101359060400135610729565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b61029d6004803603604081101561031257600080fd5b50803590602001356107f4565b610265610854565b61034d6004803603602081101561033d57600080fd5b50356001600160a01b031661085a565b60408051938452602084019290925282820152519081900360600190f35b61029d6004803603602081101561038157600080fd5b50356108c3565b610390610959565b604080516001600160a01b039092168252519081900360200190f35b61029d600480360360208110156103c257600080fd5b5035610968565b61029d600480360360208110156103df57600080fd5b503515156109d4565b61029d600480360360208110156103fe57600080fd5b50356001600160a01b0316610a26565b610265610a8d565b61029d6004803603602081101561042c57600080fd5b50356001600160a01b0316610a93565b610265610afe565b61029d6004803603604081101561045a57600080fd5b5080359060200135610b04565b6102d1610b57565b61029d6004803603602081101561048557600080fd5b5035610b6d565b610265610de9565b610265600480360360608110156104aa57600080fd5b506001600160a01b038135169060208101359060400135610def565b6104ce610e06565b604080519115158252519081900360200190f35b61034d600480360360208110156104f857600080fd5b50356001600160a01b0316610e16565b610510610e37565b604080519485526020850193909352838301919091526060830152519081900360800190f35b61029d610e49565b61029d6004803603606081101561055457600080fd5b5080359060208101359060400135610ea8565b6105106004803603604081101561057d57600080fd5b5080359060200135610fab565b61026561102e565b610390611034565b61029d600480360360208110156105b057600080fd5b5035611043565b61029d600480360360208110156105cd57600080fd5b503561129d565b6104ce6112b1565b6102656112c1565b61034d600480360360208110156105fa57600080fd5b50356112c7565b61029d6004803603602081101561061757600080fd5b50356001600160a01b03166112f7565b61034d611349565b61039061136a565b61034d6004803603602081101561064d57600080fd5b5035611379565b61029d6004803603602081101561066a57600080fd5b503515156113da565b61026561142c565b61029d6004803603604081101561069157600080fd5b506001600160a01b038135169060200135611432565b60006106b560008484611445565b90505b92915050565b6000546001600160a01b031633146107075760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b600680546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006107396129c0565b506001600160a01b03881660009081526008602090815260409182902082516060810184528154808252600180840154948301949094526002909201549381019390935290549096506107ad57600a60008154811061079457fe5b90600052602060002090600302016000015494506107d0565b600a6000815481106107bb57fe5b90600052602060002090600302016000015494505b6107d9896116bf565b92506107e6898989611445565b915050939792965093509350565b6000546001600160a01b0316331461083d5760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b61084561179c565b506108508282611a36565b5050565b60035481565b60008060006108676129c0565b506001600160a01b03841660009081526008602090815260408083208151606081018352815481526001820154938101939093526002015490820152906108ad866116bf565b8251602090930151929792965094509092505050565b6000546001600160a01b0316331461090c5760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b60095481101561094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180612b086025913960400191505060405180910390fd5b61095681611a7c565b50565b6007546001600160a01b031681565b600054600160a81b900460ff16156109c0576040805162461bcd60e51b8152602060048201526016602482015275195c9c9bdc8e881dda5d1a191c985dc8131bd8dad95960521b604482015290519081900360640190fd5b336109ca81611c0b565b6108508183611ce0565b6000546001600160a01b03163314610a1d5760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b61095681611ede565b600054600160a01b900460ff1615610a7b576040805162461bcd60e51b8152602060048201526013602482015272195c9c9bdc8e8818db185a5b48131bd8dad959606a1b604482015290519081900360640190fd5b610a8481611c0b565b61095681611f31565b60095481565b6000546001600160a01b03163314610adc5760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b600780546001600160a01b0319166001600160a01b0392909216919091179055565b60045481565b6000546001600160a01b03163314610b4d5760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b6108508282611a36565b6001546002546003546004546005549091929394565b6000546001600160a01b03163314610bb65760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b8015610c8957600754600080546040805163a9059cbb60e01b81526001600160a01b039283166004820152602481018690529051919093169263a9059cbb9260448083019360209390929083900390910190829087803b158015610c1957600080fd5b505af1158015610c2d573d6000803e3d6000fd5b505050506040513d6020811015610c4357600080fd5b5051610c84576040805162461bcd60e51b815260206004820152600b60248201526a3a37b5b2b71032b93937b960a91b604482015290519081900360640190fd5b610dc7565b600754600054604080516370a0823160e01b815230600482015290516001600160a01b039384169363a9059cbb93169184916370a0823191602480820192602092909190829003018186803b158015610ce157600080fd5b505afa158015610cf5573d6000803e3d6000fd5b505050506040513d6020811015610d0b57600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b158015610d5c57600080fd5b505af1158015610d70573d6000803e3d6000fd5b505050506040513d6020811015610d8657600080fd5b5051610dc7576040805162461bcd60e51b815260206004820152600b60248201526a3a37b5b2b71032b93937b960a91b604482015290519081900360640190fd5b6000600581905560018190556002819055600381905561095690600a906129e1565b60025481565b6000610dfc848484611445565b90505b9392505050565b600054600160a81b900460ff1681565b60086020526000908152604090208054600182015460029092015490919083565b60015460035460045460055490919293565b600054600160a01b900460ff1615610e9e576040805162461bcd60e51b8152602060048201526013602482015272195c9c9bdc8e8818db185a5b48131bd8dad959606a1b604482015290519081900360640190fd5b33610a8481611c0b565b6000546001600160a01b03163314610ef15760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b438311610f2f5760405162461bcd60e51b8152600401808060200182810382526029815260200180612a986029913960400191505060405180910390fd5b600a541580610f605750600a80546000198101908110610f4b57fe5b90600052602060002090600302016000015483115b610f9b5760405162461bcd60e51b8152600401808060200182810382526029815260200180612b2d6029913960400191505060405180910390fd5b610fa683838361209c565b505050565b60008060008060015460001415610fe357600a600081548110610fca57fe5b9060005260206000209060030201600001549350611006565b600a600081548110610ff157fe5b90600052602060002090600302016000015493505b61101060006116bf565b9250600554915061102360008787611445565b905092959194509250565b60015481565b6000546001600160a01b031681565b6000546001600160a01b0316331461108c5760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b801561115f57600754600080546040805163a9059cbb60e01b81526001600160a01b039283166004820152602481018690529051919093169263a9059cbb9260448083019360209390929083900390910190829087803b1580156110ef57600080fd5b505af1158015611103573d6000803e3d6000fd5b505050506040513d602081101561111957600080fd5b505161115a576040805162461bcd60e51b815260206004820152600b60248201526a3a37b5b2b71032b93937b960a91b604482015290519081900360640190fd5b610956565b600754600054604080516370a0823160e01b815230600482015290516001600160a01b039384169363a9059cbb93169184916370a0823191602480820192602092909190829003018186803b1580156111b757600080fd5b505afa1580156111cb573d6000803e3d6000fd5b505050506040513d60208110156111e157600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b15801561123257600080fd5b505af1158015611246573d6000803e3d6000fd5b505050506040513d602081101561125c57600080fd5b5051610956576040805162461bcd60e51b815260206004820152600b60248201526a3a37b5b2b71032b93937b960a91b604482015290519081900360640190fd5b336112a781611c0b565b610850818361219d565b600054600160a01b900460ff1681565b600a5490565b600a81815481106112d457fe5b600091825260209091206003909102018054600182015460029092015490925083565b6000546001600160a01b031633146113405760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b610956816122d8565b60008060008061135761233d565b6001546002549095509350915050909192565b6006546001600160a01b031681565b60008060006113866129c0565b600a858154811061139357fe5b600091825260209182902060408051606081018252600393909302909101805480845260018201549484018590526002909101549290910182905297919650945092505050565b6000546001600160a01b031633146114235760405162461bcd60e51b815260040180806020018281038252602c815260200180612b56602c913960400191505060405180910390fd5b6109568161234e565b60055481565b61143b82611c0b565b610850828261219d565b600061144f612a02565b600a54815260055460e082015260a0810184905260c08101849052611473846123a1565b6101808401819052610140840182905260408401839052606084018390526101608401919091526101a083015260808201849052600061010083018190526101208301525b81518110156115af576114c96129c0565b600a82815481106114d657fe5b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905080600001518360c0015110801561152b57506080830151815111155b156115a057600182016060840152805160c084015161154a91906124f2565b6020840181905261012084015160e08501516101608601516101a08701516115719461254f565b6101608501908152610120850191909152815160c08501526020820151905260408101516101a08401526115a6565b506115af565b506001016114b8565b508060c0015181608001511115611610576115d281608001518260c001516124f2565b60208201819052608082015160c083015261012082015160e08301516101608401516101a08501516116039461254f565b6101608301526101208201525b6116186129c0565b6001600160a01b0386161561166c57506001600160a01b0385166000908152600860209081526040918290208251606081018452815481526001820154928101929092526002015491810191909152611690565b60405180606001604052808360e00151815260200160008152602001600081525090505b6116b56116a682600001518461012001516125ea565b6116b086886124f2565b612603565b9695505050505050565b60006116c96129c0565b60006001600160a01b0384161561173c5760086000856001600160a01b03166001600160a01b031681526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050915061173560045461266a565b905061176a565b604051806060016040528060055481526020016000815260200160008152509150611767600061266a565b90505b600061177a8284602001516124f2565b9050600061178c8460000151836125ea565b90506116b584604001518261289d565b60006117a6612a02565b600a54815260055460e0820152600954604082018190526060820181905243608083015260045460a0830181905260c08301526003546101008301819052610120830152600154610140830181905261016083015260025461018083018190526101a08301525b815181101561194a5761181e6129c0565b600a828154811061182b57fe5b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905080600001518360c0015110801561188057506080830151815111155b1561193b57600182016060840152805160c084015161189f91906124f2565b6020840181905261012084015160e08501516101608601516101a08701516118c69461254f565b6101608501908152610120850191909152815160c085015260208083018051909252604083810180516101a088015284519351905182519485529284015282810191909152517fc2d5f9e666d2dd7e740ece9acaf1b93ce48894cbc0336d693410badb7c40aead9181900360600190a1611941565b5061194a565b5060010161180d565b5080608001518160c0015110156119ab5761196d81608001518260c001516124f2565b60208201819052608082015160c083015261012082015160e08301516101608401516101a085015161199e9461254f565b6101608301526101208201525b8060c001518160a00151146119c35760c08101516004555b80606001518160400151146119db5760608101516009555b806101200151816101000151146119f6576101208101516003555b80610160015181610140015114611a11576101608101516001555b806101a0015181610180015114611a2c576101a08101516002555b6101200151905090565b604080518381526020810183905281517fbfc739097487a2d01d113d21aef3ef3d22331f56d3273bc4907d61407e5b0856929181900390910190a1600191909155600255565b600a548015801590611a8d57508082105b611ac85760405162461bcd60e51b8152600401808060200182810382526026815260200180612ac16026913960400191505060405180910390fd5b611ad06129c0565b600a8381548110611add57fe5b6000918252602091829020604080516060808201835260039094029092018054808452600182015484870181905260029092015484840181905283518a81529687019190915285830191909152928401929092526000198501608084015290519092507f543ba8eaac0e28f58eb335897e63175861579bc16306e05ab5936084c1f074919181900360a00190a1825b60018303811015611bd557600a8160010181548110611b8757fe5b9060005260206000209060030201600a8281548110611ba257fe5b60009182526020909120825460039092020190815560018083015481830155600292830154929091019190915501611b6c565b50600a805480611be157fe5b60008281526020812060036000199093019283020181815560018101829055600201559055505050565b611c136129c0565b506001600160a01b0381166000908152600860209081526040808320815160608101835281548152600182015493810193909352600201549082015290611c5861179c565b90506000611c6a8284602001516124f2565b90506000611c7c8460000151836125ea565b905082846020015114611ca8576001600160a01b03851660009081526008602052604090206001018390555b8015611cd957611cbc84604001518261289d565b6001600160a01b0386166000908152600860205260409020600201555b5050505050565b611ce86129c0565b506001600160a01b038216600090815260086020908152604091829020825160608101845281548082526001830154938201939093526002909101549281019290925260055490831115611d83576040805162461bcd60e51b815260206004820152601760248201527f6e6f7420656e6f7567682075736572204465706f736974000000000000000000604482015290519081900360640190fd5b8151611d8f90846124f2565b8083526001600160a01b038516600090815260086020526040902055600554611db890846124f2565b600581905590508215611ed8578151604080516001600160a01b0387168152602081018690528082019290925260608201839052517f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca949181900360800190a16006546040805163a9059cbb60e01b81526001600160a01b038781166004830152602482018790529151919092169163a9059cbb9160448083019260209291908290030181600087803b158015611e6d57600080fd5b505af1158015611e81573d6000803e3d6000fd5b505050506040513d6020811015611e9757600080fd5b5051611ed8576040805162461bcd60e51b815260206004820152600b60248201526a3a37b5b2b71032b93937b960a91b604482015290519081900360640190fd5b50505050565b60408051821515815290517f24e8043bbab505bf23b3d9b569ad2dc34a6a563516daca26e3ad818b40c14f659181900360200190a160008054911515600160a81b0260ff60a81b19909216919091179055565b611f396129c0565b506001600160a01b038116600090815260086020908152604091829020825160608101845281548152600182015492810192909252600201549181018290529015610850576040808201516001600160a01b0384166000818152600860209081528482206002019190915583519182528101829052825191927f47cee97cb7acd717b3c0aa1435d004cd5b3c8c57d70dbceb4e4458bbd60e39d492918290030190a16007546040805163a9059cbb60e01b81526001600160a01b038681166004830152602482018590529151919092169163a9059cbb9160448083019260209291908290030181600087803b15801561203157600080fd5b505af1158015612045573d6000803e3d6000fd5b505050506040513d602081101561205b57600080fd5b5051610fa6576040805162461bcd60e51b815260206004820152600b60248201526a3a37b5b2b71032b93937b960a91b604482015290519081900360640190fd5b6120a46129c0565b60405180606001604052808581526020018481526020018381525090507f1fdf2820867a17742112aebea1dc9d50d73c902c1e5e2ac7f03b0b11e697adb384848460405180848152602001838152602001828152602001935050505060405180910390a1600a805460018101825560009190915281517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a860039092029182015560208201517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a98201556040909101517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2aa90910155505050565b6121a56129c0565b506001600160a01b0382166000908152600860209081526040918290208251606081018452815480825260018301549382019390935260029091015492810192909252600554906121f6908461289d565b8083526001600160a01b03851660009081526008602052604090205560055461221f908461289d565b600581905590508215611ed8578151604080516001600160a01b0387168152602081018690528082019290925260608201839052517f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e9181900360800190a1600654604080516323b872dd60e01b81523360048201523060248201526044810186905290516001600160a01b03909216916323b872dd916064808201926020929091908290030181600087803b158015611e6d57600080fd5b604080513381526001600160a01b038316602082015281517f22500af037c600dd7b720644ab6e358635085601d9ac508ad83eb2d6b2d729ca929181900390910190a1600080546001600160a01b0319166001600160a01b0392909216919091179055565b600061234960006116bf565b905090565b60408051821515815290517f4d23c25ea752bd74a0dfa4a88c011a2c7bf8713a06a6b1028feb1fd277746c4f9181900360200190a160008054911515600160a01b0260ff60a01b19909216919091179055565b600a54600090819081908190819081908190801561246257600092505b80831015612462576123ce6129c0565b600a84815481106123db57fe5b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905080600001518a101580156124285750805115155b15612443578392508060200151955080604001519450612455565b805161244f5750612457565b50612462565b505b6001909201916123be565b61246a6129c0565b600a838154811061247757fe5b600091825260209182902060408051606081018252600390930290910180548084526001820154948401859052600290910154918301829052929850965091508a11156124e1576124de866124d9876124d48e86600001516124f2565b6128f7565b6124f2565b95505b509198939750919550919350505050565b600081831015612549576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600080808415612579576125638686612603565b90508084111561257557809350612579565b5060005b600087156125be576125af61258f888789612950565b6125aa6125a4670de0b6b3a76400008c612993565b886128f7565b6125ea565b90506125bb898261289d565b98505b81156125cd57600096506125db565b6125d88787876129b0565b96505b50969794965093945050505050565b60006106b56125f984846128f7565b670de0b6b3a76400005b6000808211612659576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161266257fe5b049392505050565b6000612674612a02565b600a54815260055460e0820152826126dd576000604082018190526060820181905243608083015260a0820181905260c08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a0820152612734565b60095460408201819052606082015243608082015260a0810183905260c081018390526003546101008201819052610120820152600154610140820181905261016082015260025461018082018190526101a08201525b60408101515b81518110156128315761274b6129c0565b600a828154811061275857fe5b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905080600001518360c001511080156127ad57506080830151815111155b1561282257600182016060840152805160c08401516127cc91906124f2565b6020840181905261012084015160e08501516101608601516101a08701516127f39461254f565b6101608501908152610120850191909152815160c08501526020820151905260408101516101a0840152612828565b50612831565b5060010161273a565b508060c00151816080015111156128925761285481608001518260c001516124f2565b60208201819052608082015160c083015261012082015160e08301516101608401516101a08501516128859461254f565b6101608301526101208201525b610120015192915050565b6000828201838110156106b5576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a2061646474696f6e206f766572666c6f77000000000000604482015290519081900360640190fd5b600082612906575060006106b8565b8282028284828161291357fe5b04146106b55760405162461bcd60e51b8152600401808060200182810382526021815260200180612ae76021913960400191505060405180910390fd5b6000821561298b5761298461297d6129696002876128f7565b6124d96129778760016124f2565b866128f7565b6002612603565b9050610dff565b506000610dff565b60006106b56129aa84670de0b6b3a76400006128f7565b83612603565b6000610dfc846124d985856128f7565b60405180606001604052806000815260200160008152602001600081525090565b50805460008255600302906000526020600020908101906109569190612a71565b604051806101c0016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b80821115612a93576000808255600182018190556002820155600301612a72565b509056fe6e65772052657761726420706172616d732073686f756c64207265676973746572206561726c6965726572726f723a206e6f20656c656d656e747320696e2072656769737465726564506f696e7473536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775265776172642076656c6f6369747920706f696e7420616c7265616479207061737365642e456172696c6965722076656c6f6369747920706f696e74732061726520616c7265616479207365742e6f6e6c794f776e65723a2065787465726e616c2066756e6374696f6e2061636365737320636f6e74726f6c21a2646970667358221220c4a83c86d0f7ef3050ab249a43e9a049c0888eb6032b03d57b942652efa27fd964736f6c634300060c0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000359903041de93c69828f911aeb0be29cc9ccc58b0000000000000000000000000c7d5ae016f806603cb1782bea29ac69471cab9c000000000000000000000000db7bb52ac3f9e2f6153a3f9dcdd4d67f9f8360340000000000000000000000000000000000000000000000000000000000b09d48

-----Decoded View---------------
Arg [0] : _owner (address): 0x359903041dE93c69828F911aeB0BE29CC9ccc58b
Arg [1] : _lpErc (address): 0x0c7D5ae016f806603CB1782bEa29AC69471CAb9c
Arg [2] : _rewardErc (address): 0xDb7BB52ac3f9e2f6153a3f9dcdD4D67f9F836034
Arg [3] : _start (uint256): 11574600

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000359903041de93c69828f911aeb0be29cc9ccc58b
Arg [1] : 0000000000000000000000000c7d5ae016f806603cb1782bea29ac69471cab9c
Arg [2] : 000000000000000000000000db7bb52ac3f9e2f6153a3f9dcdd4d67f9f836034
Arg [3] : 0000000000000000000000000000000000000000000000000000000000b09d48


Deployed Bytecode Sourcemap

37916:472:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31936:187;;;;;;;;;;;;;;;;-1:-1:-1;31936:187:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;32879:97;;;;;;;;;;;;;;;;-1:-1:-1;32879:97:0;-1:-1:-1;;;;;32879:97:0;;:::i;:::-;;21285:834;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;21285:834:0;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37194:203;;;;;;;;;;;;;;;;-1:-1:-1;37194:203:0;;;;;;;:::i;5626:25::-;;;:::i;22894:283::-;;;;;;;;;;;;;;;;-1:-1:-1;22894:283:0;-1:-1:-1;;;;;22894:283:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;36898:215;;;;;;;;;;;;;;;;-1:-1:-1;36898:215:0;;:::i;5752:22::-;;;:::i;:::-;;;;-1:-1:-1;;;;;5752:22:0;;;;;;;;;;;;;;35196:180;;;;;;;;;;;;;;;;-1:-1:-1;35196:180:0;;:::i;36121:96::-;;;;;;;;;;;;;;;;-1:-1:-1;36121:96:0;;;;:::i;35837:139::-;;;;;;;;;;;;;;;;-1:-1:-1;35837:139:0;-1:-1:-1;;;;;35837:139:0;;:::i;5835:26::-;;;:::i;33112:100::-;;;;;;;;;;;;;;;;-1:-1:-1;33112:100:0;-1:-1:-1;;;;;33112:100:0;;:::i;5660:27::-;;;:::i;33303:164::-;;;;;;;;;;;;;;;;-1:-1:-1;33303:164:0;;;;;;;:::i;22127:196::-;;;:::i;33541:503::-;;;;;;;;;;;;;;;;-1:-1:-1;33541:503:0;;:::i;5583:36::-;;;:::i;31726:202::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;31726:202:0;;;;;;;;;;;;;:::i;5514:24::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;5783:43;;;;;;;;;;;;;;;;-1:-1:-1;5783:43:0;-1:-1:-1;;;;;5783:43:0;;:::i;22331:164::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35504:161;;;:::i;36408:484::-;;;;;;;;;;;;;;;;-1:-1:-1;36408:484:0;;;;;;;;;;;;:::i;20523:754::-;;;;;;;;;;;;;;;;-1:-1:-1;20523:754:0;;;;;;;:::i;5547:29::-;;;:::i;5457:20::-;;;:::i;34129:313::-;;;;;;;;;;;;;;;;-1:-1:-1;34129:313:0;;:::i;34576:158::-;;;;;;;;;;;;;;;;-1:-1:-1;34576:158:0;;:::i;5486:21::-;;;:::i;22503:117::-;;;:::i;5868:45::-;;;;;;;;;;;;;;;;-1:-1:-1;5868:45:0;;:::i;36223:99::-;;;;;;;;;;;;;;;;-1:-1:-1;36223:99:0;-1:-1:-1;;;;;36223:99:0;;:::i;23185:261::-;;;:::i;5732:18::-;;;:::i;22628:258::-;;;;;;;;;;;;;;;;-1:-1:-1;22628:258:0;;:::i;36025:90::-;;;;;;;;;;;;;;;;-1:-1:-1;36025:90:0;;;;:::i;5694:29::-;;;:::i;34923:138::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;34923:138:0;;;;;;;;:::i;31936:187::-;32033:7;32060:55;32080:1;32084:15;32101:13;32060:11;:55::i;:::-;32053:62;;31936:187;;;;;:::o;32879:97::-;32456:5;;-1:-1:-1;;;;;32456:5:0;32442:10;:19;32434:76;;;;-1:-1:-1;;;32434:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32944:5:::1;:24:::0;;-1:-1:-1;;;;;;32944:24:0::1;-1:-1:-1::0;;;;;32944:24:0;;;::::1;::::0;;;::::1;::::0;;32879:97::o;21285:834::-;21411:25;21447:30;21488:29;21528:25;21564:16;21608:19;;:::i;:::-;-1:-1:-1;;;;;;21630:18:0;;;;;;:8;:18;;;;;;;;;21608:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21711:14;;21608:40;;-1:-1:-1;21708:152:0;;21757:16;21774:1;21757:19;;;;;;;;;;;;;;;;;;:31;;;21732:56;;21708:152;;;21829:16;21846:1;21829:19;;;;;;;;;;;;;;;;;;:31;;;21804:56;;21708:152;21893:24;21908:8;21893:14;:24::i;:::-;21873:44;;21941:55;21953:8;21963:16;21981:14;21941:11;:55::i;:::-;21930:66;;22009:102;21285:834;;;;;;;;;:::o;37194:203::-;32456:5;;-1:-1:-1;;;;;32456:5:0;32442:10;:19;32434:76;;;;-1:-1:-1;;;32434:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37308:19:::1;:17;:19::i;:::-;;37338:51;37349:15;37366:22;37338:10;:51::i;:::-;37194:203:::0;;:::o;5626:25::-;;;;:::o;22894:283::-;22953:7;22962;22971;22991:19;;:::i;:::-;-1:-1:-1;;;;;;23013:18:0;;;;;;:8;:18;;;;;;;;22991:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23071:24;23022:8;23071:14;:24::i;:::-;23116:14;;23132:16;;;;;23116:14;;23132:16;;-1:-1:-1;23132:16:0;-1:-1:-1;22894:283:0;;-1:-1:-1;;;22894:283:0:o;36898:215::-;32456:5;;-1:-1:-1;;;;;32456:5:0;32442:10;:19;32434:76;;;;-1:-1:-1;;;32434:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37002:11:::1;;36992:6;:21;;36984:71;;;;-1:-1:-1::0;;;36984:71:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37066:39;37098:6;37066:31;:39::i;:::-;36898:215:::0;:::o;5752:22::-;;;-1:-1:-1;;;;;5752:22:0;;:::o;35196:180::-;32694:12;;-1:-1:-1;;;32694:12:0;;;;32693:13;32685:48;;;;;-1:-1:-1;;;32685:48:0;;;;;;;;;;;;-1:-1:-1;;;32685:48:0;;;;;;;;;;;;;;;35289:10:::1;35310:20;35289:10:::0;35310::::1;:20::i;:::-;35341:27;35351:8;35361:6;35341:9;:27::i;36121:96::-:0;32456:5;;-1:-1:-1;;;;;32456:5:0;32442:10;:19;32434:76;;;;-1:-1:-1;;;32434:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36187:22:::1;36204:4;36187:16;:22::i;35837:139::-:0;32584:9;;-1:-1:-1;;;32584:9:0;;;;32583:10;32575:42;;;;;-1:-1:-1;;;32575:42:0;;;;;;;;;;;;-1:-1:-1;;;32575:42:0;;;;;;;;;;;;;;;35915:20:::1;35926:8;35915:10;:20::i;:::-;35946:22;35959:8;35946:12;:22::i;5835:26::-:0;;;;:::o;33112:100::-;32456:5;;-1:-1:-1;;;;;32456:5:0;32442:10;:19;32434:76;;;;-1:-1:-1;;;32434:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33176:9:::1;:28:::0;;-1:-1:-1;;;;;;33176:28:0::1;-1:-1:-1::0;;;;;33176:28:0;;;::::1;::::0;;;::::1;::::0;;33112:100::o;5660:27::-;;;;:::o;33303:164::-;32456:5;;-1:-1:-1;;;;;32456:5:0;32442:10;:19;32434:76;;;;-1:-1:-1;;;32434:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33408:51:::1;33419:15;33436:22;33408:10;:51::i;22127:196::-:0;22235:14;;22251:21;;22274:10;;22286:12;;22300:14;;22127:196;;;;;:::o;33541:503::-;32456:5;;-1:-1:-1;;;;;32456:5:0;32442:10;:19;32434:76;;;;-1:-1:-1;;;32434:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33612:11;;33608:232:::1;;33649:9;::::0;::::1;33668:5:::0;;33649:33:::1;::::0;;-1:-1:-1;;;33649:33:0;;-1:-1:-1;;;;;33668:5:0;;::::1;33649:33;::::0;::::1;::::0;;;;;;;;;:9;;;::::1;::::0;:18:::1;::::0;:33;;;;;::::1;::::0;;;;;;;;;;;;;:9;:33;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;33649:33:0;33640:59:::1;;;::::0;;-1:-1:-1;;;33640:59:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;33640:59:0;;;;;;;;;;;;;::::1;;33608:232;;;33750:9;::::0;::::1;33769:5:::0;33776:34:::1;::::0;;-1:-1:-1;;;33776:34:0;;33804:4:::1;33776:34;::::0;::::1;::::0;;;-1:-1:-1;;;;;33750:9:0;;::::1;::::0;:18:::1;::::0;33769:5:::1;::::0;33750:9;;33776:19:::1;::::0;:34;;;;;::::1;::::0;;;;;;;;;33750:9;33776:34;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;33776:34:0;33750:61:::1;::::0;;-1:-1:-1;;;;;;33750:61:0::1;::::0;;;;;;-1:-1:-1;;;;;33750:61:0;;::::1;;::::0;::::1;::::0;;;;;;;;;;;;;;33776:34:::1;::::0;33750:61;;;;;;;-1:-1:-1;33750:61:0;;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;33750:61:0;33741:87:::1;;;::::0;;-1:-1:-1;;;33741:87:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;33741:87:0;;;;;;;;;;;;;::::1;;33850:21;33857:14;33850:21:::0;;;33889:14:::1;33882:21:::0;;;33921::::1;33914:28:::0;;;-1:-1:-1;33953:17:0;;;34013:23:::1;::::0;34020:16:::1;::::0;34013:23:::1;:::i;5583:36::-:0;;;;:::o;31726:202::-;31840:7;31867:53;31879:8;31889:15;31906:13;31867:11;:53::i;:::-;31860:60;;31726:202;;;;;;:::o;5514:24::-;;;-1:-1:-1;;;5514:24:0;;;;;:::o;5783:43::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;22331:164::-;22430:14;;22446:10;;22458:12;;22472:14;;22331:164;;;;:::o;35504:161::-;32584:9;;-1:-1:-1;;;32584:9:0;;;;32583:10;32575:42;;;;;-1:-1:-1;;;32575:42:0;;;;;;;;;;;;-1:-1:-1;;;32575:42:0;;;;;;;;;;;;;;;35583:10:::1;35604:20;35583:10:::0;35604::::1;:20::i;36408:484::-:0;32456:5;;-1:-1:-1;;;;;32456:5:0;32442:10;:19;32434:76;;;;-1:-1:-1;;;32434:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36570:12:::1;36555;:27;36547:81;;;;-1:-1:-1::0;;;36547:81:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36647:16;:23:::0;:28;;:102:::1;;-1:-1:-1::0;36694:16:0::1;36711:23:::0;;-1:-1:-1;;36711:25:0;;;36694:43;::::1;;;;;;;;;;;;;;;:55;;;36679:12;:70;36647:102;36639:156;;;;-1:-1:-1::0;;;36639:156:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36806:78;36830:12;36844:15;36861:22;36806:23;:78::i;:::-;36408:484:::0;;;:::o;20523:754::-;20633:30;20674:25;20710:20;20741:16;20788:14;;20806:1;20788:19;20785:152;;;20834:16;20851:1;20834:19;;;;;;;;;;;;;;;;;;:31;;;20809:56;;20785:152;;;20906:16;20923:1;20906:19;;;;;;;;;;;;;;;;;;:31;;;20881:56;;20785:152;20970:26;20993:1;20970:14;:26::i;:::-;20950:46;;21024:14;;21009:29;;21062:57;21082:1;21086:16;21104:14;21062:11;:57::i;:::-;21051:68;;20523:754;;;;;;;:::o;5547:29::-;;;;:::o;5457:20::-;;;-1:-1:-1;;;;;5457:20:0;;:::o;34129:313::-;32456:5;;-1:-1:-1;;;;;32456:5:0;32442:10;:19;32434:76;;;;-1:-1:-1;;;32434:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34209:11;;34205:230:::1;;34246:9;::::0;::::1;34265:5:::0;;34246:33:::1;::::0;;-1:-1:-1;;;34246:33:0;;-1:-1:-1;;;;;34265:5:0;;::::1;34246:33;::::0;::::1;::::0;;;;;;;;;:9;;;::::1;::::0;:18:::1;::::0;:33;;;;;::::1;::::0;;;;;;;;;;;;;:9;:33;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;34246:33:0;34237:58:::1;;;::::0;;-1:-1:-1;;;34237:58:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;34237:58:0;;;;;;;;;;;;;::::1;;34205:230;;;34346:9;::::0;::::1;34365:5:::0;34372:34:::1;::::0;;-1:-1:-1;;;34372:34:0;;34400:4:::1;34372:34;::::0;::::1;::::0;;;-1:-1:-1;;;;;34346:9:0;;::::1;::::0;:18:::1;::::0;34365:5:::1;::::0;34346:9;;34372:19:::1;::::0;:34;;;;;::::1;::::0;;;;;;;;;34346:9;34372:34;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;34372:34:0;34346:61:::1;::::0;;-1:-1:-1;;;;;;34346:61:0::1;::::0;;;;;;-1:-1:-1;;;;;34346:61:0;;::::1;;::::0;::::1;::::0;;;;;;;;;;;;;;34372:34:::1;::::0;34346:61;;;;;;;-1:-1:-1;34346:61:0;;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;34346:61:0;34337:86:::1;;;::::0;;-1:-1:-1;;;34337:86:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;34337:86:0;;;;;;;;;;;;;::::1;34576:158:::0;34648:10;34669:20;34648:10;34669;:20::i;:::-;34700:26;34709:8;34719:6;34700:8;:26::i;5486:21::-;;;-1:-1:-1;;;5486:21:0;;;;;:::o;22503:117::-;22589:16;:23;22503:117;:::o;5868:45::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5868:45:0;:::o;36223:99::-;32456:5;;-1:-1:-1;;;;;32456:5:0;32442:10;:19;32434:76;;;;-1:-1:-1;;;32434:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36292:22:::1;36311:2;36292:18;:22::i;23185:261::-:0;23236:7;23245;23254;23274:40;23317:30;:28;:30::i;:::-;23366:14;;23382:21;;23366:14;;-1:-1:-1;23382:21:0;-1:-1:-1;23274:73:0;-1:-1:-1;;23185:261:0;;;:::o;5732:18::-;;;-1:-1:-1;;;;;5732:18:0;;:::o;22628:258::-;22694:7;22703;22712;22732:32;;:::i;:::-;22767:16;22784:5;22767:23;;;;;;;;;;;;;;;;;22732:58;;;;;;;;22767:23;;;;;;;;22732:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22732:58:0;-1:-1:-1;22628:258:0;-1:-1:-1;;;22628:258:0:o;36025:90::-;32456:5;;-1:-1:-1;;;;;32456:5:0;32442:10;:19;32434:76;;;;-1:-1:-1;;;32434:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36088:19:::1;36102:4;36088:13;:19::i;5694:29::-:0;;;;:::o;34923:138::-;34996:20;35007:8;34996:10;:20::i;:::-;35027:26;35036:8;35046:6;35027:8;:26::i;28000:2508::-;28110:7;28130:33;;:::i;:::-;28187:16;:23;28176:34;;28244:14;;28221:20;;;:37;28294:20;;;:38;;;28271:20;;;:61;;;28422:39;28317:15;28422:22;:39::i;:::-;28389:29;;;28343:118;;;28365:22;;;28343:118;;;28344:19;;;28343:118;;;28472:19;;;:41;;;28524:22;;;:47;;;;28582:29;;;:61;28656:20;;;:36;;;-1:-1:-1;;28724:18:0;;:22;;;-1:-1:-1;28703:18:0;;:43;28759:962;28796:8;;28794:10;;28759:962;;;28826:32;;:::i;:::-;28861:16;28878:1;28861:19;;;;;;;;;;;;;;;;;;28826:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28923:5;:17;;;28900:4;:20;;;:40;:85;;;;-1:-1:-1;28965:20:0;;;;28944:17;;:41;;28900:85;28897:813;;;29030:1;29028:3;;29006:19;;;:25;29079:17;;29098:20;;;;29071:48;;29079:17;29071:7;:48::i;:::-;29050:18;;;:69;;;29243:18;;;;29284:20;;;;29327:22;;;;29372:29;;;;29202:241;;:18;:241::i;:::-;29159:22;;;29138:305;;;29139:18;;;29138:305;;;;29487:17;;29464:20;;;:40;29548:20;;;;29523:45;;-1:-1:-1;29619:27:0;;;29587:29;;;:59;28897:813;;;29689:5;;;28897:813;-1:-1:-1;28806:3:0;;28759:962;;;;29759:4;:20;;;29736:4;:20;;;:43;29733:501;;;29817:51;29825:4;:20;;;29847:4;:20;;;29817:7;:51::i;:::-;29796:18;;;:72;;;29906:20;;;;29883;;;:43;30038:18;;;;30075:20;;;;30114:22;;;;30155:29;;;;30001:221;;:18;:221::i;:::-;29962:22;;;29941:281;29942:18;;;29941:281;29733:501;30246:19;;:::i;:::-;-1:-1:-1;;;;;30280:22:0;;;30276:112;;-1:-1:-1;;;;;;30312:18:0;;;;;;:8;:18;;;;;;;;;30305:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30276:112;;;30353:35;;;;;;;;30361:4;:20;;;30353:35;;;;30383:1;30353:35;;;;30386:1;30353:35;;;30346:42;;30276:112;30408:92;30416:42;30423:4;:14;;;30439:4;:18;;;30416:6;:42::i;:::-;30460:39;30468:13;30483:15;30460:7;:39::i;:::-;30408:7;:92::i;:::-;30401:99;28000:2508;-1:-1:-1;;;;;;28000:2508:0:o;23588:623::-;23653:7;23673:19;;:::i;:::-;23703:21;-1:-1:-1;;;;;23739:22:0;;;23735:271;;23786:8;:18;23795:8;-1:-1:-1;;;;;23786:18:0;-1:-1:-1;;;;;23786:18:0;;;;;;;;;;;;23779:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23835:35;23857:12;;23835:21;:35::i;:::-;23819:51;;23735:271;;;23910:29;;;;;;;;23918:14;;23910:29;;;;23934:1;23910:29;;;;23937:1;23910:29;;;23903:36;;23970:24;23992:1;23970:21;:24::i;:::-;23954:40;;23735:271;24018:16;24037:40;24045:13;24060:4;:16;;;24037:7;:40::i;:::-;24018:59;;24088:20;24111:32;24118:4;:14;;;24134:8;24111:6;:32::i;:::-;24088:55;;24163:40;24171:4;:17;;;24190:12;24163:7;:40::i;11759:3658::-;11806:7;11902:33;;:::i;:::-;11959:16;:23;11948:34;;12016:14;;11993:20;;;:37;12087:11;;12065:19;;;:33;;;12043:19;;;:55;;;12134:12;-1:-1:-1;12111:20:0;;:35;12203:12;;-1:-1:-1;12180:20:0;;:35;;;12157:20;;;:58;12270:10;;12249:18;;;:31;;;12228:18;;;:52;12341:14;;12316:22;;;:39;;;12291:22;;;:64;12430:21;;12398:29;;;:53;;;12366:29;;;:85;12464:1623;12501:8;;12499:10;;12464:1623;;;12531:32;;:::i;:::-;12566:16;12583:1;12566:19;;;;;;;;;;;;;;;;;;12531:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12774:5;:17;;;12751:4;:20;;;:40;:85;;;;-1:-1:-1;12816:20:0;;;;12795:17;;:41;;12751:85;12748:1328;;;12881:1;12879:3;;12857:19;;;:25;13002:17;;13021:20;;;;12994:48;;13002:17;12994:7;:48::i;:::-;12973:18;;;:69;;;13166:18;;;;13207:20;;;;13250:22;;;;13295:29;;;;13125:241;;:18;:241::i;:::-;13082:22;;;13061:305;;;13062:18;;;13061:305;;;;13494:17;;13471:20;;;:40;13555:20;;;;;;13530:45;;;-1:-1:-1;13626:27:0;;;;;13594:29;;;:59;13859:17;;13878:20;;13900:27;;13840:88;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13840:88:0;;;12748:1328;;;14055:5;;;12748:1328;-1:-1:-1;12511:3:0;;12464:1623;;;;14286:4;:20;;;14263:4;:20;;;:43;14259:503;;;14345:51;14353:4;:20;;;14375:4;:20;;;14345:7;:51::i;:::-;14324:18;;;:72;;;14434:20;;;;14411;;;:43;14566:18;;;;14603:20;;;;14642:22;;;;14683:29;;;;14529:221;;:18;:221::i;:::-;14490:22;;;14469:281;14470:18;;;14469:281;14259:503;14902:4;:20;;;14878:4;:20;;;:44;14875:84;;14939:20;;;;14924:12;:35;14875:84;14996:4;:19;;;14973:4;:19;;;:42;14970:80;;15031:19;;;;15017:11;:33;14970:80;15086:4;:18;;;15064:4;:18;;;:40;15061:76;;15119:18;;;;15106:10;:31;15061:76;15177:4;:22;;;15151:4;:22;;;:48;15148:92;;15218:22;;;;15201:14;:39;15148:92;15287:4;:29;;;15254:4;:29;;;:62;15251:120;;15342:29;;;;15318:21;:53;15251:120;15391:18;;;;-1:-1:-1;11759:3658:0;:::o;18814:266::-;18916:56;;;;;;;;;;;;;;;;;;;;;;;;;18983:14;:32;;;;19026:21;:46;18814:266::o;18013:557::-;18104:16;:23;18146:8;;;;;:24;;;18167:3;18158:6;:12;18146:24;18138:75;;;;-1:-1:-1;;;18138:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18226:32;;:::i;:::-;18261:16;18278:6;18261:24;;;;;;;;;;;;;;;;;18226:59;;;;;;;;;18261:24;;;;;;;18226:59;;;;;;;;;;;;;;;;;;;;;;;;;;18301:111;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;18406:5:0;;18301:111;;;;;;18226:59;;-1:-1:-1;18301:111:0;;;;;;;;;18437:6;18423:106;18451:1;18447:3;:5;18445:1;:7;18423:106;;;18496:16;18513:1;18515;18513:3;18496:21;;;;;;;;;;;;;;;;;;18474:16;18491:1;18474:19;;;;;;;;;;;;;;;;:43;;:19;;;;;:43;;;;;;;;;;;;;;;;;;;;;;;;;18454:3;18423:106;;;;18539:16;:22;;;;;;;;;;;;;;;-1:-1:-1;;18539:22:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;18013:557:0:o;10318:504::-;10376:19;;:::i;:::-;-1:-1:-1;;;;;;10398:18:0;;;;;;:8;:18;;;;;;;;10376:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10453:19;:17;:19::i;:::-;10429:43;;10485:16;10504:40;10512:13;10527:4;:16;;;10504:7;:40::i;:::-;10485:59;;10555:20;10578:32;10585:4;:14;;;10601:8;10578:6;:32::i;:::-;10555:55;;10646:13;10626:4;:16;;;:33;10623:84;;-1:-1:-1;;;;;10661:18:0;;;;;;:8;:18;;;;;:30;;:46;;;10623:84;10721:17;;10718:96;;10774:40;10782:4;:17;;;10801:12;10774:7;:40::i;:::-;-1:-1:-1;;;;;10740:18:0;;;;;;:8;:18;;;;;:31;;:74;10718:96;10318:504;;;;;:::o;9350:716::-;9423:19;;:::i;:::-;-1:-1:-1;;;;;;9445:18:0;;;;;;:8;:18;;;;;;;;;9423:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9497:14;;;9530:24;-1:-1:-1;9530:24:0;9522:60;;;;;-1:-1:-1;;;9522:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;9620:14;;9612:31;;9636:6;9612:7;:31::i;:::-;9595:48;;;-1:-1:-1;;;;;9654:18:0;;9595:14;9654:18;;;:8;:18;;;;;:45;9733:14;;9725:31;;9749:6;9725:7;:31::i;:::-;9767:14;:29;;;9710:46;-1:-1:-1;9812:10:0;;9809:250;;9945:14;;9918:56;;;-1:-1:-1;;;;;9918:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9998:5;;:32;;;-1:-1:-1;;;9998:32:0;;-1:-1:-1;;;;;9998:32:0;;;;;;;;;;;;;;;:5;;;;;:14;;:32;;;;;;;;;;;;;;:5;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9998:32:0;9989:58;;;;;-1:-1:-1;;;9989:58:0;;;;;;;;;;;;-1:-1:-1;;;9989:58:0;;;;;;;;;;;;;;;9350:716;;;;:::o;19979:118::-;20041:18;;;;;;;;;;;;;;;;;;;20070:12;:19;;;;;-1:-1:-1;;;20070:19:0;-1:-1:-1;;;;20070:19:0;;;;;;;;;19979:118::o;11012:448::-;11072:19;;:::i;:::-;-1:-1:-1;;;;;;11094:18:0;;;;;;:8;:18;;;;;;;;;11072:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11128:22;11125:328;;11184:17;;;;;-1:-1:-1;;;;;11216:18:0;;11167:14;11216:18;;;:8;:18;;;;;;;:31;;:35;;;;11342:23;;;;;;;;;;;;11184:17;;11342:23;;;;;;;;;11388:9;;:36;;;-1:-1:-1;;;11388:36:0;;-1:-1:-1;;;;;11388:36:0;;;;;;;;;;;;;;;:9;;;;;:18;;:36;;;;;;;;;;;;;;:9;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11388:36:0;11380:61;;;;;-1:-1:-1;;;11380:61:0;;;;;;;;;;;;-1:-1:-1;;;11380:61:0;;;;;;;;;;;;;;17328:385;17460:35;;:::i;:::-;17498:74;;;;;;;;17518:12;17498:74;;;;17532:15;17498:74;;;;17549:22;17498:74;;;17460:112;;17588:75;17609:12;17623:15;17640:22;17588:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17674:16;:31;;;;;;;-1:-1:-1;17674:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;17328:385:0:o;8484:663::-;8556:19;;:::i;:::-;-1:-1:-1;;;;;;8578:18:0;;;;;;:8;:18;;;;;;;;;8556:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8630:14;;;8674:31;;8698:6;8674:7;:31::i;:::-;8657:48;;;-1:-1:-1;;;;;8716:18:0;;8657:14;8716:18;;;:8;:18;;;;;:45;8795:14;;8787:31;;8811:6;8787:7;:31::i;:::-;8829:14;:29;;;8772:46;-1:-1:-1;8874:10:0;;8871:269;;9005:14;;8979:55;;;-1:-1:-1;;;;;8979:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9058:5;;:53;;;-1:-1:-1;;;9058:53:0;;9077:10;9058:53;;;;9097:4;9058:53;;;;;;;;;;;;-1:-1:-1;;;;;9058:5:0;;;;:18;;:53;;;;;;;;;;;;;;;:5;;:53;;;;;;;;;;20105:127;20170:33;;;20188:10;20170:33;;-1:-1:-1;;;;;20170:33:0;;;;;;;;;;;;;;;;;;;20214:5;:10;;-1:-1:-1;;;;;;20214:10:0;-1:-1:-1;;;;;20214:10:0;;;;;;;;;;20105:127::o;23454:126::-;23517:7;23544:28;23568:1;23544:14;:28::i;:::-;23537:35;;23454:126;:::o;19862:109::-;19921:15;;;;;;;;;;;;;;;;;;;19947:9;:16;;;;;-1:-1:-1;;;19947:16:0;-1:-1:-1;;;;19947:16:0;;;;;;;;;19862:109::o;30516:1202::-;30762:16;:23;30593:7;;;;;;;;;;;;;;30800:15;;30796:508;;30841:1;30837:5;;30833:460;30848:11;30844:1;:15;30833:460;;;30885:32;;:::i;:::-;30920:16;30937:1;30920:19;;;;;;;;;;;;;;;;;;30885:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30977:5;:17;;;30961:12;:33;;:59;;;;-1:-1:-1;31003:17:0;;30998:22;;30961:59;30958:319;;;31060:1;31045:16;;31102:5;:20;;;31084:38;;31158:5;:27;;;31145:40;;30958:319;;;31220:17;;31211:66;;31240:8;;;31211:66;31272:5;;;31211:66;30833:460;;30861:3;;;;;30833:460;;;31314:32;;:::i;:::-;31349:16;31366:12;31349:30;;;;;;;;;;;;;;;;;31314:65;;;;;;;;31349:30;;;;;;;31314:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31314:65:0;-1:-1:-1;31314:65:0;-1:-1:-1;31493:32:0;;31490:171;;;31560:89;31568:15;31585:62;31593:10;31605:40;31613:12;31627:5;:17;;;31605:7;:40::i;:::-;31585:7;:62::i;:::-;31560:7;:89::i;:::-;31542:107;;31490:171;-1:-1:-1;31679:1:0;;31682:15;;-1:-1:-1;31699:10:0;;-1:-1:-1;30516:1202:0;;-1:-1:-1;;;;30516:1202:0:o;882:162::-;944:7;977:1;972;:6;;964:49;;;;;-1:-1:-1;;;964:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1031:5:0;;;882:162::o;15818:1067::-;16031:7;;;16105:27;;16102:246;;16171:48;16179:15;16196:22;16171:7;:48::i;:::-;16153:66;;16249:15;16241:5;:23;16238:94;;;16274:15;16266:23;;16238:94;;;-1:-1:-1;16331:1:0;16238:94;16364:16;16398:18;;16395:261;;16448:129;16456:74;16483:15;16500:5;16507:22;16456:26;:74::i;:::-;16532:43;16541:26;418:7;16553:13;16541:6;:26::i;:::-;16569:5;16532:7;:43::i;:::-;16448:6;:129::i;:::-;16437:140;;16610:30;16618:11;16631:8;16610:7;:30::i;:::-;16596:44;;16395:261;16675:20;;16672:151;;16715:1;16697:19;;16672:151;;;16754:69;16776:15;16793:22;16817:5;16754:21;:69::i;:::-;16736:87;;16672:151;-1:-1:-1;16848:11:0;;16861:15;;-1:-1:-1;15818:1067:0;;-1:-1:-1;;;;;15818:1067:0:o;564:124::-;625:7;652:28;661:13;669:1;672;661:7;:13::i;:::-;418:7;1283:157;1345:7;1377:1;1373;:5;1365:44;;;;;-1:-1:-1;;;1365:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;1430:1;1428;:3;;;;;;;1283:157;-1:-1:-1;;;1283:157:0:o;24219:3429::-;24298:7;24394:33;;:::i;:::-;24451:16;:23;24440:34;;24508:14;;24485:20;;;:37;24538:20;24535:876;;24618:1;24596:19;;;:23;;;24574:19;;;:45;;;24659:12;24636:20;;;:35;24709:20;;;:24;;;24686:20;;;:47;;;24769:18;;;:22;;;24748:18;;;:43;;;24831:22;;;:26;;;24806:22;;;:51;;;24904:29;;;:33;;;24872:29;;;:65;24535:876;;;25014:11;;24992:19;;;:33;;;24970:19;;;:55;25063:12;25040:20;;;:35;25113:20;;;:38;;;25090:20;;;:61;;;25210:10;;25189:18;;;:31;;;25168:18;;;:52;25285:14;;25260:22;;;:39;;;25235:22;;;:64;25378:21;;25346:29;;;:53;;;25314:29;;;:85;24535:876;25437:19;;;;25423:1509;25460:8;;25458:10;;25423:1509;;;25490:32;;:::i;:::-;25525:16;25542:1;25525:19;;;;;;;;;;;;;;;;;;25490:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25731:5;:17;;;25708:4;:20;;;:40;:85;;;;-1:-1:-1;25773:20:0;;;;25752:17;;:41;;25708:85;25705:1216;;;25838:1;25836:3;;25814:19;;;:25;25959:17;;25978:20;;;;25951:48;;25959:17;25951:7;:48::i;:::-;25930:18;;;:69;;;26123:18;;;;26164:20;;;;26207:22;;;;26252:29;;;;26082:241;;:18;:241::i;:::-;26039:22;;;26018:305;;;26019:18;;;26018:305;;;;26451:17;;26428:20;;;:40;26512:20;;;;26487:45;;-1:-1:-1;26583:27:0;;;26551:29;;;:59;25705:1216;;;26900:5;;;25705:1216;-1:-1:-1;25470:3:0;;25423:1509;;;;27130:4;:20;;;27107:4;:20;;;:43;27104:501;;;27188:51;27196:4;:20;;;27218:4;:20;;;27188:7;:51::i;:::-;27167:18;;;:72;;;27277:20;;;;27254;;;:43;27409:18;;;;27446:20;;;;27485:22;;;;27526:29;;;;27372:221;;:18;:221::i;:::-;27333:22;;;27312:281;27313:18;;;27312:281;27104:501;27622:18;;;;24219:3429;-1:-1:-1;;24219:3429:0:o;694:182::-;756:7;788:5;;;812:6;;;;804:45;;;;;-1:-1:-1;;;804:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;1050:227;1112:7;1135:6;1132:23;;-1:-1:-1;1152:1:0;1145:8;;1132:23;1177:5;;;1181:1;1177;:5;:1;1203:3;;;;;1202:10;1193:57;;;;-1:-1:-1;;;1193:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19204:473;19296:7;19543:5;;19539:130;;19570:62;19578:50;19587:12;19595:1;19597;19587:7;:12::i;:::-;19601:25;19610:12;19618:1;19620;19610:7;:12::i;:::-;19624:1;19601:7;:25::i;19578:50::-;19630:1;19570:7;:62::i;:::-;19563:69;;;;19539:130;-1:-1:-1;19668:1:0;19661:8;;434:124;495:7;522:28;531:15;539:1;418:7;531;:15::i;:::-;548:1;522:7;:28::i;19685:169::-;19783:7;19810:36;19818:6;19826:19;19834:3;19839:5;19826:7;:19::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

ipfs://c4a83c86d0f7ef3050ab249a43e9a049c0888eb6032b03d57b942652efa27fd9

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.