false
false
0

Contract Address Details

0xa20E39a3587cA7c3d790925c3875765669B323A1

Contract Name
SOYLocalFarm
Creator
0xc7d98c–7f3521 at 0x5207cc–1f3000
Balance
0 CLO
Tokens
Fetching tokens...
Transactions
38 Transactions
Transfers
974 Transfers
Gas Used
3,806,219
Last Balance Update
16285478
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
SOYLocalFarm




Optimization enabled
true
Compiler version
v0.8.0+commit.c7dfd78e




Optimization runs
200
EVM Version
default




Verified at
2024-09-26T15:34:14.796599Z

Constructor Arguments

0x00000000000000000000000064fa36acd0d13472fd786b03afc9c52ad5fcf0230000000000000000000000009fae2529863bd691b4a7171bdfcf33c7ebb10a6500000000000000000000000093aa120b5195337d71c1af424b616c8ed5510305

Arg [0] (address) : 0x64fa36acd0d13472fd786b03afc9c52ad5fcf023
Arg [1] (address) : 0x9fae2529863bd691b4a7171bdfcf33c7ebb10a65
Arg [2] (address) : 0x93aa120b5195337d71c1af424b616c8ed5510305

              

Contract source code

// SPDX-License-Identifier: No License (None)
pragma solidity 0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow, so we distribute
        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
    }
}

abstract contract IERC223 {
    /**
     * @dev Returns the balance of the `who` address.
     */
    function balanceOf(address who) public virtual view returns (uint);
        
    /**
     * @dev Transfers `value` tokens from `msg.sender` to `to` address
     * and returns `true` on success.
     */
    function transfer(address to, uint value) public virtual returns (bool success);
        
    /**
     * @dev Transfers `value` tokens from `msg.sender` to `to` address with `data` parameter
     * and returns `true` on success.
     */
    function transfer(address to, uint value, bytes memory data) public virtual returns (bool success);
     
     /**
     * @dev Event that is fired on successful transfer.
     */
    event Transfer(address indexed from, address indexed to, uint value);
    
     /**
     * @dev Additional event that is fired on successful transfer and logs transfer metadata,
     *      this event is implemented to keep Transfer event compatible with ERC20.
     */
    event TransferData(bytes data);
}

abstract contract IERC223Recipient {
    
 struct ERC223TransferInfo
    {
        address token_contract;
        address sender;
        uint256 value;
        bytes   data;
    }
    ERC223TransferInfo private tkn;
    
/**
 * @dev Standard ERC223 function that will handle incoming token transfers.
 *
 * @param _from  Token sender address.
 * @param _value Amount of tokens.
 * @param _data  Transaction metadata.
 */
    function tokenReceived(address _from, uint _value, bytes calldata _data) public virtual;
}


/**
 * @dev Collection of functions related to the address type,
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * This test is non-exhaustive, and there may be false-negatives: during the
     * execution of a contract's constructor, its address will be reported as
     * not containing a contract.
     *
     * > It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies in extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }
}

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the `nonReentrant` modifier
 * available, which can be aplied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 */
contract ReentrancyGuard {
    /// @dev counter to allow mutex lock with only one SSTORE operation
    uint256 private _guardCounter;

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _guardCounter += 1;
        uint256 localCounter = _guardCounter;
        _;
        require(localCounter == _guardCounter, "ReentrancyGuard: reentrant call");
    }
}

abstract contract RewardsRecipient {
    address public globalFarm;

    function notifyRewardAmount(uint256 reward) external virtual;

    modifier onlyGlobalFarm() {
        require(msg.sender == globalFarm, "Caller is not global Farm contract");
        _;
    }
}


interface ISimplifiedGlobalFarm {
    function mintFarmingReward(address _localFarm) external;
    function getAllocationX1000(address _farm) external view returns (uint256);
    function getRewardPerSecond() external view returns (uint256);
    function rewardMintingAvailable(address _farm) external view returns (bool);
    function farmExists(address _farmAddress) external view returns (bool);
}


/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 *
 * Source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/v2.1.3/contracts/ownership/Ownable.sol
 * This contract is copied here and renamed from the original to avoid clashes in the compiled artifacts
 * when the user imports a zos-lib contract (that transitively causes this contract to be compiled and added to the
 * build/artifacts folder) as well as the vanilla Ownable implementation from an openzeppelin version.
 */
