ETH Price: $3,374.45 (+0.21%)

Contract

0x5E4935fe0f1f622bfc9521c0e098898e7b8b573c
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Get Reward144101582022-03-18 11:31:201017 days ago1647603080IN
0x5E4935fe...e7b8b573c
0 ETH0.0047129220.1
Get Reward142867152022-02-27 6:53:121036 days ago1645944792IN
0x5E4935fe...e7b8b573c
0 ETH0.0194591320.54449601
Get Reward138164642021-12-16 13:32:111109 days ago1639661531IN
0x5E4935fe...e7b8b573c
0 ETH0.009476664
Get Reward138158842021-12-16 11:13:401109 days ago1639653220IN
0x5E4935fe...e7b8b573c
0 ETH0.0096369264
Get Reward132153912021-09-13 4:58:301203 days ago1631509110IN
0x5E4935fe...e7b8b573c
0 ETH0.0213879
Get Reward131941772021-09-09 22:05:391206 days ago1631225139IN
0x5E4935fe...e7b8b573c
0 ETH0.0135818381
Get Reward131199412021-08-29 10:50:091218 days ago1630234209IN
0x5E4935fe...e7b8b573c
0 ETH0.0130477539.97227833
Get Reward130421772021-08-17 10:31:131230 days ago1629196273IN
0x5E4935fe...e7b8b573c
0 ETH0.0082056942.05093825
Get Reward129825942021-08-08 5:46:491239 days ago1628401609IN
0x5E4935fe...e7b8b573c
0 ETH0.0092586739
Get Reward129624632021-08-05 2:53:101242 days ago1628131990IN
0x5E4935fe...e7b8b573c
0 ETH0.0112894947
Get Reward129156242021-07-28 17:09:351249 days ago1627492175IN
0x5E4935fe...e7b8b573c
0 ETH0.0068297935
Get Reward128858892021-07-24 0:53:071254 days ago1627087987IN
0x5E4935fe...e7b8b573c
0 ETH0.03304521110
Get Reward128694692021-07-21 11:16:151257 days ago1626866175IN
0x5E4935fe...e7b8b573c
0 ETH0.0016880612
Get Reward128386952021-07-16 15:24:531261 days ago1626449093IN
0x5E4935fe...e7b8b573c
0 ETH0.03399732120
Get Reward127965522021-07-10 1:00:561268 days ago1625878856IN
0x5E4935fe...e7b8b573c
0 ETH0.0052872317.6
Get Reward127733512021-07-06 10:28:121272 days ago1625567292IN
0x5E4935fe...e7b8b573c
0 ETH0.009604664
Get Reward127415702021-07-01 11:44:541277 days ago1625139894IN
0x5E4935fe...e7b8b573c
0 ETH0.0025814610
Get Reward127351692021-06-30 11:54:371278 days ago1625054077IN
0x5E4935fe...e7b8b573c
0 ETH0.0036759314
Get Reward127155222021-06-27 10:16:151281 days ago1624788975IN
0x5E4935fe...e7b8b573c
0 ETH0.0014037710
Get Reward127020192021-06-25 7:42:341283 days ago1624606954IN
0x5E4935fe...e7b8b573c
0 ETH0.0023752412
Get Reward126824832021-06-22 6:41:151286 days ago1624344075IN
0x5E4935fe...e7b8b573c
0 ETH0.0085021311.1
Get Reward126598662021-06-18 17:51:331289 days ago1624038693IN
0x5E4935fe...e7b8b573c
0 ETH0.0046466218
Get Reward126341672021-06-14 18:28:201293 days ago1623695300IN
0x5E4935fe...e7b8b573c
0 ETH0.0030014420
Get Reward126055892021-06-10 8:01:541298 days ago1623312114IN
0x5E4935fe...e7b8b573c
0 ETH0.002870411
Get Reward125801612021-06-06 9:32:111302 days ago1622971931IN
0x5E4935fe...e7b8b573c
0 ETH0.0015581811.1
View all transactions

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block
From
To
114602252020-12-15 21:57:091474 days ago1608069429
0x5E4935fe...e7b8b573c
 Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
StakingRewardsDecay

Compiler Version
v0.5.12+commit.7709ece9

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-12-16
*/

// hevm: flattened sources of src/rewardDecay.sol
pragma solidity >0.4.13 >=0.4.23 >=0.5.12 >=0.5.0 <0.6.0 >=0.5.10 <0.6.0 >=0.5.12 <0.6.0;

////// src/IERC20.sol
/* pragma solidity ^0.5.0; */

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

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

    function mint(address account, uint256 amount) external;

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

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

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

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

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

////// src/ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

/* pragma solidity ^0.5.12; */

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied 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.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() internal {
        _status = _NOT_ENTERED;
    }

    /**
     * @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() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

////// src/base.sol
/* pragma solidity ^0.5.0; */

/* import "./IERC20.sol"; */

interface IAdapter {
    function calc(
        address gem,
        uint256 acc,
        uint256 factor
    ) external view returns (uint256);
}

interface IGemForRewardChecker {
    function check(address gem) external view returns (bool);
}

////// src/lib.sol
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

/* pragma solidity >=0.5.12; */

contract LibNote {
    event LogNote(
        bytes4 indexed sig,
        address indexed usr,
        bytes32 indexed arg1,
        bytes32 indexed arg2,
        bytes data
    ) anonymous;

    modifier note {
        _;
        assembly {
            // log an 'anonymous' event with a constant 6 words of calldata
            // and four indexed topics: selector, caller, arg1 and arg2
            let mark := msize() // end of memory ensures zero
            mstore(0x40, add(mark, 288)) // update free memory pointer
            mstore(mark, 0x20) // bytes type data offset
            mstore(add(mark, 0x20), 224) // bytes size (padded)
            calldatacopy(add(mark, 0x40), 0, 224) // bytes payload
            log4(
                mark,
                288, // calldata
                shl(224, shr(224, calldataload(0))), // msg.sig
                caller(), // msg.sender
                calldataload(4), // arg1
                calldataload(36) // arg2
            )
        }
    }
}

contract Auth is LibNote {
    mapping(address => uint256) public wards;
    address public deployer;

    function rely(address usr) external note auth {
        wards[usr] = 1;
    }

    function deny(address usr) external note auth {
        wards[usr] = 0;
    }

    modifier auth {
        require(wards[msg.sender] == 1 || deployer == msg.sender, "Auth/not-authorized");
        _;
    }
}

////// src/safeMath.sol
/* pragma solidity ^0.5.0; */

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

        return c;
    }

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

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

        return c;
    }

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

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

        return c;
    }

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

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

        return c;
    }

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

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

    function min(uint x, uint y) internal pure returns (uint z) {
        return x <= y ? x : y;
    }
}

////// src/safeERC20.sol
/* pragma solidity ^0.5.12; */

/* import "./IERC20.sol"; */
/* import "./safeMath.sol"; */



/**
 * @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.
     *
     * IMPORTANT: 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.

        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != 0x0 && codehash != accountHash);
    }

    /**
     * @dev Converts an `address` into `address payable`. Note that this is
     * simply a type cast: the actual underlying value is not changed.
     *
     * _Available since v2.4.0._
     */
    function toPayable(address account) internal pure returns (address payable) {
        return address(uint160(account));
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     *
     * _Available since v2.4.0._
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-call-value
        (bool success, ) = recipient.call.value(amount)("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }
}




/**
 * @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, "SafeERC20: decreased allowance below zero");
        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");
        }
    }
}


////// src/lpTokenWrapper.sol
/**
 *Submitted for verification at Etherscan.io on 2020-08-12
 */

/**
 *Submitted for verification at Etherscan.io on
 */

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

* Synthetix: YFIRewards.sol
*
* Docs: https://docs.synthetix.io/
*
*
* 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
*/

/* pragma solidity ^0.5.12; */

/* import "./IERC20.sol"; */
/* import "./base.sol"; */
/* import "./safeMath.sol"; */
/* import "./safeERC20.sol"; */

// File: @openzeppelin/contracts/math/Math.sol

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

// File: @openzeppelin/contracts/GSN/Context.sol

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

    // solhint-disable-previous-line no-empty-blocks

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

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

// File: @openzeppelin/contracts/ownership/Ownable.sol

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() internal {
        _owner = _msgSender();
        emit OwnershipTransferred(address(0), _owner);
    }

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Returns true if the caller is the current owner.
     */
    function isOwner() public view returns (bool) {
        return _msgSender() == _owner;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

/**
 * @title Initializable
 *
 * @dev Helper contract to support initializer functions. To use it, replace
 * the constructor with a function that has the `initializer` modifier.
 * WARNING: Unlike constructors, initializer functions must be manually
 * invoked. This applies both to deploying an Initializable contract, as well
 * as extending an Initializable contract via inheritance.
 * WARNING: When used with inheritance, manual care must be taken to not invoke
 * a parent initializer twice, or ensure that all initializers are idempotent,
 * because this is not dealt with automatically as with constructors.
 */
contract Initializable {
    /**
     * @dev Indicates that the contract has been initialized.
     */
    bool private initialized;

    /**
     * @dev Indicates that the contract is in the process of being initialized.
     */
    bool private initializing;

    /**
     * @dev Modifier to use in the initializer function of a contract.
     */
    modifier initializer() {
        require(
            initializing || isConstructor() || !initialized,
            "Contract instance has already been initialized"
        );

        bool wasInitializing = initializing;
        initializing = true;
        initialized = true;

        _;

        initializing = wasInitializing;
    }

    /// @dev Returns true if and only if the function is running in the constructor
    function isConstructor() private view returns (bool) {
        // extcodesize checks the size of the code stored in an address, and
        // address returns the current address. Since the code is still not
        // deployed when running a constructor, any checks on its code size will
        // yield zero, making it an effective way to detect if a contract is
        // under construction or not.
        uint256 cs;
        assembly {
            cs := extcodesize(address)
        }
        return cs == 0;
    }

    // Reserved storage space to allow for layout changes in the future.
    uint256[50] private ______gap;
}

contract LPTokenWrapper is Initializable {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    struct PairDesc {
        address gem;
        address adapter;
        address staker;
        uint256 factor;
        bytes32 name;
    }

    mapping(address => PairDesc) public pairDescs;

    address[] private registeredGems;

    uint256 public decimals = 18;

    uint256 public prec = 1e18;

    mapping(address => uint256) private _totalSupply;

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

    IGemForRewardChecker public gemForRewardChecker;

    function checkGem(address gem) internal view returns (bool) {
        return gemForRewardChecker.check(gem);
    }

    function registerGem(address gem) internal {
        for (uint256 i = 0; i < registeredGems.length; i++) {
            if (registeredGems[i] == gem) {
                return;
            }
        }
        registeredGems.push(gem);
    }

    function totalSupply() public view returns (uint256) {
        uint256 res = 0;
        for (uint256 i = 0; i < registeredGems.length; i++) {
            res = res.add(_totalSupply[registeredGems[i]]);
        }
        return res.div(prec);
    }

    function balanceOf(address account) public view returns (uint256) {
        uint256 res = 0;
        for (uint256 i = 0; i < registeredGems.length; i++) {
            res = res.add(_balances[registeredGems[i]][account]);
        }
        return res.div(prec);
    }

    function calcCheckValue(uint256 amount, address gem) public view returns (uint256) {
        require(amount > 0);
        PairDesc storage desc = pairDescs[gem];
        require(desc.adapter != address(0x0));
        assert(desc.gem == gem);
        uint256 r = IAdapter(desc.adapter).calc(gem, amount, desc.factor);
        require(r > 0);
        return r;
    }

    function stakeLp(
        uint256 amount,
        address gem,
        address usr
    ) internal {
        uint256 value = calcCheckValue(amount, gem).mul(prec);

        _balances[gem][usr] = _balances[gem][usr].add(value);
        _amounts[gem][usr] = _amounts[gem][usr].add(amount);
        _totalSupply[gem] = _totalSupply[gem].add(value);
    }

    function withdrawLp(
        uint256 amount,
        address gem,
        address usr
    ) internal {
        uint256 value = amount.mul(_balances[gem][usr]).div(_amounts[gem][usr]);

        _balances[gem][usr] = _balances[gem][usr].sub(value);
        _amounts[gem][usr] = _amounts[gem][usr].sub(amount);
        _totalSupply[gem] = _totalSupply[gem].sub(value);
    }
}

////// src/rewardsDecayHolder.sol
/* pragma solidity ^0.5.12; */

/* import "./IERC20.sol"; */
/* import "./safeMath.sol"; */
/* import "./safeERC20.sol"; */

interface IRewarder {
    function stake(
        address account,
        uint256 amount,
        address gem
    ) external;

    function withdraw(
        address account,
        uint256 amount,
        address gem
    ) external;
}

contract StakingRewardsDecayHolder {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    IRewarder public rewarder;

    uint256 public withdrawErrorCount;

    mapping(address => mapping(address => uint256)) public amounts;

    event withdrawError(uint256 amount, address gem);

    constructor(address _rewarder) public {
        rewarder = IRewarder(_rewarder);
    }

    function stake(uint256 amount, address gem) public {
        require(amount > 0, "Cannot stake 0");

        rewarder.stake(msg.sender, amount, gem);

        amounts[gem][msg.sender] = amounts[gem][msg.sender].add(amount);
        IERC20(gem).safeTransferFrom(msg.sender, address(this), amount);
    }

    function withdraw(uint256 amount, address gem) public {
        require(amount > 0, "Cannot withdraw 0");

        (bool success, ) =
            address(rewarder).call(
                abi.encodeWithSelector(rewarder.withdraw.selector, msg.sender, amount, gem)
            );
        if (!success) {
            //don't interfere with user to withdraw his money regardless
            //of potential rewarder's bug or hacks
            //only amounts map matters
            emit withdrawError(amount, gem);
            withdrawErrorCount++;
        }

        amounts[gem][msg.sender] = amounts[gem][msg.sender].sub(amount);
        IERC20(gem).safeTransfer(msg.sender, amount);
    }
}

////// src/rewardDecay.sol
/*
 * MIT License
 * ===========
 *
 * Copyright (c) 2020 Freeliquid
 *
 * 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
 */

/* pragma solidity ^0.5.12; */

/* import "./lpTokenWrapper.sol"; */
/* import "./rewardsDecayHolder.sol"; */
/* import "./lib.sol"; */
/* import "./ReentrancyGuard.sol"; */

contract StakingRewardsDecay is LPTokenWrapper, Auth, ReentrancyGuard {
    address public gov;
    address public aggregator;
    uint256 public totalRewards = 0;

    struct EpochData {
        mapping(address => uint256) userRewardPerTokenPaid;
        mapping(address => uint256) rewards;
        uint256 initreward;
        uint256 duration;
        uint256 starttime;
        uint256 periodFinish;
        uint256 rewardRate;
        uint256 lastUpdateTime;
        uint256 rewardPerTokenStored;
        uint256 lastTotalSupply;
        bool closed;
    }

    uint256 public EPOCHCOUNT = 0;
    uint256 public epochInited = 0;
    EpochData[] public epochs;

    mapping(bytes32 => address) public pairNameToGem;

    mapping(address => uint256) public lastClaimedEpoch;
    mapping(address => uint256) public yetNotClaimedOldEpochRewards;
    uint256 public currentEpoch;

    StakingRewardsDecayHolder public holder;

    event RewardAdded(uint256 reward, uint256 epoch, uint256 duration, uint256 starttime);
    event StopRewarding();
    event Staked(address indexed user, address indexed gem, uint256 amount);
    event Withdrawn(address indexed user, address indexed gem, uint256 amount);
    event RewardTakeStock(address indexed user, uint256 reward, uint256 epoch);
    event RewardPaid(address indexed user, uint256 reward);

    constructor() public {
        deployer = msg.sender;
    }

    function initialize(address _gov, uint256 epochCount) public initializer {
        // only deployer can initialize
        require(deployer == msg.sender);

        gov = _gov;
        require(gov != address(0));
        require(epochCount > 0);

        EPOCHCOUNT = epochCount;
        EpochData memory data;
        for (uint256 i = 0; i < epochCount; i++) {
            epochs.push(data);
        }

        holder = new StakingRewardsDecayHolder(address(this));
    }

    function setupAggregator(address _aggregator) public {
        require(deployer == msg.sender);
        require(_aggregator != address(0));
        require(aggregator == address(0)); //only one set allowed

        aggregator = _aggregator;
    }

    function getStartTime() public view returns (uint256) {
        return epochs[0].starttime;
    }

    modifier checkStart() {
        require(block.timestamp >= getStartTime(), "not start");
        require(epochInited == EPOCHCOUNT, "not all epochs was inited");
        _;
    }

    function initRewardAmount(
        uint256 reward,
        uint256 starttime,
        uint256 duration,
        uint256 idx
    ) public {
        // only deployer can
        require(deployer == msg.sender);
        require(epochInited == 0, "not allowed after approve");
        initEpoch(reward, starttime, duration, idx);
    }

    function setupGemForRewardChecker(address a) public {
        require(deployer == msg.sender);
        gemForRewardChecker = IGemForRewardChecker(a);
    }

    function initEpoch(
        uint256 reward,
        uint256 starttime,
        uint256 duration,
        uint256 idx
    ) internal {
        require(idx < EPOCHCOUNT, "idx < EPOCHCOUNT");
        require(duration > 0, "duration > 0");
        require(starttime >= block.timestamp, "starttime > block.timestamp");

        EpochData storage epoch = epochs[idx];

        epoch.rewardPerTokenStored = 0;
        epoch.starttime = starttime;
        epoch.duration = duration;
        epoch.rewardRate = reward.div(duration);
        require(epoch.rewardRate > 0, "zero rewardRate");

        epoch.initreward = reward;
        epoch.lastUpdateTime = starttime;
        epoch.periodFinish = starttime.add(duration);

        emit RewardAdded(reward, idx, duration, starttime);
    }

    function initAllEpochs(
        uint256[] memory rewards,
        uint256 starttime,
        uint256 duration
    ) public {
        // only deployer can
        require(deployer == msg.sender);
        require(epochInited == 0, "not allowed after approve");

        require(duration > 0);
        require(starttime > 0);

        assert(rewards.length == EPOCHCOUNT);

        uint256 time = starttime;

        for (uint256 i = 0; i < EPOCHCOUNT; i++) {
            initEpoch(rewards[i], time, duration, i);
            time = time.add(duration);
        }
    }

    function getEpochRewardRate(uint256 epochIdx) public view returns (uint256) {
        return epochs[epochIdx].rewardRate;
    }

    function getEpochStartTime(uint256 epochIdx) public view returns (uint256) {
        return epochs[epochIdx].starttime;
    }

    function getEpochFinishTime(uint256 epochIdx) public view returns (uint256) {
        return epochs[epochIdx].periodFinish;
    }

    function getTotalRewards() public view returns (uint256 result) {
        require(epochInited == EPOCHCOUNT, "not inited");

        result = 0;

        for (uint256 i = 0; i < EPOCHCOUNT; i++) {
            result = result.add(epochs[i].initreward);
        }
    }

    function getTotalRewardTime() public view returns (uint256 result) {
        require(epochInited == EPOCHCOUNT, "not inited");

        result = 0;

        for (uint256 i = 0; i < EPOCHCOUNT; i++) {
            result = result.add(epochs[i].duration);
        }
    }

    function approveEpochsConsistency() public {
        require(deployer == msg.sender);
        require(epochInited == 0, "double call not allowed");

        uint256 totalReward = epochs[0].initreward;
        require(getStartTime() > 0);

        for (uint256 i = 1; i < EPOCHCOUNT; i++) {
            EpochData storage epoch = epochs[i];
            require(epoch.starttime > 0);
            require(epoch.starttime == epochs[i - 1].periodFinish);
            totalReward = totalReward.add(epoch.initreward);
        }

        require(IERC20(gov).balanceOf(address(this)) >= totalReward, "GOV balance not enought");

        epochInited = EPOCHCOUNT;
    }

    function resetDeployer() public {
        // only deployer can do it
        require(deployer == msg.sender);
        require(epochInited == EPOCHCOUNT);
        deployer = address(0);
    }

    function calcCurrentEpoch() public view returns (uint256 res) {
        res = 0;
        for (
            uint256 i = currentEpoch;
            i < EPOCHCOUNT && epochs[i].starttime <= block.timestamp;
            i++
        ) {
            res = i;
        }
    }

    modifier updateCurrentEpoch() {
        currentEpoch = calcCurrentEpoch();

        uint256 supply = totalSupply();
        epochs[currentEpoch].lastTotalSupply = supply;

        for (int256 i = int256(currentEpoch) - 1; i >= 0; i--) {
            EpochData storage epoch = epochs[uint256(i)];
            if (epoch.closed) {
                break;
            }

            epoch.lastTotalSupply = supply;
            epoch.closed = true;
        }

        _;
    }

    function registerPairDesc(
        address gem,
        address adapter,
        uint256 factor,
        bytes32 name
    ) public auth nonReentrant {
        require(gem != address(0x0), "gem is null");
        require(adapter != address(0x0), "adapter is null");

        require(checkGem(gem), "bad gem");

        require(pairNameToGem[name] == address(0) || pairNameToGem[name] == gem, "duplicate name");

        if (pairDescs[gem].name != "") {
            delete pairNameToGem[pairDescs[gem].name];
        }

        registerGem(gem);

        pairDescs[gem] = PairDesc({
            gem: gem,
            adapter: adapter,
            factor: factor,
            staker: address(0),
            name: name
        });

        pairNameToGem[name] = gem;
    }

    function getPairInfo(bytes32 name, address account)
        public
        view
        returns (
            address gem,
            uint256 avail,
            uint256 locked,
            uint256 lockedValue,
            uint256 availValue
        )
    {
        gem = pairNameToGem[name];
        if (gem == address(0)) {
            return (address(0), 0, 0, 0, 0);
        }

        PairDesc storage desc = pairDescs[gem];
        locked = holder.amounts(gem, account);
        lockedValue = IAdapter(desc.adapter).calc(gem, locked, desc.factor);
        avail = IERC20(gem).balanceOf(account);
        availValue = IAdapter(desc.adapter).calc(gem, avail, desc.factor);
    }

    function getPrice(bytes32 name) public view returns (uint256) {
        address gem = pairNameToGem[name];
        if (gem == address(0)) {
            return 0;
        }

        PairDesc storage desc = pairDescs[gem];
        return IAdapter(desc.adapter).calc(gem, 1, desc.factor);
    }

    function getRewardPerHour() public view returns (uint256) {
        EpochData storage epoch = epochs[calcCurrentEpoch()];
        return epoch.rewardRate * 3600;
    }

    function lastTimeRewardApplicable(EpochData storage epoch) internal view returns (uint256) {
        assert(block.timestamp >= epoch.starttime);
        return Math.min(block.timestamp, epoch.periodFinish);
    }

    function rewardPerToken(EpochData storage epoch, uint256 lastTotalSupply)
        internal
        view
        returns (uint256)
    {
        if (lastTotalSupply == 0) {
            return epoch.rewardPerTokenStored;
        }
        return
            epoch.rewardPerTokenStored.add(
                lastTimeRewardApplicable(epoch)
                    .sub(epoch.lastUpdateTime)
                    .mul(epoch.rewardRate)
                    .mul(1e18 * (10**decimals))
                    .div(lastTotalSupply)
            );
    }

    function earnedEpoch(
        address account,
        EpochData storage epoch,
        uint256 lastTotalSupply
    ) internal view returns (uint256) {
        return
            balanceOf(account)
                .mul(
                rewardPerToken(epoch, lastTotalSupply).sub(epoch.userRewardPerTokenPaid[account])
            )
                .div(1e18 * (10**decimals))
                .add(epoch.rewards[account]);
    }

    function earned(address account) public view returns (uint256 acc) {
        uint256 currentSupply = totalSupply();
        int256 lastClaimedEpochIdx = int256(lastClaimedEpoch[account]);

        for (int256 i = int256(calcCurrentEpoch()); i >= lastClaimedEpochIdx; i--) {
            EpochData storage epoch = epochs[uint256(i)];

            uint256 epochTotalSupply = currentSupply;
            if (epoch.closed) {
                epochTotalSupply = epoch.lastTotalSupply;
            }
            acc = acc.add(earnedEpoch(account, epoch, epochTotalSupply));
        }

        acc = acc.add(yetNotClaimedOldEpochRewards[account]);
    }

    function getRewardEpoch(address account, EpochData storage epoch) internal returns (uint256) {
        uint256 reward = earnedEpoch(account, epoch, epoch.lastTotalSupply);
        if (reward > 0) {
            epoch.rewards[account] = 0;
            return reward;
        }
        return 0;
    }

    function takeStockReward(address account) internal returns (uint256 acc) {
        for (uint256 i = lastClaimedEpoch[account]; i <= currentEpoch; i++) {
            uint256 reward = getRewardEpoch(account, epochs[i]);
            acc = acc.add(reward);
            emit RewardTakeStock(account, reward, i);
        }
        lastClaimedEpoch[account] = currentEpoch;
    }

    function gatherOldEpochReward(address account) internal {
        if (currentEpoch == 0) {
            return;
        }

        uint256 acc = takeStockReward(account);
        yetNotClaimedOldEpochRewards[account] = yetNotClaimedOldEpochRewards[account].add(acc);
    }

    function stakeEpoch(
        uint256 amount,
        address gem,
        address usr,
        EpochData storage epoch
    ) internal updateReward(usr, epoch) {
        gatherOldEpochReward(usr);
        stakeLp(amount, gem, usr);
        emit Staked(usr, gem, amount);
    }

    function stake(
        address account,
        uint256 amount,
        address gem
    ) public nonReentrant checkStart updateCurrentEpoch {
        require(address(holder) == msg.sender);
        assert(amount > 0);
        stakeEpoch(amount, gem, account, epochs[currentEpoch]);
    }

    function withdrawEpoch(
        uint256 amount,
        address gem,
        address usr,
        EpochData storage epoch
    ) internal updateReward(usr, epoch) {
        gatherOldEpochReward(usr);
        withdrawLp(amount, gem, usr);
        emit Withdrawn(usr, gem, amount);
    }

    function withdraw(
        address account,
        uint256 amount,
        address gem
    ) public nonReentrant checkStart updateCurrentEpoch {
        require(address(holder) == msg.sender);
        assert(amount > 0);
        withdrawEpoch(amount, gem, account, epochs[currentEpoch]);
    }

    function getRewardCore(address account)
        internal
        checkStart
        updateCurrentEpoch
        updateReward(account, epochs[currentEpoch])
        returns (uint256 acc)
    {
        acc = takeStockReward(account);

        acc = acc.add(yetNotClaimedOldEpochRewards[account]);
        yetNotClaimedOldEpochRewards[account] = 0;

        if (acc > 0) {
            totalRewards = totalRewards.add(acc);
            IERC20(gov).safeTransfer(account, acc);
            emit RewardPaid(account, acc);
        }
    }

    function getReward() public nonReentrant returns (uint256) {
        return getRewardCore(msg.sender);
    }

    function getRewardEx(address account) public nonReentrant returns (uint256) {
        require(aggregator == msg.sender);
        return getRewardCore(account);
    }

    modifier updateReward(address account, EpochData storage epoch) {
        assert(account != address(0));

        epoch.rewardPerTokenStored = rewardPerToken(epoch, epoch.lastTotalSupply);
        epoch.lastUpdateTime = lastTimeRewardApplicable(epoch);
        epoch.rewards[account] = earnedEpoch(account, epoch, epoch.lastTotalSupply);
        epoch.userRewardPerTokenPaid[account] = epoch.rewardPerTokenStored;
        _;
    }
}

contract RewardDecayAggregator {
    using SafeMath for uint256;

    StakingRewardsDecay[2] public rewarders;

    constructor(address rewarder0, address rewarder1) public {
        rewarders[0] = StakingRewardsDecay(rewarder0);
        rewarders[1] = StakingRewardsDecay(rewarder1);
    }

    function claimReward() public {
        for (uint256 i = 0; i < rewarders.length; i++) {
            rewarders[i].getRewardEx(msg.sender);
        }
    }

    function earned() public view returns (uint256 res) {
        for (uint256 i = 0; i < rewarders.length; i++) {
            res = res.add(rewarders[i].earned(msg.sender));
        }
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":true,"inputs":[{"indexed":true,"internalType":"bytes4","name":"sig","type":"bytes4"},{"indexed":true,"internalType":"address","name":"usr","type":"address"},{"indexed":true,"internalType":"bytes32","name":"arg1","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"arg2","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"LogNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"starttime","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":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"RewardTakeStock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"gem","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[],"name":"StopRewarding","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"gem","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"constant":true,"inputs":[],"name":"EPOCHCOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"aggregator","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"approveEpochsConsistency","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":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"gem","type":"address"}],"name":"calcCheckValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"calcCurrentEpoch","outputs":[{"internalType":"uint256","name":"res","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"usr","type":"address"}],"name":"deny","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"deployer","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"acc","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"epochInited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochs","outputs":[{"internalType":"uint256","name":"initreward","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"starttime","type":"uint256"},{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"lastTotalSupply","type":"uint256"},{"internalType":"bool","name":"closed","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"gemForRewardChecker","outputs":[{"internalType":"contract IGemForRewardChecker","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"epochIdx","type":"uint256"}],"name":"getEpochFinishTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"epochIdx","type":"uint256"}],"name":"getEpochRewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"epochIdx","type":"uint256"}],"name":"getEpochStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"name","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"getPairInfo","outputs":[{"internalType":"address","name":"gem","type":"address"},{"internalType":"uint256","name":"avail","type":"uint256"},{"internalType":"uint256","name":"locked","type":"uint256"},{"internalType":"uint256","name":"lockedValue","type":"uint256"},{"internalType":"uint256","name":"availValue","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"name","type":"bytes32"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"getReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getRewardEx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getRewardPerHour","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getTotalRewardTime","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getTotalRewards","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"gov","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"holder","outputs":[{"internalType":"contract StakingRewardsDecayHolder","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256[]","name":"rewards","type":"uint256[]"},{"internalType":"uint256","name":"starttime","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"initAllEpochs","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"starttime","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"idx","type":"uint256"}],"name":"initRewardAmount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_gov","type":"address"},{"internalType":"uint256","name":"epochCount","type":"uint256"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastClaimedEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pairDescs","outputs":[{"internalType":"address","name":"gem","type":"address"},{"internalType":"address","name":"adapter","type":"address"},{"internalType":"address","name":"staker","type":"address"},{"internalType":"uint256","name":"factor","type":"uint256"},{"internalType":"bytes32","name":"name","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"pairNameToGem","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"prec","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"gem","type":"address"},{"internalType":"address","name":"adapter","type":"address"},{"internalType":"uint256","name":"factor","type":"uint256"},{"internalType":"bytes32","name":"name","type":"bytes32"}],"name":"registerPairDesc","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"usr","type":"address"}],"name":"rely","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"resetDeployer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_aggregator","type":"address"}],"name":"setupAggregator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"a","type":"address"}],"name":"setupGemForRewardChecker","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"gem","type":"address"}],"name":"stake","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"wards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"gem","type":"address"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"yetNotClaimedOldEpochRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]

