Contract 0x347E15f035B4645C6E330d758F73eC3AD2bFa5B5

Contract Overview

Balance:
0 Ether
Txn Hash Method
Block
From
To
Value
0xdff407eafe673ed6617245f8f5149634d4f8d71d95476974f44a559c17677b90Exit197893382020-07-24 8:07:04298 days 11 hrs ago0x3787d321e3ece1e4ca7d7449d49a4fb5f85dc447 IN  0x347e15f035b4645c6e330d758f73ec3ad2bfa5b50 Ether0.0036285930
0xa2ab736874566831c4ca63f4c3ce5123e23de8f11f4ec609eedc7aa6a735b1a3Stake197892622020-07-24 8:02:00298 days 11 hrs ago0x3787d321e3ece1e4ca7d7449d49a4fb5f85dc447 IN  0x347e15f035b4645c6e330d758f73ec3ad2bfa5b50 Ether0.0067714830
0x96224eb3db6c1c2d19e42783f1ce26af94d672a94300a5a05849e016c2b1b47eExit197892132020-07-24 7:58:40298 days 11 hrs ago0x3787d321e3ece1e4ca7d7449d49a4fb5f85dc447 IN  0x347e15f035b4645c6e330d758f73ec3ad2bfa5b50 Ether0.0037545930
0xd20eb1f3de825f016f82316a84bf5aa39dc351fae129d95ad9da438faa464096Stake197886892020-07-24 7:23:36298 days 12 hrs ago0x3787d321e3ece1e4ca7d7449d49a4fb5f85dc447 IN  0x347e15f035b4645c6e330d758f73ec3ad2bfa5b50 Ether0.01647602773
0xe5c87228d1a5b435fb556d478e8f56de71bf67ac315b23bb961b16cd8ab112820x60806040197885192020-07-24 7:12:12298 days 12 hrs ago0xb64ff7a4a33acdf48d97dab0d764afd0f6176882 IN  Contract Creation0 Ether0.0014359171
[ Download CSV Export 
Latest 4 internal transactions
Parent Txn Hash Block From To Value
0xdff407eafe673ed6617245f8f5149634d4f8d71d95476974f44a559c17677b90197893382020-07-24 8:07:04298 days 11 hrs ago 0x347e15f035b4645c6e330d758f73ec3ad2bfa5b5 0x498df32429693fe31685da7fb9b4b65696a5508d0 Ether
0xa2ab736874566831c4ca63f4c3ce5123e23de8f11f4ec609eedc7aa6a735b1a3197892622020-07-24 8:02:00298 days 11 hrs ago 0x347e15f035b4645c6e330d758f73ec3ad2bfa5b5 0x498df32429693fe31685da7fb9b4b65696a5508d0 Ether
0x96224eb3db6c1c2d19e42783f1ce26af94d672a94300a5a05849e016c2b1b47e197892132020-07-24 7:58:40298 days 11 hrs ago 0x347e15f035b4645c6e330d758f73ec3ad2bfa5b5 0x498df32429693fe31685da7fb9b4b65696a5508d0 Ether
0xd20eb1f3de825f016f82316a84bf5aa39dc351fae129d95ad9da438faa464096197886892020-07-24 7:23:36298 days 12 hrs ago 0x347e15f035b4645c6e330d758f73ec3ad2bfa5b5 0x498df32429693fe31685da7fb9b4b65696a5508d0 Ether
[ Download CSV Export 
Loading

Contract Source Code Verified (Similar Match)
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0x72Bfefac12fAbC2224fE66d7840E8134BEf95e39

Contract Name:
StakingRewards

Compiler Version
v0.5.16+commit.9c3226ce

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-07-24
*/

/*
   ____            __   __        __   _
  / __/__ __ ___  / /_ / /  ___  / /_ (_)__ __
 _\ \ / // // _ \/ __// _ \/ -_)/ __// / \ \ /
/___/ \_, //_//_/\__//_//_/\__/ \__//_/ /_\_\
     /___/

* Synthetix: StakingRewards.sol
*
* Latest source (may be newer): https://github.com/Synthetixio/synthetix/blob/master/contracts/StakingRewards.sol
* Docs: https://docs.synthetix.io/contracts/StakingRewards
*
* Contract Dependencies: 
*	- IERC20
*	- IStakingRewards
*	- Owned
*	- ReentrancyGuard
*	- RewardsDistributionRecipient
* Libraries: 
*	- Address
*	- Math
*	- SafeERC20
*	- SafeMath
*
* MIT License
* ===========
*
* Copyright (c) 2020 Synthetix
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*/

/* ===============================================
* Flattened with Solidifier by Coinage
* 
* https://solidifier.coina.ge
* ===============================================
*/


pragma solidity ^0.5.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);
    }
}


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

        return c;
    }

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

        return c;
    }

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

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

        return c;
    }

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

        return c;
    }

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


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

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

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

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

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

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

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

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