contract Ownable {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev The Ownable constructor sets the original `owner` of the contract to the sender
     * account.
     */
    constructor () {
        _owner = msg.sender;
        emit OwnershipTransferred(address(0), _owner);
    }

    /**
     * @return the address of the owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner(),"Not Owner");
        _;
    }

    /**
     * @return true if `msg.sender` is the owner of the contract.
     */
    function isOwner() public view returns (bool) {
        return msg.sender == _owner;
    }

    /**
     * @dev Allows the current owner to relinquish control of the contract.
     * @notice Renouncing to ownership will leave the contract without an owner.
     * It will not be possible to call the functions with the `onlyOwner`
     * modifier anymore.
     */
    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Allows the current owner to transfer control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0),"Zero address not allowed");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

contract SOYLocalFarm is IERC223Recipient, ReentrancyGuard, RewardsRecipient, Ownable
{

    /* ========== EVENTS ========== */

    event RewardAdded(uint256 reward);
    event Staked(address indexed user, uint256 amount);
    event Withdraw(address indexed user, uint256 amount);
    event EmergencyWithdraw(address indexed user, uint256 amount);
    event RewardPaid(address indexed user, uint256 reward);
    
    
    /* ========== VARIABLES ========== */

    struct UserInfo {
        uint256 amount;     // How many LP tokens the user has provided.
        uint256 rewardDebt; // Reward debt. See explanation below.
    }
    // Info of each user that stakes LP tokens.
    mapping (address => UserInfo) public userInfo;
    
    uint256 public limitAmount = 1e40; // Prevents accumulatedRewardPerShare from overflowing.
    
    IERC223 public rewardsToken;
    IERC223 public lpToken;
    
    uint256 public lastRewardTimestamp;  // Last block number that SOY distribution occurs.
    uint256 public accumulatedRewardPerShare; // Accumulated SOY per share, times 1e18. See below.

    /* ========== CONSTRUCTOR ========== */

    constructor(
        address _rewardsDistribution,   // GlobalFarm contract
        address _rewardsToken,          // SOY token
        address _lpToken           // LP token that will be staked in this Local Farm
    )
    {
        rewardsToken        = IERC223(_rewardsToken);
        lpToken             = IERC223(_lpToken);
        globalFarm          = _rewardsDistribution;
    }
    
    bool active = false;
    
    modifier onlyActive {
        require(active, "The farm is not enabled by owner!");
        _;
    }
    
    function setActive(bool _status) external onlyOwner
    {
        active = _status;
    }
    
    /* ========== ERC223 transaction handlers ====== */
    
    // Analogue of deposit() function.
    function tokenReceived(address _from, uint256 _amount, bytes memory _data) public override nonReentrant onlyActive
    {
        require(msg.sender == address(lpToken), "Trying to deposit wrong token");
        require(userInfo[_from].amount + _amount <= limitAmount, 'exceed the top');

        update();
        if (userInfo[_from].amount > 0) {
            uint256 pending = userInfo[_from].amount * accumulatedRewardPerShare / 1e18 - userInfo[_from].rewardDebt;
            if(pending > 0) {
                rewardsToken.transfer(address(_from), pending);
            }
        }
        if(_amount > 0) {
            userInfo[_from].amount += _amount;
        }
        userInfo[_from].rewardDebt = userInfo[_from].amount * accumulatedRewardPerShare / 1e18;
        
        emit Staked(_from, _amount);
    }
    
    
    function notifyRewardAmount(uint256 reward) external override
    {
        emit RewardAdded(reward);
    }
    
    function getRewardPerSecond() public view returns (uint256)
    {
        return ISimplifiedGlobalFarm(globalFarm).getRewardPerSecond();
    }
    
    function getAllocationX1000() public view returns (uint256)
    {
        return ISimplifiedGlobalFarm(globalFarm).getAllocationX1000(address(this));
    }
    
    /* ========== Farm Functions ====== */

    // View function to see pending Reward on frontend.
    function pendingReward(address _user) external view returns (uint256) {
        UserInfo storage user = userInfo[_user];
        uint256 _accumulatedRewardPerShare = accumulatedRewardPerShare;
        uint256 lpSupply = lpToken.balanceOf(address(this));
        if (block.timestamp > lastRewardTimestamp && lpSupply != 0) {
            uint256 multiplier = block.timestamp - lastRewardTimestamp;
            uint256 _reward = multiplier * getRewardPerSecond() * getAllocationX1000() / 1000;
            _accumulatedRewardPerShare = accumulatedRewardPerShare + (_reward * 1e18 / lpSupply);
        }
        return user.amount * _accumulatedRewardPerShare / 1e18 - user.rewardDebt;
    }
    
    

    // Update reward variables of this Local Farm to be up-to-date.
    function update() public reward_request {
        if (block.timestamp <= lastRewardTimestamp) {
            return;
        }
        uint256 lpSupply = lpToken.balanceOf(address(this));
       
        if (lpSupply == 0) {
            lastRewardTimestamp = block.timestamp;
            return;
        }
        uint256 multiplier = block.timestamp - lastRewardTimestamp;
        
        // This silently calculates "assumed" reward!
        // This function does not take contract's actual balance into account
        // Global Farm and `reward_request` modifier are responsible for keeping this contract
        // stocked with funds to pay actual rewards.
        
        uint256 _reward = multiplier * getRewardPerSecond() * getAllocationX1000() / 1000;
        accumulatedRewardPerShare = accumulatedRewardPerShare + (_reward * 1e18 / lpSupply);
        lastRewardTimestamp = block.timestamp;
    }
    
    

    // Withdraw tokens from STAKING.
    function withdraw(uint256 _amount) public nonReentrant {
        UserInfo storage user = userInfo[msg.sender];
        require(user.amount >= _amount, "withdraw: not good");
        
        update();
        uint256 pending = user.amount * accumulatedRewardPerShare / 1e18 - user.rewardDebt;
        if(pending > 0) {
            rewardsToken.transfer(address(msg.sender), pending);
        }
        if(_amount > 0) {
            user.amount = user.amount - _amount;
            lpToken.transfer(address(msg.sender), _amount);
        }
        user.rewardDebt = user.amount * accumulatedRewardPerShare / 1e18;

        emit Withdraw(msg.sender, _amount);
    }

    // Withdraw without caring about rewards. EMERGENCY ONLY.
    function emergencyWithdraw() public nonReentrant {
        UserInfo storage user = userInfo[msg.sender];
        lpToken.transfer(address(msg.sender), user.amount);
        emit EmergencyWithdraw(msg.sender, user.amount);
        user.amount = 0;
        user.rewardDebt = 0;
    }
    
    // Special function that allows owner to withdraw remaining unclaimed tokens of inactive farms
    function withdrawInactiveReward() public onlyOwner
    {
        require(!ISimplifiedGlobalFarm(globalFarm).farmExists(address(this)), "Farm must not be active");
        
        rewardsToken.transfer(msg.sender, rewardsToken.balanceOf(address(this)));
    }

/*
    // Withdraw reward. EMERGENCY ONLY.
    function emergencyRewardWithdraw(uint256 _amount) public onlyOwner {
        require(_amount < rewardToken.balanceOf(address(this)), 'not enough token');
        rewardsToken.transfer(address(msg.sender), _amount);
    }
    */
    
    
    modifier reward_request
    {
        if(ISimplifiedGlobalFarm(globalFarm).rewardMintingAvailable(address(this)))
        {
            ISimplifiedGlobalFarm(globalFarm).mintFarmingReward(address(this));
        }
        _;
    }
    
    function rescueERC20(address token, address to) external onlyOwner {
        require(token != address(rewardsToken), "Reward token is not prone to ERC20 issues");
        require(token != address(lpToken), "LP token is not prone to ERC20 issues");
        
        uint256 value = IERC223(token).balanceOf(address(this));
        IERC223(token).transfer(to, value);
    }
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_rewardsDistribution","internalType":"address"},{"type":"address","name":"_rewardsToken","internalType":"address"},{"type":"address","name":"_lpToken","internalType":"address"}]},{"type":"event","name":"EmergencyWithdraw","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RewardAdded","inputs":[{"type":"uint256","name":"reward","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"RewardPaid","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"reward","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Staked","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Withdraw","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"accumulatedRewardPerShare","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"emergencyWithdraw","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getAllocationX1000","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getRewardPerSecond","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"globalFarm","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isOwner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastRewardTimestamp","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"limitAmount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC223"}],"name":"lpToken","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"notifyRewardAmount","inputs":[{"type":"uint256","name":"reward","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"pendingReward","inputs":[{"type":"address","name":"_user","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"rescueERC20","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"address","name":"to","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC223"}],"name":"rewardsToken","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setActive","inputs":[{"type":"bool","name":"_status","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"tokenReceived","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"update","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"rewardDebt","internalType":"uint256"}],"name":"userInfo","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawInactiveReward","inputs":[]}]
              

