ETH Price: $1,969.29 (-0.98%)

Contract

0xE9F97FCa1C8C1dDC6649104A6dBCD400D073A445
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Execute Withdraw...139858542022-01-11 18:18:531516 days ago1641925133IN
0xE9F97FCa...0D073A445
0 ETH0.01967427142.94947265
Execute Withdraw...135365892021-11-02 8:51:491587 days ago1635843109IN
0xE9F97FCa...0D073A445
0 ETH0.01772351128.77562586
Initiate Withdra...134859822021-10-25 10:10:391595 days ago1635156639IN
0xE9F97FCa...0D073A445
0 ETH0.0044294152.40916236
Execute Withdraw...126066062021-06-10 11:54:231731 days ago1623326063IN
0xE9F97FCa...0D073A445
0 ETH0.0012994910.45
Initiate Withdra...123506322021-05-01 20:59:221771 days ago1619902762IN
0xE9F97FCa...0D073A445
0 ETH0.0027045132
Execute Withdraw...123166222021-04-26 14:55:491776 days ago1619448949IN
0xE9F97FCa...0D073A445
0 ETH0.0069188550
Execute Withdraw...122910962021-04-22 16:22:291780 days ago1619108549IN
0xE9F97FCa...0D073A445
0 ETH0.0307848202
Initiate Withdra...122710252021-04-19 14:22:481783 days ago1618842168IN
0xE9F97FCa...0D073A445
0 ETH0.01605804190
Execute Withdraw...122558912021-04-17 6:05:351786 days ago1618639535IN
0xE9F97FCa...0D073A445
0 ETH0.01414484111
Initiate Withdra...122426272021-04-15 4:56:331788 days ago1618462593IN
0xE9F97FCa...0D073A445
0 ETH0.0059275283.00000145
Initiate Withdra...122293402021-04-13 3:30:251790 days ago1618284625IN
0xE9F97FCa...0D073A445
0 ETH0.0047848767
Initiate Withdra...122072792021-04-09 18:31:341793 days ago1617993094IN
0xE9F97FCa...0D073A445
0 ETH0.00785576110
Execute Withdraw...121944732021-04-07 19:03:041795 days ago1617822184IN
0xE9F97FCa...0D073A445
0 ETH0.01271803130
Execute Withdraw...121232202021-03-27 20:16:301806 days ago1616876190IN
0xE9F97FCa...0D073A445
0 ETH0.01334945102
Initiate Withdra...120743042021-03-20 7:15:501814 days ago1616224550IN
0xE9F97FCa...0D073A445
0 ETH0.00742726104
Execute Withdraw...118591902021-02-15 4:36:471847 days ago1613363807IN
0xE9F97FCa...0D073A445
0 ETH0.01310935134
Initiate Withdra...118133252021-02-08 3:14:211854 days ago1612754061IN
0xE9F97FCa...0D073A445
0 ETH0.0071416100
Initiate Withdra...117173202021-01-24 8:46:561869 days ago1611478016IN
0xE9F97FCa...0D073A445
0 ETH0.003570850
Execute Withdraw...116976412021-01-21 8:16:351872 days ago1611216995IN
0xE9F97FCa...0D073A445
0 ETH0.0057669365.00000134
Initiate Withdra...116945642021-01-20 20:37:011872 days ago1611175021IN
0xE9F97FCa...0D073A445
0 ETH0.0064274490
Execute Withdraw...116479582021-01-13 17:17:021879 days ago1610558222IN
0xE9F97FCa...0D073A445
0 ETH0.0101138883.00000145
Execute Withdraw...116380592021-01-12 4:48:441881 days ago1610426924IN
0xE9F97FCa...0D073A445
0 ETH0.007134951
Initiate Withdra...116018472021-01-06 15:26:241886 days ago1609946784IN
0xE9F97FCa...0D073A445
0 ETH0.0046420465
Initiate Withdra...115875942021-01-04 11:01:531889 days ago1609758113IN
0xE9F97FCa...0D073A445
0 ETH0.02892348405
Execute Withdraw...115566182020-12-30 16:57:301893 days ago1609347450IN
0xE9F97FCa...0D073A445
0 ETH0.01483225128
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
StakingContract

Compiler Version
v0.5.15+commit.6a57276f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license
/**
 *Submitted for verification at Etherscan.io on 2020-01-03
*/

// File: contracts/libs/math/SafeMath.sol

pragma solidity 0.5.15;

/**
 * @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 {
    uint constant TEN18 = 10**18;

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

// File: contracts/libs/math/Math.sol

pragma solidity 0.5.15;

/**
 * @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: contracts/libs/utils/Address.sol

pragma solidity 0.5.15;

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

// File: contracts/libs/utils/Arrays.sol

pragma solidity 0.5.15;


/**
 * @dev Collection of functions related to array types.
 */
library Arrays {
   /**
     * @dev Searches a sorted `array` and returns the first index that contains
     * a value greater or equal to `element`. If no such index exists (i.e. all
     * values in the array are strictly less than `element`), the array length is
     * returned. Time complexity O(log n).
     *
     * `array` is expected to be sorted in ascending order, and to contain no
     * repeated elements.
     */
    function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
        if (array.length == 0) {
            return 0;
        }

        uint256 low = 0;
        uint256 high = array.length;

        while (low < high) {
            uint256 mid = Math.average(low, high);

            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
            // because Math.average rounds down (it does integer division with truncation).
            if (array[mid] > element) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.
        if (low > 0 && array[low - 1] == element) {
            return low - 1;
        } else {
            return low;
        }
    }
}

// File: contracts/libs/utils/ReentrancyGuard.sol

pragma solidity 0.5.15;

/**
 * @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.
 */