/**
 * @dev Optional functions from the ERC20 standard.
 */
contract ERC20Detailed is IERC20 {
    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of
     * these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name, string memory symbol, uint8 decimals) public {
        _name = name;
        _symbol = symbol;
        _decimals = decimals;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei.
     *
     * > Note that this information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * `IERC20.balanceOf` and `IERC20.transfer`.
     */
    function decimals() public view returns (uint8) {
        return _decimals;
    }
}


/**
 * @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;
    }
}


/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using SafeMath for uint256;
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).add(value);
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value);
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves.

        // A Solidity high level call has three parts:
        //  1. The target address is checked to verify it contains contract code
        //  2. The call itself is made, and success asserted
        //  3. The return value is decoded, which in turn checks the size of the returned data.
        // solhint-disable-next-line max-line-length
        require(address(token).isContract(), "SafeERC20: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = address(token).call(data);
        require(success, "SafeERC20: low-level call failed");

        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}


/**
 * @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;

    constructor () internal {
        // The counter starts at one to prevent changing it from zero to a non-zero
        // value, which is a more expensive operation.
        _guardCounter = 1;
    }

    /**
     * @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");
    }
}


interface IStakingRewards {
    // Views
    function lastTimeRewardApplicable() external view returns (uint256);

    function rewardPerToken() external view returns (uint256);

    function earned(address account) external view returns (uint256);

    function getRewardForDuration() external view returns (uint256);

    function totalSupply() external view returns (uint256);

    function balanceOf(address account) external view returns (uint256);

    // Mutative

    function stake(uint256 amount) external;

    function withdraw(uint256 amount) external;

    function getReward() external;

    function exit() external;
}


// https://docs.synthetix.io/contracts/Owned
contract Owned {
    address public owner;
    address public nominatedOwner;

    constructor(address _owner) public {
        require(_owner != address(0), "Owner address cannot be 0");
        owner = _owner;
        emit OwnerChanged(address(0), _owner);
    }

    function nominateNewOwner(address _owner) external onlyOwner {
        nominatedOwner = _owner;
        emit OwnerNominated(_owner);
    }

    function acceptOwnership() external {
        require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership");
        emit OwnerChanged(owner, nominatedOwner);
        owner = nominatedOwner;
        nominatedOwner = address(0);
    }

    modifier onlyOwner {
        require(msg.sender == owner, "Only the contract owner may perform this action");
        _;
    }

    event OwnerNominated(address newOwner);
    event OwnerChanged(address oldOwner, address newOwner);
}


// Inheritance


// https://docs.synthetix.io/contracts/RewardsDistributionRecipient
contract RewardsDistributionRecipient is Owned {
    address public rewardsDistribution;

    function notifyRewardAmount(uint256 reward) external;

    modifier onlyRewardsDistribution() {
        require(msg.sender == rewardsDistribution, "Caller is not RewardsDistribution contract");
        _;
    }

    function setRewardsDistribution(address _rewardsDistribution) external onlyOwner {
        rewardsDistribution = _rewardsDistribution;
    }
}


// Inheritance


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
    ) public Owned(_owner) {
        rewardsToken = IERC20(_rewardsToken);
        stakingToken = IERC20(_stakingToken);
        rewardsDistribution = _rewardsDistribution;
    }

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

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

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

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

    function rewardPerToken() public view 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 returns (uint256) {
        return _balances[account].mul(rewardPerToken().sub(userRewardPerTokenPaid[account])).div(1e18).add(rewards[account]);
    }

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

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

    function stake(uint256 amount) external 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 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 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 {
        withdraw(_balances[msg.sender]);
        getReward();
    }

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

    function notifyRewardAmount(uint256 reward) external 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);
        }
        lastUpdateTime = block.timestamp;
        periodFinish = block.timestamp.add(rewardsDuration);
        emit RewardAdded(reward);
    }

    // Added to support recovering LP Rewards from other systems to be distributed to holders
    function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner {
        // If it's SNX we have to query the token symbol to ensure its not a proxy or underlying
        bool isSNX = (keccak256(bytes("SNX")) == keccak256(bytes(ERC20Detailed(tokenAddress).symbol())));
        // Cannot recover the staking token or the rewards token
        require(tokenAddress != address(stakingToken) && tokenAddress != address(rewardsToken) && !isSNX, "Cannot withdraw the staking or rewards tokens");
        IERC20(tokenAddress).safeTransfer(owner, tokenAmount);
        emit Recovered(tokenAddress, tokenAmount);
    }

    function setRewardsDuration(uint256 _rewardsDuration) external onlyOwner {
        require(periodFinish == 0 || 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

[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_rewardsDistribution","type":"address"},{"internalType":"address","name":"_rewardsToken","type":"address"},{"internalType":"address","name":"_stakingToken","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"RewardsDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"exit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"getReward","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getRewardForDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastTimeRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"reward","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"periodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"rewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"rewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"rewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"rewardsDistribution","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"rewardsDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"rewardsToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_rewardsDistribution","type":"address"}],"name":"setRewardsDistribution","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_rewardsDuration","type":"uint256"}],"name":"setRewardsDuration","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userRewardPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

60806040526000600655600060075562093a8060085534801561002157600080fd5b506040516117fe3803806117fe8339818101604052608081101561004457600080fd5b5080516020820151604083015160609093015191929091836001600160a01b0381166100b7576040805162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f74206265203000000000000000604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b038316908117825560408051928352602083019190915280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a1506001600355600480546001600160a01b039384166001600160a01b03199182161790915560058054928416928216929092179091556002805493909216921691909117905550611699806101656000396000f3fe608060405234801561001057600080fd5b50600436106101c35760003560e01c806379ba5097116100f9578063c8f33c9111610097578063d1af0c7d11610071578063d1af0c7d146103e4578063df136d65146103ec578063e9fad8ee146103f4578063ebe2b12b146103fc576101c3565b8063c8f33c91146103b7578063cc1a378f146103bf578063cd3daf9d146103dc576101c3565b80638980f11f116100d35780638980f11f146103405780638b8763471461036c5780638da5cb5b14610392578063a694fc3a1461039a576101c3565b806379ba5097146103285780637b0a47ee1461033057806380faa57d14610338576101c3565b8063386a9525116101665780633fc6df6e116101405780633fc6df6e146102ce57806353a47bb7146102f257806370a08231146102fa57806372f702f314610320576101c3565b8063386a9525146102a15780633c6b16ab146102a95780633d18b912146102c6576101c3565b806318160ddd116101a257806318160ddd1461024e57806319762143146102565780631c1f78eb1461027c5780632e1a7d4d14610284576101c3565b80628cc262146101c85780630700037d146102005780631627540c14610226575b600080fd5b6101ee600480360360208110156101de57600080fd5b50356001600160a01b0316610404565b60408051918252519081900360200190f35b6101ee6004803603602081101561021657600080fd5b50356001600160a01b031661049a565b61024c6004803603602081101561023c57600080fd5b50356001600160a01b03166104ac565b005b6101ee610549565b61024c6004803603602081101561026c57600080fd5b50356001600160a01b0316610550565b6101ee6105bb565b61024c6004803603602081101561029a57600080fd5b50356105d9565b6101ee61077b565b61024c600480360360208110156102bf57600080fd5b5035610781565b61024c6108ed565b6102d6610a24565b604080516001600160a01b039092168252519081900360200190f35b6102d6610a33565b6101ee6004803603602081101561031057600080fd5b50356001600160a01b0316610a42565b6102d6610a5d565b61024c610a6c565b6101ee610b28565b6101ee610b2e565b61024c6004803603604081101561035657600080fd5b506001600160a01b038135169060200135610b3c565b6101ee6004803603602081101561038257600080fd5b50356001600160a01b0316610dd0565b6102d6610de2565b61024c600480360360208110156103b057600080fd5b5035610df1565b6101ee610f8d565b61024c600480360360208110156103d557600080fd5b5035610f93565b6101ee611062565b6102d66110bc565b6101ee6110cb565b61024c6110d1565b6101ee6110f4565b6001600160a01b0381166000908152600c6020908152604080832054600b909252822054610494919061048890670de0b6b3a76400009061047c906104579061044b611062565b9063ffffffff6110fa16565b6001600160a01b0388166000908152600e60205260409020549063ffffffff61115716565b9063ffffffff6111b716565b9063ffffffff61122116565b92915050565b600c6020526000908152604090205481565b6000546001600160a01b031633146104f55760405162461bcd60e51b815260040180806020018281038252602f815260200180611594602f913960400191505060405180910390fd5b600180546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229181900360200190a150565b600d545b90565b6000546001600160a01b031633146105995760405162461bcd60e51b815260040180806020018281038252602f815260200180611594602f913960400191505060405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60006105d460085460075461115790919063ffffffff16565b905090565b6003805460010190819055336105ed611062565b600a556105f8610b2e565b6009556001600160a01b0381161561063f5761061381610404565b6001600160a01b0382166000908152600c6020908152604080832093909355600a54600b909152919020555b60008311610688576040805162461bcd60e51b8152602060048201526011602482015270043616e6e6f74207769746864726177203607c1b604482015290519081900360640190fd5b600d5461069b908463ffffffff6110fa16565b600d55336000908152600e60205260409020546106be908463ffffffff6110fa16565b336000818152600e60205260409020919091556005546106ea916001600160a01b03909116908561127b565b60408051848152905133917f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5919081900360200190a2506003548114610777576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b5050565b60085481565b6002546001600160a01b031633146107ca5760405162461bcd60e51b815260040180806020018281038252602a815260200180611611602a913960400191505060405180910390fd5b60006107d4611062565b600a556107df610b2e565b6009556001600160a01b03811615610826576107fa81610404565b6001600160a01b0382166000908152600c6020908152604080832093909355600a54600b909152919020555b600654421061084b5760085461084390839063ffffffff6111b716565b60075561089a565b600654600090610861904263ffffffff6110fa16565b9050600061087a6007548361115790919063ffffffff16565b6008549091506108949061047c868463ffffffff61122116565b60075550505b4260098190556008546108b3919063ffffffff61122116565b6006556040805183815290517fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9181900360200190a15050565b600380546001019081905533610901611062565b600a5561090c610b2e565b6009556001600160a01b038116156109535761092781610404565b6001600160a01b0382166000908152600c6020908152604080832093909355600a54600b909152919020555b336000908152600c602052604090205480156109c957336000818152600c6020526040812055600454610992916001600160a01b03909116908361127b565b60408051828152905133917fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486919081900360200190a25b50506003548114610a21576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b50565b6002546001600160a01b031681565b6001546001600160a01b031681565b6001600160a01b03166000908152600e602052604090205490565b6005546001600160a01b031681565b6001546001600160a01b03163314610ab55760405162461bcd60e51b815260040180806020018281038252603581526020018061155f6035913960400191505060405180910390fd5b600054600154604080516001600160a01b03938416815292909116602083015280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b60075481565b60006105d4426006546112d2565b6000546001600160a01b03163314610b855760405162461bcd60e51b815260040180806020018281038252602f815260200180611594602f913960400191505060405180910390fd5b6000826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015610bc057600080fd5b505afa158015610bd4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610bfd57600080fd5b8101908080516040519392919084640100000000821115610c1d57600080fd5b908301906020820185811115610c3257600080fd5b8251640100000000811182820188101715610c4c57600080fd5b82525081516020918201929091019080838360005b83811015610c79578181015183820152602001610c61565b50505050905090810190601f168015610ca65780820380516001836020036101000a031916815260200191505b506040818152855160209687012082820190915260038252620a69cb60eb1b959091019490945250506005547fc33e514e79311fe606801af4b4f343c83a3b72dca711239a516f2103673922d19092149250506001600160a01b03848116911614801590610d2257506004546001600160a01b03848116911614155b8015610d2c575080155b610d675760405162461bcd60e51b815260040180806020018281038252602d8152602001806115e4602d913960400191505060405180910390fd5b600054610d87906001600160a01b0385811691168463ffffffff61127b16565b604080516001600160a01b03851681526020810184905281517f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa28929181900390910190a1505050565b600b6020526000908152604090205481565b6000546001600160a01b031681565b600380546001019081905533610e05611062565b600a55610e10610b2e565b6009556001600160a01b03811615610e5757610e2b81610404565b6001600160a01b0382166000908152600c6020908152604080832093909355600a54600b909152919020555b60008311610e9d576040805162461bcd60e51b815260206004820152600e60248201526d043616e6e6f74207374616b6520360941b604482015290519081900360640190fd5b600d54610eb0908463ffffffff61122116565b600d55336000908152600e6020526040902054610ed3908463ffffffff61122116565b336000818152600e6020526040902091909155600554610f00916001600160a01b039091169030866112e8565b60408051848152905133917f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d919081900360200190a2506003548114610777576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60095481565b6000546001600160a01b03163314610fdc5760405162461bcd60e51b815260040180806020018281038252602f815260200180611594602f913960400191505060405180910390fd5b6006541580610fec575060065442115b6110275760405162461bcd60e51b81526004018080602001828103825260588152602001806115076058913960600191505060405180910390fd5b60088190556040805182815290517ffb46ca5a5e06d4540d6387b930a7c978bce0db5f449ec6b3f5d07c6e1d44f2d39181900360200190a150565b6000600d54600014156110785750600a5461054d565b6105d46110ad600d5461047c670de0b6b3a76400006110a16007546110a160095461044b610b2e565b9063ffffffff61115716565b600a549063ffffffff61122116565b6004546001600160a01b031681565b600a5481565b336000908152600e60205260409020546110ea906105d9565b6110f26108ed565b565b60065481565b600082821115611151576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b60008261116657506000610494565b8282028284828161117357fe5b04146111b05760405162461bcd60e51b81526004018080602001828103825260218152602001806115c36021913960400191505060405180910390fd5b9392505050565b600080821161120d576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b600082848161121857fe5b04949350505050565b6000828201838110156111b0576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526112cd908490611348565b505050565b60008183106112e157816111b0565b5090919050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611342908590611348565b50505050565b61135a826001600160a01b0316611500565b6113ab576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106113e95780518252601f1990920191602091820191016113ca565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461144b576040519150601f19603f3d011682016040523d82523d6000602084013e611450565b606091505b5091509150816114a7576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115611342578080602001905160208110156114c357600080fd5b50516113425760405162461bcd60e51b815260040180806020018281038252602a81526020018061163b602a913960400191505060405180910390fd5b3b15159056fe50726576696f7573207265776172647320706572696f64206d75737420626520636f6d706c657465206265666f7265206368616e67696e6720746865206475726174696f6e20666f7220746865206e657720706572696f64596f75206d757374206265206e6f6d696e61746564206265666f726520796f752063616e20616363657074206f776e6572736869704f6e6c792074686520636f6e7472616374206f776e6572206d617920706572666f726d207468697320616374696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7743616e6e6f7420776974686472617720746865207374616b696e67206f72207265776172647320746f6b656e7343616c6c6572206973206e6f742052657761726473446973747269627574696f6e20636f6e74726163745361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a72315820df34aeb963d50a59215e58b1f50bbdac67d7d5638574279144eb41f5c109cb6164736f6c63430005100032000000000000000000000000b64ff7a4a33acdf48d97dab0d764afd0f6176882000000000000000000000000d29160e4f5d2e5818041f9cd9192853ba349c47e0000000000000000000000006d4e4821480b30082f8a1abe6c3cd294d9c40f32000000000000000000000000f418d59792e4bd9ab8cc4b733ea60edc01abc77c

Deployed ByteCode Sourcemap

19063:5836:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;19063:5836:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20866:198;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;20866:198:0;-1:-1:-1;;;;;20866:198:0;;:::i;:::-;;;;;;;;;;;;;;;;19609:42;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;19609:42:0;-1:-1:-1;;;;;19609:42:0;;:::i;17809:141::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;17809:141:0;-1:-1:-1;;;;;17809:141:0;;:::i;:::-;;20168:93;;;:::i;18892:142::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;18892:142:0;-1:-1:-1;;;;;18892:142:0;;:::i;21072:121::-;;;:::i;21632:357::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21632:357:0;;:::i;19419:39::-;;;:::i;22473:578::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;22473:578:0;;:::i;21997:307::-;;;:::i;18626:34::-;;;:::i;:::-;;;;-1:-1:-1;;;;;18626:34:0;;;;;;;;;;;;;;17578:29;;;:::i;20269:112::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;20269:112:0;-1:-1:-1;;;;;20269:112:0;;:::i;19312:26::-;;;:::i;17958:271::-;;;:::i;19383:29::-;;;:::i;20389:131::-;;;:::i;23154:636::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;23154:636:0;;;;;;;;:::i;19545:57::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;19545:57:0;-1:-1:-1;;;;;19545:57:0;;:::i;17551:20::-;;;:::i;21255:369::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21255:369:0;;:::i;19465:29::-;;;:::i;23798:344::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;23798:344:0;;:::i;20528:330::-;;;:::i;19279:26::-;;;:::i;19501:35::-;;;:::i;22312:97::-;;;:::i;19345:31::-;;;:::i;20866:198::-;-1:-1:-1;;;;;21039:16:0;;20920:7;21039:16;;;:7;:16;;;;;;;;;20991:22;:31;;;;;;20947:109;;21039:16;20947:87;;21029:4;;20947:77;;20970:53;;:16;:14;:16::i;:::-;:20;:53;:20;:53;:::i;:::-;-1:-1:-1;;;;;20947:18:0;;;;;;:9;:18;;;;;;;:77;:22;:77;:::i;:::-;:81;:87;:81;:87;:::i;:::-;:91;:109;:91;:109;:::i;:::-;20940:116;20866:198;-1:-1:-1;;20866:198:0:o;19609:42::-;;;;;;;;;;;;;:::o;17809:141::-;18289:5;;-1:-1:-1;;;;;18289:5:0;18275:10;:19;18267:79;;;;-1:-1:-1;;;18267:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17881:14;:23;;-1:-1:-1;;;;;17881:23:0;;-1:-1:-1;;;;;;17881:23:0;;;;;;;;17920:22;;;;;;;;;;;;;;;;17809:141;:::o;20168:93::-;20241:12;;20168:93;;:::o;18892:142::-;18289:5;;-1:-1:-1;;;;;18289:5:0;18275:10;:19;18267:79;;;;-1:-1:-1;;;18267:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18984:19;:42;;-1:-1:-1;;;;;;18984:42:0;-1:-1:-1;;;;;18984:42:0;;;;;;;;;;18892:142::o;21072:121::-;21127:7;21154:31;21169:15;;21154:10;;:14;;:31;;;;:::i;:::-;21147:38;;21072:121;:::o;21632:357::-;16642:13;:18;;16659:1;16642:18;;;;;21699:10;24268:16;:14;:16::i;:::-;24245:20;:39;24312:26;:24;:26::i;:::-;24295:14;:43;-1:-1:-1;;;;;24353:21:0;;;24349:157;;24410:15;24417:7;24410:6;:15::i;:::-;-1:-1:-1;;;;;24391:16:0;;;;;;:7;:16;;;;;;;;:34;;;;24474:20;;24440:22;:31;;;;;;:54;24349:157;21739:1;21730:6;:10;21722:40;;;;;-1:-1:-1;;;21722:40:0;;;;;;;;;;;;-1:-1:-1;;;21722:40:0;;;;;;;;;;;;;;;21788:12;;:24;;21805:6;21788:24;:16;:24;:::i;:::-;21773:12;:39;21857:10;21847:21;;;;:9;:21;;;;;;:33;;21873:6;21847:33;:25;:33;:::i;:::-;21833:10;21823:21;;;;:9;:21;;;;;:57;;;;21891:12;;:45;;-1:-1:-1;;;;;21891:12:0;;;;21929:6;21891:25;:45::i;:::-;21952:29;;;;;;;;21962:10;;21952:29;;;;;;;;;;16718:1;16754:13;;16738:12;:29;16730:73;;;;;-1:-1:-1;;;16730:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;21632:357;;:::o;19419:39::-;;;;:::o;22473:578::-;18798:19;;-1:-1:-1;;;;;18798:19:0;18784:10;:33;18776:88;;;;-1:-1:-1;;;18776:88:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22571:1;24268:16;:14;:16::i;:::-;24245:20;:39;24312:26;:24;:26::i;:::-;24295:14;:43;-1:-1:-1;;;;;24353:21:0;;;24349:157;;24410:15;24417:7;24410:6;:15::i;:::-;-1:-1:-1;;;;;24391:16:0;;;;;;:7;:16;;;;;;;;:34;;;;24474:20;;24440:22;:31;;;;;;:54;24349:157;22609:12;;22590:15;:31;22586:318;;22662:15;;22651:27;;:6;;:27;:10;:27;:::i;:::-;22638:10;:40;22586:318;;;22731:12;;22711:17;;22731:33;;22748:15;22731:33;:16;:33;:::i;:::-;22711:53;;22779:16;22798:25;22812:10;;22798:9;:13;;:25;;;;:::i;:::-;22876:15;;22779:44;;-1:-1:-1;22851:41:0;;:20;:6;22779:44;22851:20;:10;:20;:::i;:41::-;22838:10;:54;-1:-1:-1;;22586:318:0;22931:15;22914:14;:32;;;22992:15;;22972:36;;22931:15;22972:36;:19;:36;:::i;:::-;22957:12;:51;23024:19;;;;;;;;;;;;;;;;;18875:1;22473:578;:::o;21997:307::-;16642:13;:18;;16659:1;16642:18;;;;;22051:10;24268:16;:14;:16::i;:::-;24245:20;:39;24312:26;:24;:26::i;:::-;24295:14;:43;-1:-1:-1;;;;;24353:21:0;;;24349:157;;24410:15;24417:7;24410:6;:15::i;:::-;-1:-1:-1;;;;;24391:16:0;;;;;;:7;:16;;;;;;;;:34;;;;24474:20;;24440:22;:31;;;;;;:54;24349:157;22099:10;22074:14;22091:19;;;:7;:19;;;;;;22125:10;;22121:176;;22160:10;22174:1;22152:19;;;:7;:19;;;;;:23;22190:12;;:45;;-1:-1:-1;;;;;22190:12:0;;;;22228:6;22190:25;:45::i;:::-;22255:30;;;;;;;;22266:10;;22255:30;;;;;;;;;;22121:176;24516:1;16718;16754:13;;16738:12;:29;16730:73;;;;;-1:-1:-1;;;16730:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;21997:307;:::o;18626:34::-;;;-1:-1:-1;;;;;18626:34:0;;:::o;17578:29::-;;;-1:-1:-1;;;;;17578:29:0;;:::o;20269:112::-;-1:-1:-1;;;;;20355:18:0;20328:7;20355:18;;;:9;:18;;;;;;;20269:112::o;19312:26::-;;;-1:-1:-1;;;;;19312:26:0;;:::o;17958:271::-;18027:14;;-1:-1:-1;;;;;18027:14:0;18013:10;:28;18005:94;;;;-1:-1:-1;;;18005:94:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18128:5;;;18135:14;18115:35;;;-1:-1:-1;;;;;18128:5:0;;;18115:35;;18135:14;;;;18115:35;;;;;;;;;;;;;;;;18169:14;;;;18161:22;;-1:-1:-1;;;;;;18161:22:0;;;-1:-1:-1;;;;;18169:14:0;;18161:22;;;;18194:27;;;17958:271::o;19383:29::-;;;;:::o;20389:131::-;20446:7;20473:39;20482:15;20499:12;;20473:8;:39::i;23154:636::-;18289:5;;-1:-1:-1;;;;;18289:5:0;18275:10;:19;18267:79;;;;-1:-1:-1;;;18267:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23347:10;23418:12;-1:-1:-1;;;;;23404:34:0;;:36;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;23404:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;23404:36:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;23404:36:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;13:2;5:11;;2:2;;;29:1;26;19:12;2:2;23404:36:0;;;;;;;;;;;;;19:11:-1;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;213:10;;261:11;244:29;;285:43;;;282:58;-1:-1;233:115;230:2;;;361:1;358;351:12;230:2;372:25;;-1:-1;23404:36:0;;420:4:-1;411:14;;;;23404:36:0;;;;;411:14:-1;23404:36:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;23404:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;23404:36:0;;;;23388:54;;;;;;;23371:12;;;;;;;;;-1:-1:-1;;;23371:12:0;;;;;;;;-1:-1:-1;;23552:12:0;;23361:23;:81;;;;-1:-1:-1;;;;;;;23528:37:0;;;23552:12;;23528:37;;;;:78;;-1:-1:-1;23593:12:0;;-1:-1:-1;;;;;23569:37:0;;;23593:12;;23569:37;;23528:78;:88;;;;;23611:5;23610:6;23528:88;23520:146;;;;-1:-1:-1;;;23520:146:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23711:5;;23677:53;;-1:-1:-1;;;;;23677:33:0;;;;23711:5;23718:11;23677:53;:33;:53;:::i;:::-;23746:36;;;-1:-1:-1;;;;;23746:36:0;;;;;;;;;;;;;;;;;;;;;;;18357:1;23154:636;;:::o;19545:57::-;;;;;;;;;;;;;:::o;17551:20::-;;;-1:-1:-1;;;;;17551:20:0;;:::o;21255:369::-;16642:13;:18;;16659:1;16642:18;;;;;21321:10;24268:16;:14;:16::i;:::-;24245:20;:39;24312:26;:24;:26::i;:::-;24295:14;:43;-1:-1:-1;;;;;24353:21:0;;;24349:157;;24410:15;24417:7;24410:6;:15::i;:::-;-1:-1:-1;;;;;24391:16:0;;;;;;:7;:16;;;;;;;;:34;;;;24474:20;;24440:22;:31;;;;;;:54;24349:157;21361:1;21352:6;:10;21344:37;;;;;-1:-1:-1;;;21344:37:0;;;;;;;;;;;;-1:-1:-1;;;21344:37:0;;;;;;;;;;;;;;;21407:12;;:24;;21424:6;21407:24;:16;:24;:::i;:::-;21392:12;:39;21476:10;21466:21;;;;:9;:21;;;;;;:33;;21492:6;21466:33;:25;:33;:::i;:::-;21452:10;21442:21;;;;:9;:21;;;;;:57;;;;21510:12;;:64;;-1:-1:-1;;;;;21510:12:0;;;;21560:4;21567:6;21510:29;:64::i;:::-;21590:26;;;;;;;;21597:10;;21590:26;;;;;;;;;;16718:1;16754:13;;16738:12;:29;16730:73;;;;;-1:-1:-1;;;16730:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;19465:29;;;;:::o;23798:344::-;18289:5;;-1:-1:-1;;;;;18289:5:0;18275:10;:19;18267:79;;;;-1:-1:-1;;;18267:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23890:12;;:17;;:51;;;23929:12;;23911:15;:30;23890:51;23882:152;;;;-1:-1:-1;;;23882:152:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24045:15;:34;;;24095:39;;;;;;;;;;;;;;;;;23798:344;:::o;20528:330::-;20575:7;20599:12;;20615:1;20599:17;20595:77;;;-1:-1:-1;20640:20:0;;20633:27;;20595:77;20702:148;20745:90;20822:12;;20745:72;20812:4;20745:62;20796:10;;20745:46;20776:14;;20745:26;:24;:26::i;:46::-;:50;:62;:50;:62;:::i;:90::-;20702:20;;;:148;:24;:148;:::i;19279:26::-;;;-1:-1:-1;;;;;19279:26:0;;:::o;19501:35::-;;;;:::o;22312:97::-;22367:10;22357:21;;;;:9;:21;;;;;;22348:31;;:8;:31::i;:::-;22390:11;:9;:11::i;:::-;22312:97::o;19345:31::-;;;;:::o;4021:184::-;4079:7;4112:1;4107;:6;;4099:49;;;;;-1:-1:-1;;;4099:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4171:5:0;;;4021:184::o;4456:470::-;4514:7;4758:6;4754:47;;-1:-1:-1;4788:1:0;4781:8;;4754:47;4825:5;;;4829:1;4825;:5;:1;4849:5;;;;;:10;4841:56;;;;-1:-1:-1;;;4841:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4917:1;4456:470;-1:-1:-1;;;4456:470:0:o;5394:333::-;5452:7;5551:1;5547;:5;5539:44;;;;;-1:-1:-1;;;5539:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;5594:9;5610:1;5606;:5;;;;;;;5394:333;-1:-1:-1;;;;5394:333:0:o;3565:181::-;3623:7;3655:5;;;3679:6;;;;3671:46;;;;;-1:-1:-1;;;3671:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;12219:176;12328:58;;;-1:-1:-1;;;;;12328:58:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;12328:58:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;12302:85:0;;12321:5;;12302:18;:85::i;:::-;12219:176;;;:::o;2306:106::-;2364:7;2395:1;2391;:5;:13;;2403:1;2391:13;;;-1:-1:-1;2399:1:0;;2384:20;-1:-1:-1;2306:106:0:o;12403:204::-;12530:68;;;-1:-1:-1;;;;;12530:68:0;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;12530:68:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;12504:95:0;;12523:5;;12504:18;:95::i;:::-;12403:204;;;;:::o;14213:1114::-;14817:27;14825:5;-1:-1:-1;;;;;14817:25:0;;:27::i;:::-;14809:71;;;;;-1:-1:-1;;;14809:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;14954:12;14968:23;15003:5;-1:-1:-1;;;;;14995:19:0;15015:4;14995:25;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;14995:25:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;14953:67:0;;;;15039:7;15031:52;;;;;-1:-1:-1;;;15031:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15100:17;;:21;15096:224;;15242:10;15231:30;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;15231:30:0;15223:85;;;;-1:-1:-1;;;15223:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11230:422;11597:20;11636:8;;;11230:422::o

Swarm Source

bzzr://df34aeb963d50a59215e58b1f50bbdac67d7d5638574279144eb41f5c109cb61
Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading