Address Details
contract

0x572564B0efEC39Dd325138187F5DD4e75B17251E

Contract Name
StakingRewards
Creator
0x9ee360–7a65d2 at 0x326c20–38c74d
Balance
0 CELO ( )
Locked CELO Balance
0.00 CELO
Voting CELO Balance
0.00 CELO
Pending Unlocked Gold
0.00 CELO
Tokens
Fetching tokens...
Transactions
14,703 Transactions
Transfers
15,289 Transfers
Gas Used
1,175,014,932
Last Balance Update
24266522
This contract has been verified via Sourcify. View contract in Sourcify repository
Contract name:
StakingRewards




Optimization enabled
true
Compiler version
v0.8.3+commit.8d00100c




Optimization runs
999999
EVM Version
istanbul




Verified at
2021-05-02T20:52:29.209587Z

Contract source code

// SPDX-License-Identifier: MIT
// solhint-disable not-rely-on-time

pragma solidity ^0.8.3;

import "../../openzeppelin-solidity/contracts/Math.sol";
import "../../openzeppelin-solidity/contracts/SafeMath.sol";
import "../../openzeppelin-solidity/contracts/SafeERC20.sol";
import "../../openzeppelin-solidity/contracts/ReentrancyGuard.sol";

// Inheritance
import "./interfaces/IStakingRewards.sol";
import "./RewardsDistributionRecipient.sol";