contract ReentrancyGuard {
    // counter to allow mutex lock with only one SSTORE operation
    uint256 private _guardCounter;

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

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

// File: contracts/libs/ownership/Ownable.sol

pragma solidity 0.5.15;

/**
 * @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 {
    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 = msg.sender;
        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 msg.sender == _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;
    }
}

// File: contracts/libs/lifecycle/Pausable.sol

pragma solidity 0.5.15;


/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
contract Pausable is Ownable {
    /**
     * @dev Emitted when the pause is triggered by a pauser (`account`).
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by a pauser (`account`).
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state. Assigns the Pauser role
     * to the deployer.
     */
    constructor () internal {
        _paused = true;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     */
    modifier whenNotPaused() {
        require(!_paused, "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     */
    modifier whenPaused() {
        require(_paused, "Pausable: not paused");
        _;
    }

    /**
     * @dev Called by a owner to pause, triggers stopped state.
     */
    function pause() public onlyOwner whenNotPaused {
        _paused = true;
        emit Paused(msg.sender);
    }

    /**
     * @dev Called by a owner to unpause, returns to normal state.
     */
    function unpause() public onlyOwner whenPaused {
        _paused = false;
        emit Unpaused(msg.sender);
    }
}

// File: contracts/token/ERC20/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 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * 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);
}

// File: contracts/StakingContract.sol

pragma solidity 0.5.15;








contract StakingContract is Pausable, ReentrancyGuard {

    using SafeMath for uint256;
    using Math for uint256;
    using Address for address;
    using Arrays for uint256[];

    enum Status {Setup, Running, RewardsDisabled}

    // EVENTS
    event StakeDeposited(address indexed account, uint256 amount);
    event WithdrawInitiated(address indexed account, uint256 amount);
    event WithdrawExecuted(address indexed account, uint256 amount, uint256 reward);

    // STRUCT DECLARATIONS
    struct StakeDeposit {
        uint256 amount;
        uint256 startDate;
        uint256 endDate;
        uint256 startCheckpointIndex;
        uint256 endCheckpointIndex;
        bool exists;
    }

    struct SetupState {
        bool staking;
        bool rewards;
    }

    struct StakingLimitConfig {
        uint256 maxAmount;
        uint256 initialAmount;
        uint256 daysInterval;
        uint256 maxIntervals;
        uint256 unstakingPeriod;
    }

    struct BaseRewardCheckpoint {
        uint256 baseRewardIndex;
        uint256 startTimestamp;
        uint256 endTimestamp;
        uint256 fromBlock;
    }

    struct BaseReward {
        uint256 anualRewardRate;
        uint256 lowerBound;
        uint256 upperBound;
    }

    struct RewardConfig {
        BaseReward[] baseRewards;
        uint256[] upperBounds;
        uint256 multiplier; // percent of the base reward applicable
    }

    // CONTRACT STATE VARIABLES
    IERC20 public token;
    Status public currentStatus;

    SetupState public setupState;
    StakingLimitConfig public stakingLimitConfig;
    RewardConfig public rewardConfig;

    address public rewardsAddress;
    uint256 public launchTimestamp;
    uint256 public currentTotalStake;

    mapping(address => StakeDeposit) private _stakeDeposits;
    BaseRewardCheckpoint[] private _baseRewardHistory;

    // MODIFIERS
    modifier guardMaxStakingLimit(uint256 amount)
    {
        uint256 resultedStakedAmount = currentTotalStake.add(amount);
        uint256 currentStakingLimit = _computeCurrentStakingLimit();
        require(resultedStakedAmount <= currentStakingLimit, "[Deposit] Your deposit would exceed the current staking limit");
        _;
    }

    modifier guardForPrematureWithdrawal()
    {
        uint256 intervalsPassed = _getIntervalsPassed();
        require(intervalsPassed >= stakingLimitConfig.maxIntervals, "[Withdraw] Not enough days passed");
        _;
    }

    modifier onlyContract(address account)
    {
        require(account.isContract(), "[Validation] The address does not contain a contract");
        _;
    }

    modifier onlyDuringSetup()
    {
        require(currentStatus == Status.Setup, "[Lifecycle] Setup is already done");
        _;
    }

    modifier onlyAfterSetup()
    {
        require(currentStatus != Status.Setup, "[Lifecycle] Setup is not done");
        _;
    }

    // PUBLIC FUNCTIONS
    constructor(address _token, address _rewardsAddress)
    onlyContract(_token)
    public
    {
        require(_rewardsAddress != address(0), "[Validation] _rewardsAddress is the zero address");

        token = IERC20(_token);
        rewardsAddress = _rewardsAddress;
        launchTimestamp = now;
        currentStatus = Status.Setup;
    }

    function deposit(uint256 amount)
    public
    nonReentrant
    onlyAfterSetup
    whenNotPaused
    guardMaxStakingLimit(amount)
    {
        require(amount > 0, "[Validation] The stake deposit has to be larger than 0");
        require(!_stakeDeposits[msg.sender].exists, "[Deposit] You already have a stake");

        StakeDeposit storage stakeDeposit = _stakeDeposits[msg.sender];
        stakeDeposit.amount = stakeDeposit.amount.add(amount);
        stakeDeposit.startDate = now;
        stakeDeposit.startCheckpointIndex = _baseRewardHistory.length - 1;
        stakeDeposit.exists = true;

        currentTotalStake = currentTotalStake.add(amount);
        _updateBaseRewardHistory();

        // Transfer the Tokens to this contract
        require(token.transferFrom(msg.sender, address(this), amount), "[Deposit] Something went wrong during the token transfer");
        emit StakeDeposited(msg.sender, amount);
    }

    function initiateWithdrawal()
    external
    whenNotPaused
    onlyAfterSetup
    guardForPrematureWithdrawal
    {
        StakeDeposit storage stakeDeposit = _stakeDeposits[msg.sender];
        require(stakeDeposit.exists && stakeDeposit.amount != 0, "[Initiate Withdrawal] There is no stake deposit for this account");
        require(stakeDeposit.endDate == 0, "[Initiate Withdrawal] You already initiated the withdrawal");

        stakeDeposit.endDate = now;
        stakeDeposit.endCheckpointIndex = _baseRewardHistory.length - 1;
        emit WithdrawInitiated(msg.sender, stakeDeposit.amount);
    }

    function executeWithdrawal()
    external
    nonReentrant
    whenNotPaused
    onlyAfterSetup
    {
        StakeDeposit storage stakeDeposit = _stakeDeposits[msg.sender];
        require(stakeDeposit.exists && stakeDeposit.amount != 0, "[Withdraw] There is no stake deposit for this account");
        require(stakeDeposit.endDate != 0, "[Withdraw] Withdraw is not initialized");
        // validate enough days have passed from initiating the withdrawal
        uint256 daysPassed = (now - stakeDeposit.endDate) / 1 days;
        require(stakingLimitConfig.unstakingPeriod <= daysPassed, "[Withdraw] The unstaking period did not pass");

        uint256 amount = stakeDeposit.amount;
        uint256 reward = _computeReward(stakeDeposit);

        stakeDeposit.amount = 0;

        currentTotalStake = currentTotalStake.sub(amount);
        _updateBaseRewardHistory();

        require(token.transfer(msg.sender, amount), "[Withdraw] Something went wrong while transferring your initial deposit");
        require(token.transferFrom(rewardsAddress, msg.sender, reward), "[Withdraw] Something went wrong while transferring your reward");

        emit WithdrawExecuted(msg.sender, amount, reward);
    }

    function toggleRewards(bool enabled)
    external
    onlyOwner
    onlyAfterSetup
    {
        Status newStatus = enabled ? Status.Running : Status.RewardsDisabled;
        require(currentStatus != newStatus, "[ToggleRewards] This status is already set");

        uint256 index;

        if (newStatus == Status.RewardsDisabled) {
            index = rewardConfig.baseRewards.length - 1;
        }

        if (newStatus == Status.Running) {
            index = _computeCurrentBaseReward();
        }

        _insertNewCheckpoint(index);

        currentStatus = newStatus;
    }

    // VIEW FUNCTIONS FOR HELPING THE USER AND CLIENT INTERFACE
    function currentStakingLimit()
    public
    onlyAfterSetup
    view
    returns (uint256)
    {
        return _computeCurrentStakingLimit();
    }

    function currentReward(address account)
    external
    onlyAfterSetup
    view
    returns (uint256 initialDeposit, uint256 reward)
    {
        require(_stakeDeposits[account].exists && _stakeDeposits[account].amount != 0, "[Validation] This account doesn't have a stake deposit");

        StakeDeposit memory stakeDeposit = _stakeDeposits[account];
        stakeDeposit.endDate = now;

        return (stakeDeposit.amount, _computeReward(stakeDeposit));
    }

    function getStakeDeposit()
    external
    onlyAfterSetup
    view
    returns (uint256 amount, uint256 startDate, uint256 endDate, uint256 startCheckpointIndex, uint256 endCheckpointIndex)
    {
        require(_stakeDeposits[msg.sender].exists, "[Validation] This account doesn't have a stake deposit");
        StakeDeposit memory s = _stakeDeposits[msg.sender];

        return (s.amount, s.startDate, s.endDate, s.startCheckpointIndex, s.endCheckpointIndex);
    }

    function baseRewardsLength()
    external
    onlyAfterSetup
    view
    returns (uint256)
    {
        return rewardConfig.baseRewards.length;
    }

    function baseReward(uint256 index)
    external
    onlyAfterSetup
    view
    returns (uint256, uint256, uint256)
    {
        BaseReward memory br = rewardConfig.baseRewards[index];

        return (br.anualRewardRate, br.lowerBound, br.upperBound);
    }

    function baseRewardHistoryLength()
    external
    view
    returns (uint256)
    {
        return _baseRewardHistory.length;
    }

    function baseRewardHistory(uint256 index)
    external
    onlyAfterSetup
    view
    returns (uint256, uint256, uint256, uint256)
    {
        BaseRewardCheckpoint memory c = _baseRewardHistory[index];

        return (c.baseRewardIndex, c.startTimestamp, c.endTimestamp, c.fromBlock);
    }

    // OWNER SETUP
    function setupStakingLimit(uint256 maxAmount, uint256 initialAmount, uint256 daysInterval, uint256 unstakingPeriod)
    external
    onlyOwner
    whenPaused
    onlyDuringSetup
    {
        require(maxAmount > 0 && initialAmount > 0 && daysInterval > 0 && unstakingPeriod >= 0, "[Validation] Some parameters are 0");
        require(maxAmount.mod(initialAmount) == 0, "[Validation] maxAmount should be a multiple of initialAmount");

        uint256 maxIntervals = maxAmount.div(initialAmount);
        // set the staking limits
        stakingLimitConfig.maxAmount = maxAmount;
        stakingLimitConfig.initialAmount = initialAmount;
        stakingLimitConfig.daysInterval = daysInterval;
        stakingLimitConfig.unstakingPeriod = unstakingPeriod;
        stakingLimitConfig.maxIntervals = maxIntervals;

        setupState.staking = true;
        _updateSetupState();
    }

    function setupRewards(
        uint256 multiplier,
        uint256[] calldata anualRewardRates,
        uint256[] calldata lowerBounds,
        uint256[] calldata upperBounds
    )
    external
    onlyOwner
    whenPaused
    onlyDuringSetup
    {
        _validateSetupRewardsParameters(multiplier, anualRewardRates, lowerBounds, upperBounds);

        // Setup rewards
        rewardConfig.multiplier = multiplier;

        for (uint256 i = 0; i < anualRewardRates.length; i++) {
            _addBaseReward(anualRewardRates[i], lowerBounds[i], upperBounds[i]);
        }

        uint256 highestUpperBound = upperBounds[upperBounds.length - 1];

        // Add the zero annual reward rate
        _addBaseReward(0, highestUpperBound, highestUpperBound + 10);

        // initiate baseRewardHistory with the first one which should start from 0
        _initBaseRewardHistory();

        setupState.rewards = true;
        _updateSetupState();
    }

    // INTERNAL
    function _updateSetupState()
    private
    {
        if (!setupState.rewards || !setupState.staking) {
            return;
        }

        currentStatus = Status.Running;
    }

    function _computeCurrentStakingLimit()
    private
    view
    returns (uint256)
    {
        uint256 intervalsPassed = _getIntervalsPassed();
        uint256 baseStakingLimit = stakingLimitConfig.initialAmount;

        uint256 intervals = intervalsPassed.min(stakingLimitConfig.maxIntervals - 1);

        // initialLimit * ((now - launchMoment) / interval)
        return baseStakingLimit.add(baseStakingLimit.mul(intervals));
    }

    function _getIntervalsPassed()
    private
    view
    returns (uint256)
    {
        uint256 daysPassed = (now - launchTimestamp) / 1 days;
        return daysPassed / stakingLimitConfig.daysInterval;
    }

    function _computeReward(StakeDeposit memory stakeDeposit)
    private
    view
    returns (uint256)
    {
        uint256 scale = 10 ** 18;
        (uint256 weightedSum, uint256 stakingPeriod) = _computeRewardRatesWeightedSum(stakeDeposit);

        if (stakingPeriod == 0) {
            return 0;
        }

        // scaling weightedSum and stakingPeriod because the weightedSum is in the thousands magnitude
        // and we risk losing detail while rounding
        weightedSum = weightedSum.mul(scale);

        uint256 weightedAverage = weightedSum.div(stakingPeriod);

        // rewardConfig.multiplier is a percentage expressed in 1/10 (a tenth) of a percent hence we divide by 1000
        uint256 accumulator = rewardConfig.multiplier.mul(weightedSum).div(1000);
        uint256 effectiveRate = weightedAverage.add(accumulator);
        uint256 denominator = scale.mul(36500);

        return stakeDeposit.amount.mul(effectiveRate).mul(stakingPeriod).div(denominator);
    }

    function _computeRewardRatesWeightedSum(StakeDeposit memory stakeDeposit)
    private
    view
    returns (uint256, uint256)
    {
        uint256 stakingPeriod = (stakeDeposit.endDate - stakeDeposit.startDate) / 1 days;
        uint256 weight;
        uint256 rate;

        // The contract never left the first checkpoint
        if (stakeDeposit.startCheckpointIndex == stakeDeposit.endCheckpointIndex) {
            rate = _baseRewardFromHistoryIndex(stakeDeposit.startCheckpointIndex).anualRewardRate;

            return (rate.mul(stakingPeriod), stakingPeriod);
        }

        // Computing the first segment base reward
        // User could deposit in the middle of the segment so we need to get the segment from which the user deposited
        // to the moment the base reward changes
        weight = (_baseRewardHistory[stakeDeposit.startCheckpointIndex].endTimestamp - stakeDeposit.startDate) / 1 days;
        rate = _baseRewardFromHistoryIndex(stakeDeposit.startCheckpointIndex).anualRewardRate;
        uint256 weightedSum = rate.mul(weight);

        // Starting from the second checkpoint because the first one is already computed
        for (uint256 i = stakeDeposit.startCheckpointIndex + 1; i < stakeDeposit.endCheckpointIndex; i++) {
            weight = (_baseRewardHistory[i].endTimestamp - _baseRewardHistory[i].startTimestamp) / 1 days;
            rate = _baseRewardFromHistoryIndex(i).anualRewardRate;
            weightedSum = weightedSum.add(rate.mul(weight));
        }

        // Computing the base reward for the last segment
        // days between start timestamp of the last checkpoint to the moment he initialized the withdrawal
        weight = (stakeDeposit.endDate - _baseRewardHistory[stakeDeposit.endCheckpointIndex].startTimestamp) / 1 days;
        rate = _baseRewardFromHistoryIndex(stakeDeposit.endCheckpointIndex).anualRewardRate;
        weightedSum = weightedSum.add(weight.mul(rate));

        return (weightedSum, stakingPeriod);
    }

    function _addBaseReward(uint256 anualRewardRate, uint256 lowerBound, uint256 upperBound)
    private
    {
        rewardConfig.baseRewards.push(BaseReward(anualRewardRate, lowerBound, upperBound));
        rewardConfig.upperBounds.push(upperBound);
    }

    function _initBaseRewardHistory()
    private
    {
        require(_baseRewardHistory.length == 0, "[Logical] Base reward history has already been initialized");

        _baseRewardHistory.push(BaseRewardCheckpoint(0, now, 0, block.number));
    }

    function _updateBaseRewardHistory()
    private
    {
        if (currentStatus == Status.RewardsDisabled) {
            return;
        }

        BaseReward memory currentBaseReward = _currentBaseReward();

        // Do nothing if currentTotalStake is in the current base reward bounds
        if (currentBaseReward.lowerBound <= currentTotalStake && currentTotalStake <= currentBaseReward.upperBound) {
            return;
        }

        uint256 newIndex = _computeCurrentBaseReward();
        _insertNewCheckpoint(newIndex);
    }

    function _insertNewCheckpoint(uint256 newIndex)
    private
    {
        BaseRewardCheckpoint storage oldCheckPoint = _lastBaseRewardCheckpoint();

        if (oldCheckPoint.fromBlock < block.number) {
            oldCheckPoint.endTimestamp = now;
            _baseRewardHistory.push(BaseRewardCheckpoint(newIndex, now, 0, block.number));
        } else {
            oldCheckPoint.baseRewardIndex = newIndex;
        }
    }

    function _currentBaseReward()
    private
    view
    returns (BaseReward memory)
    {
        // search for the current base reward from current total staked amount
        uint256 currentBaseRewardIndex = _lastBaseRewardCheckpoint().baseRewardIndex;

        return rewardConfig.baseRewards[currentBaseRewardIndex];
    }

    function _baseRewardFromHistoryIndex(uint256 index)
    private
    view
    returns (BaseReward memory)
    {
        return rewardConfig.baseRewards[_baseRewardHistory[index].baseRewardIndex];
    }

    function _lastBaseRewardCheckpoint()
    private
    view
    returns (BaseRewardCheckpoint storage)
    {
        return _baseRewardHistory[_baseRewardHistory.length - 1];
    }

    function _computeCurrentBaseReward()
    private
    view
    returns (uint256)
    {
        uint256 index = rewardConfig.upperBounds.findUpperBound(currentTotalStake);

        require(index < rewardConfig.upperBounds.length, "[NotFound] The current total staked is out of bounds");

        return index;
    }

    function _validateSetupRewardsParameters
    (
        uint256 multiplier,
        uint256[] memory anualRewardRates,
        uint256[] memory lowerBounds,
        uint256[] memory upperBounds
    )
    private
    pure
    {
        require(
            anualRewardRates.length > 0 && lowerBounds.length > 0 && upperBounds.length > 0,
            "[Validation] All parameters must have at least one element"
        );
        require(
            anualRewardRates.length == lowerBounds.length && lowerBounds.length == upperBounds.length,
            "[Validation] All parameters must have the same number of elements"
        );
        require(lowerBounds[0] == 0, "[Validation] First lower bound should be 0");
        require(
            (multiplier < 100) && (uint256(100).mod(multiplier) == 0),
            "[Validation] Multiplier should be smaller than 100 and divide it equally"
        );
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_rewardsAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakeDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"WithdrawExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawInitiated","type":"event"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"baseReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"baseRewardHistory","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"baseRewardHistoryLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"baseRewardsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"currentReward","outputs":[{"internalType":"uint256","name":"initialDeposit","type":"uint256"},{"internalType":"uint256","name":"reward","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentStakingLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentStatus","outputs":[{"internalType":"enum StakingContract.Status","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentTotalStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"executeWithdrawal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getStakeDeposit","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"startDate","type":"uint256"},{"internalType":"uint256","name":"endDate","type":"uint256"},{"internalType":"uint256","name":"startCheckpointIndex","type":"uint256"},{"internalType":"uint256","name":"endCheckpointIndex","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"initiateWithdrawal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"launchTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"rewardConfig","outputs":[{"internalType":"uint256","name":"multiplier","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"rewardsAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"multiplier","type":"uint256"},{"internalType":"uint256[]","name":"anualRewardRates","type":"uint256[]"},{"internalType":"uint256[]","name":"lowerBounds","type":"uint256[]"},{"internalType":"uint256[]","name":"upperBounds","type":"uint256[]"}],"name":"setupRewards","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"maxAmount","type":"uint256"},{"internalType":"uint256","name":"initialAmount","type":"uint256"},{"internalType":"uint256","name":"daysInterval","type":"uint256"},{"internalType":"uint256","name":"unstakingPeriod","type":"uint256"}],"name":"setupStakingLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"setupState","outputs":[{"internalType":"bool","name":"staking","type":"bool"},{"internalType":"bool","name":"rewards","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"stakingLimitConfig","outputs":[{"internalType":"uint256","name":"maxAmount","type":"uint256"},{"internalType":"uint256","name":"initialAmount","type":"uint256"},{"internalType":"uint256","name":"daysInterval","type":"uint256"},{"internalType":"uint256","name":"maxIntervals","type":"uint256"},{"internalType":"uint256","name":"unstakingPeriod","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"toggleRewards","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b50604051620047b3380380620047b3833981810160405260408110156200003757600080fd5b810190808051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36001600060146101000a81548160ff02191690831515021790555060018081905550816200015d8173ffffffffffffffffffffffffffffffffffffffff16620002f360201b62003e8b1760201c565b620001b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260348152602001806200477f6034913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156200023c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001806200474f6030913960400191505060405180910390fd5b82600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555042600d819055506000600260146101000a81548160ff02191690836002811115620002e557fe5b02179055505050506200033f565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f91506000801b8214158015620003365750808214155b92505050919050565b614400806200034f6000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80638f32d59b116100f9578063c3977fcd11610097578063ef8a923511610071578063ef8a9235146106fb578063f2fde38b14610727578063fa45aa001461076b578063fc0c546a14610775576101c4565b8063c3977fcd1461066f578063c3bc0c3e146106bf578063ce4843e9146106dd576101c4565b8063b51d1d4f116100d3578063b51d1d4f146105cf578063b6b55f25146105d9578063bc5ca93c14610607578063c0973eed14610625576101c4565b80638f32d59b146105145780639d18e4b014610536578063aef91d5f14610595576101c4565b806365cf7c9b116101665780638456cb59116101405780638456cb5914610444578063893bec431461044e5780638c19ec8b1461049a5780638da5cb5b146104ca576101c4565b806365cf7c9b146103e2578063715018a61461040057806373fe4a041461040a576101c4565b80633f4ba83a116101a25780633f4ba83a1461026b5780634716e2c4146102755780634e94c285146103a25780635c975abb146103c0576101c4565b80630f31859a146101c95780633769209b146101f65780633818548b1461024d575b600080fd5b6101d16107bf565b6040518083151515158152602001821515151581526020019250505060405180910390f35b6102226004803603602081101561020c57600080fd5b81019080803590602001909291905050506107eb565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b610255610909565b6040518082815260200191505060405180910390f35b6102736109b3565b005b6103a06004803603608081101561028b57600080fd5b8101908080359060200190929190803590602001906401000000008111156102b257600080fd5b8201836020820111156102c457600080fd5b803590602001918460208302840111640100000000831117156102e657600080fd5b90919293919293908035906020019064010000000081111561030757600080fd5b82018360208201111561031957600080fd5b8035906020019184602083028401116401000000008311171561033b57600080fd5b90919293919293908035906020019064010000000081111561035c57600080fd5b82018360208201111561036e57600080fd5b8035906020019184602083028401116401000000008311171561039057600080fd5b9091929391929390505050610b2e565b005b6103aa610e45565b6040518082815260200191505060405180910390f35b6103c8610e51565b604051808215151515815260200191505060405180910390f35b6103ea610e67565b6040518082815260200191505060405180910390f35b610408610e6d565b005b610412610fa6565b604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390f35b61044c610fca565b005b6104986004803603608081101561046457600080fd5b8101908080359060200190929190803590602001909291908035906020019092919080359060200190929190505050611147565b005b6104c8600480360360208110156104b057600080fd5b8101908080351515906020019092919050505061141f565b005b6104d2611650565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61051c611679565b604051808215151515815260200191505060405180910390f35b6105786004803603602081101561054c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506116d0565b604051808381526020018281526020019250505060405180910390f35b61059d611926565b604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390f35b6105d7611b3a565b005b610605600480360360208110156105ef57600080fd5b8101908080359060200190929190505050611e4b565b005b61060f6123f5565b6040518082815260200191505060405180910390f35b61062d612402565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61069b6004803603602081101561068557600080fd5b8101908080359060200190929190505050612428565b60405180848152602001838152602001828152602001935050505060405180910390f35b6106c7612536565b6040518082815260200191505060405180910390f35b6106e56125e1565b6040518082815260200191505060405180910390f35b6107036125e7565b6040518082600281111561071357fe5b60ff16815260200191505060405180910390f35b6107696004803603602081101561073d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506125fa565b005b610773612680565b005b61077d612d7a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60038060000160009054906101000a900460ff16908060000160019054906101000a900460ff16905082565b600080600080600060028111156107fe57fe5b600260149054906101000a900460ff16600281111561081957fe5b141561088d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b610895613e0a565b601086815481106108a257fe5b9060005260206000209060040201604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050905080600001518160200151826040015183606001519450945094509450509193509193565b600080600281111561091757fe5b600260149054906101000a900460ff16600281111561093257fe5b14156109a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b6109ae612da0565b905090565b6109bb611679565b610a2d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060149054906101000a900460ff16610aaf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5061757361626c653a206e6f742070617573656400000000000000000000000081525060200191505060405180910390fd5b60008060146101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1565b610b36611679565b610ba8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060149054906101000a900460ff16610c2a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5061757361626c653a206e6f742070617573656400000000000000000000000081525060200191505060405180910390fd5b60006002811115610c3757fe5b600260149054906101000a900460ff166002811115610c5257fe5b14610ca8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061401e6021913960400191505060405180910390fd5b610d7787878780806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050868680806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050858580806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050612e03565b8660096002018190555060008090505b86869050811015610de057610dd3878783818110610da157fe5b90506020020135868684818110610db457fe5b90506020020135858585818110610dc757fe5b90506020020135612fc9565b8080600101915050610d87565b506000828260018585905003818110610df557fe5b905060200201359050610e0d600082600a8401612fc9565b610e15613069565b6001600360000160016101000a81548160ff021916908315150217905550610e3b613144565b5050505050505050565b60098060020154905081565b60008060149054906101000a900460ff16905090565b600d5481565b610e75611679565b610ee7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60048060000154908060010154908060020154908060030154908060040154905085565b610fd2611679565b611044576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060149054906101000a900460ff16156110c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b6001600060146101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1565b61114f611679565b6111c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060149054906101000a900460ff16611243576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5061757361626c653a206e6f742070617573656400000000000000000000000081525060200191505060405180910390fd5b6000600281111561125057fe5b600260149054906101000a900460ff16600281111561126b57fe5b146112c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061401e6021913960400191505060405180910390fd5b6000841180156112d15750600083115b80156112dd5750600082115b80156112ea575060008110155b61133f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806142a16022913960400191505060405180910390fd5b600061135484866131a490919063ffffffff16565b146113aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c8152602001806140f4603c913960400191505060405180910390fd5b60006113bf84866131ee90919063ffffffff16565b9050846004600001819055508360046001018190555082600460020181905550816004800181905550806004600301819055506001600360000160006101000a81548160ff021916908315150217905550611418613144565b5050505050565b611427611679565b611499576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060028111156114a657fe5b600260149054906101000a900460ff1660028111156114c157fe5b1415611535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b600081611543576002611546565b60015b905080600281111561155457fe5b600260149054906101000a900460ff16600281111561156f57fe5b14156115c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613f84602a913960400191505060405180910390fd5b60006002808111156115d457fe5b8260028111156115e057fe5b14156115f55760016009600001805490500390505b6001600281111561160257fe5b82600281111561160e57fe5b141561161f5761161c613238565b90505b611628816132bd565b81600260146101000a81548160ff0219169083600281111561164657fe5b0217905550505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b600080600060028111156116e057fe5b600260149054906101000a900460ff1660028111156116fb57fe5b141561176f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050160009054906101000a900460ff16801561180e57506000600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015414155b611863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061432c6036913960400191505060405180910390fd5b61186b613e32565b600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060c001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820160009054906101000a900460ff161515151581525050905042816040018181525050806000015161191c8261336b565b9250925050915091565b600080600080600080600281111561193a57fe5b600260149054906101000a900460ff16600281111561195557fe5b14156119c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050160009054906101000a900460ff16611a6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061432c6036913960400191505060405180910390fd5b611a76613e32565b600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060c001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820160009054906101000a900460ff16151515158152505090508060000151816020015182604001518360600151846080015195509550955095509550509091929394565b600060149054906101000a900460ff1615611bbd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b60006002811115611bca57fe5b600260149054906101000a900460ff166002811115611be557fe5b1415611c59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b6000611c63613474565b9050600460030154811015611cc3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061430b6021913960400191505060405180910390fd5b6000600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060050160009054906101000a900460ff168015611d2957506000816000015414155b611d7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604081526020018061438c6040913960400191505060405180910390fd5b6000816002015414611ddb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a815260200180613fae603a913960400191505060405180910390fd5b42816002018190555060016010805490500381600401819055503373ffffffffffffffffffffffffffffffffffffffff167f15e1f18cd8cc91e09c1a1a056f1d8e61884aec50ad8502f88defaa64820e8fc282600001546040518082815260200191505060405180910390a25050565b600180600082825401925050819055506000600154905060006002811115611e6f57fe5b600260149054906101000a900460ff166002811115611e8a57fe5b1415611efe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b600060149054906101000a900460ff1615611f81576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b816000611f9982600e5461349f90919063ffffffff16565b90506000611fa5612da0565b905080821115612000576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d8152602001806141f8603d913960400191505060405180910390fd5b60008511612059576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180613fe86036913960400191505060405180910390fd5b600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050160009054906101000a900460ff16156120ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806141d66022913960400191505060405180910390fd5b6000600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061215986826000015461349f90919063ffffffff16565b8160000181905550428160010181905550600160108054905003816003018190555060018160050160006101000a81548160ff0219169083151502179055506121ad86600e5461349f90919063ffffffff16565b600e819055506121bb613527565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330896040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561229857600080fd5b505af11580156122ac573d6000803e3d6000fd5b505050506040513d60208110156122c257600080fd5b8101908080519060200190929190505050612328576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260388152602001806142696038913960400191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f0a7bb2e28cc4698aac06db79cf9163bfcc20719286cf59fa7d492ceda1b8edc2876040518082815260200191505060405180910390a25050505060015481146123f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b5050565b6000601080549050905090565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600080600281111561243957fe5b600260149054906101000a900460ff16600281111561245457fe5b14156124c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b6124d0613e6a565b600960000185815481106124e057fe5b906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820154815250509050806000015181602001518260400151935093509350509193909250565b600080600281111561254457fe5b600260149054906101000a900460ff16600281111561255f57fe5b14156125d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b600960000180549050905090565b600e5481565b600260149054906101000a900460ff1681565b612602611679565b612674576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61267d816135ac565b50565b6001806000828254019250508190555060006001549050600060149054906101000a900460ff161561271a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b6000600281111561272757fe5b600260149054906101000a900460ff16600281111561274257fe5b14156127b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b6000600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060050160009054906101000a900460ff16801561281c57506000816000015414155b612871576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526035815260200180613f296035913960400191505060405180910390fd5b6000816002015414156128cf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613f036026913960400191505060405180910390fd5b60006201518082600201544203816128e357fe5b0490508060048001541115612943576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613ed7602c913960400191505060405180910390fd5b60008260000154905060006129af846040518060c001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820160009054906101000a900460ff16151515158152505061336b565b9050600084600001819055506129d082600e546136f090919063ffffffff16565b600e819055506129de613527565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612a8757600080fd5b505af1158015612a9b573d6000803e3d6000fd5b505050506040513d6020811015612ab157600080fd5b8101908080519060200190929190505050612b17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604781526020018061418f6047913960600191505060405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633846040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015612c1657600080fd5b505af1158015612c2a573d6000803e3d6000fd5b505050506040513d6020811015612c4057600080fd5b8101908080519060200190929190505050612ca6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603e815260200180614151603e913960400191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167ff6c0fc94edc8fd2a37514f1fb85af88fca386b00a54127b912273e6b83322e088383604051808381526020018281526020019250505060405180910390a2505050506001548114612d77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080612dab613474565b9050600060046001015490506000612dd46001600460030154038461373a90919063ffffffff16565b9050612dfb612dec828461375390919063ffffffff16565b8361349f90919063ffffffff16565b935050505090565b60008351118015612e15575060008251115b8015612e22575060008151115b612e77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a81526020018061403f603a913960400191505060405180910390fd5b81518351148015612e89575080518251145b612ede576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260418152602001806140b36041913960600191505060405180910390fd5b600082600081518110612eed57fe5b602002602001015114612f4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180614362602a913960400191505060405180910390fd5b606484108015612f6e57506000612f6c8560646131a490919063ffffffff16565b145b612fc3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260488152602001806142c36048913960600191505060405180910390fd5b50505050565b6009600001604051806060016040528085815260200184815260200183815250908060018154018082558091505090600182039060005260206000209060030201600090919290919091506000820151816000015560208201518160010155604082015181600201555050506009600101819080600181540180825580915050906001820390600052602060002001600090919290919091505550505050565b6000601080549050146130c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a815260200180614079603a913960400191505060405180910390fd5b601060405180608001604052806000815260200142815260200160008152602001438152509080600181540180825580915050906001820390600052602060002090600402016000909192909190915060008201518160000155602082015181600101556040820151816002015560608201518160030155505050565b600360000160019054906101000a900460ff1615806131735750600360000160009054906101000a900460ff16155b1561317d576131a2565b6001600260146101000a81548160ff0219169083600281111561319c57fe5b02179055505b565b60006131e683836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f00000000000000008152506137d9565b905092915050565b600061323083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061389a565b905092915050565b600080613254600e54600960010161396090919063ffffffff16565b905060096001018054905081106132b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260348152602001806142356034913960400191505060405180910390fd5b8091505090565b60006132c7613a15565b9050438160030154101561335d574281600201819055506010604051806080016040528084815260200142815260200160008152602001438152509080600181540180825580915050906001820390600052602060002090600402016000909192909190915060008201518160000155602082015181600101556040820151816002015560608201518160030155505050613367565b8181600001819055505b5050565b600080670de0b6b3a7640000905060008061338585613a3f565b91509150600081141561339e576000935050505061346f565b6133b1838361375390919063ffffffff16565b915060006133c882846131ee90919063ffffffff16565b905060006133f86103e86133ea8660096002015461375390919063ffffffff16565b6131ee90919063ffffffff16565b9050600061340f828461349f90919063ffffffff16565b90506000613428618e948861375390919063ffffffff16565b90506134658161345787613449868e6000015161375390919063ffffffff16565b61375390919063ffffffff16565b6131ee90919063ffffffff16565b9750505050505050505b919050565b60008062015180600d5442038161348757fe5b049050600460020154818161349857fe5b0491505090565b60008082840190508381101561351d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60028081111561353357fe5b600260149054906101000a900460ff16600281111561354e57fe5b1415613559576135aa565b613561613e6a565b613569613c2f565b9050600e5481602001511115801561358757508060400151600e5411155b1561359257506135aa565b600061359c613238565b90506135a7816132bd565b50505b565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415613632576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613f5e6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600061373283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613c94565b905092915050565b6000818310613749578161374b565b825b905092915050565b60008083141561376657600090506137d3565b600082840290508284828161377757fe5b04146137ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806141306021913960400191505060405180910390fd5b809150505b92915050565b6000808314158290613886576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561384b578082015181840152602081019050613830565b50505050905090810190601f1680156138785780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5082848161389057fe5b0690509392505050565b60008083118290613946576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561390b5780820151818401526020810190506138f0565b50505050905090810190601f1680156139385780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161395257fe5b049050809150509392505050565b600080838054905014156139775760009050613a0f565b60008090506000848054905090505b808210156139cf57600061399a8383613d54565b9050848682815481106139a957fe5b906000526020600020015411156139c2578091506139c9565b6001810192505b50613986565b6000821180156139f75750838560018403815481106139ea57fe5b9060005260206000200154145b15613a09576001820392505050613a0f565b81925050505b92915050565b6000601060016010805490500381548110613a2c57fe5b9060005260206000209060040201905090565b600080600062015180846020015185604001510381613a5a57fe5b049050600080856080015186606001511415613aa357613a7d8660600151613d96565b600001519050613a96838261375390919063ffffffff16565b8394509450505050613c2a565b6201518086602001516010886060015181548110613abd57fe5b9060005260206000209060040201600201540381613ad757fe5b049150613ae78660600151613d96565b6000015190506000613b02838361375390919063ffffffff16565b90506000600188606001510190505b8760800151811015613bad576201518060108281548110613b2e57fe5b90600052602060002090600402016001015460108381548110613b4d57fe5b9060005260206000209060040201600201540381613b6757fe5b049350613b7381613d96565b600001519250613b9e613b8f858561375390919063ffffffff16565b8361349f90919063ffffffff16565b91508080600101915050613b11565b50620151806010886080015181548110613bc357fe5b90600052602060002090600402016001015488604001510381613be257fe5b049250613bf28760800151613d96565b600001519150613c1d613c0e838561375390919063ffffffff16565b8261349f90919063ffffffff16565b9050808495509550505050505b915091565b613c37613e6a565b6000613c41613a15565b60000154905060096000018181548110613c5757fe5b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505091505090565b6000838311158290613d41576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613d06578082015181840152602081019050613ceb565b50505050905090810190601f168015613d335780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b60006002808381613d6157fe5b0660028581613d6c57fe5b060181613d7557fe5b0460028381613d8057fe5b0460028581613d8b57fe5b040101905092915050565b613d9e613e6a565b600960000160108381548110613db057fe5b90600052602060002090600402016000015481548110613dcc57fe5b906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820154815250509050919050565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b6040518060c0016040528060008152602001600081526020016000815260200160008152602001600081526020016000151581525090565b60405180606001604052806000815260200160008152602001600081525090565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f91506000801b8214158015613ecd5750808214155b9250505091905056fe5b57697468647261775d2054686520756e7374616b696e6720706572696f6420646964206e6f7420706173735b57697468647261775d205769746864726177206973206e6f7420696e697469616c697a65645b57697468647261775d205468657265206973206e6f207374616b65206465706f73697420666f722074686973206163636f756e744f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573735b546f67676c65526577617264735d20546869732073746174757320697320616c7265616479207365745b496e697469617465205769746864726177616c5d20596f7520616c726561647920696e6974696174656420746865207769746864726177616c5b56616c69646174696f6e5d20546865207374616b65206465706f7369742068617320746f206265206c6172676572207468616e20305b4c6966656379636c655d20536574757020697320616c726561647920646f6e655b56616c69646174696f6e5d20416c6c20706172616d6574657273206d7573742068617665206174206c65617374206f6e6520656c656d656e745b4c6f676963616c5d20426173652072657761726420686973746f72792068617320616c7265616479206265656e20696e697469616c697a65645b56616c69646174696f6e5d20416c6c20706172616d6574657273206d7573742068617665207468652073616d65206e756d626572206f6620656c656d656e74735b56616c69646174696f6e5d206d6178416d6f756e742073686f756c642062652061206d756c7469706c65206f6620696e697469616c416d6f756e74536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775b57697468647261775d20536f6d657468696e672077656e742077726f6e67207768696c65207472616e7366657272696e6720796f7572207265776172645b57697468647261775d20536f6d657468696e672077656e742077726f6e67207768696c65207472616e7366657272696e6720796f757220696e697469616c206465706f7369745b4465706f7369745d20596f7520616c726561647920686176652061207374616b655b4465706f7369745d20596f7572206465706f73697420776f756c6420657863656564207468652063757272656e74207374616b696e67206c696d69745b4e6f74466f756e645d205468652063757272656e7420746f74616c207374616b6564206973206f7574206f6620626f756e64735b4465706f7369745d20536f6d657468696e672077656e742077726f6e6720647572696e672074686520746f6b656e207472616e736665725b56616c69646174696f6e5d20536f6d6520706172616d65746572732061726520305b56616c69646174696f6e5d204d756c7469706c6965722073686f756c6420626520736d616c6c6572207468616e2031303020616e642064697669646520697420657175616c6c795b57697468647261775d204e6f7420656e6f7567682064617973207061737365645b56616c69646174696f6e5d2054686973206163636f756e7420646f65736e277420686176652061207374616b65206465706f7369745b56616c69646174696f6e5d204669727374206c6f77657220626f756e642073686f756c6420626520305b496e697469617465205769746864726177616c5d205468657265206973206e6f207374616b65206465706f73697420666f722074686973206163636f756e74a265627a7a72315820e356c1da018e02172721d0a92bceb5956202c0b037176d883376c9d2a99617b264736f6c634300050f00325b56616c69646174696f6e5d205f726577617264734164647265737320697320746865207a65726f20616464726573735b56616c69646174696f6e5d20546865206164647265737320646f6573206e6f7420636f6e7461696e206120636f6e7472616374000000000000000000000000f9986d445ced31882377b5d6a5f58eaea72288c3000000000000000000000000b1a2ee4dfdadfca7ecff42295768a3e65d930c56

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101c45760003560e01c80638f32d59b116100f9578063c3977fcd11610097578063ef8a923511610071578063ef8a9235146106fb578063f2fde38b14610727578063fa45aa001461076b578063fc0c546a14610775576101c4565b8063c3977fcd1461066f578063c3bc0c3e146106bf578063ce4843e9146106dd576101c4565b8063b51d1d4f116100d3578063b51d1d4f146105cf578063b6b55f25146105d9578063bc5ca93c14610607578063c0973eed14610625576101c4565b80638f32d59b146105145780639d18e4b014610536578063aef91d5f14610595576101c4565b806365cf7c9b116101665780638456cb59116101405780638456cb5914610444578063893bec431461044e5780638c19ec8b1461049a5780638da5cb5b146104ca576101c4565b806365cf7c9b146103e2578063715018a61461040057806373fe4a041461040a576101c4565b80633f4ba83a116101a25780633f4ba83a1461026b5780634716e2c4146102755780634e94c285146103a25780635c975abb146103c0576101c4565b80630f31859a146101c95780633769209b146101f65780633818548b1461024d575b600080fd5b6101d16107bf565b6040518083151515158152602001821515151581526020019250505060405180910390f35b6102226004803603602081101561020c57600080fd5b81019080803590602001909291905050506107eb565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b610255610909565b6040518082815260200191505060405180910390f35b6102736109b3565b005b6103a06004803603608081101561028b57600080fd5b8101908080359060200190929190803590602001906401000000008111156102b257600080fd5b8201836020820111156102c457600080fd5b803590602001918460208302840111640100000000831117156102e657600080fd5b90919293919293908035906020019064010000000081111561030757600080fd5b82018360208201111561031957600080fd5b8035906020019184602083028401116401000000008311171561033b57600080fd5b90919293919293908035906020019064010000000081111561035c57600080fd5b82018360208201111561036e57600080fd5b8035906020019184602083028401116401000000008311171561039057600080fd5b9091929391929390505050610b2e565b005b6103aa610e45565b6040518082815260200191505060405180910390f35b6103c8610e51565b604051808215151515815260200191505060405180910390f35b6103ea610e67565b6040518082815260200191505060405180910390f35b610408610e6d565b005b610412610fa6565b604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390f35b61044c610fca565b005b6104986004803603608081101561046457600080fd5b8101908080359060200190929190803590602001909291908035906020019092919080359060200190929190505050611147565b005b6104c8600480360360208110156104b057600080fd5b8101908080351515906020019092919050505061141f565b005b6104d2611650565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61051c611679565b604051808215151515815260200191505060405180910390f35b6105786004803603602081101561054c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506116d0565b604051808381526020018281526020019250505060405180910390f35b61059d611926565b604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390f35b6105d7611b3a565b005b610605600480360360208110156105ef57600080fd5b8101908080359060200190929190505050611e4b565b005b61060f6123f5565b6040518082815260200191505060405180910390f35b61062d612402565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61069b6004803603602081101561068557600080fd5b8101908080359060200190929190505050612428565b60405180848152602001838152602001828152602001935050505060405180910390f35b6106c7612536565b6040518082815260200191505060405180910390f35b6106e56125e1565b6040518082815260200191505060405180910390f35b6107036125e7565b6040518082600281111561071357fe5b60ff16815260200191505060405180910390f35b6107696004803603602081101561073d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506125fa565b005b610773612680565b005b61077d612d7a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60038060000160009054906101000a900460ff16908060000160019054906101000a900460ff16905082565b600080600080600060028111156107fe57fe5b600260149054906101000a900460ff16600281111561081957fe5b141561088d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b610895613e0a565b601086815481106108a257fe5b9060005260206000209060040201604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050905080600001518160200151826040015183606001519450945094509450509193509193565b600080600281111561091757fe5b600260149054906101000a900460ff16600281111561093257fe5b14156109a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b6109ae612da0565b905090565b6109bb611679565b610a2d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060149054906101000a900460ff16610aaf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5061757361626c653a206e6f742070617573656400000000000000000000000081525060200191505060405180910390fd5b60008060146101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1565b610b36611679565b610ba8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060149054906101000a900460ff16610c2a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5061757361626c653a206e6f742070617573656400000000000000000000000081525060200191505060405180910390fd5b60006002811115610c3757fe5b600260149054906101000a900460ff166002811115610c5257fe5b14610ca8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061401e6021913960400191505060405180910390fd5b610d7787878780806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050868680806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050858580806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050612e03565b8660096002018190555060008090505b86869050811015610de057610dd3878783818110610da157fe5b90506020020135868684818110610db457fe5b90506020020135858585818110610dc757fe5b90506020020135612fc9565b8080600101915050610d87565b506000828260018585905003818110610df557fe5b905060200201359050610e0d600082600a8401612fc9565b610e15613069565b6001600360000160016101000a81548160ff021916908315150217905550610e3b613144565b5050505050505050565b60098060020154905081565b60008060149054906101000a900460ff16905090565b600d5481565b610e75611679565b610ee7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60048060000154908060010154908060020154908060030154908060040154905085565b610fd2611679565b611044576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060149054906101000a900460ff16156110c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b6001600060146101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1565b61114f611679565b6111c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060149054906101000a900460ff16611243576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5061757361626c653a206e6f742070617573656400000000000000000000000081525060200191505060405180910390fd5b6000600281111561125057fe5b600260149054906101000a900460ff16600281111561126b57fe5b146112c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061401e6021913960400191505060405180910390fd5b6000841180156112d15750600083115b80156112dd5750600082115b80156112ea575060008110155b61133f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806142a16022913960400191505060405180910390fd5b600061135484866131a490919063ffffffff16565b146113aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c8152602001806140f4603c913960400191505060405180910390fd5b60006113bf84866131ee90919063ffffffff16565b9050846004600001819055508360046001018190555082600460020181905550816004800181905550806004600301819055506001600360000160006101000a81548160ff021916908315150217905550611418613144565b5050505050565b611427611679565b611499576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060028111156114a657fe5b600260149054906101000a900460ff1660028111156114c157fe5b1415611535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b600081611543576002611546565b60015b905080600281111561155457fe5b600260149054906101000a900460ff16600281111561156f57fe5b14156115c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613f84602a913960400191505060405180910390fd5b60006002808111156115d457fe5b8260028111156115e057fe5b14156115f55760016009600001805490500390505b6001600281111561160257fe5b82600281111561160e57fe5b141561161f5761161c613238565b90505b611628816132bd565b81600260146101000a81548160ff0219169083600281111561164657fe5b0217905550505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b600080600060028111156116e057fe5b600260149054906101000a900460ff1660028111156116fb57fe5b141561176f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050160009054906101000a900460ff16801561180e57506000600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015414155b611863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061432c6036913960400191505060405180910390fd5b61186b613e32565b600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060c001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820160009054906101000a900460ff161515151581525050905042816040018181525050806000015161191c8261336b565b9250925050915091565b600080600080600080600281111561193a57fe5b600260149054906101000a900460ff16600281111561195557fe5b14156119c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050160009054906101000a900460ff16611a6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061432c6036913960400191505060405180910390fd5b611a76613e32565b600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060c001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820160009054906101000a900460ff16151515158152505090508060000151816020015182604001518360600151846080015195509550955095509550509091929394565b600060149054906101000a900460ff1615611bbd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b60006002811115611bca57fe5b600260149054906101000a900460ff166002811115611be557fe5b1415611c59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b6000611c63613474565b9050600460030154811015611cc3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061430b6021913960400191505060405180910390fd5b6000600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060050160009054906101000a900460ff168015611d2957506000816000015414155b611d7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604081526020018061438c6040913960400191505060405180910390fd5b6000816002015414611ddb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a815260200180613fae603a913960400191505060405180910390fd5b42816002018190555060016010805490500381600401819055503373ffffffffffffffffffffffffffffffffffffffff167f15e1f18cd8cc91e09c1a1a056f1d8e61884aec50ad8502f88defaa64820e8fc282600001546040518082815260200191505060405180910390a25050565b600180600082825401925050819055506000600154905060006002811115611e6f57fe5b600260149054906101000a900460ff166002811115611e8a57fe5b1415611efe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b600060149054906101000a900460ff1615611f81576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b816000611f9982600e5461349f90919063ffffffff16565b90506000611fa5612da0565b905080821115612000576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d8152602001806141f8603d913960400191505060405180910390fd5b60008511612059576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180613fe86036913960400191505060405180910390fd5b600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050160009054906101000a900460ff16156120ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806141d66022913960400191505060405180910390fd5b6000600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061215986826000015461349f90919063ffffffff16565b8160000181905550428160010181905550600160108054905003816003018190555060018160050160006101000a81548160ff0219169083151502179055506121ad86600e5461349f90919063ffffffff16565b600e819055506121bb613527565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330896040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561229857600080fd5b505af11580156122ac573d6000803e3d6000fd5b505050506040513d60208110156122c257600080fd5b8101908080519060200190929190505050612328576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260388152602001806142696038913960400191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f0a7bb2e28cc4698aac06db79cf9163bfcc20719286cf59fa7d492ceda1b8edc2876040518082815260200191505060405180910390a25050505060015481146123f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b5050565b6000601080549050905090565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600080600281111561243957fe5b600260149054906101000a900460ff16600281111561245457fe5b14156124c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b6124d0613e6a565b600960000185815481106124e057fe5b906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820154815250509050806000015181602001518260400151935093509350509193909250565b600080600281111561254457fe5b600260149054906101000a900460ff16600281111561255f57fe5b14156125d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b600960000180549050905090565b600e5481565b600260149054906101000a900460ff1681565b612602611679565b612674576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61267d816135ac565b50565b6001806000828254019250508190555060006001549050600060149054906101000a900460ff161561271a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f5061757361626c653a207061757365640000000000000000000000000000000081525060200191505060405180910390fd5b6000600281111561272757fe5b600260149054906101000a900460ff16600281111561274257fe5b14156127b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5b4c6966656379636c655d205365747570206973206e6f7420646f6e6500000081525060200191505060405180910390fd5b6000600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060050160009054906101000a900460ff16801561281c57506000816000015414155b612871576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526035815260200180613f296035913960400191505060405180910390fd5b6000816002015414156128cf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613f036026913960400191505060405180910390fd5b60006201518082600201544203816128e357fe5b0490508060048001541115612943576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613ed7602c913960400191505060405180910390fd5b60008260000154905060006129af846040518060c001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820160009054906101000a900460ff16151515158152505061336b565b9050600084600001819055506129d082600e546136f090919063ffffffff16565b600e819055506129de613527565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612a8757600080fd5b505af1158015612a9b573d6000803e3d6000fd5b505050506040513d6020811015612ab157600080fd5b8101908080519060200190929190505050612b17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604781526020018061418f6047913960600191505060405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633846040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015612c1657600080fd5b505af1158015612c2a573d6000803e3d6000fd5b505050506040513d6020811015612c4057600080fd5b8101908080519060200190929190505050612ca6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603e815260200180614151603e913960400191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167ff6c0fc94edc8fd2a37514f1fb85af88fca386b00a54127b912273e6b83322e088383604051808381526020018281526020019250505060405180910390a2505050506001548114612d77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080612dab613474565b9050600060046001015490506000612dd46001600460030154038461373a90919063ffffffff16565b9050612dfb612dec828461375390919063ffffffff16565b8361349f90919063ffffffff16565b935050505090565b60008351118015612e15575060008251115b8015612e22575060008151115b612e77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a81526020018061403f603a913960400191505060405180910390fd5b81518351148015612e89575080518251145b612ede576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260418152602001806140b36041913960600191505060405180910390fd5b600082600081518110612eed57fe5b602002602001015114612f4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180614362602a913960400191505060405180910390fd5b606484108015612f6e57506000612f6c8560646131a490919063ffffffff16565b145b612fc3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260488152602001806142c36048913960600191505060405180910390fd5b50505050565b6009600001604051806060016040528085815260200184815260200183815250908060018154018082558091505090600182039060005260206000209060030201600090919290919091506000820151816000015560208201518160010155604082015181600201555050506009600101819080600181540180825580915050906001820390600052602060002001600090919290919091505550505050565b6000601080549050146130c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a815260200180614079603a913960400191505060405180910390fd5b601060405180608001604052806000815260200142815260200160008152602001438152509080600181540180825580915050906001820390600052602060002090600402016000909192909190915060008201518160000155602082015181600101556040820151816002015560608201518160030155505050565b600360000160019054906101000a900460ff1615806131735750600360000160009054906101000a900460ff16155b1561317d576131a2565b6001600260146101000a81548160ff0219169083600281111561319c57fe5b02179055505b565b60006131e683836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f00000000000000008152506137d9565b905092915050565b600061323083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061389a565b905092915050565b600080613254600e54600960010161396090919063ffffffff16565b905060096001018054905081106132b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260348152602001806142356034913960400191505060405180910390fd5b8091505090565b60006132c7613a15565b9050438160030154101561335d574281600201819055506010604051806080016040528084815260200142815260200160008152602001438152509080600181540180825580915050906001820390600052602060002090600402016000909192909190915060008201518160000155602082015181600101556040820151816002015560608201518160030155505050613367565b8181600001819055505b5050565b600080670de0b6b3a7640000905060008061338585613a3f565b91509150600081141561339e576000935050505061346f565b6133b1838361375390919063ffffffff16565b915060006133c882846131ee90919063ffffffff16565b905060006133f86103e86133ea8660096002015461375390919063ffffffff16565b6131ee90919063ffffffff16565b9050600061340f828461349f90919063ffffffff16565b90506000613428618e948861375390919063ffffffff16565b90506134658161345787613449868e6000015161375390919063ffffffff16565b61375390919063ffffffff16565b6131ee90919063ffffffff16565b9750505050505050505b919050565b60008062015180600d5442038161348757fe5b049050600460020154818161349857fe5b0491505090565b60008082840190508381101561351d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60028081111561353357fe5b600260149054906101000a900460ff16600281111561354e57fe5b1415613559576135aa565b613561613e6a565b613569613c2f565b9050600e5481602001511115801561358757508060400151600e5411155b1561359257506135aa565b600061359c613238565b90506135a7816132bd565b50505b565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415613632576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613f5e6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600061373283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613c94565b905092915050565b6000818310613749578161374b565b825b905092915050565b60008083141561376657600090506137d3565b600082840290508284828161377757fe5b04146137ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806141306021913960400191505060405180910390fd5b809150505b92915050565b6000808314158290613886576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561384b578082015181840152602081019050613830565b50505050905090810190601f1680156138785780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5082848161389057fe5b0690509392505050565b60008083118290613946576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561390b5780820151818401526020810190506138f0565b50505050905090810190601f1680156139385780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161395257fe5b049050809150509392505050565b600080838054905014156139775760009050613a0f565b60008090506000848054905090505b808210156139cf57600061399a8383613d54565b9050848682815481106139a957fe5b906000526020600020015411156139c2578091506139c9565b6001810192505b50613986565b6000821180156139f75750838560018403815481106139ea57fe5b9060005260206000200154145b15613a09576001820392505050613a0f565b81925050505b92915050565b6000601060016010805490500381548110613a2c57fe5b9060005260206000209060040201905090565b600080600062015180846020015185604001510381613a5a57fe5b049050600080856080015186606001511415613aa357613a7d8660600151613d96565b600001519050613a96838261375390919063ffffffff16565b8394509450505050613c2a565b6201518086602001516010886060015181548110613abd57fe5b9060005260206000209060040201600201540381613ad757fe5b049150613ae78660600151613d96565b6000015190506000613b02838361375390919063ffffffff16565b90506000600188606001510190505b8760800151811015613bad576201518060108281548110613b2e57fe5b90600052602060002090600402016001015460108381548110613b4d57fe5b9060005260206000209060040201600201540381613b6757fe5b049350613b7381613d96565b600001519250613b9e613b8f858561375390919063ffffffff16565b8361349f90919063ffffffff16565b91508080600101915050613b11565b50620151806010886080015181548110613bc357fe5b90600052602060002090600402016001015488604001510381613be257fe5b049250613bf28760800151613d96565b600001519150613c1d613c0e838561375390919063ffffffff16565b8261349f90919063ffffffff16565b9050808495509550505050505b915091565b613c37613e6a565b6000613c41613a15565b60000154905060096000018181548110613c5757fe5b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505091505090565b6000838311158290613d41576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613d06578082015181840152602081019050613ceb565b50505050905090810190601f168015613d335780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b60006002808381613d6157fe5b0660028581613d6c57fe5b060181613d7557fe5b0460028381613d8057fe5b0460028581613d8b57fe5b040101905092915050565b613d9e613e6a565b600960000160108381548110613db057fe5b90600052602060002090600402016000015481548110613dcc57fe5b906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820154815250509050919050565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b6040518060c0016040528060008152602001600081526020016000815260200160008152602001600081526020016000151581525090565b60405180606001604052806000815260200160008152602001600081525090565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f91506000801b8214158015613ecd5750808214155b9250505091905056fe5b57697468647261775d2054686520756e7374616b696e6720706572696f6420646964206e6f7420706173735b57697468647261775d205769746864726177206973206e6f7420696e697469616c697a65645b57697468647261775d205468657265206973206e6f207374616b65206465706f73697420666f722074686973206163636f756e744f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573735b546f67676c65526577617264735d20546869732073746174757320697320616c7265616479207365745b496e697469617465205769746864726177616c5d20596f7520616c726561647920696e6974696174656420746865207769746864726177616c5b56616c69646174696f6e5d20546865207374616b65206465706f7369742068617320746f206265206c6172676572207468616e20305b4c6966656379636c655d20536574757020697320616c726561647920646f6e655b56616c69646174696f6e5d20416c6c20706172616d6574657273206d7573742068617665206174206c65617374206f6e6520656c656d656e745b4c6f676963616c5d20426173652072657761726420686973746f72792068617320616c7265616479206265656e20696e697469616c697a65645b56616c69646174696f6e5d20416c6c20706172616d6574657273206d7573742068617665207468652073616d65206e756d626572206f6620656c656d656e74735b56616c69646174696f6e5d206d6178416d6f756e742073686f756c642062652061206d756c7469706c65206f6620696e697469616c416d6f756e74536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775b57697468647261775d20536f6d657468696e672077656e742077726f6e67207768696c65207472616e7366657272696e6720796f7572207265776172645b57697468647261775d20536f6d657468696e672077656e742077726f6e67207768696c65207472616e7366657272696e6720796f757220696e697469616c206465706f7369745b4465706f7369745d20596f7520616c726561647920686176652061207374616b655b4465706f7369745d20596f7572206465706f73697420776f756c6420657863656564207468652063757272656e74207374616b696e67206c696d69745b4e6f74466f756e645d205468652063757272656e7420746f74616c207374616b6564206973206f7574206f6620626f756e64735b4465706f7369745d20536f6d657468696e672077656e742077726f6e6720647572696e672074686520746f6b656e207472616e736665725b56616c69646174696f6e5d20536f6d6520706172616d65746572732061726520305b56616c69646174696f6e5d204d756c7469706c6965722073686f756c6420626520736d616c6c6572207468616e2031303020616e642064697669646520697420657175616c6c795b57697468647261775d204e6f7420656e6f7567682064617973207061737365645b56616c69646174696f6e5d2054686973206163636f756e7420646f65736e277420686176652061207374616b65206465706f7369745b56616c69646174696f6e5d204669727374206c6f77657220626f756e642073686f756c6420626520305b496e697469617465205769746864726177616c5d205468657265206973206e6f207374616b65206465706f73697420666f722074686973206163636f756e74a265627a7a72315820e356c1da018e02172721d0a92bceb5956202c0b037176d883376c9d2a99617b264736f6c634300050f0032

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

000000000000000000000000f9986d445ced31882377b5d6a5f58eaea72288c3000000000000000000000000b1a2ee4dfdadfca7ecff42295768a3e65d930c56

-----Decoded View---------------
Arg [0] : _token (address): 0xF9986D445ceD31882377b5D6a5F58EaEa72288c3
Arg [1] : _rewardsAddress (address): 0xB1a2eE4dfdadfcA7ecFF42295768A3E65d930C56

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000f9986d445ced31882377b5d6a5f58eaea72288c3
Arg [1] : 000000000000000000000000b1a2ee4dfdadfca7ecff42295768a3e65d930c56


Deployed Bytecode Sourcemap

20010:18341:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20010:18341:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21580:28;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28619:303;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;28619:303:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26894:156;;;:::i;:::-;;;;;;;;;;;;;;;;;;;16937:117;;;:::i;:::-;;29860:980;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;29860:980:0;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;29860:980:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;29860:980:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;29860:980:0;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;29860:980:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;29860:980:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;29860:980:0;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;29860:980:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;29860:980:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;29860:980:0;;;;;;;;;;;;:::i;:::-;;21666:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;16149:78;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;21743:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;14270:140;;;:::i;:::-;;21615:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16728:115;;;:::i;:::-;;28950:902;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;28950:902:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;26217:604;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;26217:604:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;13461:79;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;13827:92;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;27058:477;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;27058:477:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;27543:480;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24347:623;;;:::i;:::-;;23386:953;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;23386:953:0;;;;;;;;;;;;;;;;;:::i;:::-;;28473:138;;;:::i;:::-;;;;;;;;;;;;;;;;;;;21707:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;28197:268;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;28197:268:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28031:158;;;:::i;:::-;;;;;;;;;;;;;;;;;;;21780:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;21544:27;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14565:109;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;14565:109:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;24978:1231;;;:::i;:::-;;21518:19;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;21580:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;28619:303::-;28719:7;28728;28737;28746;22925:12;22908:29;;;;;;;;:13;;;;;;;;;;;:29;;;;;;;;;;22900:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28771:29;;:::i;:::-;28803:18;28822:5;28803:25;;;;;;;;;;;;;;;;;;28771:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28849:1;:17;;;28868:1;:16;;;28886:1;:14;;;28902:1;:11;;;28841:73;;;;;;;;;28619:303;;;;;:::o;26894:156::-;26981:7;22925:12;22908:29;;;;;;;;:13;;;;;;;;;;;:29;;;;;;;;;;22900:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27013:29;:27;:29::i;:::-;27006:36;;26894:156;:::o;16937:117::-;13673:9;:7;:9::i;:::-;13665:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16585:7;;;;;;;;;;;16577:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17005:5;16995:7;;:15;;;;;;;;;;;;;;;;;;17026:20;17035:10;17026:20;;;;;;;;;;;;;;;;;;;;;;16937:117::o;29860:980::-;13673:9;:7;:9::i;:::-;13665:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16585:7;;;;;;;;;;;16577:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22780:12;22763:29;;;;;;;;:13;;;;;;;;;;;:29;;;;;;;;;22755:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30128:87;30160:10;30172:16;;30128:87;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;30128:87:0;;;;;;30190:11;;30128:87;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;30128:87:0;;;;;;30203:11;;30128:87;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;30128:87:0;;;;;;:31;:87::i;:::-;30280:10;30254:12;:23;;:36;;;;30308:9;30320:1;30308:13;;30303:148;30327:16;;:23;;30323:1;:27;30303:148;;;30372:67;30387:16;;30404:1;30387:19;;;;;;;;;;;;;30408:11;;30420:1;30408:14;;;;;;;;;;;;;30424:11;;30436:1;30424:14;;;;;;;;;;;;;30372;:67::i;:::-;30352:3;;;;;;;30303:148;;;;30463:25;30491:11;;30524:1;30503:11;;:18;;:22;30491:35;;;;;;;;;;;;;30463:63;;30583:60;30598:1;30601:17;30640:2;30620:17;:22;30583:14;:60::i;:::-;30740:24;:22;:24::i;:::-;30798:4;30777:10;:18;;;:25;;;;;;;;;;;;;;;;;;30813:19;:17;:19::i;:::-;22841:1;29860:980;;;;;;;:::o;21666:32::-;;;;;;;;;:::o;16149:78::-;16188:4;16212:7;;;;;;;;;;;16205:14;;16149:78;:::o;21743:30::-;;;;:::o;14270:140::-;13673:9;:7;:9::i;:::-;13665:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14369:1;14332:40;;14353:6;;;;;;;;;;;14332:40;;;;;;;;;;;;14400:1;14383:6;;:19;;;;;;;;;;;;;;;;;;14270:140::o;21615:44::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;16728:115::-;13673:9;:7;:9::i;:::-;13665:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16386:7;;;;;;;;;;;16385:8;16377:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16797:4;16787:7;;:14;;;;;;;;;;;;;;;;;;16817:18;16824:10;16817:18;;;;;;;;;;;;;;;;;;;;;;16728:115::o;28950:902::-;13673:9;:7;:9::i;:::-;13665:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16585:7;;;;;;;;;;;16577:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22780:12;22763:29;;;;;;;;:13;;;;;;;;;;;:29;;;;;;;;;22755:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29168:1;29156:9;:13;:34;;;;;29189:1;29173:13;:17;29156:34;:54;;;;;29209:1;29194:12;:16;29156:54;:78;;;;;29233:1;29214:15;:20;;29156:78;29148:125;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29324:1;29292:28;29306:13;29292:9;:13;;:28;;;;:::i;:::-;:33;29284:106;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29403:20;29426:28;29440:13;29426:9;:13;;:28;;;;:::i;:::-;29403:51;;29531:9;29500:18;:28;;:40;;;;29586:13;29551:18;:32;;:48;;;;29644:12;29610:18;:31;;:46;;;;29704:15;29667:18;:34;;:52;;;;29764:12;29730:18;:31;;:46;;;;29810:4;29789:10;:18;;;:25;;;;;;;;;;;;;;;;;;29825:19;:17;:19::i;:::-;22841:1;28950:902;;;;:::o;26217:604::-;13673:9;:7;:9::i;:::-;13665:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22925:12;22908:29;;;;;;;;:13;;;;;;;;;;;:29;;;;;;;;;;22900:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26319:16;26338:7;:49;;26365:22;26338:49;;;26348:14;26338:49;26319:68;;26423:9;26406:26;;;;;;;;:13;;;;;;;;;;;:26;;;;;;;;;;26398:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26492:13;26535:22;26522:35;;;;;;;;:9;:35;;;;;;;;;26518:111;;;26616:1;26582:12;:24;;:31;;;;:35;26574:43;;26518:111;26658:14;26645:27;;;;;;;;:9;:27;;;;;;;;;26641:95;;;26697:27;:25;:27::i;:::-;26689:35;;26641:95;26748:27;26769:5;26748:20;:27::i;:::-;26804:9;26788:13;;:25;;;;;;;;;;;;;;;;;;;;;;;;22982:1;;26217:604;:::o;13461:79::-;13499:7;13526:6;;;;;;;;;;;13519:13;;13461:79;:::o;13827:92::-;13867:4;13905:6;;;;;;;;;;;13891:20;;:10;:20;;;13884:27;;13827:92;:::o;27058:477::-;27156:22;27180:14;22925:12;22908:29;;;;;;;;:13;;;;;;;;;;;:29;;;;;;;;;;22900:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27220:14;:23;27235:7;27220:23;;;;;;;;;;;;;;;:30;;;;;;;;;;;;:69;;;;;27288:1;27254:14;:23;27269:7;27254:23;;;;;;;;;;;;;;;:30;;;:35;;27220:69;27212:136;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27361:32;;:::i;:::-;27396:14;:23;27411:7;27396:23;;;;;;;;;;;;;;;27361:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27453:3;27430:12;:20;;:26;;;;;27477:12;:19;;;27498:28;27513:12;27498:14;:28::i;:::-;27469:58;;;;;27058:477;;;:::o;27543:480::-;27628:14;27644:17;27663:15;27680:28;27710:26;22925:12;22908:29;;;;;;;;:13;;;;;;;;;;;:29;;;;;;;;;;22900:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27762:14;:26;27777:10;27762:26;;;;;;;;;;;;;;;:33;;;;;;;;;;;;27754:100;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27865:21;;:::i;:::-;27889:14;:26;27904:10;27889:26;;;;;;;;;;;;;;;27865:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27936:1;:8;;;27946:1;:11;;;27959:1;:9;;;27970:1;:22;;;27994:1;:20;;;27928:87;;;;;;;;;;;27543:480;;;;;:::o;24347:623::-;16386:7;;;;;;;;;;;16385:8;16377:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22925:12;22908:29;;;;;;;;:13;;;;;;;;;;;:29;;;;;;;;;;22900:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22362:23;22388:21;:19;:21::i;:::-;22362:47;;22447:18;:31;;;22428:15;:50;;22420:96;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24479:33;24515:14;:26;24530:10;24515:26;;;;;;;;;;;;;;;24479:62;;24560:12;:19;;;;;;;;;;;;:47;;;;;24606:1;24583:12;:19;;;:24;;24560:47;24552:124;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24719:1;24695:12;:20;;;:25;24687:96;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24819:3;24796:12;:20;;:26;;;;24895:1;24867:18;:25;;;;:29;24833:12;:31;;:63;;;;24930:10;24912:50;;;24942:12;:19;;;24912:50;;;;;;;;;;;;;;;;;;22527:1;22982;24347:623::o;23386:953::-;12411:1;12394:13;;:18;;;;;;;;;;;12423:20;12446:13;;12423:36;;22925:12;22908:29;;;;;;;;:13;;;;;;;;;;;:29;;;;;;;;;;22900:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16386:7;;;;;;;;;;;16385:8;16377:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23514:6;22021:28;22052:29;22074:6;22052:17;;:21;;:29;;;;:::i;:::-;22021:60;;22092:27;22122:29;:27;:29::i;:::-;22092:59;;22194:19;22170:20;:43;;22162:117;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23555:1;23546:6;:10;23538:77;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23635:14;:26;23650:10;23635:26;;;;;;;;;;;;;;;:33;;;;;;;;;;;;23634:34;23626:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23720:33;23756:14;:26;23771:10;23756:26;;;;;;;;;;;;;;;23720:62;;23815:31;23839:6;23815:12;:19;;;:23;;:31;;;;:::i;:::-;23793:12;:19;;:53;;;;23882:3;23857:12;:22;;:28;;;;23960:1;23932:18;:25;;;;:29;23896:12;:33;;:65;;;;23994:4;23972:12;:19;;;:26;;;;;;;;;;;;;;;;;;24031:29;24053:6;24031:17;;:21;;:29;;;;:::i;:::-;24011:17;:49;;;;24071:26;:24;:26::i;:::-;24167:5;;;;;;;;;;;:18;;;24186:10;24206:4;24213:6;24167:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;24167:53:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;24167:53:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;24167:53:0;;;;;;;;;;;;;;;;24159:122;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24312:10;24297:34;;;24324:6;24297:34;;;;;;;;;;;;;;;;;;22290:1;16425;;;12506:13;;12490:12;:29;12482:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23386:953;;:::o;28473:138::-;28546:7;28578:18;:25;;;;28571:32;;28473:138;:::o;21707:29::-;;;;;;;;;;;;;:::o;28197:268::-;28290:7;28299;28308;22925:12;22908:29;;;;;;;;:13;;;;;;;;;;;:29;;;;;;;;;;22900:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28333:20;;:::i;:::-;28356:12;:24;;28381:5;28356:31;;;;;;;;;;;;;;;;;;28333:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28408:2;:18;;;28428:2;:13;;;28443:2;:13;;;28400:57;;;;;;;28197:268;;;;;:::o;28031:158::-;28118:7;22925:12;22908:29;;;;;;;;:13;;;;;;;;;;;:29;;;;;;;;;;22900:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28150:12;:24;;:31;;;;28143:38;;28031:158;:::o;21780:32::-;;;;:::o;21544:27::-;;;;;;;;;;;;;:::o;14565:109::-;13673:9;:7;:9::i;:::-;13665:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14638:28;14657:8;14638:18;:28::i;:::-;14565:109;:::o;24978:1231::-;12411:1;12394:13;;:18;;;;;;;;;;;12423:20;12446:13;;12423:36;;16386:7;;;;;;;;;;;16385:8;16377:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22925:12;22908:29;;;;;;;;:13;;;;;;;;;;;:29;;;;;;;;;;22900:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25094:33;25130:14;:26;25145:10;25130:26;;;;;;;;;;;;;;;25094:62;;25175:12;:19;;;;;;;;;;;;:47;;;;;25221:1;25198:12;:19;;;:24;;25175:47;25167:113;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25323:1;25299:12;:20;;;:25;;25291:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25454:18;25506:6;25482:12;:20;;;25476:3;:26;25475:37;;;;;;25454:58;;25569:10;25531:18;:34;;;:48;;25523:105;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25641:14;25658:12;:19;;;25641:36;;25688:14;25705:28;25720:12;25705:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:14;:28::i;:::-;25688:45;;25768:1;25746:12;:19;;:23;;;;25802:29;25824:6;25802:17;;:21;;:29;;;;:::i;:::-;25782:17;:49;;;;25842:26;:24;:26::i;:::-;25889:5;;;;;;;;;;;:14;;;25904:10;25916:6;25889:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25889:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;25889:34:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;25889:34:0;;;;;;;;;;;;;;;;25881:118;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26018:5;;;;;;;;;;;:18;;;26037:14;;;;;;;;;;;26053:10;26065:6;26018:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26018:54:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;26018:54:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;26018:54:0;;;;;;;;;;;;;;;;26010:129;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26174:10;26157:44;;;26186:6;26194;26157:44;;;;;;;;;;;;;;;;;;;;;;;;22982:1;;;;12506:13;;12490:12;:29;12482:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24978:1231;:::o;21518:19::-;;;;;;;;;;;;;:::o;31062:449::-;31138:7;31163:23;31189:21;:19;:21::i;:::-;31163:47;;31221:24;31248:18;:32;;;31221:59;;31293:17;31313:56;31367:1;31333:18;:31;;;:35;31313:15;:19;;:56;;;;:::i;:::-;31293:76;;31450:53;31471:31;31492:9;31471:16;:20;;:31;;;;:::i;:::-;31450:16;:20;;:53;;;;:::i;:::-;31443:60;;;;;31062:449;:::o;37419:929::-;37711:1;37685:16;:23;:27;:53;;;;;37737:1;37716:11;:18;:22;37685:53;:79;;;;;37763:1;37742:11;:18;:22;37685:79;37663:187;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37910:11;:18;37883:16;:23;:45;:89;;;;;37954:11;:18;37932:11;:18;:40;37883:89;37861:204;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38102:1;38084:11;38096:1;38084:14;;;;;;;;;;;;;;:19;38076:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38197:3;38184:10;:16;38183:57;;;;;38238:1;38206:28;38223:10;38214:3;38206:16;;:28;;;;:::i;:::-;:33;38183:57;38161:179;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37419:929;;;;:::o;34801:260::-;34919:12;:24;;34949:51;;;;;;;;34960:15;34949:51;;;;34977:10;34949:51;;;;34989:10;34949:51;;;34919:82;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;34919:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35012:12;:24;;35042:10;35012:41;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;35012:41:0;;;;;;;;;;;;;;;;;;;;;;34801:260;;;:::o;35069:255::-;35169:1;35140:18;:25;;;;:30;35132:101;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35246:18;35270:45;;;;;;;;35291:1;35270:45;;;;35294:3;35270:45;;;;35299:1;35270:45;;;;35302:12;35270:45;;;35246:70;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;35246:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35069:255::o;30865:189::-;30928:10;:18;;;;;;;;;;;;30927:19;:42;;;;30951:10;:18;;;;;;;;;;;;30950:19;30927:42;30923:81;;;30986:7;;30923:81;31032:14;31016:13;;:30;;;;;;;;;;;;;;;;;;;;;;;;30865:189;:::o;4716:130::-;4774:7;4801:37;4805:1;4808;4801:37;;;;;;;;;;;;;;;;;:3;:37::i;:::-;4794:44;;4716:130;;;;:::o;3252:132::-;3310:7;3337:39;3341:1;3344;3337:39;;;;;;;;;;;;;;;;;:3;:39::i;:::-;3330:46;;3252:132;;;;:::o;37088:323::-;37162:7;37187:13;37203:58;37243:17;;37203:12;:24;;:39;;:58;;;;:::i;:::-;37187:74;;37290:12;:24;;:31;;;;37282:5;:39;37274:104;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37398:5;37391:12;;;37088:323;:::o;35895:437::-;35972:42;36017:27;:25;:27::i;:::-;35972:72;;36087:12;36061:13;:23;;;:38;36057:268;;;36145:3;36116:13;:26;;:32;;;;36163:18;36187:52;;;;;;;;36208:8;36187:52;;;;36218:3;36187:52;;;;36223:1;36187:52;;;;36226:12;36187:52;;;36163:77;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;36163:77:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36057:268;;;36305:8;36273:13;:29;;:40;;;;36057:268;35895:437;;:::o;31743:1012::-;31838:7;31863:13;31879:8;31863:24;;31899:19;31920:21;31945:44;31976:12;31945:30;:44::i;:::-;31898:91;;;;32023:1;32006:13;:18;32002:59;;;32048:1;32041:8;;;;;;;32002:59;32244:22;32260:5;32244:11;:15;;:22;;;;:::i;:::-;32230:36;;32279:23;32305:30;32321:13;32305:11;:15;;:30;;;;:::i;:::-;32279:56;;32465:19;32487:50;32532:4;32487:40;32515:11;32487:12;:23;;;:27;;:40;;;;:::i;:::-;:44;;:50;;;;:::i;:::-;32465:72;;32548:21;32572:32;32592:11;32572:15;:19;;:32;;;;:::i;:::-;32548:56;;32615:19;32637:16;32647:5;32637;:9;;:16;;;;:::i;:::-;32615:38;;32673:74;32735:11;32673:57;32716:13;32673:38;32697:13;32673:12;:19;;;:23;;:38;;;;:::i;:::-;:42;;:57;;;;:::i;:::-;:61;;:74;;;;:::i;:::-;32666:81;;;;;;;;;31743:1012;;;;:::o;31519:216::-;31587:7;31612:18;31659:6;31640:15;;31634:3;:21;31633:32;;;;;;31612:53;;31696:18;:31;;;31683:10;:44;;;;;;31676:51;;;31519:216;:::o;941:181::-;999:7;1019:9;1035:1;1031;:5;1019:17;;1060:1;1055;:6;;1047:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1113:1;1106:8;;;941:181;;;;:::o;35332:555::-;35418:22;35401:39;;;;;;;;:13;;;;;;;;;;;:39;;;;;;;;;35397:78;;;35457:7;;35397:78;35487:35;;:::i;:::-;35525:20;:18;:20::i;:::-;35487:58;;35675:17;;35643;:28;;;:49;;:102;;;;;35717:17;:28;;;35696:17;;:49;;35643:102;35639:141;;;35762:7;;;35639:141;35792:16;35811:27;:25;:27::i;:::-;35792:46;;35849:30;35870:8;35849:20;:30::i;:::-;35332:555;;;:::o;14780:229::-;14874:1;14854:22;;:8;:22;;;;14846:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14964:8;14935:38;;14956:6;;;;;;;;;;;14935:38;;;;;;;;;;;;14993:8;14984:6;;:17;;;;;;;;;;;;;;;;;;14780:229;:::o;1397:136::-;1455:7;1482:43;1486:1;1489;1482:43;;;;;;;;;;;;;;;;;:3;:43::i;:::-;1475:50;;1397:136;;;;:::o;5953:106::-;6011:7;6042:1;6038;:5;:13;;6050:1;6038:13;;;6046:1;6038:13;6031:20;;5953:106;;;;:::o;2313:471::-;2371:7;2621:1;2616;:6;2612:47;;;2646:1;2639:8;;;;2612:47;2671:9;2687:1;2683;:5;2671:17;;2716:1;2711;2707;:5;;;;;;:10;2699:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2775:1;2768:8;;;2313:471;;;;;:::o;5365:166::-;5451:7;5484:1;5479;:6;;5487:12;5471:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;5471:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5522:1;5518;:5;;;;;;5511:12;;5365:166;;;;;:::o;3914:345::-;4000:7;4099:1;4095;:5;4102:12;4087:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;4087:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4126:9;4142:1;4138;:5;;;;;;4126:17;;4250:1;4243:8;;;3914:345;;;;;:::o;10088:918::-;10177:7;10217:1;10201:5;:12;;;;:17;10197:58;;;10242:1;10235:8;;;;10197:58;10267:11;10281:1;10267:15;;10293:12;10308:5;:12;;;;10293:27;;10333:424;10346:4;10340:3;:10;10333:424;;;10367:11;10381:23;10394:3;10399:4;10381:12;:23::i;:::-;10367:37;;10638:7;10625:5;10631:3;10625:10;;;;;;;;;;;;;;;;:20;10621:125;;;10673:3;10666:10;;10621:125;;;10729:1;10723:3;:7;10717:13;;10621:125;10333:424;;;;10883:1;10877:3;:7;:36;;;;;10906:7;10888:5;10900:1;10894:3;:7;10888:14;;;;;;;;;;;;;;;;:25;10877:36;10873:126;;;10943:1;10937:3;:7;10930:14;;;;;;10873:126;10984:3;10977:10;;;;10088:918;;;;;:::o;36896:184::-;36970:28;37023:18;37070:1;37042:18;:25;;;;:29;37023:49;;;;;;;;;;;;;;;;;;37016:56;;36896:184;:::o;32763:2030::-;32874:7;32883;32908:21;32982:6;32956:12;:22;;;32933:12;:20;;;:45;32932:56;;;;;;32908:80;;32999:14;33024:12;33147;:31;;;33110:12;:33;;;:68;33106:250;;;33202:62;33230:12;:33;;;33202:27;:62::i;:::-;:78;;;33195:85;;33305:23;33314:13;33305:4;:8;;:23;;;;:::i;:::-;33330:13;33297:47;;;;;;;;;33106:250;33695:6;33669:12;:22;;;33600:18;33619:12;:33;;;33600:53;;;;;;;;;;;;;;;;;;:66;;;:91;33599:102;;;;;;33590:111;;33719:62;33747:12;:33;;;33719:27;:62::i;:::-;:78;;;33712:85;;33808:19;33830:16;33839:6;33830:4;:8;;:16;;;;:::i;:::-;33808:38;;33954:9;34002:1;33966:12;:33;;;:37;33954:49;;33949:348;34009:12;:31;;;34005:1;:35;33949:348;;;34149:6;34109:18;34128:1;34109:21;;;;;;;;;;;;;;;;;;:36;;;34072:18;34091:1;34072:21;;;;;;;;;;;;;;;;;;:34;;;:73;34071:84;;;;;;34062:93;;34177:30;34205:1;34177:27;:30::i;:::-;:46;;;34170:53;;34252:33;34268:16;34277:6;34268:4;:8;;:16;;;;:::i;:::-;34252:11;:15;;:33;;;;:::i;:::-;34238:47;;34042:3;;;;;;;33949:348;;;;34579:6;34509:18;34528:12;:31;;;34509:51;;;;;;;;;;;;;;;;;;:66;;;34486:12;:20;;;:89;34485:100;;;;;;34476:109;;34603:60;34631:12;:31;;;34603:27;:60::i;:::-;:76;;;34596:83;;34704:33;34720:16;34731:4;34720:6;:10;;:16;;;;:::i;:::-;34704:11;:15;;:33;;;;:::i;:::-;34690:47;;34758:11;34771:13;34750:35;;;;;;;;32763:2030;;;;:::o;36340:334::-;36407:17;;:::i;:::-;36522:30;36555:27;:25;:27::i;:::-;:43;;;36522:76;;36618:12;:24;;36643:22;36618:48;;;;;;;;;;;;;;;;;;36611:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36340:334;:::o;1870:192::-;1956:7;1989:1;1984;:6;;1992:12;1976:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;1976:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2016:9;2032:1;2028;:5;2016:17;;2053:1;2046:8;;;1870:192;;;;;:::o;6178:193::-;6240:7;6361:1;6356;6352;:5;;;;;;6348:1;6344;:5;;;;;;:13;6343:19;;;;;;6337:1;6333;:5;;;;;;6327:1;6323;:5;;;;;;6322:17;:41;6315:48;;6178:193;;;;:::o;36682:206::-;36771:17;;:::i;:::-;36813:12;:24;;36838:18;36857:5;36838:25;;;;;;;;;;;;;;;;;;:41;;;36813:67;;;;;;;;;;;;;;;;;;36806:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36682:206;;;:::o;20010:18341::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;6997:810::-;7057:4;7510:16;7537:19;7559:66;7537:88;;;;7728:7;7716:20;7704:32;;7768:3;7756:15;;:8;:15;;:42;;;;;7787:11;7775:8;:23;;7756:42;7748:51;;;;6997:810;;;:::o

Swarm Source

bzzr://e356c1da018e02172721d0a92bceb5956202c0b037176d883376c9d2a99617b2

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

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