Contract Creation Code

Verify & Publish
0x6080604052701d6329f1c35ca4bfabb9f5610000000000600855600d805460ff191690553480156200003057600080fd5b506040516200183938038062001839833981016040819052620000539162000102565b600680546001600160a01b0319163317908190556040516001600160a01b0391909116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3600980546001600160a01b039384166001600160a01b031991821617909155600a805492841692821692909217909155600580549390921692169190911790556200014b565b80516001600160a01b0381168114620000fd57600080fd5b919050565b60008060006060848603121562000117578283fd5b6200012284620000e5565b92506200013260208501620000e5565b91506200014260408501620000e5565b90509250925092565b6116de806200015b6000396000f3fe608060405234801561001057600080fd5b50600436106101425760003560e01c80638cb7e27c116100b8578063d1af0c7d1161007c578063d1af0c7d14610249578063da5b4ee714610251578063db2e21bc14610259578063f2fde38b14610261578063f40f0f5214610274578063f8077fae1461028757610142565b80638cb7e27c146102095780638da5cb5b146102115780638f32d59b14610219578063a2e620451461022e578063acec338a1461023657610142565b80634f3a1ff81161010a5780634f3a1ff8146101b65780635d799f87146101cb5780635fcbd285146101de578063715018a6146101e657806378abafaf146101ee5780638943ec02146101f657610142565b80631959a002146101475780631e29653c146101715780632e1a7d4d1461018657806336d421951461019b5780633c6b16ab146101a3575b600080fd5b61015a610155366004611217565b61028f565b6040516101689291906115f2565b60405180910390f35b6101796102a8565b60405161016891906115e9565b61019961019436600461135f565b61032e565b005b610179610571565b6101996101b136600461135f565b610577565b6101be6105b1565b604051610168919061138f565b6101996101d9366004611238565b6105c0565b6101be610748565b610199610757565b6101796107c5565b61019961020436600461126a565b6107cb565b610199610a5f565b6101be610c1c565b610221610c2b565b60405161016891906113bc565b610199610c3c565b610199610244366004611327565b610e42565b6101be610e79565b610179610e88565b610199610ecd565b61019961026f366004611217565b610fe9565b610179610282366004611217565b611016565b610179611178565b6007602052600090815260409020805460019091015482565b60055460405163389bbbfd60e21b81526000916001600160a01b03169063e26eeff4906102d990309060040161138f565b60206040518083038186803b1580156102f157600080fd5b505afa158015610305573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103299190611377565b905090565b6001600460008282546103419190611600565b909155505060045433600090815260076020526040902080548311156103825760405162461bcd60e51b81526004016103799061154f565b60405180910390fd5b61038a610c3c565b60008160010154670de0b6b3a7640000600c5484600001546103ac9190611638565b6103b69190611618565b6103c09190611657565b9050801561044e5760095460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906103fa90339085906004016113a3565b602060405180830381600087803b15801561041457600080fd5b505af1158015610428573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061044c9190611343565b505b83156104e9578154610461908590611657565b8255600a5460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061049590339088906004016113a3565b602060405180830381600087803b1580156104af57600080fd5b505af11580156104c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e79190611343565b505b600c548254670de0b6b3a76400009161050191611638565b61050b9190611618565b600183015560405133907f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364906105429087906115e9565b60405180910390a25050600454811461056d5760405162461bcd60e51b8152600401610379906115b2565b5050565b600c5481565b7fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d816040516105a691906115e9565b60405180910390a150565b6005546001600160a01b031681565b6105c8610c2b565b6105e45760405162461bcd60e51b8152600401610379906114a6565b6009546001600160a01b03838116911614156106125760405162461bcd60e51b8152600401610379906113c7565b600a546001600160a01b03838116911614156106405760405162461bcd60e51b8152600401610379906114c9565b6040516370a0823160e01b81526000906001600160a01b038416906370a082319061066f90309060040161138f565b60206040518083038186803b15801561068757600080fd5b505afa15801561069b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106bf9190611377565b60405163a9059cbb60e01b81529091506001600160a01b0384169063a9059cbb906106f090859085906004016113a3565b602060405180830381600087803b15801561070a57600080fd5b505af115801561071e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107429190611343565b50505050565b600a546001600160a01b031681565b61075f610c2b565b61077b5760405162461bcd60e51b8152600401610379906114a6565b6006546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600680546001600160a01b0319169055565b60085481565b6001600460008282546107de9190611600565b9091555050600454600d5460ff166108085760405162461bcd60e51b81526004016103799061150e565b600a546001600160a01b031633146108325760405162461bcd60e51b815260040161037990611410565b6008546001600160a01b038516600090815260076020526040902054610859908590611600565b11156108775760405162461bcd60e51b815260040161037990611447565b61087f610c3c565b6001600160a01b03841660009081526007602052604090205415610979576001600160a01b03841660009081526007602052604081206001810154600c5491549091670de0b6b3a7640000916108d59190611638565b6108df9190611618565b6108e99190611657565b905080156109775760095460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061092390889085906004016113a3565b602060405180830381600087803b15801561093d57600080fd5b505af1158015610951573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109759190611343565b505b505b82156109ad576001600160a01b038416600090815260076020526040812080548592906109a7908490611600565b90915550505b600c546001600160a01b038516600090815260076020526040902054670de0b6b3a7640000916109dc91611638565b6109e69190611618565b6001600160a01b038516600081815260076020526040908190206001019290925590517f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d90610a369086906115e9565b60405180910390a260045481146107425760405162461bcd60e51b8152600401610379906115b2565b610a67610c2b565b610a835760405162461bcd60e51b8152600401610379906114a6565b600554604051630d18304560e21b81526001600160a01b0390911690633460c11490610ab390309060040161138f565b60206040518083038186803b158015610acb57600080fd5b505afa158015610adf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b039190611343565b15610b205760405162461bcd60e51b81526004016103799061146f565b6009546040516370a0823160e01b81526001600160a01b039091169063a9059cbb90339083906370a0823190610b5a90309060040161138f565b60206040518083038186803b158015610b7257600080fd5b505afa158015610b86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610baa9190611377565b6040518363ffffffff1660e01b8152600401610bc79291906113a3565b602060405180830381600087803b158015610be157600080fd5b505af1158015610bf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c199190611343565b50565b6006546001600160a01b031690565b6006546001600160a01b0316331490565b60055460405163445c92c560e01b81526001600160a01b039091169063445c92c590610c6c90309060040161138f565b60206040518083038186803b158015610c8457600080fd5b505afa158015610c98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cbc9190611343565b15610d245760055460405163032453f160e51b81526001600160a01b039091169063648a7e2090610cf190309060040161138f565b600060405180830381600087803b158015610d0b57600080fd5b505af1158015610d1f573d6000803e3d6000fd5b505050505b600b544211610d3257610e40565b600a546040516370a0823160e01b81526000916001600160a01b0316906370a0823190610d6390309060040161138f565b60206040518083038186803b158015610d7b57600080fd5b505afa158015610d8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db39190611377565b905080610dc4575042600b55610e40565b6000600b5442610dd49190611657565b905060006103e8610de36102a8565b610deb610e88565b610df59085611638565b610dff9190611638565b610e099190611618565b905082610e1e82670de0b6b3a7640000611638565b610e289190611618565b600c54610e359190611600565b600c55505042600b55505b565b610e4a610c2b565b610e665760405162461bcd60e51b8152600401610379906114a6565b600d805460ff1916911515919091179055565b6009546001600160a01b031681565b6005546040805163da5b4ee760e01b815290516000926001600160a01b03169163da5b4ee7916004808301926020929190829003018186803b1580156102f157600080fd5b600160046000828254610ee09190611600565b9091555050600480543360008181526007602052604090819020600a548154925163a9059cbb60e01b8152949591946001600160a01b039091169363a9059cbb93610f2f9391929091016113a3565b602060405180830381600087803b158015610f4957600080fd5b505af1158015610f5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f819190611343565b50805460405133917f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd969591610fb591906115e9565b60405180910390a260008082556001909101556004548114610c195760405162461bcd60e51b8152600401610379906115b2565b610ff1610c2b565b61100d5760405162461bcd60e51b8152600401610379906114a6565b610c198161117e565b6001600160a01b03808216600090815260076020526040808220600c54600a5492516370a0823160e01b8152939491939092859216906370a082319061106090309060040161138f565b60206040518083038186803b15801561107857600080fd5b505afa15801561108c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b09190611377565b9050600b54421180156110c257508015155b1561113d576000600b54426110d79190611657565b905060006103e86110e66102a8565b6110ee610e88565b6110f89085611638565b6111029190611638565b61110c9190611618565b90508261112182670de0b6b3a7640000611638565b61112b9190611618565b600c546111389190611600565b935050505b60018301548354670de0b6b3a764000090611159908590611638565b6111639190611618565b61116d9190611657565b93505050505b919050565b600b5481565b6001600160a01b0381166111a45760405162461bcd60e51b81526004016103799061157b565b6006546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600680546001600160a01b0319166001600160a01b0392909216919091179055565b80356001600160a01b038116811461117357600080fd5b600060208284031215611228578081fd5b61123182611200565b9392505050565b6000806040838503121561124a578081fd5b61125383611200565b915061126160208401611200565b90509250929050565b60008060006060848603121561127e578081fd5b61128784611200565b92506020808501359250604085013567ffffffffffffffff808211156112ab578384fd5b818701915087601f8301126112be578384fd5b8135818111156112d0576112d0611684565b604051601f8201601f19168101850183811182821017156112f3576112f3611684565b60405281815283820185018a1015611309578586fd5b81858501868301378585838301015280955050505050509250925092565b600060208284031215611338578081fd5b81356112318161169a565b600060208284031215611354578081fd5b81516112318161169a565b600060208284031215611370578081fd5b5035919050565b600060208284031215611388578081fd5b5051919050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b60208082526029908201527f52657761726420746f6b656e206973206e6f742070726f6e6520746f2045524360408201526832302069737375657360b81b606082015260800190565b6020808252601d908201527f547279696e6720746f206465706f7369742077726f6e6720746f6b656e000000604082015260600190565b6020808252600e908201526d06578636565642074686520746f760941b604082015260600190565b60208082526017908201527f4661726d206d757374206e6f7420626520616374697665000000000000000000604082015260600190565b6020808252600990820152682737ba1027bbb732b960b91b604082015260600190565b60208082526025908201527f4c5020746f6b656e206973206e6f742070726f6e6520746f2045524332302069604082015264737375657360d81b606082015260800190565b60208082526021908201527f546865206661726d206973206e6f7420656e61626c6564206279206f776e65726040820152602160f81b606082015260800190565b6020808252601290820152711dda5d1a191c985dce881b9bdd0819dbdbd960721b604082015260600190565b60208082526018908201527f5a65726f2061646472657373206e6f7420616c6c6f7765640000000000000000604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b90815260200190565b918252602082015260400190565b600082198211156116135761161361166e565b500190565b60008261163357634e487b7160e01b81526012600452602481fd5b500490565b60008160001904831182151516156116525761165261166e565b500290565b6000828210156116695761166961166e565b500390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b8015158114610c1957600080fdfea26469706673582212207b494474d824a4da49636d51f940c5f48389dea855e45c170783fffda8373d3564736f6c6343000800003300000000000000000000000064fa36acd0d13472fd786b03afc9c52ad5fcf0230000000000000000000000009fae2529863bd691b4a7171bdfcf33c7ebb10a6500000000000000000000000093aa120b5195337d71c1af424b616c8ed5510305

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101425760003560e01c80638cb7e27c116100b8578063d1af0c7d1161007c578063d1af0c7d14610249578063da5b4ee714610251578063db2e21bc14610259578063f2fde38b14610261578063f40f0f5214610274578063f8077fae1461028757610142565b80638cb7e27c146102095780638da5cb5b146102115780638f32d59b14610219578063a2e620451461022e578063acec338a1461023657610142565b80634f3a1ff81161010a5780634f3a1ff8146101b65780635d799f87146101cb5780635fcbd285146101de578063715018a6146101e657806378abafaf146101ee5780638943ec02146101f657610142565b80631959a002146101475780631e29653c146101715780632e1a7d4d1461018657806336d421951461019b5780633c6b16ab146101a3575b600080fd5b61015a610155366004611217565b61028f565b6040516101689291906115f2565b60405180910390f35b6101796102a8565b60405161016891906115e9565b61019961019436600461135f565b61032e565b005b610179610571565b6101996101b136600461135f565b610577565b6101be6105b1565b604051610168919061138f565b6101996101d9366004611238565b6105c0565b6101be610748565b610199610757565b6101796107c5565b61019961020436600461126a565b6107cb565b610199610a5f565b6101be610c1c565b610221610c2b565b60405161016891906113bc565b610199610c3c565b610199610244366004611327565b610e42565b6101be610e79565b610179610e88565b610199610ecd565b61019961026f366004611217565b610fe9565b610179610282366004611217565b611016565b610179611178565b6007602052600090815260409020805460019091015482565b60055460405163389bbbfd60e21b81526000916001600160a01b03169063e26eeff4906102d990309060040161138f565b60206040518083038186803b1580156102f157600080fd5b505afa158015610305573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103299190611377565b905090565b6001600460008282546103419190611600565b909155505060045433600090815260076020526040902080548311156103825760405162461bcd60e51b81526004016103799061154f565b60405180910390fd5b61038a610c3c565b60008160010154670de0b6b3a7640000600c5484600001546103ac9190611638565b6103b69190611618565b6103c09190611657565b9050801561044e5760095460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906103fa90339085906004016113a3565b602060405180830381600087803b15801561041457600080fd5b505af1158015610428573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061044c9190611343565b505b83156104e9578154610461908590611657565b8255600a5460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061049590339088906004016113a3565b602060405180830381600087803b1580156104af57600080fd5b505af11580156104c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e79190611343565b505b600c548254670de0b6b3a76400009161050191611638565b61050b9190611618565b600183015560405133907f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364906105429087906115e9565b60405180910390a25050600454811461056d5760405162461bcd60e51b8152600401610379906115b2565b5050565b600c5481565b7fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d816040516105a691906115e9565b60405180910390a150565b6005546001600160a01b031681565b6105c8610c2b565b6105e45760405162461bcd60e51b8152600401610379906114a6565b6009546001600160a01b03838116911614156106125760405162461bcd60e51b8152600401610379906113c7565b600a546001600160a01b03838116911614156106405760405162461bcd60e51b8152600401610379906114c9565b6040516370a0823160e01b81526000906001600160a01b038416906370a082319061066f90309060040161138f565b60206040518083038186803b15801561068757600080fd5b505afa15801561069b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106bf9190611377565b60405163a9059cbb60e01b81529091506001600160a01b0384169063a9059cbb906106f090859085906004016113a3565b602060405180830381600087803b15801561070a57600080fd5b505af115801561071e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107429190611343565b50505050565b600a546001600160a01b031681565b61075f610c2b565b61077b5760405162461bcd60e51b8152600401610379906114a6565b6006546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600680546001600160a01b0319169055565b60085481565b6001600460008282546107de9190611600565b9091555050600454600d5460ff166108085760405162461bcd60e51b81526004016103799061150e565b600a546001600160a01b031633146108325760405162461bcd60e51b815260040161037990611410565b6008546001600160a01b038516600090815260076020526040902054610859908590611600565b11156108775760405162461bcd60e51b815260040161037990611447565b61087f610c3c565b6001600160a01b03841660009081526007602052604090205415610979576001600160a01b03841660009081526007602052604081206001810154600c5491549091670de0b6b3a7640000916108d59190611638565b6108df9190611618565b6108e99190611657565b905080156109775760095460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061092390889085906004016113a3565b602060405180830381600087803b15801561093d57600080fd5b505af1158015610951573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109759190611343565b505b505b82156109ad576001600160a01b038416600090815260076020526040812080548592906109a7908490611600565b90915550505b600c546001600160a01b038516600090815260076020526040902054670de0b6b3a7640000916109dc91611638565b6109e69190611618565b6001600160a01b038516600081815260076020526040908190206001019290925590517f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d90610a369086906115e9565b60405180910390a260045481146107425760405162461bcd60e51b8152600401610379906115b2565b610a67610c2b565b610a835760405162461bcd60e51b8152600401610379906114a6565b600554604051630d18304560e21b81526001600160a01b0390911690633460c11490610ab390309060040161138f565b60206040518083038186803b158015610acb57600080fd5b505afa158015610adf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b039190611343565b15610b205760405162461bcd60e51b81526004016103799061146f565b6009546040516370a0823160e01b81526001600160a01b039091169063a9059cbb90339083906370a0823190610b5a90309060040161138f565b60206040518083038186803b158015610b7257600080fd5b505afa158015610b86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610baa9190611377565b6040518363ffffffff1660e01b8152600401610bc79291906113a3565b602060405180830381600087803b158015610be157600080fd5b505af1158015610bf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c199190611343565b50565b6006546001600160a01b031690565b6006546001600160a01b0316331490565b60055460405163445c92c560e01b81526001600160a01b039091169063445c92c590610c6c90309060040161138f565b60206040518083038186803b158015610c8457600080fd5b505afa158015610c98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cbc9190611343565b15610d245760055460405163032453f160e51b81526001600160a01b039091169063648a7e2090610cf190309060040161138f565b600060405180830381600087803b158015610d0b57600080fd5b505af1158015610d1f573d6000803e3d6000fd5b505050505b600b544211610d3257610e40565b600a546040516370a0823160e01b81526000916001600160a01b0316906370a0823190610d6390309060040161138f565b60206040518083038186803b158015610d7b57600080fd5b505afa158015610d8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db39190611377565b905080610dc4575042600b55610e40565b6000600b5442610dd49190611657565b905060006103e8610de36102a8565b610deb610e88565b610df59085611638565b610dff9190611638565b610e099190611618565b905082610e1e82670de0b6b3a7640000611638565b610e289190611618565b600c54610e359190611600565b600c55505042600b55505b565b610e4a610c2b565b610e665760405162461bcd60e51b8152600401610379906114a6565b600d805460ff1916911515919091179055565b6009546001600160a01b031681565b6005546040805163da5b4ee760e01b815290516000926001600160a01b03169163da5b4ee7916004808301926020929190829003018186803b1580156102f157600080fd5b600160046000828254610ee09190611600565b9091555050600480543360008181526007602052604090819020600a548154925163a9059cbb60e01b8152949591946001600160a01b039091169363a9059cbb93610f2f9391929091016113a3565b602060405180830381600087803b158015610f4957600080fd5b505af1158015610f5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f819190611343565b50805460405133917f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd969591610fb591906115e9565b60405180910390a260008082556001909101556004548114610c195760405162461bcd60e51b8152600401610379906115b2565b610ff1610c2b565b61100d5760405162461bcd60e51b8152600401610379906114a6565b610c198161117e565b6001600160a01b03808216600090815260076020526040808220600c54600a5492516370a0823160e01b8152939491939092859216906370a082319061106090309060040161138f565b60206040518083038186803b15801561107857600080fd5b505afa15801561108c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b09190611377565b9050600b54421180156110c257508015155b1561113d576000600b54426110d79190611657565b905060006103e86110e66102a8565b6110ee610e88565b6110f89085611638565b6111029190611638565b61110c9190611618565b90508261112182670de0b6b3a7640000611638565b61112b9190611618565b600c546111389190611600565b935050505b60018301548354670de0b6b3a764000090611159908590611638565b6111639190611618565b61116d9190611657565b93505050505b919050565b600b5481565b6001600160a01b0381166111a45760405162461bcd60e51b81526004016103799061157b565b6006546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600680546001600160a01b0319166001600160a01b0392909216919091179055565b80356001600160a01b038116811461117357600080fd5b600060208284031215611228578081fd5b61123182611200565b9392505050565b6000806040838503121561124a578081fd5b61125383611200565b915061126160208401611200565b90509250929050565b60008060006060848603121561127e578081fd5b61128784611200565b92506020808501359250604085013567ffffffffffffffff808211156112ab578384fd5b818701915087601f8301126112be578384fd5b8135818111156112d0576112d0611684565b604051601f8201601f19168101850183811182821017156112f3576112f3611684565b60405281815283820185018a1015611309578586fd5b81858501868301378585838301015280955050505050509250925092565b600060208284031215611338578081fd5b81356112318161169a565b600060208284031215611354578081fd5b81516112318161169a565b600060208284031215611370578081fd5b5035919050565b600060208284031215611388578081fd5b5051919050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b60208082526029908201527f52657761726420746f6b656e206973206e6f742070726f6e6520746f2045524360408201526832302069737375657360b81b606082015260800190565b6020808252601d908201527f547279696e6720746f206465706f7369742077726f6e6720746f6b656e000000604082015260600190565b6020808252600e908201526d06578636565642074686520746f760941b604082015260600190565b60208082526017908201527f4661726d206d757374206e6f7420626520616374697665000000000000000000604082015260600190565b6020808252600990820152682737ba1027bbb732b960b91b604082015260600190565b60208082526025908201527f4c5020746f6b656e206973206e6f742070726f6e6520746f2045524332302069604082015264737375657360d81b606082015260800190565b60208082526021908201527f546865206661726d206973206e6f7420656e61626c6564206279206f776e65726040820152602160f81b606082015260800190565b6020808252601290820152711dda5d1a191c985dce881b9bdd0819dbdbd960721b604082015260600190565b60208082526018908201527f5a65726f2061646472657373206e6f7420616c6c6f7765640000000000000000604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b90815260200190565b918252602082015260400190565b600082198211156116135761161361166e565b500190565b60008261163357634e487b7160e01b81526012600452602481fd5b500490565b60008160001904831182151516156116525761165261166e565b500290565b6000828210156116695761166961166e565b500390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b8015158114610c1957600080fdfea26469706673582212207b494474d824a4da49636d51f940c5f48389dea855e45c170783fffda8373d3564736f6c63430008000033