// https://docs.synthetix.io/contracts/source/contracts/stakingrewards
// XXX: removed Pausable
contract StakingRewards is IStakingRewards, RewardsDistributionRecipient, ReentrancyGuard {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    /* ========== STATE VARIABLES ========== */

    IERC20 public rewardsToken;
    IERC20 public stakingToken;
    uint256 public periodFinish = 0;
    uint256 public rewardRate = 0;
    uint256 public rewardsDuration = 7 days;
    uint256 public lastUpdateTime;
    uint256 public rewardPerTokenStored;

    mapping(address => uint256) public userRewardPerTokenPaid;
    mapping(address => uint256) public rewards;

    uint256 private _totalSupply;
    mapping(address => uint256) private _balances;

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

    constructor(
        address _owner,
        address _rewardsDistribution,
        address _rewardsToken,
        address _stakingToken
    ) Owned(_owner) {
        rewardsToken = IERC20(_rewardsToken);
        stakingToken = IERC20(_stakingToken);
        rewardsDistribution = _rewardsDistribution;
    }

    /* ========== VIEWS ========== */

    function totalSupply() external view override returns (uint256) {
        return _totalSupply;
    }

    function balanceOf(address account) external view override returns (uint256) {
        return _balances[account];
    }

    function lastTimeRewardApplicable() public view override returns (uint256) {
        return Math.min(block.timestamp, periodFinish);
    }

    function rewardPerToken() public view override returns (uint256) {
        if (_totalSupply == 0) {
            return rewardPerTokenStored;
        }
        return
            rewardPerTokenStored.add(
                lastTimeRewardApplicable().sub(lastUpdateTime).mul(rewardRate).mul(1e18).div(_totalSupply)
            );
    }

    function earned(address account) public view override returns (uint256) {
        return _balances[account].mul(rewardPerToken().sub(userRewardPerTokenPaid[account])).div(1e18).add(rewards[account]);
    }

    function getRewardForDuration() external view override returns (uint256) {
        return rewardRate.mul(rewardsDuration);
    }

    /* ========== MUTATIVE FUNCTIONS ========== */

    // XXX: removed notPaused
    function stake(uint256 amount) external override nonReentrant updateReward(msg.sender) {
        require(amount > 0, "Cannot stake 0");
        _totalSupply = _totalSupply.add(amount);
        _balances[msg.sender] = _balances[msg.sender].add(amount);
        stakingToken.safeTransferFrom(msg.sender, address(this), amount);
        emit Staked(msg.sender, amount);
    }

    function withdraw(uint256 amount) public override nonReentrant updateReward(msg.sender) {
        require(amount > 0, "Cannot withdraw 0");
        _totalSupply = _totalSupply.sub(amount);
        _balances[msg.sender] = _balances[msg.sender].sub(amount);
        stakingToken.safeTransfer(msg.sender, amount);
        emit Withdrawn(msg.sender, amount);
    }

    function getReward() public override nonReentrant updateReward(msg.sender) {
        uint256 reward = rewards[msg.sender];
        if (reward > 0) {
            rewards[msg.sender] = 0;
            rewardsToken.safeTransfer(msg.sender, reward);
            emit RewardPaid(msg.sender, reward);
        }
    }

    function exit() external override {
        withdraw(_balances[msg.sender]);
        getReward();
    }

    /* ========== RESTRICTED FUNCTIONS ========== */

    function notifyRewardAmount(uint256 reward) external override onlyRewardsDistribution updateReward(address(0)) {
        if (block.timestamp >= periodFinish) {
            rewardRate = reward.div(rewardsDuration);
        } else {
            uint256 remaining = periodFinish.sub(block.timestamp);
            uint256 leftover = remaining.mul(rewardRate);
            rewardRate = reward.add(leftover).div(rewardsDuration);
        }

        // Ensure the provided reward amount is not more than the balance in the contract.
        // This keeps the reward rate in the right range, preventing overflows due to
        // very high values of rewardRate in the earned and rewardsPerToken functions;
        // Reward + leftover must be less than 2^256 / 10^18 to avoid overflow.
        uint balance = rewardsToken.balanceOf(address(this));
        require(rewardRate <= balance.div(rewardsDuration), "Provided reward too high");

        lastUpdateTime = block.timestamp;
        periodFinish = block.timestamp.add(rewardsDuration);
        emit RewardAdded(reward);
    }

    // End rewards emission earlier
    function updatePeriodFinish(uint timestamp) external onlyOwner updateReward(address(0)) {
        periodFinish = timestamp;
    }

    // Added to support recovering LP Rewards from other systems such as BAL to be distributed to holders
    function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner {
        require(tokenAddress != address(stakingToken), "Cannot withdraw the staking token");
        IERC20(tokenAddress).safeTransfer(owner, tokenAmount);
        emit Recovered(tokenAddress, tokenAmount);
    }

    function setRewardsDuration(uint256 _rewardsDuration) external onlyOwner {
        require(
            block.timestamp > periodFinish,
            "Previous rewards period must be complete before changing the duration for the new period"
        );
        rewardsDuration = _rewardsDuration;
        emit RewardsDurationUpdated(rewardsDuration);
    }

    /* ========== MODIFIERS ========== */

    modifier updateReward(address account) {
        rewardPerTokenStored = rewardPerToken();
        lastUpdateTime = lastTimeRewardApplicable();
        if (account != address(0)) {
            rewards[account] = earned(account);
            userRewardPerTokenPaid[account] = rewardPerTokenStored;
        }
        _;
    }

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

    event RewardAdded(uint256 reward);
    event Staked(address indexed user, uint256 amount);
    event Withdrawn(address indexed user, uint256 amount);
    event RewardPaid(address indexed user, uint256 reward);
    event RewardsDurationUpdated(uint256 newDuration);
    event Recovered(address token, uint256 amount);
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"address","name":"_rewardsDistribution","internalType":"address"},{"type":"address","name":"_rewardsToken","internalType":"address"},{"type":"address","name":"_stakingToken","internalType":"address"}]},{"type":"event","name":"OwnerChanged","inputs":[{"type":"address","name":"oldOwner","internalType":"address","indexed":false},{"type":"address","name":"newOwner","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"OwnerNominated","inputs":[{"type":"address","name":"newOwner","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"Recovered","inputs":[{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"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":"RewardsDurationUpdated","inputs":[{"type":"uint256","name":"newDuration","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":"Withdrawn","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"earned","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"exit","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"getReward","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getRewardForDuration","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastTimeRewardApplicable","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastUpdateTime","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"nominateNewOwner","inputs":[{"type":"address","name":"_owner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"nominatedOwner","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":"periodFinish","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"recoverERC20","inputs":[{"type":"address","name":"tokenAddress","internalType":"address"},{"type":"uint256","name":"tokenAmount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewardPerToken","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewardPerTokenStored","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewardRate","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewards","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"rewardsDistribution","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewardsDuration","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC20"}],"name":"rewardsToken","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setRewardsDistribution","inputs":[{"type":"address","name":"_rewardsDistribution","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setRewardsDuration","inputs":[{"type":"uint256","name":"_rewardsDuration","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"stake","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC20"}],"name":"stakingToken","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updatePeriodFinish","inputs":[{"type":"uint256","name":"timestamp","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"userRewardPerTokenPaid","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]}]
              

Contract Creation Code

0x60806040526000600655600060075562093a806008553480156200002257600080fd5b5060405162001bc438038062001bc4833981016040819052620000459162000162565b836001600160a01b038116620000a15760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f74206265203000000000000000604482015260640160405180910390fd5b600080546001600160a01b0319166001600160a01b03831690811782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1506001600355600480546001600160a01b039384166001600160a01b03199182161790915560058054928416928216929092179091556002805493909216921691909117905550620001be565b80516001600160a01b03811681146200015d57600080fd5b919050565b6000806000806080858703121562000178578384fd5b620001838562000145565b9350620001936020860162000145565b9250620001a36040860162000145565b9150620001b36060860162000145565b905092959194509250565b6119f680620001ce6000396000f3fe608060405234801561001057600080fd5b50600436106101ce5760003560e01c806372f702f311610104578063a694fc3a116100a2578063d1af0c7d11610071578063d1af0c7d146103f9578063df136d6514610419578063e9fad8ee14610422578063ebe2b12b1461042a576101ce565b8063a694fc3a146103c2578063c8f33c91146103d5578063cc1a378f146103de578063cd3daf9d146103f1576101ce565b806380faa57d116100de57806380faa57d146103675780638980f11f1461036f5780638b876347146103825780638da5cb5b146103a2576101ce565b806372f702f31461033657806379ba5097146103565780637b0a47ee1461035e576101ce565b8063386a9525116101715780633fc6df6e1161014b5780633fc6df6e1461028857806353a47bb7146102cd578063556f6e6b146102ed57806370a0823114610300576101ce565b8063386a9525146102645780633c6b16ab1461026d5780633d18b91214610280576101ce565b806318160ddd116101ad57806318160ddd1461022e57806319762143146102365780631c1f78eb146102495780632e1a7d4d14610251576101ce565b80628cc262146101d35780630700037d146101f95780631627540c14610219575b600080fd5b6101e66101e13660046117c0565b610433565b6040519081526020015b60405180910390f35b6101e66102073660046117c0565b600c6020526000908152604090205481565b61022c6102273660046117c0565b6104cd565b005b6101e661054f565b61022c6102443660046117c0565b610556565b6101e66105a5565b61022c61025f366004611823565b6105c3565b6101e660085481565b61022c61027b366004611823565b6107bb565b61022c610ab1565b6002546102a89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6001546102a89073ffffffffffffffffffffffffffffffffffffffff1681565b61022c6102fb366004611823565b610c1f565b6101e661030e3660046117c0565b73ffffffffffffffffffffffffffffffffffffffff166000908152600e602052604090205490565b6005546102a89073ffffffffffffffffffffffffffffffffffffffff1681565b61022c610ca3565b6101e660075481565b6101e6610dee565b61022c61037d3660046117da565b610dfc565b6101e66103903660046117c0565b600b6020526000908152604090205481565b6000546102a89073ffffffffffffffffffffffffffffffffffffffff1681565b61022c6103d0366004611823565b610f29565b6101e660095481565b61022c6103ec366004611823565b611110565b6101e6611204565b6004546102a89073ffffffffffffffffffffffffffffffffffffffff1681565b6101e6600a5481565b61022c611252565b6101e660065481565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600c6020908152604080832054600b9092528220546104c591906104bf90670de0b6b3a7640000906104b99061048d90610487611204565b90611275565b73ffffffffffffffffffffffffffffffffffffffff88166000908152600e602052604090205490611288565b90611294565b906112a0565b90505b919050565b6104d56112ac565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906020015b60405180910390a150565b600d545b90565b61055e6112ac565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105be60085460075461128890919063ffffffff16565b905090565b60026003541415610635576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b600260035533610643611204565b600a5561064e610dee565b60095573ffffffffffffffffffffffffffffffffffffffff8116156106af5761067681610433565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600c6020908152604080832093909355600a54600b909152919020555b60008211610719576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f43616e6e6f742077697468647261772030000000000000000000000000000000604482015260640161062c565b600d546107269083611275565b600d55336000908152600e60205260409020546107439083611275565b336000818152600e602052604090209190915560055461077c9173ffffffffffffffffffffffffffffffffffffffff9091169084611353565b60405182815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5906020015b60405180910390a250506001600355565b60025473ffffffffffffffffffffffffffffffffffffffff163314610862576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f43616c6c6572206973206e6f742052657761726473446973747269627574696f60448201527f6e20636f6e747261637400000000000000000000000000000000000000000000606482015260840161062c565b600061086c611204565b600a55610877610dee565b60095573ffffffffffffffffffffffffffffffffffffffff8116156108d85761089f81610433565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600c6020908152604080832093909355600a54600b909152919020555b60065442106108f7576008546108ef908390611294565b60075561093a565b6006546000906109079042611275565b905060006109206007548361128890919063ffffffff16565b600854909150610934906104b986846112a0565b60075550505b600480546040517f70a08231000000000000000000000000000000000000000000000000000000008152309281019290925260009173ffffffffffffffffffffffffffffffffffffffff909116906370a082319060240160206040518083038186803b1580156109a957600080fd5b505afa1580156109bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e1919061183b565b90506109f86008548261129490919063ffffffff16565b6007541115610a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f50726f76696465642072657761726420746f6f20686967680000000000000000604482015260640161062c565b426009819055600854610a7691906112a0565b6006556040518381527fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9060200160405180910390a1505050565b60026003541415610b1e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161062c565b600260035533610b2c611204565b600a55610b37610dee565b60095573ffffffffffffffffffffffffffffffffffffffff811615610b9857610b5f81610433565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600c6020908152604080832093909355600a54600b909152919020555b336000908152600c60205260409020548015610c1657336000818152600c6020526040812055600454610be49173ffffffffffffffffffffffffffffffffffffffff9091169083611353565b60405181815233907fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486906020016107aa565b50506001600355565b610c276112ac565b6000610c31611204565b600a55610c3c610dee565b60095573ffffffffffffffffffffffffffffffffffffffff811615610c9d57610c6481610433565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600c6020908152604080832093909355600a54600b909152919020555b50600655565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527f2063616e20616363657074206f776e6572736869700000000000000000000000606482015260840161062c565b6000546001546040805173ffffffffffffffffffffffffffffffffffffffff93841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160018054600080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff841617909155169055565b60006105be4260065461142c565b610e046112ac565b60055473ffffffffffffffffffffffffffffffffffffffff83811691161415610eaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f43616e6e6f7420776974686472617720746865207374616b696e6720746f6b6560448201527f6e00000000000000000000000000000000000000000000000000000000000000606482015260840161062c565b600054610ed69073ffffffffffffffffffffffffffffffffffffffff848116911683611353565b6040805173ffffffffffffffffffffffffffffffffffffffff84168152602081018390527f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa28910160405180910390a15050565b60026003541415610f96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161062c565b600260035533610fa4611204565b600a55610faf610dee565b60095573ffffffffffffffffffffffffffffffffffffffff81161561101057610fd781610433565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600c6020908152604080832093909355600a54600b909152919020555b6000821161107a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f43616e6e6f74207374616b652030000000000000000000000000000000000000604482015260640161062c565b600d5461108790836112a0565b600d55336000908152600e60205260409020546110a490836112a0565b336000818152600e60205260409020919091556005546110de9173ffffffffffffffffffffffffffffffffffffffff909116903085611442565b60405182815233907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d906020016107aa565b6111186112ac565b60065442116111cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605860248201527f50726576696f7573207265776172647320706572696f64206d7573742062652060448201527f636f6d706c657465206265666f7265206368616e67696e67207468652064757260648201527f6174696f6e20666f7220746865206e657720706572696f640000000000000000608482015260a40161062c565b60088190556040518181527ffb46ca5a5e06d4540d6387b930a7c978bce0db5f449ec6b3f5d07c6e1d44f2d390602001610544565b6000600d546000141561121a5750600a54610553565b6105be611249600d546104b9670de0b6b3a7640000611243600754611243600954610487610dee565b90611288565b600a54906112a0565b336000908152600e602052604090205461126b906105c3565b611273610ab1565b565b6000611281828461194e565b9392505050565b60006112818284611911565b600061128182846118d8565b600061128182846118c0565b60005473ffffffffffffffffffffffffffffffffffffffff163314611273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201527f6f726d207468697320616374696f6e0000000000000000000000000000000000606482015260840161062c565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526114279084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526114a6565b505050565b600081831061143b5781611281565b5090919050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526114a09085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016113a5565b50505050565b6000611508826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166115b29092919063ffffffff16565b80519091501561142757808060200190518101906115269190611803565b611427576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161062c565b60606115c184846000856115c9565b949350505050565b60608247101561165b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161062c565b843b6116c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161062c565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516116ec9190611853565b60006040518083038185875af1925050503d8060008114611729576040519150601f19603f3d011682016040523d82523d6000602084013e61172e565b606091505b509150915061173e828286611749565b979650505050505050565b60608315611758575081611281565b8251156117685782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161062c919061186f565b803573ffffffffffffffffffffffffffffffffffffffff811681146104c857600080fd5b6000602082840312156117d1578081fd5b6112818261179c565b600080604083850312156117ec578081fd5b6117f58361179c565b946020939093013593505050565b600060208284031215611814578081fd5b81518015158114611281578182fd5b600060208284031215611834578081fd5b5035919050565b60006020828403121561184c578081fd5b5051919050565b60008251611865818460208701611965565b9190910192915050565b600060208252825180602084015261188e816040850160208701611965565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600082198211156118d3576118d3611991565b500190565b60008261190c577f4e487b710000000000000000000000000000000000000000000000000000000081526012600452602481fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561194957611949611991565b500290565b60008282101561196057611960611991565b500390565b60005b83811015611980578181015183820152602001611968565b838111156114a05750506000910152565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea26469706673582212204741156476b1119a35758ba68769b1a7738761c3a0698f422dff39246b0a32a164736f6c634300080300330000000000000000000000009ee3600543eccc85020d6bc77eb553d1747a65d20000000000000000000000009ee3600543eccc85020d6bc77eb553d1747a65d200000000000000000000000000be915b9dcf56a3cbe739d9b9c202ca692409ec0000000000000000000000008c89f7bb791d94e10eed4eb78d0e886c82d7a2e3

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101ce5760003560e01c806372f702f311610104578063a694fc3a116100a2578063d1af0c7d11610071578063d1af0c7d146103f9578063df136d6514610419578063e9fad8ee14610422578063ebe2b12b1461042a576101ce565b8063a694fc3a146103c2578063c8f33c91146103d5578063cc1a378f146103de578063cd3daf9d146103f1576101ce565b806380faa57d116100de57806380faa57d146103675780638980f11f1461036f5780638b876347146103825780638da5cb5b146103a2576101ce565b806372f702f31461033657806379ba5097146103565780637b0a47ee1461035e576101ce565b8063386a9525116101715780633fc6df6e1161014b5780633fc6df6e1461028857806353a47bb7146102cd578063556f6e6b146102ed57806370a0823114610300576101ce565b8063386a9525146102645780633c6b16ab1461026d5780633d18b91214610280576101ce565b806318160ddd116101ad57806318160ddd1461022e57806319762143146102365780631c1f78eb146102495780632e1a7d4d14610251576101ce565b80628cc262146101d35780630700037d146101f95780631627540c14610219575b600080fd5b6101e66101e13660046117c0565b610433565b6040519081526020015b60405180910390f35b6101e66102073660046117c0565b600c6020526000908152604090205481565b61022c6102273660046117c0565b6104cd565b005b6101e661054f565b61022c6102443660046117c0565b610556565b6101e66105a5565b61022c61025f366004611823565b6105c3565b6101e660085481565b61022c61027b366004611823565b6107bb565b61022c610ab1565b6002546102a89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6001546102a89073ffffffffffffffffffffffffffffffffffffffff1681565b61022c6102fb366004611823565b610c1f565b6101e661030e3660046117c0565b73ffffffffffffffffffffffffffffffffffffffff166000908152600e602052604090205490565b6005546102a89073ffffffffffffffffffffffffffffffffffffffff1681565b61022c610ca3565b6101e660075481565b6101e6610dee565b61022c61037d3660046117da565b610dfc565b6101e66103903660046117c0565b600b6020526000908152604090205481565b6000546102a89073ffffffffffffffffffffffffffffffffffffffff1681565b61022c6103d0366004611823565b610f29565b6101e660095481565b61022c6103ec366004611823565b611110565b6101e6611204565b6004546102a89073ffffffffffffffffffffffffffffffffffffffff1681565b6101e6600a5481565b61022c611252565b6101e660065481565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600c6020908152604080832054600b9092528220546104c591906104bf90670de0b6b3a7640000906104b99061048d90610487611204565b90611275565b73ffffffffffffffffffffffffffffffffffffffff88166000908152600e602052604090205490611288565b90611294565b906112a0565b90505b919050565b6104d56112ac565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906020015b60405180910390a150565b600d545b90565b61055e6112ac565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105be60085460075461128890919063ffffffff16565b905090565b60026003541415610635576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b600260035533610643611204565b600a5561064e610dee565b60095573ffffffffffffffffffffffffffffffffffffffff8116156106af5761067681610433565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600c6020908152604080832093909355600a54600b909152919020555b60008211610719576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f43616e6e6f742077697468647261772030000000000000000000000000000000604482015260640161062c565b600d546107269083611275565b600d55336000908152600e60205260409020546107439083611275565b336000818152600e602052604090209190915560055461077c9173ffffffffffffffffffffffffffffffffffffffff9091169084611353565b60405182815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5906020015b60405180910390a250506001600355565b60025473ffffffffffffffffffffffffffffffffffffffff163314610862576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f43616c6c6572206973206e6f742052657761726473446973747269627574696f60448201527f6e20636f6e747261637400000000000000000000000000000000000000000000606482015260840161062c565b600061086c611204565b600a55610877610dee565b60095573ffffffffffffffffffffffffffffffffffffffff8116156108d85761089f81610433565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600c6020908152604080832093909355600a54600b909152919020555b60065442106108f7576008546108ef908390611294565b60075561093a565b6006546000906109079042611275565b905060006109206007548361128890919063ffffffff16565b600854909150610934906104b986846112a0565b60075550505b600480546040517f70a08231000000000000000000000000000000000000000000000000000000008152309281019290925260009173ffffffffffffffffffffffffffffffffffffffff909116906370a082319060240160206040518083038186803b1580156109a957600080fd5b505afa1580156109bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e1919061183b565b90506109f86008548261129490919063ffffffff16565b6007541115610a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f50726f76696465642072657761726420746f6f20686967680000000000000000604482015260640161062c565b426009819055600854610a7691906112a0565b6006556040518381527fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9060200160405180910390a1505050565b60026003541415610b1e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161062c565b600260035533610b2c611204565b600a55610b37610dee565b60095573ffffffffffffffffffffffffffffffffffffffff811615610b9857610b5f81610433565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600c6020908152604080832093909355600a54600b909152919020555b336000908152600c60205260409020548015610c1657336000818152600c6020526040812055600454610be49173ffffffffffffffffffffffffffffffffffffffff9091169083611353565b60405181815233907fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486906020016107aa565b50506001600355565b610c276112ac565b6000610c31611204565b600a55610c3c610dee565b60095573ffffffffffffffffffffffffffffffffffffffff811615610c9d57610c6481610433565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600c6020908152604080832093909355600a54600b909152919020555b50600655565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527f2063616e20616363657074206f776e6572736869700000000000000000000000606482015260840161062c565b6000546001546040805173ffffffffffffffffffffffffffffffffffffffff93841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160018054600080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff841617909155169055565b60006105be4260065461142c565b610e046112ac565b60055473ffffffffffffffffffffffffffffffffffffffff83811691161415610eaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f43616e6e6f7420776974686472617720746865207374616b696e6720746f6b6560448201527f6e00000000000000000000000000000000000000000000000000000000000000606482015260840161062c565b600054610ed69073ffffffffffffffffffffffffffffffffffffffff848116911683611353565b6040805173ffffffffffffffffffffffffffffffffffffffff84168152602081018390527f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa28910160405180910390a15050565b60026003541415610f96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161062c565b600260035533610fa4611204565b600a55610faf610dee565b60095573ffffffffffffffffffffffffffffffffffffffff81161561101057610fd781610433565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600c6020908152604080832093909355600a54600b909152919020555b6000821161107a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f43616e6e6f74207374616b652030000000000000000000000000000000000000604482015260640161062c565b600d5461108790836112a0565b600d55336000908152600e60205260409020546110a490836112a0565b336000818152600e60205260409020919091556005546110de9173ffffffffffffffffffffffffffffffffffffffff909116903085611442565b60405182815233907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d906020016107aa565b6111186112ac565b60065442116111cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605860248201527f50726576696f7573207265776172647320706572696f64206d7573742062652060448201527f636f6d706c657465206265666f7265206368616e67696e67207468652064757260648201527f6174696f6e20666f7220746865206e657720706572696f640000000000000000608482015260a40161062c565b60088190556040518181527ffb46ca5a5e06d4540d6387b930a7c978bce0db5f449ec6b3f5d07c6e1d44f2d390602001610544565b6000600d546000141561121a5750600a54610553565b6105be611249600d546104b9670de0b6b3a7640000611243600754611243600954610487610dee565b90611288565b600a54906112a0565b336000908152600e602052604090205461126b906105c3565b611273610ab1565b565b6000611281828461194e565b9392505050565b60006112818284611911565b600061128182846118d8565b600061128182846118c0565b60005473ffffffffffffffffffffffffffffffffffffffff163314611273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201527f6f726d207468697320616374696f6e0000000000000000000000000000000000606482015260840161062c565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526114279084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526114a6565b505050565b600081831061143b5781611281565b5090919050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526114a09085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016113a5565b50505050565b6000611508826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166115b29092919063ffffffff16565b80519091501561142757808060200190518101906115269190611803565b611427576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161062c565b60606115c184846000856115c9565b949350505050565b60608247101561165b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161062c565b843b6116c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161062c565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516116ec9190611853565b60006040518083038185875af1925050503d8060008114611729576040519150601f19603f3d011682016040523d82523d6000602084013e61172e565b606091505b509150915061173e828286611749565b979650505050505050565b60608315611758575081611281565b8251156117685782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161062c919061186f565b803573ffffffffffffffffffffffffffffffffffffffff811681146104c857600080fd5b6000602082840312156117d1578081fd5b6112818261179c565b600080604083850312156117ec578081fd5b6117f58361179c565b946020939093013593505050565b600060208284031215611814578081fd5b81518015158114611281578182fd5b600060208284031215611834578081fd5b5035919050565b60006020828403121561184c578081fd5b5051919050565b60008251611865818460208701611965565b9190910192915050565b600060208252825180602084015261188e816040850160208701611965565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600082198211156118d3576118d3611991565b500190565b60008261190c577f4e487b710000000000000000000000000000000000000000000000000000000081526012600452602481fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561194957611949611991565b500290565b60008282101561196057611960611991565b500390565b60005b83811015611980578181015183820152602001611968565b838111156114a05750506000910152565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea26469706673582212204741156476b1119a35758ba68769b1a7738761c3a0698f422dff39246b0a32a164736f6c63430008030033