60806040526012603555670de0b6b3a764000060365560006040556000604155600060425534801561003057600080fd5b506001603d55603c80546001600160a01b03191633179055613df8806100576000396000f3fe608060405234801561001057600080fd5b506004361061027d5760003560e01c8063633e9e091161015c578063c181c482116100ce578063d69a1d6d11610087578063d69a1d6d146107e0578063dc8b5e3c14610806578063e2c50b4b1461082c578063e534155d14610834578063e627f2db1461083c578063f41c33e9146108445761027d565b8063c181c482146106a7578063c6b61e4c146106d3578063c828371e1461073d578063cd6dc68714610745578063d420354b14610771578063d5f39488146107d85761027d565b80638b751038116101205780638b751038146106265780639c52a7f11461062e578063a6c9912314610654578063ad3548e314610671578063b25fb84214610679578063bf353dbb146106815761027d565b8063633e9e091461057f57806365fae35e1461059c57806369328dec146105c257806370a08231146105f8578063766718081461061e5761027d565b806331d98b3f116101f5578063470d970f116101b9578063470d970f146104ac57806351dcb0aa146104b457806354423bb81461051757806356605475146105345780635c96732c1461055a5780635ff45b43146105625761027d565b806331d98b3f1461042a5780633bee8472146104475780633d18b9121461046d57806341e58d261461047557806343690526146104a45761027d565b806318160ddd1161024757806318160ddd1461032c578063245a7bfc14610334578063294091cd1461033c5780632a240243146103725780632ff685201461037a578063313ce567146104225761027d565b80628cc26214610282578062bee478146102ba5780630e15561a146102f857806312d43a511461030057806315a9946e14610324575b600080fd5b6102a86004803603602081101561029857600080fd5b50356001600160a01b031661086a565b60405190815260200160405180910390f35b6102f6600480360360808110156102d057600080fd5b506001600160a01b0381358116916020810135909116906040810135906060013561093a565b005b6102a8610cb2565b610308610cb8565b6040516001600160a01b03909116815260200160405180910390f35b610308610cc7565b6102a8610cd6565b610308610d50565b6102f66004803603606081101561035257600080fd5b506001600160a01b03813581169160208101359160409091013516610d5f565b6102a8610f35565b6102f66004803603606081101561039057600080fd5b8101906020810181356401000000008111156103ab57600080fd5b8201836020820111156103bd57600080fd5b803590602001918460208302840111640100000000831117156103df57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505082359350505060200135610f7f565b6102a861105a565b6102a86004803603602081101561044057600080fd5b5035611060565b6102a86004803603602081101561045d57600080fd5b50356001600160a01b031661114b565b6102a861115f565b6102f66004803603608081101561048b57600080fd5b50803590602081013590604081013590606001356111be565b6102f6611237565b6102a8611270565b6104da600480360360208110156104ca57600080fd5b50356001600160a01b0316611276565b6040516001600160a01b0395861681529385166020850152919093166040808401919091526060830193909352608082015260a001905180910390f35b6103086004803603602081101561052d57600080fd5b50356112b3565b6102a86004803603602081101561054a57600080fd5b50356001600160a01b03166112d0565b6102f6611347565b6102a86004803603602081101561057857600080fd5b5035611560565b6102a86004803603602081101561059557600080fd5b5035611588565b6102f6600480360360208110156105b257600080fd5b50356001600160a01b03166115b0565b6102f6600480360360608110156105d857600080fd5b506001600160a01b03813581169160208101359160409091013516611674565b6102a86004803603602081101561060e57600080fd5b50356001600160a01b031661183f565b6102a86118d3565b6102a86118d9565b6102f66004803603602081101561064457600080fd5b50356001600160a01b03166118df565b6102a86004803603602081101561066a57600080fd5b50356119a0565b6102a86119c8565b6102a86119ce565b6102a86004803603602081101561069757600080fd5b50356001600160a01b0316611a5d565b6102a8600480360360408110156106bd57600080fd5b50803590602001356001600160a01b0316611a71565b6106f0600480360360208110156106e957600080fd5b5035611b80565b60405198895260208901979097526040808901969096526060880194909452608087019290925260a086015260c085015260e0840152901515610100830152610120909101905180910390f35b6102a8611bde565b6102f66004803603604081101561075b57600080fd5b506001600160a01b038135169060200135611c05565b61079d6004803603604081101561078757600080fd5b50803590602001356001600160a01b0316611e00565b6040516001600160a01b03909516855260208501939093526040808501929092526060840152608083019190915260a0909101905180910390f35b6103086120b1565b6102f6600480360360208110156107f657600080fd5b50356001600160a01b03166120c0565b6102f66004803603602081101561081c57600080fd5b50356001600160a01b0316612122565b6102a861215b565b61030861218f565b6102a861219e565b6102a86004803603602081101561085a57600080fd5b50356001600160a01b031661222d565b600080610875610cd6565b6001600160a01b0384166000908152604560205290915060408120549050600061089d610f35565b90505b818112610907576000604382815481106108b657fe5b906000526020600020600a600b9092020190810154909150849060ff16156108df575060098101545b6108fa6108ed888484612241565b879063ffffffff6122e316565b95505050600019016108a0565b506001600160a01b03841660009081526046602052610932906040902054849063ffffffff6122e316565b949350505050565b336000908152603b6020526040902054600114806109625750603c546001600160a01b031633145b6109a85760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b604482015260640160405180910390fd5b6002603d5414156109ed5760405162461bcd60e51b815260206004820152601f6024820152600080516020613d2b833981519152604482015260640160405180910390fd5b6002603d556001600160a01b038416610a3a5760405162461bcd60e51b815260206004820152600b60248201526a19d95b481a5cc81b9d5b1b60aa1b604482015260640160405180910390fd5b6001600160a01b038316610a865760405162461bcd60e51b815260206004820152600f60248201526e1859185c1d195c881a5cc81b9d5b1b608a1b604482015260640160405180910390fd5b610a8f8461233c565b610ac95760405162461bcd60e51b81526020600482015260076024820152666261642067656d60c81b604482015260640160405180910390fd5b6000818152604460205260408120546001600160a01b03161480610b0d5750600081815260446020526001600160a01b0385169060409020546001600160a01b0316145b610b4e5760405162461bcd60e51b815260206004820152600e60248201526d6475706c6963617465206e616d6560901b604482015260640160405180910390fd5b6001600160a01b03841660009081526033602052604090206004015415610bab576001600160a01b038416600090815260336020526044906040812060040154815260200190815260200160002080546001600160a01b03191690555b610bb4846123c9565b60405160a0810160409081526001600160a01b03808716808452908616602080850191909152600083850181905260608501879052608085018690529182526033905220815181546001600160a01b0319166001600160a01b039190911617815560208201516001820180546001600160a01b0319166001600160a01b039290921691909117905560408201516002820180546001600160a01b0319166001600160a01b0392909216919091179055606082015181600301556080820151600490910155506000818152604460205284906040902080546001600160a01b0319166001600160a01b039290921691909117905550506001603d555050565b60405481565b603e546001600160a01b031681565b603a546001600160a01b031681565b600080805b603454811015610d3557610d2b6037600060348481548110610cf957fe5b90600052602060002001546001600160a01b03168152602081019190915260400160002054839063ffffffff6122e316565b9150600101610cdb565b50603654610d4a90829063ffffffff61245416565b91505090565b603f546001600160a01b031681565b6002603d541415610da45760405162461bcd60e51b815260206004820152601f6024820152600080516020613d2b833981519152604482015260640160405180910390fd5b6002603d55610db1611bde565b421015610df05760405162461bcd60e51b81526020600482015260096024820152681b9bdd081cdd185c9d60ba1b604482015260640160405180910390fd5b60415460425414610e435760405162461bcd60e51b81526020600482015260196024820152781b9bdd08185b1b08195c1bd8da1cc81dd85cc81a5b9a5d1959603a1b604482015260640160405180910390fd5b610e4b610f35565b6047556000610e58610cd6565b905080604360475481548110610e6a57fe5b9060005260206000206009600b909202010155604754600019015b60008112610ee057600060438281548110610e9c57fe5b906000526020600020600a600b909202019081015490915060ff1615610ec25750610ee0565b60098101839055600a01805460ff1916600117905560001901610e85565b506048546001600160a01b03163314610ef857600080fd5b60008311610f0257fe5b610f2a838386604360475481548110610f1757fe5b90600052602060002090600b0201612494565b50506001603d555050565b6047546000905b60415481108015610f6b57504260438281548110610f5657fe5b90600052602060002090600b02016004015411155b15610f7b57905060018101610f3c565b5090565b603c546001600160a01b03163314610f9657600080fd5b60425415610fe65760405162461bcd60e51b81526020600482015260196024820152786e6f7420616c6c6f77656420616674657220617070726f766560381b604482015260640160405180910390fd5b60008111610ff357600080fd5b6000821161100057600080fd5b60415483511461100c57fe5b8160005b6041548110156110535761103985828151811061102957fe5b6020026020010151838584612575565b611049828463ffffffff6122e316565b9150600101611010565b5050505050565b60355481565b600081815260446020528060408120546001600160a01b031690508061108a576000915050611146565b6001600160a01b038116600090815260336020526040812060018082015460038301549293506001600160a01b031691639e5232a59185916040516001600160e01b031960e086901b1681526001600160a01b0390931660048401526024830191909152604482015260640160206040518083038186803b15801561110e57600080fd5b505afa158015611122573d6000803e3d6000fd5b505050506040513d602081101561113857600080fd5b810190808051955050505050505b919050565b604660205280600052604060002054905081565b60006002603d5414156111a65760405162461bcd60e51b815260206004820152601f6024820152600080516020613d2b833981519152604482015260640160405180910390fd5b6002603d556111b43361275e565b90506001603d5590565b603c546001600160a01b031633146111d557600080fd5b604254156112255760405162461bcd60e51b81526020600482015260196024820152786e6f7420616c6c6f77656420616674657220617070726f766560381b604482015260640160405180910390fd5b61123184848484612575565b50505050565b603c546001600160a01b0316331461124e57600080fd5b6041546042541461125e57600080fd5b603c80546001600160a01b0319169055565b60365481565b603360205280600052604060002080546001820154600283015460038401546004909401546001600160a01b039384169550918316939216919085565b6044602052806000526040600020546001600160a01b0316905081565b60006002603d5414156113175760405162461bcd60e51b815260206004820152601f6024820152600080516020613d2b833981519152604482015260640160405180910390fd5b6002603d55603f546001600160a01b0316331461133357600080fd5b61133c8261275e565b6001603d5592915050565b603c546001600160a01b0316331461135e57600080fd5b604254156113b25760405162461bcd60e51b815260206004820152601760248201527f646f75626c652063616c6c206e6f7420616c6c6f776564000000000000000000604482015260640160405180910390fd5b600060436000815481106113c257fe5b90600052602060002090600b020160020154905060006113e0611bde565b116113ea57600080fd5b60015b6041548110156114795760006043828154811061140657fe5b90600052602060002090600b02019050600081600401541161142757600080fd5b6043600183038154811061143757fe5b90600052602060002090600b02016005015481600401541461145857600080fd5b600281015461146e90849063ffffffff6122e316565b9250506001016113ed565b50603e5481906001600160a01b03166370a08231306040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b1580156114cd57600080fd5b505afa1580156114e1573d6000803e3d6000fd5b505050506040513d60208110156114f757600080fd5b810190808051939093101592506115579150505760405162461bcd60e51b815260206004820152601760248201527f474f562062616c616e6365206e6f7420656e6f75676874000000000000000000604482015260640160405180910390fd5b50604154604255565b60006043828154811061156f57fe5b90600052602060002090600b0201600601549050919050565b60006043828154811061159757fe5b90600052602060002090600b0201600401549050919050565b336000908152603b6020526040902054600114806115d85750603c546001600160a01b031633145b61161e5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b604482015260640160405180910390fd5b6001600160a01b0381166000908152603b60205260019060409020555961012081016040526020815260e0602082015260e060006040830137602435600435336001600160e01b03196000351661012085a45050565b6002603d5414156116b95760405162461bcd60e51b815260206004820152601f6024820152600080516020613d2b833981519152604482015260640160405180910390fd5b6002603d556116c6611bde565b4210156117055760405162461bcd60e51b81526020600482015260096024820152681b9bdd081cdd185c9d60ba1b604482015260640160405180910390fd5b604154604254146117585760405162461bcd60e51b81526020600482015260196024820152781b9bdd08185b1b08195c1bd8da1cc81dd85cc81a5b9a5d1959603a1b604482015260640160405180910390fd5b611760610f35565b604755600061176d610cd6565b90508060436047548154811061177f57fe5b9060005260206000206009600b909202010155604754600019015b600081126117f5576000604382815481106117b157fe5b906000526020600020600a600b909202019081015490915060ff16156117d757506117f5565b60098101839055600a01805460ff191660011790556000190161179a565b506048546001600160a01b0316331461180d57600080fd5b6000831161181757fe5b610f2a83838660436047548154811061182c57fe5b90600052602060002090600b0201612a04565b600080805b6034548110156118b7576118ad603960006034848154811061186257fe5b90600052602060002001546001600160a01b0316815260208101919091526040016000206001600160a01b03861660009081526020919091526040902054839063ffffffff6122e316565b9150600101611844565b506036546118cc90829063ffffffff61245416565b9392505050565b60475481565b60425481565b336000908152603b6020526040902054600114806119075750603c546001600160a01b031633145b61194d5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b604482015260640160405180910390fd5b6001600160a01b0381166000908152603b60205260408120555961012081016040526020815260e0602082015260e060006040830137602435600435336001600160e01b03196000351661012085a45050565b6000604382815481106119af57fe5b90600052602060002090600b0201600501549050919050565b60415481565b600060415460425414611a145760405162461bcd60e51b815260206004820152600a6024820152691b9bdd081a5b9a5d195960b21b604482015260640160405180910390fd5b506000805b604154811015610f7b57611a5360438281548110611a3357fe5b9060005260206000206003600b909202010154839063ffffffff6122e316565b9150600101611a19565b603b60205280600052604060002054905081565b6000808311611a7f57600080fd5b6001600160a01b038216600090815260336020526040812060018101549091506001600160a01b0316611ab157600080fd5b80546001600160a01b03848116911614611ac757fe5b600181015460038201546000916001600160a01b031690639e5232a590869088906040516001600160e01b031960e086901b1681526001600160a01b0390931660048401526024830191909152604482015260640160206040518083038186803b158015611b3457600080fd5b505afa158015611b48573d6000803e3d6000fd5b505050506040513d6020811015611b5e57600080fd5b810190808051935050508115159050611b7657600080fd5b9150505b92915050565b60438181548110611b8d57fe5b9060005260206000206002600b90920201908101546003820154600483015460058401546006850154600786015460088701546009880154600a909801549698509496939592949193909260ff1689565b60006043600081548110611bee57fe5b90600052602060002090600b020160040154905090565b600054610100900460ff1680611c1e5750611c1e612ae5565b80611c2c575060005460ff16155b611c675760405162461bcd60e51b815260040180806020018281038252602e815260200180613d6c602e913960400191505060405180910390fd5b60008054600161010061ff00198316811760ff191691909117909255603c5491900460ff1690336001600160a01b0390911614611ca357600080fd5b603e80546001600160a01b0319166001600160a01b03858116919091179182905516611cce57600080fd5b60008211611cdb57600080fd5b6041829055611ce86133b7565b60005b83811015611d875760438054600181018083556000928352849290919060209020919291600b90910201815181600201556020820151816003015560408201518160040155606082015181600501556080820151816006015560a0820151816007015560c0820151816008015560e08201518160090155610100820151600a91909101805460ff19169115159190911790555050600101611ceb565b5030604051611d9590613405565b6001600160a01b039091168152602001604051809103906000f080158015611dc1573d6000803e3d6000fd5b50604880546001600160a01b0319166001600160a01b0392909216919091179055506000805461ff001916610100921515929092029190911790555050565b600082815260446020528080808060408120546001600160a01b0316945084611e37575060009350839250829150819050806120a7565b6001600160a01b03851660009081526033602052604081206048549091506001600160a01b031663e44cf92a87896040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260440160206040518083038186803b158015611eab57600080fd5b505afa158015611ebf573d6000803e3d6000fd5b505050506040513d6020811015611ed557600080fd5b810190808051600185015460038601549198506001600160a01b03169350639e5232a5925089915087906040516001600160e01b031960e086901b1681526001600160a01b0390931660048401526024830191909152604482015260640160206040518083038186803b158015611f4b57600080fd5b505afa158015611f5f573d6000803e3d6000fd5b505050506040513d6020811015611f7557600080fd5b810190808051955050506001600160a01b03871690506370a08231886040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b158015611fd057600080fd5b505afa158015611fe4573d6000803e3d6000fd5b505050506040513d6020811015611ffa57600080fd5b810190808051600185015460038601549199506001600160a01b03169350639e5232a5925089915088906040516001600160e01b031960e086901b1681526001600160a01b0390931660048401526024830191909152604482015260640160206040518083038186803b15801561207057600080fd5b505afa158015612084573d6000803e3d6000fd5b505050506040513d602081101561209a57600080fd5b8101908080519450505050505b9295509295909350565b603c546001600160a01b031681565b603c546001600160a01b031633146120d757600080fd5b6001600160a01b0381166120ea57600080fd5b603f546001600160a01b03161561210057600080fd5b603f80546001600160a01b0319166001600160a01b0392909216919091179055565b603c546001600160a01b0316331461213957600080fd5b603a80546001600160a01b0319166001600160a01b0392909216919091179055565b6000806043612168610f35565b8154811061217257fe5b9060005260206000206006600b909202010154610e100291505090565b6048546001600160a01b031681565b6000604154604254146121e45760405162461bcd60e51b815260206004820152600a6024820152691b9bdd081a5b9a5d195960b21b604482015260640160405180910390fd5b506000805b604154811015610f7b576122236043828154811061220357fe5b9060005260206000206002600b909202010154839063ffffffff6122e316565b91506001016121e9565b604560205280600052604060002054905081565b6001600160a01b03831660009081526001830160205261093260408220546122d7603554600a0a670de0b6b3a7640000026122cb6122b68860000160008b6001600160a01b03166001600160a01b03168152602001908152602001600020546122aa8a8a612aeb565b9063ffffffff612b4116565b6122bf8a61183f565b9063ffffffff612b8116565b9063ffffffff61245416565b9063ffffffff6122e316565b6000828201838110156118cc5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015260640160405180910390fd5b603a546000906001600160a01b031663c23697a8836040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b15801561239057600080fd5b505afa1580156123a4573d6000803e3d6000fd5b505050506040513d60208110156123ba57600080fd5b81019080805195945050505050565b60005b60345481101561241557816001600160a01b0316603482815481106123ed57fe5b90600052602060002001546001600160a01b0316141561240d5750612451565b6001016123cc565b50603480546001810180835560009283528392909190602090200180546001600160a01b0319166001600160a01b039390931692909217909155505b50565b60006118cc838360405160408082019052601a81527f536166654d6174683a206469766973696f6e206279207a65726f0000000000006020820152612bda565b81816001600160a01b0382166124a657fe5b6124b4818260090154612aeb565b60088201556124c281612c7c565b81600701819055506124d982828360090154612241565b6001600160a01b038316600090815260018301602052604090205560088101546001600160a01b03831660009081526020839052604090205561251b84612c9a565b612526868686612cfc565b846001600160a01b0316846001600160a01b03167f5dac0c1b1112564a045ba943c9d50270893e8e826c49be8e7073adc713ab7bd78860405190815260200160405180910390a3505050505050565b60415481106125bd5760405162461bcd60e51b815260206004820152601060248201526f1a591e080f08115413d0d210d3d5539560821b604482015260640160405180910390fd5b600082116126005760405162461bcd60e51b815260206004820152600c60248201526b06475726174696f6e203e20360a41b604482015260640160405180910390fd5b428310156126545760405162461bcd60e51b815260206004820152601b60248201527f737461727474696d65203e20626c6f636b2e74696d657374616d700000000000604482015260640160405180910390fd5b60006043828154811061266357fe5b90600052602060002060006008600b909302909101918201556004810185905560038101849055905061269c858463ffffffff61245416565b600682018190556126e55760405162461bcd60e51b815260206004820152600f60248201526e7a65726f207265776172645261746560881b604482015260640160405180910390fd5b6002810185905560078101849055612703848463ffffffff6122e316565b60058201557f3ffbf598271669161ecd81ce333d0a0b574924ce7a91e396841eb2225e59e26e858385876040518085815260200184815260200183815260200182815260200194505050505060405180910390a15050505050565b6000612768611bde565b4210156127a75760405162461bcd60e51b81526020600482015260096024820152681b9bdd081cdd185c9d60ba1b604482015260640160405180910390fd5b604154604254146127fa5760405162461bcd60e51b81526020600482015260196024820152781b9bdd08185b1b08195c1bd8da1cc81dd85cc81a5b9a5d1959603a1b604482015260640160405180910390fd5b612802610f35565b604755600061280f610cd6565b90508060436047548154811061282157fe5b9060005260206000206009600b909202010155604754600019015b600081126128975760006043828154811061285357fe5b906000526020600020600a600b909202019081015490915060ff16156128795750612897565b60098101839055600a01805460ff191660011790556000190161283c565b50826043604754815481106128a857fe5b906000526020600020600b909102016001600160a01b0382166128c757fe5b6128d5818260090154612aeb565b60088201556128e381612c7c565b81600701819055506128fa82828360090154612241565b6001600160a01b038316600090815260018301602052604090205560088101546001600160a01b03831660009081526020839052604090205561293c85612e47565b6001600160a01b03861660009081526046602052909450612969906040902054859063ffffffff6122e316565b6001600160a01b03861660009081526046602052909450604081205583156129fc5760405461299e908563ffffffff6122e316565b604055603e546129be906001600160a01b0316868663ffffffff612f1616565b846001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e04868560405190815260200160405180910390a25b505050919050565b81816001600160a01b038216612a1657fe5b612a24818260090154612aeb565b6008820155612a3281612c7c565b8160070181905550612a4982828360090154612241565b6001600160a01b038316600090815260018301602052604090205560088101546001600160a01b038316600090815260208390526040902055612a8b84612c9a565b612a96868686612f77565b846001600160a01b0316846001600160a01b03167fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb8860405190815260200160405180910390a3505050505050565b303b1590565b600081612afd57506008820154611b7a565b6118cc612b30836122cb603554600a0a670de0b6b3a7640000026122bf88600601546122bf8a600701546122aa8c612c7c565b60088501549063ffffffff6122e316565b60006118cc838360405160408082019052601e81527f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006020820152613109565b600082612b9057506000611b7a565b82820282848281612b9d57fe5b04146118cc5760405162461bcd60e51b8152600401808060200182810382526021815260200180613d4b6021913960400191505060405180910390fd5b60008183612c665760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612c2b578082015183820152602001612c13565b50505050905090810190601f168015612c585780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581612c7257fe5b0495945050505050565b60008160040154421015612c8c57fe5b611b7a428360050154613163565b604754612ca657612451565b6000612cb182612e47565b6001600160a01b03831660009081526046602052909150612cdf90829060409020549063ffffffff6122e316565b6001600160a01b0383166000908152604660205260409020555050565b6000612d0e6036546122bf8686611a71565b6001600160a01b03841660009081526039602052909150612d55908290604090206001600160a01b038516600090815260209190915260409020549063ffffffff6122e316565b6001600160a01b03841660009081526039602052604090206001600160a01b038416600090815260209190915260409020556001600160a01b03831660009081526038602052612dcb908590604090206001600160a01b038516600090815260209190915260409020549063ffffffff6122e316565b6001600160a01b03841660009081526038602052604090206001600160a01b038416600090815260209190915260409020556001600160a01b03831660009081526037602052612e2890829060409020549063ffffffff6122e316565b6001600160a01b03841660009081526037602052604090205550505050565b6001600160a01b0381166000908152604560205280604081205490505b6047548111612ef4576000612e938460438481548110612e8057fe5b90600052602060002090600b0201613179565b9050612ea5838263ffffffff6122e316565b9250836001600160a01b03167fd79ae009b12e66b13c4bd4034783c61534acc351aa8e53765ec3367744f3d78c828460405191825260208201526040908101905180910390a250600101612e64565b506047546001600160a01b038316600090815260456020526040902055919050565b612f728363a9059cbb60e01b84846040516001600160a01b0390921660248301526044820152606401604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b031690911790526131bf565b505050565b6001600160a01b03821660009081526038602052612fef604082206001600160a01b038416600090815260209190915260409020546001600160a01b038516600090815260396020526122cb90604090206001600160a01b03861660009081526020919091526040902054879063ffffffff612b8116565b6001600160a01b03841660009081526039602052909150613036908290604090206001600160a01b038516600090815260209190915260409020549063ffffffff612b4116565b6001600160a01b03841660009081526039602052604090206001600160a01b038416600090815260209190915260409020556001600160a01b038316600090815260386020526130ac908590604090206001600160a01b038516600090815260209190915260409020549063ffffffff612b4116565b6001600160a01b03841660009081526038602052604090206001600160a01b038416600090815260209190915260409020556001600160a01b03831660009081526037602052612e2890829060409020549063ffffffff612b4116565b6000818484111561315b5760405162461bcd60e51b8152600401808060200182810382528381815181526020019150805160209091019080838360008315612c2b578082015183820152602001612c13565b505050900390565b600081831061317257816118cc565b5090919050565b60008061318b84848560090154612241565b905080156131b5576001600160a01b03841660009081526001840160205260408120559050611b7a565b5060009392505050565b6131d1826001600160a01b0316613380565b6132215760405162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015260640160405180910390fd5b60006060836001600160a01b0316836040518082805190602001908083835b6020831061325f5780518252601f199092019160209182019101613240565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146132c1576040513d603f01601f191681016040523d815291503d6000602084013e6132c6565b606091505b50915091508161331c5760405162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015260640160405180910390fd5b60008151111561123157602081018151602081101561333a57600080fd5b81019080805192506112319150505760405162461bcd60e51b815260040180806020018281038252602a815260200180613d9a602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081158015906109325750141592915050565b60405180610120016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000151581525090565b610918806134138339019056fe608060405234801561001057600080fd5b506040516109183803806109188339818101604052602081101561003357600080fd5b5051600080546001600160a01b039092166001600160a01b03199092169190911790556108b3806100656000396000f3fe608060405234801561001057600080fd5b50600436106100565760003560e01c8062f714ce1461005b5780637acb775714610089578063dcc3e06e146100b5578063e44cf92a146100d9578063f581aff714610119575b600080fd5b6100876004803603604081101561007157600080fd5b50803590602001356001600160a01b0316610121565b005b6100876004803603604081101561009f57600080fd5b50803590602001356001600160a01b031661031b565b6100bd610442565b604080516001600160a01b039092168252519081900360200190f35b610107600480360360408110156100ef57600080fd5b506001600160a01b0381358116916020013516610451565b60408051918252519081900360200190f35b61010761046e565b6000821161016a576040805162461bcd60e51b8152602060048201526011602482015270043616e6e6f74207769746864726177203607c1b604482015290519081900360640190fd5b6000805460408051336024820152604481018690526001600160a01b0385811660648084019190915283518084039091018152608490920183526020820180516001600160e01b0316631a4ca37b60e21b178152925182519190941693919282918083835b602083106101ee5780518252601f1990920191602091820191016101cf565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610250576040519150601f19603f3d011682016040523d82523d6000602084013e610255565b606091505b50509050806102aa57604080518481526001600160a01b038416602082015281517fc7db832b9d7d07bc1dc206c2ba54d1ef830d4cacfaa2a833b1e1418431b0cba7929181900390910190a160018054810190555b6001600160a01b03821660009081526002602090815260408083203384529091529020546102de908463ffffffff61047416565b6001600160a01b038316600081815260026020908152604080832033808552925290912092909255610316918563ffffffff6104bd16565b505050565b60008211610361576040805162461bcd60e51b815260206004820152600e60248201526d043616e6e6f74207374616b6520360941b604482015290519081900360640190fd5b600080546040805163294091cd60e01b8152336004820152602481018690526001600160a01b0385811660448301529151919092169263294091cd926064808201939182900301818387803b1580156103b957600080fd5b505af11580156103cd573d6000803e3d6000fd5b5050506001600160a01b038216600090815260026020908152604080832033845290915290205461040591508363ffffffff61050f16565b6001600160a01b03821660008181526002602090815260408083203380855292529091209290925561043e91308563ffffffff61056916565b5050565b6000546001600160a01b031681565b600260209081526000928352604080842090915290825290205481565b60015481565b60006104b683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506105c9565b9392505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610316908490610660565b6000828201838110156104b6576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526105c3908590610660565b50505050565b600081848411156106585760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561061d578181015183820152602001610605565b50505050905090810190601f16801561064a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b610672826001600160a01b0316610818565b6106c3576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106107015780518252601f1990920191602091820191016106e2565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610763576040519150601f19603f3d011682016040523d82523d6000602084013e610768565b606091505b5091509150816107bf576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b8051156105c3578080602001905160208110156107db57600080fd5b50516105c35760405162461bcd60e51b815260040180806020018281038252602a815260200180610855602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470811580159061084c5750808214155b94935050505056fe5361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a72315820fc2b7749b9cab8492921973fc2ccf837404321021cf58a8ceebf528daec5d72064736f6c634300050c00325265656e7472616e637947756172643a207265656e7472616e742063616c6c00536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a65645361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a723158207447af8f7d52d4a7f840d9149401762648de8f093fd3eb58f2e62486a284fa4964736f6c634300050c0032

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061027d5760003560e01c8063633e9e091161015c578063c181c482116100ce578063d69a1d6d11610087578063d69a1d6d146107e0578063dc8b5e3c14610806578063e2c50b4b1461082c578063e534155d14610834578063e627f2db1461083c578063f41c33e9146108445761027d565b8063c181c482146106a7578063c6b61e4c146106d3578063c828371e1461073d578063cd6dc68714610745578063d420354b14610771578063d5f39488146107d85761027d565b80638b751038116101205780638b751038146106265780639c52a7f11461062e578063a6c9912314610654578063ad3548e314610671578063b25fb84214610679578063bf353dbb146106815761027d565b8063633e9e091461057f57806365fae35e1461059c57806369328dec146105c257806370a08231146105f8578063766718081461061e5761027d565b806331d98b3f116101f5578063470d970f116101b9578063470d970f146104ac57806351dcb0aa146104b457806354423bb81461051757806356605475146105345780635c96732c1461055a5780635ff45b43146105625761027d565b806331d98b3f1461042a5780633bee8472146104475780633d18b9121461046d57806341e58d261461047557806343690526146104a45761027d565b806318160ddd1161024757806318160ddd1461032c578063245a7bfc14610334578063294091cd1461033c5780632a240243146103725780632ff685201461037a578063313ce567146104225761027d565b80628cc26214610282578062bee478146102ba5780630e15561a146102f857806312d43a511461030057806315a9946e14610324575b600080fd5b6102a86004803603602081101561029857600080fd5b50356001600160a01b031661086a565b60405190815260200160405180910390f35b6102f6600480360360808110156102d057600080fd5b506001600160a01b0381358116916020810135909116906040810135906060013561093a565b005b6102a8610cb2565b610308610cb8565b6040516001600160a01b03909116815260200160405180910390f35b610308610cc7565b6102a8610cd6565b610308610d50565b6102f66004803603606081101561035257600080fd5b506001600160a01b03813581169160208101359160409091013516610d5f565b6102a8610f35565b6102f66004803603606081101561039057600080fd5b8101906020810181356401000000008111156103ab57600080fd5b8201836020820111156103bd57600080fd5b803590602001918460208302840111640100000000831117156103df57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505082359350505060200135610f7f565b6102a861105a565b6102a86004803603602081101561044057600080fd5b5035611060565b6102a86004803603602081101561045d57600080fd5b50356001600160a01b031661114b565b6102a861115f565b6102f66004803603608081101561048b57600080fd5b50803590602081013590604081013590606001356111be565b6102f6611237565b6102a8611270565b6104da600480360360208110156104ca57600080fd5b50356001600160a01b0316611276565b6040516001600160a01b0395861681529385166020850152919093166040808401919091526060830193909352608082015260a001905180910390f35b6103086004803603602081101561052d57600080fd5b50356112b3565b6102a86004803603602081101561054a57600080fd5b50356001600160a01b03166112d0565b6102f6611347565b6102a86004803603602081101561057857600080fd5b5035611560565b6102a86004803603602081101561059557600080fd5b5035611588565b6102f6600480360360208110156105b257600080fd5b50356001600160a01b03166115b0565b6102f6600480360360608110156105d857600080fd5b506001600160a01b03813581169160208101359160409091013516611674565b6102a86004803603602081101561060e57600080fd5b50356001600160a01b031661183f565b6102a86118d3565b6102a86118d9565b6102f66004803603602081101561064457600080fd5b50356001600160a01b03166118df565b6102a86004803603602081101561066a57600080fd5b50356119a0565b6102a86119c8565b6102a86119ce565b6102a86004803603602081101561069757600080fd5b50356001600160a01b0316611a5d565b6102a8600480360360408110156106bd57600080fd5b50803590602001356001600160a01b0316611a71565b6106f0600480360360208110156106e957600080fd5b5035611b80565b60405198895260208901979097526040808901969096526060880194909452608087019290925260a086015260c085015260e0840152901515610100830152610120909101905180910390f35b6102a8611bde565b6102f66004803603604081101561075b57600080fd5b506001600160a01b038135169060200135611c05565b61079d6004803603604081101561078757600080fd5b50803590602001356001600160a01b0316611e00565b6040516001600160a01b03909516855260208501939093526040808501929092526060840152608083019190915260a0909101905180910390f35b6103086120b1565b6102f6600480360360208110156107f657600080fd5b50356001600160a01b03166120c0565b6102f66004803603602081101561081c57600080fd5b50356001600160a01b0316612122565b6102a861215b565b61030861218f565b6102a861219e565b6102a86004803603602081101561085a57600080fd5b50356001600160a01b031661222d565b600080610875610cd6565b6001600160a01b0384166000908152604560205290915060408120549050600061089d610f35565b90505b818112610907576000604382815481106108b657fe5b906000526020600020600a600b9092020190810154909150849060ff16156108df575060098101545b6108fa6108ed888484612241565b879063ffffffff6122e316565b95505050600019016108a0565b506001600160a01b03841660009081526046602052610932906040902054849063ffffffff6122e316565b949350505050565b336000908152603b6020526040902054600114806109625750603c546001600160a01b031633145b6109a85760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b604482015260640160405180910390fd5b6002603d5414156109ed5760405162461bcd60e51b815260206004820152601f6024820152600080516020613d2b833981519152604482015260640160405180910390fd5b6002603d556001600160a01b038416610a3a5760405162461bcd60e51b815260206004820152600b60248201526a19d95b481a5cc81b9d5b1b60aa1b604482015260640160405180910390fd5b6001600160a01b038316610a865760405162461bcd60e51b815260206004820152600f60248201526e1859185c1d195c881a5cc81b9d5b1b608a1b604482015260640160405180910390fd5b610a8f8461233c565b610ac95760405162461bcd60e51b81526020600482015260076024820152666261642067656d60c81b604482015260640160405180910390fd5b6000818152604460205260408120546001600160a01b03161480610b0d5750600081815260446020526001600160a01b0385169060409020546001600160a01b0316145b610b4e5760405162461bcd60e51b815260206004820152600e60248201526d6475706c6963617465206e616d6560901b604482015260640160405180910390fd5b6001600160a01b03841660009081526033602052604090206004015415610bab576001600160a01b038416600090815260336020526044906040812060040154815260200190815260200160002080546001600160a01b03191690555b610bb4846123c9565b60405160a0810160409081526001600160a01b03808716808452908616602080850191909152600083850181905260608501879052608085018690529182526033905220815181546001600160a01b0319166001600160a01b039190911617815560208201516001820180546001600160a01b0319166001600160a01b039290921691909117905560408201516002820180546001600160a01b0319166001600160a01b0392909216919091179055606082015181600301556080820151600490910155506000818152604460205284906040902080546001600160a01b0319166001600160a01b039290921691909117905550506001603d555050565b60405481565b603e546001600160a01b031681565b603a546001600160a01b031681565b600080805b603454811015610d3557610d2b6037600060348481548110610cf957fe5b90600052602060002001546001600160a01b03168152602081019190915260400160002054839063ffffffff6122e316565b9150600101610cdb565b50603654610d4a90829063ffffffff61245416565b91505090565b603f546001600160a01b031681565b6002603d541415610da45760405162461bcd60e51b815260206004820152601f6024820152600080516020613d2b833981519152604482015260640160405180910390fd5b6002603d55610db1611bde565b421015610df05760405162461bcd60e51b81526020600482015260096024820152681b9bdd081cdd185c9d60ba1b604482015260640160405180910390fd5b60415460425414610e435760405162461bcd60e51b81526020600482015260196024820152781b9bdd08185b1b08195c1bd8da1cc81dd85cc81a5b9a5d1959603a1b604482015260640160405180910390fd5b610e4b610f35565b6047556000610e58610cd6565b905080604360475481548110610e6a57fe5b9060005260206000206009600b909202010155604754600019015b60008112610ee057600060438281548110610e9c57fe5b906000526020600020600a600b909202019081015490915060ff1615610ec25750610ee0565b60098101839055600a01805460ff1916600117905560001901610e85565b506048546001600160a01b03163314610ef857600080fd5b60008311610f0257fe5b610f2a838386604360475481548110610f1757fe5b90600052602060002090600b0201612494565b50506001603d555050565b6047546000905b60415481108015610f6b57504260438281548110610f5657fe5b90600052602060002090600b02016004015411155b15610f7b57905060018101610f3c565b5090565b603c546001600160a01b03163314610f9657600080fd5b60425415610fe65760405162461bcd60e51b81526020600482015260196024820152786e6f7420616c6c6f77656420616674657220617070726f766560381b604482015260640160405180910390fd5b60008111610ff357600080fd5b6000821161100057600080fd5b60415483511461100c57fe5b8160005b6041548110156110535761103985828151811061102957fe5b6020026020010151838584612575565b611049828463ffffffff6122e316565b9150600101611010565b5050505050565b60355481565b600081815260446020528060408120546001600160a01b031690508061108a576000915050611146565b6001600160a01b038116600090815260336020526040812060018082015460038301549293506001600160a01b031691639e5232a59185916040516001600160e01b031960e086901b1681526001600160a01b0390931660048401526024830191909152604482015260640160206040518083038186803b15801561110e57600080fd5b505afa158015611122573d6000803e3d6000fd5b505050506040513d602081101561113857600080fd5b810190808051955050505050505b919050565b604660205280600052604060002054905081565b60006002603d5414156111a65760405162461bcd60e51b815260206004820152601f6024820152600080516020613d2b833981519152604482015260640160405180910390fd5b6002603d556111b43361275e565b90506001603d5590565b603c546001600160a01b031633146111d557600080fd5b604254156112255760405162461bcd60e51b81526020600482015260196024820152786e6f7420616c6c6f77656420616674657220617070726f766560381b604482015260640160405180910390fd5b61123184848484612575565b50505050565b603c546001600160a01b0316331461124e57600080fd5b6041546042541461125e57600080fd5b603c80546001600160a01b0319169055565b60365481565b603360205280600052604060002080546001820154600283015460038401546004909401546001600160a01b039384169550918316939216919085565b6044602052806000526040600020546001600160a01b0316905081565b60006002603d5414156113175760405162461bcd60e51b815260206004820152601f6024820152600080516020613d2b833981519152604482015260640160405180910390fd5b6002603d55603f546001600160a01b0316331461133357600080fd5b61133c8261275e565b6001603d5592915050565b603c546001600160a01b0316331461135e57600080fd5b604254156113b25760405162461bcd60e51b815260206004820152601760248201527f646f75626c652063616c6c206e6f7420616c6c6f776564000000000000000000604482015260640160405180910390fd5b600060436000815481106113c257fe5b90600052602060002090600b020160020154905060006113e0611bde565b116113ea57600080fd5b60015b6041548110156114795760006043828154811061140657fe5b90600052602060002090600b02019050600081600401541161142757600080fd5b6043600183038154811061143757fe5b90600052602060002090600b02016005015481600401541461145857600080fd5b600281015461146e90849063ffffffff6122e316565b9250506001016113ed565b50603e5481906001600160a01b03166370a08231306040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b1580156114cd57600080fd5b505afa1580156114e1573d6000803e3d6000fd5b505050506040513d60208110156114f757600080fd5b810190808051939093101592506115579150505760405162461bcd60e51b815260206004820152601760248201527f474f562062616c616e6365206e6f7420656e6f75676874000000000000000000604482015260640160405180910390fd5b50604154604255565b60006043828154811061156f57fe5b90600052602060002090600b0201600601549050919050565b60006043828154811061159757fe5b90600052602060002090600b0201600401549050919050565b336000908152603b6020526040902054600114806115d85750603c546001600160a01b031633145b61161e5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b604482015260640160405180910390fd5b6001600160a01b0381166000908152603b60205260019060409020555961012081016040526020815260e0602082015260e060006040830137602435600435336001600160e01b03196000351661012085a45050565b6002603d5414156116b95760405162461bcd60e51b815260206004820152601f6024820152600080516020613d2b833981519152604482015260640160405180910390fd5b6002603d556116c6611bde565b4210156117055760405162461bcd60e51b81526020600482015260096024820152681b9bdd081cdd185c9d60ba1b604482015260640160405180910390fd5b604154604254146117585760405162461bcd60e51b81526020600482015260196024820152781b9bdd08185b1b08195c1bd8da1cc81dd85cc81a5b9a5d1959603a1b604482015260640160405180910390fd5b611760610f35565b604755600061176d610cd6565b90508060436047548154811061177f57fe5b9060005260206000206009600b909202010155604754600019015b600081126117f5576000604382815481106117b157fe5b906000526020600020600a600b909202019081015490915060ff16156117d757506117f5565b60098101839055600a01805460ff191660011790556000190161179a565b506048546001600160a01b0316331461180d57600080fd5b6000831161181757fe5b610f2a83838660436047548154811061182c57fe5b90600052602060002090600b0201612a04565b600080805b6034548110156118b7576118ad603960006034848154811061186257fe5b90600052602060002001546001600160a01b0316815260208101919091526040016000206001600160a01b03861660009081526020919091526040902054839063ffffffff6122e316565b9150600101611844565b506036546118cc90829063ffffffff61245416565b9392505050565b60475481565b60425481565b336000908152603b6020526040902054600114806119075750603c546001600160a01b031633145b61194d5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b604482015260640160405180910390fd5b6001600160a01b0381166000908152603b60205260408120555961012081016040526020815260e0602082015260e060006040830137602435600435336001600160e01b03196000351661012085a45050565b6000604382815481106119af57fe5b90600052602060002090600b0201600501549050919050565b60415481565b600060415460425414611a145760405162461bcd60e51b815260206004820152600a6024820152691b9bdd081a5b9a5d195960b21b604482015260640160405180910390fd5b506000805b604154811015610f7b57611a5360438281548110611a3357fe5b9060005260206000206003600b909202010154839063ffffffff6122e316565b9150600101611a19565b603b60205280600052604060002054905081565b6000808311611a7f57600080fd5b6001600160a01b038216600090815260336020526040812060018101549091506001600160a01b0316611ab157600080fd5b80546001600160a01b03848116911614611ac757fe5b600181015460038201546000916001600160a01b031690639e5232a590869088906040516001600160e01b031960e086901b1681526001600160a01b0390931660048401526024830191909152604482015260640160206040518083038186803b158015611b3457600080fd5b505afa158015611b48573d6000803e3d6000fd5b505050506040513d6020811015611b5e57600080fd5b810190808051935050508115159050611b7657600080fd5b9150505b92915050565b60438181548110611b8d57fe5b9060005260206000206002600b90920201908101546003820154600483015460058401546006850154600786015460088701546009880154600a909801549698509496939592949193909260ff1689565b60006043600081548110611bee57fe5b90600052602060002090600b020160040154905090565b600054610100900460ff1680611c1e5750611c1e612ae5565b80611c2c575060005460ff16155b611c675760405162461bcd60e51b815260040180806020018281038252602e815260200180613d6c602e913960400191505060405180910390fd5b60008054600161010061ff00198316811760ff191691909117909255603c5491900460ff1690336001600160a01b0390911614611ca357600080fd5b603e80546001600160a01b0319166001600160a01b03858116919091179182905516611cce57600080fd5b60008211611cdb57600080fd5b6041829055611ce86133b7565b60005b83811015611d875760438054600181018083556000928352849290919060209020919291600b90910201815181600201556020820151816003015560408201518160040155606082015181600501556080820151816006015560a0820151816007015560c0820151816008015560e08201518160090155610100820151600a91909101805460ff19169115159190911790555050600101611ceb565b5030604051611d9590613405565b6001600160a01b039091168152602001604051809103906000f080158015611dc1573d6000803e3d6000fd5b50604880546001600160a01b0319166001600160a01b0392909216919091179055506000805461ff001916610100921515929092029190911790555050565b600082815260446020528080808060408120546001600160a01b0316945084611e37575060009350839250829150819050806120a7565b6001600160a01b03851660009081526033602052604081206048549091506001600160a01b031663e44cf92a87896040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260440160206040518083038186803b158015611eab57600080fd5b505afa158015611ebf573d6000803e3d6000fd5b505050506040513d6020811015611ed557600080fd5b810190808051600185015460038601549198506001600160a01b03169350639e5232a5925089915087906040516001600160e01b031960e086901b1681526001600160a01b0390931660048401526024830191909152604482015260640160206040518083038186803b158015611f4b57600080fd5b505afa158015611f5f573d6000803e3d6000fd5b505050506040513d6020811015611f7557600080fd5b810190808051955050506001600160a01b03871690506370a08231886040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b158015611fd057600080fd5b505afa158015611fe4573d6000803e3d6000fd5b505050506040513d6020811015611ffa57600080fd5b810190808051600185015460038601549199506001600160a01b03169350639e5232a5925089915088906040516001600160e01b031960e086901b1681526001600160a01b0390931660048401526024830191909152604482015260640160206040518083038186803b15801561207057600080fd5b505afa158015612084573d6000803e3d6000fd5b505050506040513d602081101561209a57600080fd5b8101908080519450505050505b9295509295909350565b603c546001600160a01b031681565b603c546001600160a01b031633146120d757600080fd5b6001600160a01b0381166120ea57600080fd5b603f546001600160a01b03161561210057600080fd5b603f80546001600160a01b0319166001600160a01b0392909216919091179055565b603c546001600160a01b0316331461213957600080fd5b603a80546001600160a01b0319166001600160a01b0392909216919091179055565b6000806043612168610f35565b8154811061217257fe5b9060005260206000206006600b909202010154610e100291505090565b6048546001600160a01b031681565b6000604154604254146121e45760405162461bcd60e51b815260206004820152600a6024820152691b9bdd081a5b9a5d195960b21b604482015260640160405180910390fd5b506000805b604154811015610f7b576122236043828154811061220357fe5b9060005260206000206002600b909202010154839063ffffffff6122e316565b91506001016121e9565b604560205280600052604060002054905081565b6001600160a01b03831660009081526001830160205261093260408220546122d7603554600a0a670de0b6b3a7640000026122cb6122b68860000160008b6001600160a01b03166001600160a01b03168152602001908152602001600020546122aa8a8a612aeb565b9063ffffffff612b4116565b6122bf8a61183f565b9063ffffffff612b8116565b9063ffffffff61245416565b9063ffffffff6122e316565b6000828201838110156118cc5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015260640160405180910390fd5b603a546000906001600160a01b031663c23697a8836040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b15801561239057600080fd5b505afa1580156123a4573d6000803e3d6000fd5b505050506040513d60208110156123ba57600080fd5b81019080805195945050505050565b60005b60345481101561241557816001600160a01b0316603482815481106123ed57fe5b90600052602060002001546001600160a01b0316141561240d5750612451565b6001016123cc565b50603480546001810180835560009283528392909190602090200180546001600160a01b0319166001600160a01b039390931692909217909155505b50565b60006118cc838360405160408082019052601a81527f536166654d6174683a206469766973696f6e206279207a65726f0000000000006020820152612bda565b81816001600160a01b0382166124a657fe5b6124b4818260090154612aeb565b60088201556124c281612c7c565b81600701819055506124d982828360090154612241565b6001600160a01b038316600090815260018301602052604090205560088101546001600160a01b03831660009081526020839052604090205561251b84612c9a565b612526868686612cfc565b846001600160a01b0316846001600160a01b03167f5dac0c1b1112564a045ba943c9d50270893e8e826c49be8e7073adc713ab7bd78860405190815260200160405180910390a3505050505050565b60415481106125bd5760405162461bcd60e51b815260206004820152601060248201526f1a591e080f08115413d0d210d3d5539560821b604482015260640160405180910390fd5b600082116126005760405162461bcd60e51b815260206004820152600c60248201526b06475726174696f6e203e20360a41b604482015260640160405180910390fd5b428310156126545760405162461bcd60e51b815260206004820152601b60248201527f737461727474696d65203e20626c6f636b2e74696d657374616d700000000000604482015260640160405180910390fd5b60006043828154811061266357fe5b90600052602060002060006008600b909302909101918201556004810185905560038101849055905061269c858463ffffffff61245416565b600682018190556126e55760405162461bcd60e51b815260206004820152600f60248201526e7a65726f207265776172645261746560881b604482015260640160405180910390fd5b6002810185905560078101849055612703848463ffffffff6122e316565b60058201557f3ffbf598271669161ecd81ce333d0a0b574924ce7a91e396841eb2225e59e26e858385876040518085815260200184815260200183815260200182815260200194505050505060405180910390a15050505050565b6000612768611bde565b4210156127a75760405162461bcd60e51b81526020600482015260096024820152681b9bdd081cdd185c9d60ba1b604482015260640160405180910390fd5b604154604254146127fa5760405162461bcd60e51b81526020600482015260196024820152781b9bdd08185b1b08195c1bd8da1cc81dd85cc81a5b9a5d1959603a1b604482015260640160405180910390fd5b612802610f35565b604755600061280f610cd6565b90508060436047548154811061282157fe5b9060005260206000206009600b909202010155604754600019015b600081126128975760006043828154811061285357fe5b906000526020600020600a600b909202019081015490915060ff16156128795750612897565b60098101839055600a01805460ff191660011790556000190161283c565b50826043604754815481106128a857fe5b906000526020600020600b909102016001600160a01b0382166128c757fe5b6128d5818260090154612aeb565b60088201556128e381612c7c565b81600701819055506128fa82828360090154612241565b6001600160a01b038316600090815260018301602052604090205560088101546001600160a01b03831660009081526020839052604090205561293c85612e47565b6001600160a01b03861660009081526046602052909450612969906040902054859063ffffffff6122e316565b6001600160a01b03861660009081526046602052909450604081205583156129fc5760405461299e908563ffffffff6122e316565b604055603e546129be906001600160a01b0316868663ffffffff612f1616565b846001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e04868560405190815260200160405180910390a25b505050919050565b81816001600160a01b038216612a1657fe5b612a24818260090154612aeb565b6008820155612a3281612c7c565b8160070181905550612a4982828360090154612241565b6001600160a01b038316600090815260018301602052604090205560088101546001600160a01b038316600090815260208390526040902055612a8b84612c9a565b612a96868686612f77565b846001600160a01b0316846001600160a01b03167fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb8860405190815260200160405180910390a3505050505050565b303b1590565b600081612afd57506008820154611b7a565b6118cc612b30836122cb603554600a0a670de0b6b3a7640000026122bf88600601546122bf8a600701546122aa8c612c7c565b60088501549063ffffffff6122e316565b60006118cc838360405160408082019052601e81527f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006020820152613109565b600082612b9057506000611b7a565b82820282848281612b9d57fe5b04146118cc5760405162461bcd60e51b8152600401808060200182810382526021815260200180613d4b6021913960400191505060405180910390fd5b60008183612c665760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612c2b578082015183820152602001612c13565b50505050905090810190601f168015612c585780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581612c7257fe5b0495945050505050565b60008160040154421015612c8c57fe5b611b7a428360050154613163565b604754612ca657612451565b6000612cb182612e47565b6001600160a01b03831660009081526046602052909150612cdf90829060409020549063ffffffff6122e316565b6001600160a01b0383166000908152604660205260409020555050565b6000612d0e6036546122bf8686611a71565b6001600160a01b03841660009081526039602052909150612d55908290604090206001600160a01b038516600090815260209190915260409020549063ffffffff6122e316565b6001600160a01b03841660009081526039602052604090206001600160a01b038416600090815260209190915260409020556001600160a01b03831660009081526038602052612dcb908590604090206001600160a01b038516600090815260209190915260409020549063ffffffff6122e316565b6001600160a01b03841660009081526038602052604090206001600160a01b038416600090815260209190915260409020556001600160a01b03831660009081526037602052612e2890829060409020549063ffffffff6122e316565b6001600160a01b03841660009081526037602052604090205550505050565b6001600160a01b0381166000908152604560205280604081205490505b6047548111612ef4576000612e938460438481548110612e8057fe5b90600052602060002090600b0201613179565b9050612ea5838263ffffffff6122e316565b9250836001600160a01b03167fd79ae009b12e66b13c4bd4034783c61534acc351aa8e53765ec3367744f3d78c828460405191825260208201526040908101905180910390a250600101612e64565b506047546001600160a01b038316600090815260456020526040902055919050565b612f728363a9059cbb60e01b84846040516001600160a01b0390921660248301526044820152606401604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b031690911790526131bf565b505050565b6001600160a01b03821660009081526038602052612fef604082206001600160a01b038416600090815260209190915260409020546001600160a01b038516600090815260396020526122cb90604090206001600160a01b03861660009081526020919091526040902054879063ffffffff612b8116565b6001600160a01b03841660009081526039602052909150613036908290604090206001600160a01b038516600090815260209190915260409020549063ffffffff612b4116565b6001600160a01b03841660009081526039602052604090206001600160a01b038416600090815260209190915260409020556001600160a01b038316600090815260386020526130ac908590604090206001600160a01b038516600090815260209190915260409020549063ffffffff612b4116565b6001600160a01b03841660009081526038602052604090206001600160a01b038416600090815260209190915260409020556001600160a01b03831660009081526037602052612e2890829060409020549063ffffffff612b4116565b6000818484111561315b5760405162461bcd60e51b8152600401808060200182810382528381815181526020019150805160209091019080838360008315612c2b578082015183820152602001612c13565b505050900390565b600081831061317257816118cc565b5090919050565b60008061318b84848560090154612241565b905080156131b5576001600160a01b03841660009081526001840160205260408120559050611b7a565b5060009392505050565b6131d1826001600160a01b0316613380565b6132215760405162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015260640160405180910390fd5b60006060836001600160a01b0316836040518082805190602001908083835b6020831061325f5780518252601f199092019160209182019101613240565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146132c1576040513d603f01601f191681016040523d815291503d6000602084013e6132c6565b606091505b50915091508161331c5760405162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015260640160405180910390fd5b60008151111561123157602081018151602081101561333a57600080fd5b81019080805192506112319150505760405162461bcd60e51b815260040180806020018281038252602a815260200180613d9a602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081158015906109325750141592915050565b60405180610120016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000151581525090565b610918806134138339019056fe608060405234801561001057600080fd5b506040516109183803806109188339818101604052602081101561003357600080fd5b5051600080546001600160a01b039092166001600160a01b03199092169190911790556108b3806100656000396000f3fe608060405234801561001057600080fd5b50600436106100565760003560e01c8062f714ce1461005b5780637acb775714610089578063dcc3e06e146100b5578063e44cf92a146100d9578063f581aff714610119575b600080fd5b6100876004803603604081101561007157600080fd5b50803590602001356001600160a01b0316610121565b005b6100876004803603604081101561009f57600080fd5b50803590602001356001600160a01b031661031b565b6100bd610442565b604080516001600160a01b039092168252519081900360200190f35b610107600480360360408110156100ef57600080fd5b506001600160a01b0381358116916020013516610451565b60408051918252519081900360200190f35b61010761046e565b6000821161016a576040805162461bcd60e51b8152602060048201526011602482015270043616e6e6f74207769746864726177203607c1b604482015290519081900360640190fd5b6000805460408051336024820152604481018690526001600160a01b0385811660648084019190915283518084039091018152608490920183526020820180516001600160e01b0316631a4ca37b60e21b178152925182519190941693919282918083835b602083106101ee5780518252601f1990920191602091820191016101cf565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610250576040519150601f19603f3d011682016040523d82523d6000602084013e610255565b606091505b50509050806102aa57604080518481526001600160a01b038416602082015281517fc7db832b9d7d07bc1dc206c2ba54d1ef830d4cacfaa2a833b1e1418431b0cba7929181900390910190a160018054810190555b6001600160a01b03821660009081526002602090815260408083203384529091529020546102de908463ffffffff61047416565b6001600160a01b038316600081815260026020908152604080832033808552925290912092909255610316918563ffffffff6104bd16565b505050565b60008211610361576040805162461bcd60e51b815260206004820152600e60248201526d043616e6e6f74207374616b6520360941b604482015290519081900360640190fd5b600080546040805163294091cd60e01b8152336004820152602481018690526001600160a01b0385811660448301529151919092169263294091cd926064808201939182900301818387803b1580156103b957600080fd5b505af11580156103cd573d6000803e3d6000fd5b5050506001600160a01b038216600090815260026020908152604080832033845290915290205461040591508363ffffffff61050f16565b6001600160a01b03821660008181526002602090815260408083203380855292529091209290925561043e91308563ffffffff61056916565b5050565b6000546001600160a01b031681565b600260209081526000928352604080842090915290825290205481565b60015481565b60006104b683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506105c9565b9392505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610316908490610660565b6000828201838110156104b6576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526105c3908590610660565b50505050565b600081848411156106585760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561061d578181015183820152602001610605565b50505050905090810190601f16801561064a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b610672826001600160a01b0316610818565b6106c3576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106107015780518252601f1990920191602091820191016106e2565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610763576040519150601f19603f3d011682016040523d82523d6000602084013e610768565b606091505b5091509150816107bf576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b8051156105c3578080602001905160208110156107db57600080fd5b50516105c35760405162461bcd60e51b815260040180806020018281038252602a815260200180610855602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470811580159061084c5750808214155b94935050505056fe5361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a72315820fc2b7749b9cab8492921973fc2ccf837404321021cf58a8ceebf528daec5d72064736f6c634300050c00325265656e7472616e637947756172643a207265656e7472616e742063616c6c00536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a65645361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a723158207447af8f7d52d4a7f840d9149401762648de8f093fd3eb58f2e62486a284fa4964736f6c634300050c0032

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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