ETH Price: $2,431.49 (+0.88%)

Contract

0x09695a6DFf47B0053eF9553FEe49D2d833afA68b
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Transfer174553912023-06-11 7:28:23483 days ago1686468503IN
TheGraph: Crowdsale Address
0 ETH0.0004984814.90724932
Transfer157427722022-10-14 0:28:59723 days ago1665707339IN
TheGraph: Crowdsale Address
0 ETH0.0003364310
Transfer144050632022-03-17 16:21:00933 days ago1647534060IN
TheGraph: Crowdsale Address
0 ETH0.00503394149.62823065
Transfer120330612021-03-13 23:01:041302 days ago1615676464IN
TheGraph: Crowdsale Address
0.1 ETH0.00252120
Transfer120330542021-03-13 22:59:291302 days ago1615676369IN
TheGraph: Crowdsale Address
0.1 ETH0.002394114
Transfer119919072021-03-07 14:31:181308 days ago1615127478IN
TheGraph: Crowdsale Address
0 ETH0.00421942135
Transfer119418272021-02-27 21:40:501316 days ago1614462050IN
TheGraph: Crowdsale Address
0 ETH0.0028118790
Transfer119397852021-02-27 14:06:101316 days ago1614434770IN
TheGraph: Crowdsale Address
0.15 ETH0.002562122
Transfer119396132021-02-27 13:27:081317 days ago1614432428IN
TheGraph: Crowdsale Address
0.16897029 ETH0.00398515131
Transfer119396082021-02-27 13:25:461317 days ago1614432346IN
TheGraph: Crowdsale Address
0.19100272 ETH0.002793133
Transfer119396052021-02-27 13:23:491317 days ago1614432229IN
TheGraph: Crowdsale Address
0.19379572 ETH0.002793133
Transfer118512792021-02-13 23:41:071330 days ago1613259667IN
TheGraph: Crowdsale Address
0 ETH0.0031243100
Transfer118372872021-02-11 19:55:181332 days ago1613073318IN
TheGraph: Crowdsale Address
0 ETH0.00765267259
Transfer118372832021-02-11 19:54:531332 days ago1613073293IN
TheGraph: Crowdsale Address
0 ETH0.0076278259
Transfer117982142021-02-05 19:36:301338 days ago1612553790IN
TheGraph: Crowdsale Address
0 ETH0.0088605300
Transfer117980322021-02-05 18:51:421338 days ago1612551102IN
TheGraph: Crowdsale Address
0 ETH0.006200
Transfer117961462021-02-05 12:05:481339 days ago1612526748IN
TheGraph: Crowdsale Address
0 ETH0.00689112240
Transfer117656202021-01-31 19:09:231343 days ago1612120163IN
TheGraph: Crowdsale Address
0.04998523 ETH0.00174383
Transfer117572952021-01-30 12:32:261345 days ago1612009946IN
TheGraph: Crowdsale Address
0 ETH0.0026556585
Transfer117522082021-01-29 17:43:351345 days ago1611942215IN
TheGraph: Crowdsale Address
0 ETH0.00325052104
Transfer117521952021-01-29 17:40:481345 days ago1611942048IN
TheGraph: Crowdsale Address
0 ETH0.0050008160
Transfer117521782021-01-29 17:36:441345 days ago1611941804IN
TheGraph: Crowdsale Address
0 ETH0.00468825150
Transfer117366952021-01-27 8:21:101348 days ago1611735670IN
TheGraph: Crowdsale Address
0 ETH0.0029680895
Transfer117243932021-01-25 10:50:241350 days ago1611571824IN
TheGraph: Crowdsale Address
0 ETH0.0017502856
Transfer117032552021-01-22 4:50:041353 days ago1611291004IN
TheGraph: Crowdsale Address
0 ETH0.0028754692
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
111136462020-10-23 16:27:381443 days ago1603470458
TheGraph: Crowdsale Address
0.00000005 ETH
111136322020-10-23 16:25:161443 days ago1603470316
TheGraph: Crowdsale Address
5 wei
111136012020-10-23 16:19:191443 days ago1603469959
TheGraph: Crowdsale Address
0.0000007 ETH
111135942020-10-23 16:18:401443 days ago1603469920
TheGraph: Crowdsale Address
0.0000001 ETH
111135912020-10-23 16:18:351443 days ago1603469915
TheGraph: Crowdsale Address
0.00000001 ETH
111135912020-10-23 16:18:351443 days ago1603469915
TheGraph: Crowdsale Address
0.000003 ETH
111135912020-10-23 16:18:351443 days ago1603469915
TheGraph: Crowdsale Address
0.000001 ETH
111135872020-10-23 16:17:551443 days ago1603469875
TheGraph: Crowdsale Address
5 wei
111135862020-10-23 16:17:491443 days ago1603469869
TheGraph: Crowdsale Address
5 wei
111135862020-10-23 16:17:491443 days ago1603469869
TheGraph: Crowdsale Address
5 wei
111135862020-10-23 16:17:491443 days ago1603469869
TheGraph: Crowdsale Address
5 wei
111135862020-10-23 16:17:491443 days ago1603469869
TheGraph: Crowdsale Address
5 wei
111135862020-10-23 16:17:491443 days ago1603469869
TheGraph: Crowdsale Address
5 wei
111135862020-10-23 16:17:491443 days ago1603469869
TheGraph: Crowdsale Address
5 wei
111135862020-10-23 16:17:491443 days ago1603469869
TheGraph: Crowdsale Address
5 wei
111135842020-10-23 16:17:271443 days ago1603469847
TheGraph: Crowdsale Address
5 wei
111135842020-10-23 16:17:271443 days ago1603469847
TheGraph: Crowdsale Address
5 wei
111135842020-10-23 16:17:271443 days ago1603469847
TheGraph: Crowdsale Address
0.000003 ETH
111135782020-10-23 16:15:521443 days ago1603469752
TheGraph: Crowdsale Address
0.00001 ETH
111135712020-10-23 16:14:341443 days ago1603469674
TheGraph: Crowdsale Address
0.000002 ETH
111135692020-10-23 16:13:311443 days ago1603469611
TheGraph: Crowdsale Address
0.00002 ETH
111135642020-10-23 16:12:521443 days ago1603469572
TheGraph: Crowdsale Address
0.00016 ETH
111135632020-10-23 16:12:411443 days ago1603469561
TheGraph: Crowdsale Address
0.0002 ETH
111135622020-10-23 16:12:331443 days ago1603469553
TheGraph: Crowdsale Address
0.00008 ETH
111135612020-10-23 16:12:121443 days ago1603469532
TheGraph: Crowdsale Address
0.001 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
GraphSale

Compiler Version
v0.5.17+commit.d19bba13

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-10-22
*/

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

pragma solidity ^0.5.0;

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

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

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

// File: @openzeppelin/contracts/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: @openzeppelin/contracts/math/SafeMath.sol

pragma solidity ^0.5.0;

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

        return c;
    }

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

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

        return c;
    }

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

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

        return c;
    }

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

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

        return c;
    }

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

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

// File: @openzeppelin/contracts/utils/Address.sol

pragma solidity ^0.5.5;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is 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.
     *
     * Among others, `isContract` will return false for the following 
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // 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 != accountHash && codehash != 0x0);
    }

    /**
     * @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: @openzeppelin/contracts/token/ERC20/SafeERC20.sol

pragma solidity ^0.5.0;




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

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

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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts/utils/ReentrancyGuard.sol

pragma solidity ^0.5.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 *
 * _Since v2.5.0:_ this module is now much more gas efficient, given net gas
 * metering changes introduced in the Istanbul hardfork.
 */
contract ReentrancyGuard {
    bool private _notEntered;

    constructor () internal {
        // Storing an initial non-zero value makes deployment a bit more
        // expensive, but in exchange the refund on every call to nonReentrant
        // will be lower in amount. Since refunds are capped to a percetange of
        // the total transaction's gas, it is best to keep them low in cases
        // like this one, to increase the likelihood of the full refund coming
        // into effect.
        _notEntered = true;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_notEntered, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _notEntered = false;

        _;

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

// File: @openzeppelin/contracts/crowdsale/Crowdsale.sol

pragma solidity ^0.5.0;






/**
 * @title Crowdsale
 * @dev Crowdsale is a base contract for managing a token crowdsale,
 * allowing investors to purchase tokens with ether. This contract implements
 * such functionality in its most fundamental form and can be extended to provide additional
 * functionality and/or custom behavior.
 * The external interface represents the basic interface for purchasing tokens, and conforms
 * the base architecture for crowdsales. It is *not* intended to be modified / overridden.
 * The internal interface conforms the extensible and modifiable surface of crowdsales. Override
 * the methods to add functionality. Consider using 'super' where appropriate to concatenate
 * behavior.
 */
contract Crowdsale is Context, ReentrancyGuard {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    // The token being sold
    IERC20 private _token;

    // Address where funds are collected
    address payable private _wallet;

    // How many token units a buyer gets per wei.
    // The rate is the conversion between wei and the smallest and indivisible token unit.
    // So, if you are using a rate of 1 with a ERC20Detailed token with 3 decimals called TOK
    // 1 wei will give you 1 unit, or 0.001 TOK.
    uint256 private _rate;

    // Amount of wei raised
    uint256 private _weiRaised;

    /**
     * Event for token purchase logging
     * @param purchaser who paid for the tokens
     * @param beneficiary who got the tokens
     * @param value weis paid for purchase
     * @param amount amount of tokens purchased
     */
    event TokensPurchased(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);

    /**
     * @param rate Number of token units a buyer gets per wei
     * @dev The rate is the conversion between wei and the smallest and indivisible
     * token unit. So, if you are using a rate of 1 with a ERC20Detailed token
     * with 3 decimals called TOK, 1 wei will give you 1 unit, or 0.001 TOK.
     * @param wallet Address where collected funds will be forwarded to
     * @param token Address of the token being sold
     */
    constructor (uint256 rate, address payable wallet, IERC20 token) public {
        require(rate > 0, "Crowdsale: rate is 0");
        require(wallet != address(0), "Crowdsale: wallet is the zero address");
        require(address(token) != address(0), "Crowdsale: token is the zero address");

        _rate = rate;
        _wallet = wallet;
        _token = token;
    }

    /**
     * @dev fallback function ***DO NOT OVERRIDE***
     * Note that other contracts will transfer funds with a base gas stipend
     * of 2300, which is not enough to call buyTokens. Consider calling
     * buyTokens directly when purchasing tokens from a contract.
     */
    function () external payable {
        buyTokens(_msgSender());
    }

    /**
     * @return the token being sold.
     */
    function token() public view returns (IERC20) {
        return _token;
    }

    /**
     * @return the address where funds are collected.
     */
    function wallet() public view returns (address payable) {
        return _wallet;
    }

    /**
     * @return the number of token units a buyer gets per wei.
     */
    function rate() public view returns (uint256) {
        return _rate;
    }

    /**
     * @return the amount of wei raised.
     */
    function weiRaised() public view returns (uint256) {
        return _weiRaised;
    }

    /**
     * @dev low level token purchase ***DO NOT OVERRIDE***
     * This function has a non-reentrancy guard, so it shouldn't be called by
     * another `nonReentrant` function.
     * @param beneficiary Recipient of the token purchase
     */
    function buyTokens(address beneficiary) public nonReentrant payable {
        uint256 weiAmount = msg.value;
        _preValidatePurchase(beneficiary, weiAmount);

        // calculate token amount to be created
        uint256 tokens = _getTokenAmount(weiAmount);

        // update state
        _weiRaised = _weiRaised.add(weiAmount);

        _processPurchase(beneficiary, tokens);
        emit TokensPurchased(_msgSender(), beneficiary, weiAmount, tokens);

        _updatePurchasingState(beneficiary, weiAmount);

        _forwardFunds();
        _postValidatePurchase(beneficiary, weiAmount);
    }

    /**
     * @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met.
     * Use `super` in contracts that inherit from Crowdsale to extend their validations.
     * Example from CappedCrowdsale.sol's _preValidatePurchase method:
     *     super._preValidatePurchase(beneficiary, weiAmount);
     *     require(weiRaised().add(weiAmount) <= cap);
     * @param beneficiary Address performing the token purchase
     * @param weiAmount Value in wei involved in the purchase
     */
    function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
        require(beneficiary != address(0), "Crowdsale: beneficiary is the zero address");
        require(weiAmount != 0, "Crowdsale: weiAmount is 0");
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
    }

    /**
     * @dev Validation of an executed purchase. Observe state and use revert statements to undo rollback when valid
     * conditions are not met.
     * @param beneficiary Address performing the token purchase
     * @param weiAmount Value in wei involved in the purchase
     */
    function _postValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
        // solhint-disable-previous-line no-empty-blocks
    }

    /**
     * @dev Source of tokens. Override this method to modify the way in which the crowdsale ultimately gets and sends
     * its tokens.
     * @param beneficiary Address performing the token purchase
     * @param tokenAmount Number of tokens to be emitted
     */
    function _deliverTokens(address beneficiary, uint256 tokenAmount) internal {
        _token.safeTransfer(beneficiary, tokenAmount);
    }

    /**
     * @dev Executed when a purchase has been validated and is ready to be executed. Doesn't necessarily emit/send
     * tokens.
     * @param beneficiary Address receiving the tokens
     * @param tokenAmount Number of tokens to be purchased
     */
    function _processPurchase(address beneficiary, uint256 tokenAmount) internal {
        _deliverTokens(beneficiary, tokenAmount);
    }

    /**
     * @dev Override for extensions that require an internal state to check for validity (current user contributions,
     * etc.)
     * @param beneficiary Address receiving the tokens
     * @param weiAmount Value in wei involved in the purchase
     */
    function _updatePurchasingState(address beneficiary, uint256 weiAmount) internal {
        // solhint-disable-previous-line no-empty-blocks
    }

    /**
     * @dev Override to extend the way in which ether is converted to tokens.
     * @param weiAmount Value in wei to be converted into tokens
     * @return Number of tokens that can be purchased with the specified _weiAmount
     */
    function _getTokenAmount(uint256 weiAmount) internal view returns (uint256) {
        return weiAmount.mul(_rate);
    }

    /**
     * @dev Determines how ETH is stored/forwarded on purchases.
     */
    function _forwardFunds() internal {
        _wallet.transfer(msg.value);
    }
}

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

pragma solidity ^0.5.0;

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

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

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

// File: @openzeppelin/contracts/crowdsale/emission/AllowanceCrowdsale.sol

pragma solidity ^0.5.0;






/**
 * @title AllowanceCrowdsale
 * @dev Extension of Crowdsale where tokens are held by a wallet, which approves an allowance to the crowdsale.
 */
contract AllowanceCrowdsale is Crowdsale {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    address private _tokenWallet;

    /**
     * @dev Constructor, takes token wallet address.
     * @param tokenWallet Address holding the tokens, which has approved allowance to the crowdsale.
     */
    constructor (address tokenWallet) public {
        require(tokenWallet != address(0), "AllowanceCrowdsale: token wallet is the zero address");
        _tokenWallet = tokenWallet;
    }

    /**
     * @return the address of the wallet that will hold the tokens.
     */
    function tokenWallet() public view returns (address) {
        return _tokenWallet;
    }

    /**
     * @dev Checks the amount of tokens left in the allowance.
     * @return Amount of tokens left in the allowance
     */
    function remainingTokens() public view returns (uint256) {
        return Math.min(token().balanceOf(_tokenWallet), token().allowance(_tokenWallet, address(this)));
    }

    /**
     * @dev Overrides parent behavior by transferring tokens from wallet.
     * @param beneficiary Token purchaser
     * @param tokenAmount Amount of tokens purchased
     */
    function _deliverTokens(address beneficiary, uint256 tokenAmount) internal {
        token().safeTransferFrom(_tokenWallet, beneficiary, tokenAmount);
    }
}

// File: @openzeppelin/contracts/crowdsale/validation/CappedCrowdsale.sol

pragma solidity ^0.5.0;



/**
 * @title CappedCrowdsale
 * @dev Crowdsale with a limit for total contributions.
 */
contract CappedCrowdsale is Crowdsale {
    using SafeMath for uint256;

    uint256 private _cap;

    /**
     * @dev Constructor, takes maximum amount of wei accepted in the crowdsale.
     * @param cap Max amount of wei to be contributed
     */
    constructor (uint256 cap) public {
        require(cap > 0, "CappedCrowdsale: cap is 0");
        _cap = cap;
    }

    /**
     * @return the cap of the crowdsale.
     */
    function cap() public view returns (uint256) {
        return _cap;
    }

    /**
     * @dev Checks whether the cap has been reached.
     * @return Whether the cap was reached
     */
    function capReached() public view returns (bool) {
        return weiRaised() >= _cap;
    }

    /**
     * @dev Extend parent behavior requiring purchase to respect the funding cap.
     * @param beneficiary Token purchaser
     * @param weiAmount Amount of wei contributed
     */
    function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
        super._preValidatePurchase(beneficiary, weiAmount);
        require(weiRaised().add(weiAmount) <= _cap, "CappedCrowdsale: cap exceeded");
    }
}

// File: @openzeppelin/contracts/crowdsale/validation/TimedCrowdsale.sol

pragma solidity ^0.5.0;



/**
 * @title TimedCrowdsale
 * @dev Crowdsale accepting contributions only within a time frame.
 */
contract TimedCrowdsale is Crowdsale {
    using SafeMath for uint256;

    uint256 private _openingTime;
    uint256 private _closingTime;

    /**
     * Event for crowdsale extending
     * @param newClosingTime new closing time
     * @param prevClosingTime old closing time
     */
    event TimedCrowdsaleExtended(uint256 prevClosingTime, uint256 newClosingTime);

    /**
     * @dev Reverts if not in crowdsale time range.
     */
    modifier onlyWhileOpen {
        require(isOpen(), "TimedCrowdsale: not open");
        _;
    }

    /**
     * @dev Constructor, takes crowdsale opening and closing times.
     * @param openingTime Crowdsale opening time
     * @param closingTime Crowdsale closing time
     */
    constructor (uint256 openingTime, uint256 closingTime) public {
        // solhint-disable-next-line not-rely-on-time
        require(openingTime >= block.timestamp, "TimedCrowdsale: opening time is before current time");
        // solhint-disable-next-line max-line-length
        require(closingTime > openingTime, "TimedCrowdsale: opening time is not before closing time");

        _openingTime = openingTime;
        _closingTime = closingTime;
    }

    /**
     * @return the crowdsale opening time.
     */
    function openingTime() public view returns (uint256) {
        return _openingTime;
    }

    /**
     * @return the crowdsale closing time.
     */
    function closingTime() public view returns (uint256) {
        return _closingTime;
    }

    /**
     * @return true if the crowdsale is open, false otherwise.
     */
    function isOpen() public view returns (bool) {
        // solhint-disable-next-line not-rely-on-time
        return block.timestamp >= _openingTime && block.timestamp <= _closingTime;
    }

    /**
     * @dev Checks whether the period in which the crowdsale is open has already elapsed.
     * @return Whether crowdsale period has elapsed
     */
    function hasClosed() public view returns (bool) {
        // solhint-disable-next-line not-rely-on-time
        return block.timestamp > _closingTime;
    }

    /**
     * @dev Extend parent behavior requiring to be within contributing period.
     * @param beneficiary Token purchaser
     * @param weiAmount Amount of wei contributed
     */
    function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal onlyWhileOpen view {
        super._preValidatePurchase(beneficiary, weiAmount);
    }

    /**
     * @dev Extend crowdsale.
     * @param newClosingTime Crowdsale closing time
     */
    function _extendTime(uint256 newClosingTime) internal {
        require(!hasClosed(), "TimedCrowdsale: already closed");
        // solhint-disable-next-line max-line-length
        require(newClosingTime > _closingTime, "TimedCrowdsale: new closing time is before current closing time");

        emit TimedCrowdsaleExtended(_closingTime, newClosingTime);
        _closingTime = newClosingTime;
    }
}

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

pragma solidity ^0.5.0;

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.5.0;

/**
 * @dev A Secondary contract can only be used by its primary account (the one that created it).
 */
contract Secondary is Context {
    address private _primary;

    /**
     * @dev Emitted when the primary contract changes.
     */
    event PrimaryTransferred(
        address recipient
    );

    /**
     * @dev Sets the primary account to the one that is creating the Secondary contract.
     */
    constructor () internal {
        address msgSender = _msgSender();
        _primary = msgSender;
        emit PrimaryTransferred(msgSender);
    }

    /**
     * @dev Reverts if called from any account other than the primary.
     */
    modifier onlyPrimary() {
        require(_msgSender() == _primary, "Secondary: caller is not the primary account");
        _;
    }

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

    /**
     * @dev Transfers contract to a new primary.
     * @param recipient The address of new primary.
     */
    function transferPrimary(address recipient) public onlyPrimary {
        require(recipient != address(0), "Secondary: new primary is the zero address");
        _primary = recipient;
        emit PrimaryTransferred(recipient);
    }
}

// File: contracts/sale/GraphSale.sol

pragma solidity ^0.5.17;






contract GraphSale is Ownable, AllowanceCrowdsale, CappedCrowdsale, TimedCrowdsale {
    using SafeMath for uint256;

    enum Phase { NotStarted, One, Two, Three, Closed }
    enum AllowStatus {
        Disallowed,
        Phase1Cap1,
        Phase1Cap2,
        Phase1Cap3,
        Phase1Cap4,
        Phase2Cap1,
        Phase2Cap2,
        Phase2Cap3,
        Phase2Cap4
    }

    uint256 private constant MAX_UINT = 2**256 - 1;

    // -- State --

    uint256 private _maxGasPriceWei;

    // Allow list
    mapping(address => AllowStatus) private _allowList;

    // Account capping
    uint256[4] private _capsPerAccount; // Contribution caps that are assigned to each account
    mapping(address => uint256) private _contributions; // Contributions from an account

    // Time conditions
    uint256 private _openingTimePhase2; // opening time (phase2) in unix epoch seconds
    uint256 private _openingTimePhase3; // opening time (phase3) in unix epoch seconds

    // Post delivery
    mapping(address => uint256) private _balances;
    __unstable__TokenVault private _vault;

    // -- Events --

    event AllowListUpdated(address indexed account, AllowStatus value);

    event GraphSaleDeployed(
        uint256 rate, // rate, in TKNbits
        address payable wallet, // wallet to send Ether
        address tokenWallet, // wallet to pull tokens
        IERC20 token, // the token
        uint256 cap, // total cap, in wei
        uint256 capPerAccount1, // limit for individual contribution, in wei
        uint256 capPerAccount2, // limit for individual contribution, in wei
        uint256 capPerAccount3, // limit for individual contribution, in wei
        uint256 capPerAccount4, // limit for individual contribution, in wei
        uint256 openingTimePhase1, // opening time (phase1) in unix epoch seconds
        uint256 openingTimePhase2, // opening time (phase2) in unix epoch seconds
        uint256 openingTimePhase3, // opening time (phase3) in unix epoch seconds
        uint256 closingTime, // closing time in unix epoch seconds
        uint256 maxGasPriceWei // max gas price allowed for purchase transacctions (in wei)
    );

    event MaxGasPriceUpdated(uint256 maxGasPriceWei);

    event CapsPerAccount(
        uint256 capPerAccount1,
        uint256 capPerAccount2,
        uint256 capPerAccount3,
        uint256 capPerAccount4
    );

    /**
     * @dev Constructor.
     */
    constructor(
        uint256 rate, // rate, in TKNbits
        address payable wallet, // wallet to send Ether
        address tokenWallet, // wallet to pull tokens
        IERC20 token, // the token
        uint256 cap, // total cap, in wei
        uint256[4] memory capsPerAccount,
        uint256 openingTimePhase1, // opening time (phase1) in unix epoch seconds
        uint256 openingTimePhase2, // opening time (phase2) in unix epoch seconds
        uint256 openingTimePhase3, // opening time (phase3) in unix epoch seconds
        uint256 closingTime, // closing time in unix epoch seconds
        uint256 maxGasPriceWei // max gas price allowed for transactions (wei)
    )
        public
        Crowdsale(rate, wallet, token)
        CappedCrowdsale(cap)
        TimedCrowdsale(openingTimePhase1, closingTime)
        AllowanceCrowdsale(tokenWallet)
    {
        require(
            openingTimePhase2 > openingTimePhase1,
            "PhasedCrowdsale: phase2 must be after phase1"
        );
        require(
            openingTimePhase3 > openingTimePhase2,
            "PhasedCrowdsale: phase3 must be after phase2"
        );
        require(
            closingTime > openingTimePhase3,
            "PhasedCrowdsale: closing time must be after phase3"
        );

        require(maxGasPriceWei > 0, "Gas price cannot be zero");

        _setCapsPerAccount(capsPerAccount);
        _setMaxGasPrice(maxGasPriceWei);

        _openingTimePhase2 = openingTimePhase2;
        _openingTimePhase3 = openingTimePhase3;
        _vault = new __unstable__TokenVault();

        emit GraphSaleDeployed(
            rate,
            wallet,
            tokenWallet,
            token,
            cap,
            _capsPerAccount[0],
            _capsPerAccount[1],
            _capsPerAccount[2],
            _capsPerAccount[3],
            openingTimePhase1,
            openingTimePhase2,
            openingTimePhase3,
            closingTime,
            maxGasPriceWei
        );
    }

    // -- Configuration --

    /**
     * @dev Set the max allowed gas price for purchase transactions.
     * @param maxGasPriceWei Amount of wei to be used as max gas price.
     */
    function setMaxGasPrice(uint256 maxGasPriceWei) external onlyOwner {
        _setMaxGasPrice(maxGasPriceWei);
    }

    /**
     * @dev Internal: Set the max allowed gas price for purchase transactions.
     * @param maxGasPriceWei Amount of wei to be used as max gas price.
     */
    function _setMaxGasPrice(uint256 maxGasPriceWei) internal {
        require(maxGasPriceWei > 0, "Gas price cannot be zero");
        _maxGasPriceWei = maxGasPriceWei;
        emit MaxGasPriceUpdated(_maxGasPriceWei);
    }

    /**
     * @dev Get the max allowed gas price for purchase transactions.
     * @return Maximum gas price allowed for purchase transactions.
     */
    function maxGasPrice() public view returns (uint256) {
        return _maxGasPriceWei;
    }

    // -- Phases --

    function openingTimePhase2() public view returns (uint256) {
        return _openingTimePhase2;
    }

    function openingTimePhase3() public view returns (uint256) {
        return _openingTimePhase3;
    }

    /**
     * @dev Returns the current sale phase.
     * @return Phase
     */
    function getCurrentPhase() public view returns (Phase) {
        uint256 current = block.timestamp;
        if (current >= openingTime() && current < _openingTimePhase2) {
            return Phase.One;
        }
        if (current >= _openingTimePhase2 && current < _openingTimePhase3) {
            return Phase.Two;
        }
        if (current >= _openingTimePhase3 && current < closingTime()) {
            return Phase.Three;
        }
        if (current >= closingTime()) {
            return Phase.Closed;
        }
        return Phase.NotStarted;
    }

    // -- Allowlist --

    /**
     * @dev Return the allow status of an account.
     * @param account Address to check.
     */
    function getAllowStatus(address account) public view returns (AllowStatus) {
        return _allowList[account];
    }

    /**
     * @dev Return true if the account is authorized to participate in the crowdsale.
     * @param account Address to check.
     */
    function isAllowed(address account) public view returns (bool) {
        return getAllowStatus(account) != AllowStatus.Disallowed;
    }

    /**
     * @dev Return true if the account is currently allowed to participate.
     * @param account Address to check.
     */
    function isCurrentPhaseAllowed(address account) public view returns (bool) {
        AllowStatus status = _allowList[account];
        Phase phase = getCurrentPhase();

        // Only priority accounts can participate in Phase1
        if (phase == Phase.One) {
            return
                status == AllowStatus.Phase1Cap1 ||
                status == AllowStatus.Phase1Cap2 ||
                status == AllowStatus.Phase1Cap3 ||
                status == AllowStatus.Phase1Cap4;
        }

        // After Phase1 anyone in the allowlist can participate
        if (phase == Phase.Two || phase == Phase.Three) {
            return status != AllowStatus.Disallowed;
        }

        return false;
    }

    /**
     * @dev Set multiple accounts to the allowlist.
     * @param accounts Addresses to load on the allowlist.
     */
    function setAllowListMany(address[] calldata accounts, AllowStatus status) external onlyOwner {
        for (uint256 i = 0; i < accounts.length; i++) {
            _allowList[accounts[i]] = status;
            emit AllowListUpdated(accounts[i], status);
        }
    }

    // -- Account Capping --

    /**
     * @dev Returns the cap of individual beneficiary at the current phase.
     * @return Current cap for individual beneficiary
     */
    function getCapPerAccount(address account) public view returns (uint256) {
        AllowStatus status = _allowList[account];

        // Return the cap only if allowed to participate in current phase
        if (isCurrentPhaseAllowed(account)) {
            // No cap on Phase 3 regardless of account
            if (getCurrentPhase() == Phase.Three) {
                return MAX_UINT;
            }

            // cap1
            if (status == AllowStatus.Phase1Cap1 || status == AllowStatus.Phase2Cap1) {
                return _capsPerAccount[0];
            }
            // cap2
            if (status == AllowStatus.Phase1Cap2 || status == AllowStatus.Phase2Cap2) {
                return _capsPerAccount[1];
            }
            // cap3
            if (status == AllowStatus.Phase1Cap3 || status == AllowStatus.Phase2Cap3) {
                return _capsPerAccount[2];
            }
            // cap4
            if (status == AllowStatus.Phase1Cap4 || status == AllowStatus.Phase2Cap4) {
                return _capsPerAccount[3];
            }
        }
        return 0;
    }

    /**
     * @dev Sets the maximum contribution of all the individual beneficiaries.
     * @param capsPerAccount Array of wei limit for individual contribution for each cap tier
     */
    function setCapsPerAccount(uint256[4] calldata capsPerAccount) external onlyOwner {
        _setCapsPerAccount(capsPerAccount);
    }

    /**
     * @dev Internal: Sets the maximum contribution of all the individual beneficiaries.
     * @param capsPerAccount Array of wei limit for individual contribution for each cap tier
     */
    function _setCapsPerAccount(uint256[4] memory capsPerAccount) private {
        require(block.timestamp < openingTime(), "Can only update before start");
        for (uint256 i = 0; i < capsPerAccount.length; i++) {
            require(capsPerAccount[i] > 0, "AccountCappedCrowdsale: capPerAccount is 0");
        }
        require(capsPerAccount[0] > capsPerAccount[1], "Must be cap1 > cap2");
        require(capsPerAccount[1] > capsPerAccount[2], "Must be cap2 > cap3");
        require(capsPerAccount[2] > capsPerAccount[3], "Must be cap3 > cap4");

        _capsPerAccount = capsPerAccount;

        emit CapsPerAccount(
            _capsPerAccount[0],
            _capsPerAccount[1],
            _capsPerAccount[2],
            _capsPerAccount[3]
        );
    }

    /**
     * @dev Returns the maximum contribution for each cap tier.
     * @return Maximum contribution per account tier
     */
    function getCapsPerAccount()
        external
        view
        returns (
            uint256,
            uint256,
            uint256,
            uint256
        )
    {
        return (_capsPerAccount[0], _capsPerAccount[1], _capsPerAccount[2], _capsPerAccount[3]);
    }

    /**
     * @dev Returns the amount contributed so far by a specific beneficiary.
     * @param beneficiary Address of contributor
     * @return Beneficiary contribution so far
     */
    function getContribution(address beneficiary) public view returns (uint256) {
        return _contributions[beneficiary];
    }

    // -- Post Delivery --

    /**
     * @return the balance of an account.
     */
    function balanceOf(address account) public view returns (uint256) {
        return _balances[account];
    }

    // -- Hooks --

    /**
     * @dev Extend parent behavior to update beneficiary contributions.
     * @param beneficiary Token purchaser
     * @param weiAmount Amount of wei contributed
     */
    function _updatePurchasingState(address beneficiary, uint256 weiAmount) internal {
        super._updatePurchasingState(beneficiary, weiAmount);
        _contributions[beneficiary] = _contributions[beneficiary].add(weiAmount);
    }

    /**
     * @dev Overrides parent by storing due balances, and delivering tokens to the vault instead of the end user. This
     * ensures that the tokens will be available by the time they are withdrawn (which may not be the case if
     * `_deliverTokens` was called later).
     * @param beneficiary Token purchaser
     * @param tokenAmount Amount of tokens purchased
     */
    function _processPurchase(address beneficiary, uint256 tokenAmount) internal {
        _balances[beneficiary] = _balances[beneficiary].add(tokenAmount);
        _deliverTokens(address(_vault), tokenAmount);
    }

    /**
     * @dev Extend parent behavior requiring purchase to respect the beneficiary's funding cap.
     * Extend parent behavior requiring beneficiary to be allowlisted.
     * @param beneficiary Token purchaser
     * @param weiAmount Amount of wei contributed
     */
    function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
        require(tx.gasprice <= _maxGasPriceWei, "Gas price over limit");

        super._preValidatePurchase(beneficiary, weiAmount);
        require(
            isCurrentPhaseAllowed(beneficiary),
            "AllowListCrowdsale: beneficiary is not allowed in this phase"
        );
        require(
            _contributions[beneficiary].add(weiAmount) <= getCapPerAccount(beneficiary),
            "AccountCappedCrowdsale: beneficiary's cap exceeded"
        );
    }
}

/**
 * @title __unstable__TokenVault
 * @dev Similar to an Escrow for tokens, this contract allows its primary account to spend its tokens as it sees fit.
 * This contract is an internal helper for PostDeliveryCrowdsale, and should not be used outside of this context.
 */
// solhint-disable-next-line contract-name-camelcase
contract __unstable__TokenVault is Secondary {
    function transfer(
        IERC20 token,
        address to,
        uint256 amount
    ) public onlyPrimary {
        token.transfer(to, amount);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"rate","type":"uint256"},{"internalType":"address payable","name":"wallet","type":"address"},{"internalType":"address","name":"tokenWallet","type":"address"},{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"cap","type":"uint256"},{"internalType":"uint256[4]","name":"capsPerAccount","type":"uint256[4]"},{"internalType":"uint256","name":"openingTimePhase1","type":"uint256"},{"internalType":"uint256","name":"openingTimePhase2","type":"uint256"},{"internalType":"uint256","name":"openingTimePhase3","type":"uint256"},{"internalType":"uint256","name":"closingTime","type":"uint256"},{"internalType":"uint256","name":"maxGasPriceWei","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"enum GraphSale.AllowStatus","name":"value","type":"uint8"}],"name":"AllowListUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"capPerAccount1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"capPerAccount2","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"capPerAccount3","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"capPerAccount4","type":"uint256"}],"name":"CapsPerAccount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"rate","type":"uint256"},{"indexed":false,"internalType":"address payable","name":"wallet","type":"address"},{"indexed":false,"internalType":"address","name":"tokenWallet","type":"address"},{"indexed":false,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"cap","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"capPerAccount1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"capPerAccount2","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"capPerAccount3","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"capPerAccount4","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"openingTimePhase1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"openingTimePhase2","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"openingTimePhase3","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"closingTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxGasPriceWei","type":"uint256"}],"name":"GraphSaleDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxGasPriceWei","type":"uint256"}],"name":"MaxGasPriceUpdated","type":"event"},{"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":"uint256","name":"prevClosingTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newClosingTime","type":"uint256"}],"name":"TimedCrowdsaleExtended","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"purchaser","type":"address"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensPurchased","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"beneficiary","type":"address"}],"name":"buyTokens","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"cap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"capReached","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"closingTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getAllowStatus","outputs":[{"internalType":"enum GraphSale.AllowStatus","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getCapPerAccount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCapsPerAccount","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":[{"internalType":"address","name":"beneficiary","type":"address"}],"name":"getContribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentPhase","outputs":[{"internalType":"enum GraphSale.Phase","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"hasClosed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isCurrentPhaseAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxGasPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"openingTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"openingTimePhase2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"openingTimePhase3","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":true,"inputs":[],"name":"rate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"remainingTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"enum GraphSale.AllowStatus","name":"status","type":"uint8"}],"name":"setAllowListMany","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256[4]","name":"capsPerAccount","type":"uint256[4]"}],"name":"setCapsPerAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"maxGasPriceWei","type":"uint256"}],"name":"setMaxGasPrice","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":true,"inputs":[],"name":"tokenWallet","outputs":[{"internalType":"address","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":true,"inputs":[],"name":"wallet","outputs":[{"internalType":"address payable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"weiRaised","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b50604051620029e3380380620029e383398181016040526101c08110156200003857600080fd5b50805160208201516040830151606084015160808501516101208601516101408701516101608801516101808901516101a08a01519899979896979596949560a001948482888b8e8e8d6000620000976001600160e01b03620005aa16565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506000805460ff60a01b1916600160a01b1790558262000147576040805162461bcd60e51b815260206004820152601460248201527f43726f776473616c653a20726174652069732030000000000000000000000000604482015290519081900360640190fd5b6001600160a01b0382166200018e5760405162461bcd60e51b8152600401808060200182810382526025815260200180620029be6025913960400191505060405180910390fd5b6001600160a01b038116620001d55760405162461bcd60e51b8152600401808060200182810382526024815260200180620029686024913960400191505060405180910390fd5b600392909255600280546001600160a01b03199081166001600160a01b0393841617909155600180549091169282169290921790915581166200024a5760405162461bcd60e51b8152600401808060200182810382526034815260200180620028a76034913960400191505060405180910390fd5b600580546001600160a01b0319166001600160a01b039290921691909117905580620002bd576040805162461bcd60e51b815260206004820152601960248201527f43617070656443726f776473616c653a20636170206973203000000000000000604482015290519081900360640190fd5b60065542821015620003015760405162461bcd60e51b8152600401808060200182810382526033815260200180620028486033913960400191505060405180910390fd5b818111620003415760405162461bcd60e51b8152600401808060200182810382526037815260200180620029056037913960400191505060405180910390fd5b6007919091556008558484116200038a5760405162461bcd60e51b815260040180806020018281038252602c8152602001806200287b602c913960400191505060405180910390fd5b838311620003ca5760405162461bcd60e51b815260040180806020018281038252602c8152602001806200293c602c913960400191505060405180910390fd5b8282116200040a5760405162461bcd60e51b81526004018080602001828103825260328152602001806200298c6032913960400191505060405180910390fd5b6000811162000460576040805162461bcd60e51b815260206004820152601860248201527f4761732070726963652063616e6e6f74206265207a65726f0000000000000000604482015290519081900360640190fd5b62000474866001600160e01b03620005af16565b62000488816001600160e01b03620007f816565b60108490556011839055604051620004a0906200088f565b604051809103906000f080158015620004bd573d6000803e3d6000fd5b50601380546001600160a01b0319166001600160a01b03929092169190911790557fc78bd77e11414ab013c53d6378eaa4b902e42799f34169f7c305e6ea35fa839c8b8b8b8b8b600b60000154600b60010154600b60020154600b6003015460408051998a526001600160a01b0398891660208b015296881689880152949096166060880152608087019290925260a086015260c085015260e084019290925261010083019190915261012082018890526101408201879052610160820186905261018082018590526101a0820184905251908190036101c00190a15050505050505050505050620008fd565b335b90565b620005c26001600160e01b036200088916565b421062000616576040805162461bcd60e51b815260206004820152601c60248201527f43616e206f6e6c7920757064617465206265666f726520737461727400000000604482015290519081900360640190fd5b60005b60048110156200067e5760008282600481106200063257fe5b602002015111620006755760405162461bcd60e51b815260040180806020018281038252602a815260200180620028db602a913960400191505060405180910390fd5b60010162000619565b506020810151815111620006d9576040805162461bcd60e51b815260206004820152601360248201527f4d7573742062652063617031203e206361703200000000000000000000000000604482015290519081900360640190fd5b604081015160208201511162000736576040805162461bcd60e51b815260206004820152601360248201527f4d7573742062652063617032203e206361703300000000000000000000000000604482015290519081900360640190fd5b606081015160408201511162000793576040805162461bcd60e51b815260206004820152601360248201527f4d7573742062652063617033203e206361703400000000000000000000000000604482015290519081900360640190fd5b620007a2600b8260046200089d565b50600b54600c54600d54600e54604080519485526020850193909352838301919091526060830152517fac48558b0e9678802742f8b28678a03a783c3b6ecf7ba7f274d05677f09d7d9e9181900360800190a150565b600081116200084e576040805162461bcd60e51b815260206004820152601860248201527f4761732070726963652063616e6e6f74206265207a65726f0000000000000000604482015290519081900360640190fd5b60098190556040805182815290517fa7a07f821dfdfca8e4baa9ccc4bbe7b782baac5946918bd19f1c9c761db414109181900360200190a150565b60075490565b6103c7806200248183390190565b8260048101928215620008ce579160200282015b82811115620008ce578251825591602001919060010190620008b1565b50620008dc929150620008e0565b5090565b620005ac91905b80821115620008dc5760008155600101620008e7565b611b74806200090d6000396000f3fe6080604052600436106101d85760003560e01c806387684edd11610102578063bff99c6c11610095578063ec8ac4d811610064578063ec8ac4d8146105d7578063f2fde38b146105fd578063fb7a6fc914610630578063fc0c546a14610673576101d8565b8063bff99c6c14610550578063d1d6f79514610565578063d2fa635e1461057a578063d33937b5146105a4576101d8565b8063a3a40ea5116100d1578063a3a40ea5146104ba578063b7a8807c146104f3578063babcc53914610508578063bf5839031461053b576101d8565b806387684edd146103e75780638a255e18146104105780638da5cb5b146104905780638f32d59b146104a5576101d8565b80634042b66f1161017a578063521eb27311610149578063521eb273146103595780636acf456f1461038a57806370a082311461039f578063715018a6146103d2576101d8565b80634042b66f1461030557806347535d7b1461031a5780634b6753bc1461032f5780634f93594514610344576101d8565b80632c4e722e116101b65780632c4e722e1461028b57806334d0c19f146102a0578063355274ea146102db5780633de39c11146102f0576101d8565b806304f46aae146101ea5780631515bc2b1461023157806321eff7fc14610246575b6101e86101e3610688565b61068d565b005b3480156101f657600080fd5b5061021d6004803603602081101561020d57600080fd5b50356001600160a01b03166107bf565b604080519115158252519081900360200190f35b34801561023d57600080fd5b5061021d6108a3565b34801561025257600080fd5b506102796004803603602081101561026957600080fd5b50356001600160a01b03166108ab565b60408051918252519081900360200190f35b34801561029757600080fd5b506102796108c6565b3480156102ac57600080fd5b506102b56108cc565b604080519485526020850193909352838301919091526060830152519081900360800190f35b3480156102e757600080fd5b506102796108e0565b3480156102fc57600080fd5b506102796108e6565b34801561031157600080fd5b506102796108ec565b34801561032657600080fd5b5061021d6108f2565b34801561033b57600080fd5b5061027961090d565b34801561035057600080fd5b5061021d610913565b34801561036557600080fd5b5061036e610927565b604080516001600160a01b039092168252519081900360200190f35b34801561039657600080fd5b50610279610936565b3480156103ab57600080fd5b50610279600480360360208110156103c257600080fd5b50356001600160a01b031661093c565b3480156103de57600080fd5b506101e8610957565b3480156103f357600080fd5b506101e86004803603608081101561040a57600080fd5b506109e8565b34801561041c57600080fd5b506101e86004803603604081101561043357600080fd5b81019060208101813564010000000081111561044e57600080fd5b82018360208201111561046057600080fd5b8035906020019184602083028401116401000000008311171561048257600080fd5b91935091503560ff16610a60565b34801561049c57600080fd5b5061036e610b76565b3480156104b157600080fd5b5061021d610b85565b3480156104c657600080fd5b506104cf610ba9565b604051808260048111156104df57fe5b60ff16815260200191505060405180910390f35b3480156104ff57600080fd5b50610279610c3c565b34801561051457600080fd5b5061021d6004803603602081101561052b57600080fd5b50356001600160a01b0316610c42565b34801561054757600080fd5b50610279610c61565b34801561055c57600080fd5b5061036e610d75565b34801561057157600080fd5b50610279610d84565b34801561058657600080fd5b506101e86004803603602081101561059d57600080fd5b5035610d8a565b3480156105b057600080fd5b50610279600480360360208110156105c757600080fd5b50356001600160a01b0316610dda565b6101e8600480360360208110156105ed57600080fd5b50356001600160a01b031661068d565b34801561060957600080fd5b506101e86004803603602081101561062057600080fd5b50356001600160a01b0316610f05565b34801561063c57600080fd5b506106636004803603602081101561065357600080fd5b50356001600160a01b0316610f55565b604051808260088111156104df57fe5b34801561067f57600080fd5b5061036e610f73565b335b90565b600054600160a01b900460ff166106eb576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6000805460ff60a01b19169055346107038282610f82565b600061070e82611091565b600454909150610724908363ffffffff6110ae16565b600455610731838261110f565b826001600160a01b0316610743610688565b6001600160a01b03167f6faf93231a456e552dbc9961f58d9713ee4f2e69d15f1975b050ef0911053a7b8484604051808381526020018281526020019250505060405180910390a36107958383611163565b61079d6111b6565b6107a7838361108d565b50506000805460ff60a01b1916600160a01b17905550565b6001600160a01b0381166000908152600a602052604081205460ff16816107e4610ba9565b905060018160048111156107f457fe5b141561085457600182600881111561080857fe5b148061081f5750600282600881111561081d57fe5b145b806108355750600382600881111561083357fe5b145b8061084b5750600482600881111561084957fe5b145b9250505061089e565b600281600481111561086257fe5b14806108795750600381600481111561087757fe5b145b1561089757600082600881111561088c57fe5b14159250505061089e565b6000925050505b919050565b600854421190565b6001600160a01b03166000908152600f602052604090205490565b60035490565b600b54600c54600d54600e54929391929091565b60065490565b60095490565b60045490565b6000600754421015801561090857506008544211155b905090565b60085490565b60006006546109206108ec565b1015905090565b6002546001600160a01b031690565b60105490565b6001600160a01b031660009081526012602052604090205490565b61095f610b85565b61099e576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5e833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6109f0610b85565b610a2f576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5e833981519152604482015290519081900360640190fd5b604080516080818101909252610a5d91839060049083908390808284376000920191909152506111ef915050565b50565b610a68610b85565b610aa7576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5e833981519152604482015290519081900360640190fd5b60005b82811015610b705781600a6000868685818110610ac357fe5b602090810292909201356001600160a01b0316835250810191909152604001600020805460ff19166001836008811115610af957fe5b0217905550838382818110610b0a57fe5b905060200201356001600160a01b03166001600160a01b03167fa0fb7eb8e0cf6265ba16fae5a2966c1221ca80e6e9ae3f796616751e49692d158360405180826008811115610b5557fe5b60ff16815260200191505060405180910390a2600101610aaa565b50505050565b6000546001600160a01b031690565b600080546001600160a01b0316610b9a610688565b6001600160a01b031614905090565b600042610bb4610c3c565b8110158015610bc4575060105481105b15610bd357600191505061068a565b6010548110158015610be6575060115481105b15610bf557600291505061068a565b6011548110158015610c0d5750610c0a61090d565b81105b15610c1c57600391505061068a565b610c2461090d565b8110610c3457600491505061068a565b600091505090565b60075490565b600080610c4e83610f55565b6008811115610c5957fe5b141592915050565b6000610908610c6e610f73565b600554604080516370a0823160e01b81526001600160a01b039283166004820152905192909116916370a0823191602480820192602092909190829003018186803b158015610cbc57600080fd5b505afa158015610cd0573d6000803e3d6000fd5b505050506040513d6020811015610ce657600080fd5b5051610cf0610f73565b60055460408051636eb1769f60e11b81526001600160a01b0392831660048201523060248201529051929091169163dd62ed3e91604480820192602092909190829003018186803b158015610d4457600080fd5b505afa158015610d58573d6000803e3d6000fd5b505050506040513d6020811015610d6e57600080fd5b5051611404565b6005546001600160a01b031690565b60115490565b610d92610b85565b610dd1576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5e833981519152604482015290519081900360640190fd5b610a5d8161141a565b6001600160a01b0381166000908152600a602052604081205460ff16610dff836107bf565b15610efc576003610e0e610ba9565b6004811115610e1957fe5b1415610e2a5760001991505061089e565b6001816008811115610e3857fe5b1480610e4f57506005816008811115610e4d57fe5b145b15610e6357600b60005b015491505061089e565b6002816008811115610e7157fe5b1480610e8857506006816008811115610e8657fe5b145b15610e9657600b6001610e59565b6003816008811115610ea457fe5b1480610ebb57506007816008811115610eb957fe5b145b15610ec957600b6002610e59565b6004816008811115610ed757fe5b1480610eee57506008816008811115610eec57fe5b145b15610efc57600b6003610e59565b50600092915050565b610f0d610b85565b610f4c576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5e833981519152604482015290519081900360640190fd5b610a5d816114aa565b6001600160a01b03166000908152600a602052604090205460ff1690565b6001546001600160a01b031690565b6009543a1115610fd0576040805162461bcd60e51b815260206004820152601460248201527311d85cc81c1c9a58d9481bdd995c881b1a5b5a5d60621b604482015290519081900360640190fd5b610fda828261154a565b610fe3826107bf565b61101e5760405162461bcd60e51b815260040180806020018281038252603c815260200180611a7e603c913960400191505060405180910390fd5b61102782610dda565b6001600160a01b0383166000908152600f6020526040902054611050908363ffffffff6110ae16565b111561108d5760405162461bcd60e51b8152600401808060200182810382526032815260200180611b0e6032913960400191505060405180910390fd5b5050565b60006110a8600354836115ad90919063ffffffff16565b92915050565b600082820183811015611108576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216600090815260126020526040902054611138908263ffffffff6110ae16565b6001600160a01b0380841660009081526012602052604090209190915560135461108d911682611606565b61116d828261108d565b6001600160a01b0382166000908152600f6020526040902054611196908263ffffffff6110ae16565b6001600160a01b039092166000908152600f602052604090209190915550565b6002546040516001600160a01b03909116903480156108fc02916000818181858888f19350505050158015610a5d573d6000803e3d6000fd5b6111f7610c3c565b421061124a576040805162461bcd60e51b815260206004820152601c60248201527f43616e206f6e6c7920757064617465206265666f726520737461727400000000604482015290519081900360640190fd5b60005b60048110156112ad57600082826004811061126457fe5b6020020151116112a55760405162461bcd60e51b815260040180806020018281038252602a815260200180611a13602a913960400191505060405180910390fd5b60010161124d565b5060208101518151116112fd576040805162461bcd60e51b815260206004820152601360248201527226bab9ba1031329031b0b818901f1031b0b81960691b604482015290519081900360640190fd5b604081015160208201511161134f576040805162461bcd60e51b81526020600482015260136024820152724d7573742062652063617032203e206361703360681b604482015290519081900360640190fd5b60608101516040820151116113a1576040805162461bcd60e51b8152602060048201526013602482015272135d5cdd0818994818d85c0cc80f8818d85c0d606a1b604482015290519081900360640190fd5b6113ae600b826004611994565b50600b54600c54600d54600e54604080519485526020850193909352838301919091526060830152517fac48558b0e9678802742f8b28678a03a783c3b6ecf7ba7f274d05677f09d7d9e9181900360800190a150565b60008183106114135781611108565b5090919050565b6000811161146f576040805162461bcd60e51b815260206004820152601860248201527f4761732070726963652063616e6e6f74206265207a65726f0000000000000000604482015290519081900360640190fd5b60098190556040805182815290517fa7a07f821dfdfca8e4baa9ccc4bbe7b782baac5946918bd19f1c9c761db414109181900360200190a150565b6001600160a01b0381166114ef5760405162461bcd60e51b81526004018080602001828103825260268152602001806119ed6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6115526108f2565b6115a3576040805162461bcd60e51b815260206004820152601860248201527f54696d656443726f776473616c653a206e6f74206f70656e0000000000000000604482015290519081900360640190fd5b61108d8282611637565b6000826115bc575060006110a8565b828202828482816115c957fe5b04146111085760405162461bcd60e51b8152600401808060200182810382526021815260200180611a3d6021913960400191505060405180910390fd5b60055461108d906001600160a01b03168383611620610f73565b6001600160a01b031692919063ffffffff6116af16565b6116418282611709565b60065461165c826116506108ec565b9063ffffffff6110ae16565b111561108d576040805162461bcd60e51b815260206004820152601d60248201527f43617070656443726f776473616c653a20636170206578636565646564000000604482015290519081900360640190fd5b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052610b709085906117a0565b6001600160a01b03821661174e5760405162461bcd60e51b815260040180806020018281038252602a815260200180611aba602a913960400191505060405180910390fd5b8061108d576040805162461bcd60e51b815260206004820152601960248201527f43726f776473616c653a20776569416d6f756e74206973203000000000000000604482015290519081900360640190fd5b6117b2826001600160a01b0316611958565b611803576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106118415780518252601f199092019160209182019101611822565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146118a3576040519150601f19603f3d011682016040523d82523d6000602084013e6118a8565b606091505b5091509150816118ff576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115610b705780806020019051602081101561191b57600080fd5b5051610b705760405162461bcd60e51b815260040180806020018281038252602a815260200180611ae4602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061198c57508115155b949350505050565b82600481019282156119c2579160200282015b828111156119c25782518255916020019190600101906119a7565b506119ce9291506119d2565b5090565b61068a91905b808211156119ce57600081556001016119d856fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734163636f756e7443617070656443726f776473616c653a206361705065724163636f756e742069732030536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572416c6c6f774c69737443726f776473616c653a2062656e6566696369617279206973206e6f7420616c6c6f77656420696e207468697320706861736543726f776473616c653a2062656e656669636961727920697320746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565644163636f756e7443617070656443726f776473616c653a2062656e6566696369617279277320636170206578636565646564a265627a7a7231582057af88b0766458abf65c30607b00d9ec7864de1aa389ab43dec01ab32e1aaceb64736f6c63430005110032608060405260006100176001600160e01b0361007216565b600080546001600160a01b0383166001600160a01b0319909116811790915560408051918252519192507f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d9919081900360200190a150610076565b3390565b610342806100856000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80632348238c14610046578063beabacc81461006e578063c6dbdf61146100a4575b600080fd5b61006c6004803603602081101561005c57600080fd5b50356001600160a01b03166100c8565b005b61006c6004803603606081101561008457600080fd5b506001600160a01b038135811691602081013590911690604001356101ba565b6100ac6102a4565b604080516001600160a01b039092168252519081900360200190f35b6000546001600160a01b03166100dc6102b3565b6001600160a01b0316146101215760405162461bcd60e51b815260040180806020018281038252602c8152602001806102e2602c913960400191505060405180910390fd5b6001600160a01b0381166101665760405162461bcd60e51b815260040180806020018281038252602a8152602001806102b8602a913960400191505060405180910390fd5b600080546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d99181900360200190a150565b6000546001600160a01b03166101ce6102b3565b6001600160a01b0316146102135760405162461bcd60e51b815260040180806020018281038252602c8152602001806102e2602c913960400191505060405180910390fd5b826001600160a01b031663a9059cbb83836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561027357600080fd5b505af1158015610287573d6000803e3d6000fd5b505050506040513d602081101561029d57600080fd5b5050505050565b6000546001600160a01b031690565b339056fe5365636f6e646172793a206e6577207072696d61727920697320746865207a65726f20616464726573735365636f6e646172793a2063616c6c6572206973206e6f7420746865207072696d617279206163636f756e74a265627a7a723158206926fb617509bc8881a5ce13c10829db21bff09ac2e105181895d7d9fe2b803e64736f6c6343000511003254696d656443726f776473616c653a206f70656e696e672074696d65206973206265666f72652063757272656e742074696d6550686173656443726f776473616c653a20706861736532206d75737420626520616674657220706861736531416c6c6f77616e636543726f776473616c653a20746f6b656e2077616c6c657420697320746865207a65726f20616464726573734163636f756e7443617070656443726f776473616c653a206361705065724163636f756e74206973203054696d656443726f776473616c653a206f70656e696e672074696d65206973206e6f74206265666f726520636c6f73696e672074696d6550686173656443726f776473616c653a20706861736533206d7573742062652061667465722070686173653243726f776473616c653a20746f6b656e20697320746865207a65726f206164647265737350686173656443726f776473616c653a20636c6f73696e672074696d65206d7573742062652061667465722070686173653343726f776473616c653a2077616c6c657420697320746865207a65726f2061646472657373000000000000000000000000000000000000000000000000000000000000317a0000000000000000000000006fc78dcc8a949d1530035bd577dcb21e9787100e0000000000000000000000006fc78dcc8a949d1530035bd577dcb21e9787100e0000000000000000000000005d96113bac24d0b24f73d4cbb27b65ca7e559e100000000000000000000000000000000000000000000006affcff60406b990071000000000000000000000000000000000000000000000000b6a1b6467c24000000000000000000000000000000000000000000000000000092221335acdd000000000000000000000000000000000000000000000000000048ff46219e8e0000000000000000000000000000000000000000000000000000247fa310cf470000000000000000000000000000000000000000000000000000000000005f91ac80000000000000000000000000000000000000000000000000000000005f92fe00000000000000000000000000000000000000000000000000000000005f944f80000000000000000000000000000000000000000000000000000000005f95a1000000000000000000000000000000000000000000000000000000002e90edd000

Deployed Bytecode

0x6080604052600436106101d85760003560e01c806387684edd11610102578063bff99c6c11610095578063ec8ac4d811610064578063ec8ac4d8146105d7578063f2fde38b146105fd578063fb7a6fc914610630578063fc0c546a14610673576101d8565b8063bff99c6c14610550578063d1d6f79514610565578063d2fa635e1461057a578063d33937b5146105a4576101d8565b8063a3a40ea5116100d1578063a3a40ea5146104ba578063b7a8807c146104f3578063babcc53914610508578063bf5839031461053b576101d8565b806387684edd146103e75780638a255e18146104105780638da5cb5b146104905780638f32d59b146104a5576101d8565b80634042b66f1161017a578063521eb27311610149578063521eb273146103595780636acf456f1461038a57806370a082311461039f578063715018a6146103d2576101d8565b80634042b66f1461030557806347535d7b1461031a5780634b6753bc1461032f5780634f93594514610344576101d8565b80632c4e722e116101b65780632c4e722e1461028b57806334d0c19f146102a0578063355274ea146102db5780633de39c11146102f0576101d8565b806304f46aae146101ea5780631515bc2b1461023157806321eff7fc14610246575b6101e86101e3610688565b61068d565b005b3480156101f657600080fd5b5061021d6004803603602081101561020d57600080fd5b50356001600160a01b03166107bf565b604080519115158252519081900360200190f35b34801561023d57600080fd5b5061021d6108a3565b34801561025257600080fd5b506102796004803603602081101561026957600080fd5b50356001600160a01b03166108ab565b60408051918252519081900360200190f35b34801561029757600080fd5b506102796108c6565b3480156102ac57600080fd5b506102b56108cc565b604080519485526020850193909352838301919091526060830152519081900360800190f35b3480156102e757600080fd5b506102796108e0565b3480156102fc57600080fd5b506102796108e6565b34801561031157600080fd5b506102796108ec565b34801561032657600080fd5b5061021d6108f2565b34801561033b57600080fd5b5061027961090d565b34801561035057600080fd5b5061021d610913565b34801561036557600080fd5b5061036e610927565b604080516001600160a01b039092168252519081900360200190f35b34801561039657600080fd5b50610279610936565b3480156103ab57600080fd5b50610279600480360360208110156103c257600080fd5b50356001600160a01b031661093c565b3480156103de57600080fd5b506101e8610957565b3480156103f357600080fd5b506101e86004803603608081101561040a57600080fd5b506109e8565b34801561041c57600080fd5b506101e86004803603604081101561043357600080fd5b81019060208101813564010000000081111561044e57600080fd5b82018360208201111561046057600080fd5b8035906020019184602083028401116401000000008311171561048257600080fd5b91935091503560ff16610a60565b34801561049c57600080fd5b5061036e610b76565b3480156104b157600080fd5b5061021d610b85565b3480156104c657600080fd5b506104cf610ba9565b604051808260048111156104df57fe5b60ff16815260200191505060405180910390f35b3480156104ff57600080fd5b50610279610c3c565b34801561051457600080fd5b5061021d6004803603602081101561052b57600080fd5b50356001600160a01b0316610c42565b34801561054757600080fd5b50610279610c61565b34801561055c57600080fd5b5061036e610d75565b34801561057157600080fd5b50610279610d84565b34801561058657600080fd5b506101e86004803603602081101561059d57600080fd5b5035610d8a565b3480156105b057600080fd5b50610279600480360360208110156105c757600080fd5b50356001600160a01b0316610dda565b6101e8600480360360208110156105ed57600080fd5b50356001600160a01b031661068d565b34801561060957600080fd5b506101e86004803603602081101561062057600080fd5b50356001600160a01b0316610f05565b34801561063c57600080fd5b506106636004803603602081101561065357600080fd5b50356001600160a01b0316610f55565b604051808260088111156104df57fe5b34801561067f57600080fd5b5061036e610f73565b335b90565b600054600160a01b900460ff166106eb576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6000805460ff60a01b19169055346107038282610f82565b600061070e82611091565b600454909150610724908363ffffffff6110ae16565b600455610731838261110f565b826001600160a01b0316610743610688565b6001600160a01b03167f6faf93231a456e552dbc9961f58d9713ee4f2e69d15f1975b050ef0911053a7b8484604051808381526020018281526020019250505060405180910390a36107958383611163565b61079d6111b6565b6107a7838361108d565b50506000805460ff60a01b1916600160a01b17905550565b6001600160a01b0381166000908152600a602052604081205460ff16816107e4610ba9565b905060018160048111156107f457fe5b141561085457600182600881111561080857fe5b148061081f5750600282600881111561081d57fe5b145b806108355750600382600881111561083357fe5b145b8061084b5750600482600881111561084957fe5b145b9250505061089e565b600281600481111561086257fe5b14806108795750600381600481111561087757fe5b145b1561089757600082600881111561088c57fe5b14159250505061089e565b6000925050505b919050565b600854421190565b6001600160a01b03166000908152600f602052604090205490565b60035490565b600b54600c54600d54600e54929391929091565b60065490565b60095490565b60045490565b6000600754421015801561090857506008544211155b905090565b60085490565b60006006546109206108ec565b1015905090565b6002546001600160a01b031690565b60105490565b6001600160a01b031660009081526012602052604090205490565b61095f610b85565b61099e576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5e833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6109f0610b85565b610a2f576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5e833981519152604482015290519081900360640190fd5b604080516080818101909252610a5d91839060049083908390808284376000920191909152506111ef915050565b50565b610a68610b85565b610aa7576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5e833981519152604482015290519081900360640190fd5b60005b82811015610b705781600a6000868685818110610ac357fe5b602090810292909201356001600160a01b0316835250810191909152604001600020805460ff19166001836008811115610af957fe5b0217905550838382818110610b0a57fe5b905060200201356001600160a01b03166001600160a01b03167fa0fb7eb8e0cf6265ba16fae5a2966c1221ca80e6e9ae3f796616751e49692d158360405180826008811115610b5557fe5b60ff16815260200191505060405180910390a2600101610aaa565b50505050565b6000546001600160a01b031690565b600080546001600160a01b0316610b9a610688565b6001600160a01b031614905090565b600042610bb4610c3c565b8110158015610bc4575060105481105b15610bd357600191505061068a565b6010548110158015610be6575060115481105b15610bf557600291505061068a565b6011548110158015610c0d5750610c0a61090d565b81105b15610c1c57600391505061068a565b610c2461090d565b8110610c3457600491505061068a565b600091505090565b60075490565b600080610c4e83610f55565b6008811115610c5957fe5b141592915050565b6000610908610c6e610f73565b600554604080516370a0823160e01b81526001600160a01b039283166004820152905192909116916370a0823191602480820192602092909190829003018186803b158015610cbc57600080fd5b505afa158015610cd0573d6000803e3d6000fd5b505050506040513d6020811015610ce657600080fd5b5051610cf0610f73565b60055460408051636eb1769f60e11b81526001600160a01b0392831660048201523060248201529051929091169163dd62ed3e91604480820192602092909190829003018186803b158015610d4457600080fd5b505afa158015610d58573d6000803e3d6000fd5b505050506040513d6020811015610d6e57600080fd5b5051611404565b6005546001600160a01b031690565b60115490565b610d92610b85565b610dd1576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5e833981519152604482015290519081900360640190fd5b610a5d8161141a565b6001600160a01b0381166000908152600a602052604081205460ff16610dff836107bf565b15610efc576003610e0e610ba9565b6004811115610e1957fe5b1415610e2a5760001991505061089e565b6001816008811115610e3857fe5b1480610e4f57506005816008811115610e4d57fe5b145b15610e6357600b60005b015491505061089e565b6002816008811115610e7157fe5b1480610e8857506006816008811115610e8657fe5b145b15610e9657600b6001610e59565b6003816008811115610ea457fe5b1480610ebb57506007816008811115610eb957fe5b145b15610ec957600b6002610e59565b6004816008811115610ed757fe5b1480610eee57506008816008811115610eec57fe5b145b15610efc57600b6003610e59565b50600092915050565b610f0d610b85565b610f4c576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5e833981519152604482015290519081900360640190fd5b610a5d816114aa565b6001600160a01b03166000908152600a602052604090205460ff1690565b6001546001600160a01b031690565b6009543a1115610fd0576040805162461bcd60e51b815260206004820152601460248201527311d85cc81c1c9a58d9481bdd995c881b1a5b5a5d60621b604482015290519081900360640190fd5b610fda828261154a565b610fe3826107bf565b61101e5760405162461bcd60e51b815260040180806020018281038252603c815260200180611a7e603c913960400191505060405180910390fd5b61102782610dda565b6001600160a01b0383166000908152600f6020526040902054611050908363ffffffff6110ae16565b111561108d5760405162461bcd60e51b8152600401808060200182810382526032815260200180611b0e6032913960400191505060405180910390fd5b5050565b60006110a8600354836115ad90919063ffffffff16565b92915050565b600082820183811015611108576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216600090815260126020526040902054611138908263ffffffff6110ae16565b6001600160a01b0380841660009081526012602052604090209190915560135461108d911682611606565b61116d828261108d565b6001600160a01b0382166000908152600f6020526040902054611196908263ffffffff6110ae16565b6001600160a01b039092166000908152600f602052604090209190915550565b6002546040516001600160a01b03909116903480156108fc02916000818181858888f19350505050158015610a5d573d6000803e3d6000fd5b6111f7610c3c565b421061124a576040805162461bcd60e51b815260206004820152601c60248201527f43616e206f6e6c7920757064617465206265666f726520737461727400000000604482015290519081900360640190fd5b60005b60048110156112ad57600082826004811061126457fe5b6020020151116112a55760405162461bcd60e51b815260040180806020018281038252602a815260200180611a13602a913960400191505060405180910390fd5b60010161124d565b5060208101518151116112fd576040805162461bcd60e51b815260206004820152601360248201527226bab9ba1031329031b0b818901f1031b0b81960691b604482015290519081900360640190fd5b604081015160208201511161134f576040805162461bcd60e51b81526020600482015260136024820152724d7573742062652063617032203e206361703360681b604482015290519081900360640190fd5b60608101516040820151116113a1576040805162461bcd60e51b8152602060048201526013602482015272135d5cdd0818994818d85c0cc80f8818d85c0d606a1b604482015290519081900360640190fd5b6113ae600b826004611994565b50600b54600c54600d54600e54604080519485526020850193909352838301919091526060830152517fac48558b0e9678802742f8b28678a03a783c3b6ecf7ba7f274d05677f09d7d9e9181900360800190a150565b60008183106114135781611108565b5090919050565b6000811161146f576040805162461bcd60e51b815260206004820152601860248201527f4761732070726963652063616e6e6f74206265207a65726f0000000000000000604482015290519081900360640190fd5b60098190556040805182815290517fa7a07f821dfdfca8e4baa9ccc4bbe7b782baac5946918bd19f1c9c761db414109181900360200190a150565b6001600160a01b0381166114ef5760405162461bcd60e51b81526004018080602001828103825260268152602001806119ed6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6115526108f2565b6115a3576040805162461bcd60e51b815260206004820152601860248201527f54696d656443726f776473616c653a206e6f74206f70656e0000000000000000604482015290519081900360640190fd5b61108d8282611637565b6000826115bc575060006110a8565b828202828482816115c957fe5b04146111085760405162461bcd60e51b8152600401808060200182810382526021815260200180611a3d6021913960400191505060405180910390fd5b60055461108d906001600160a01b03168383611620610f73565b6001600160a01b031692919063ffffffff6116af16565b6116418282611709565b60065461165c826116506108ec565b9063ffffffff6110ae16565b111561108d576040805162461bcd60e51b815260206004820152601d60248201527f43617070656443726f776473616c653a20636170206578636565646564000000604482015290519081900360640190fd5b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052610b709085906117a0565b6001600160a01b03821661174e5760405162461bcd60e51b815260040180806020018281038252602a815260200180611aba602a913960400191505060405180910390fd5b8061108d576040805162461bcd60e51b815260206004820152601960248201527f43726f776473616c653a20776569416d6f756e74206973203000000000000000604482015290519081900360640190fd5b6117b2826001600160a01b0316611958565b611803576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106118415780518252601f199092019160209182019101611822565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146118a3576040519150601f19603f3d011682016040523d82523d6000602084013e6118a8565b606091505b5091509150816118ff576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115610b705780806020019051602081101561191b57600080fd5b5051610b705760405162461bcd60e51b815260040180806020018281038252602a815260200180611ae4602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061198c57508115155b949350505050565b82600481019282156119c2579160200282015b828111156119c25782518255916020019190600101906119a7565b506119ce9291506119d2565b5090565b61068a91905b808211156119ce57600081556001016119d856fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734163636f756e7443617070656443726f776473616c653a206361705065724163636f756e742069732030536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572416c6c6f774c69737443726f776473616c653a2062656e6566696369617279206973206e6f7420616c6c6f77656420696e207468697320706861736543726f776473616c653a2062656e656669636961727920697320746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565644163636f756e7443617070656443726f776473616c653a2062656e6566696369617279277320636170206578636565646564a265627a7a7231582057af88b0766458abf65c30607b00d9ec7864de1aa389ab43dec01ab32e1aaceb64736f6c63430005110032

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

000000000000000000000000000000000000000000000000000000000000317a0000000000000000000000006fc78dcc8a949d1530035bd577dcb21e9787100e0000000000000000000000006fc78dcc8a949d1530035bd577dcb21e9787100e0000000000000000000000005d96113bac24d0b24f73d4cbb27b65ca7e559e100000000000000000000000000000000000000000000006affcff60406b990071000000000000000000000000000000000000000000000000b6a1b6467c24000000000000000000000000000000000000000000000000000092221335acdd000000000000000000000000000000000000000000000000000048ff46219e8e0000000000000000000000000000000000000000000000000000247fa310cf470000000000000000000000000000000000000000000000000000000000005f91ac80000000000000000000000000000000000000000000000000000000005f92fe00000000000000000000000000000000000000000000000000000000005f944f80000000000000000000000000000000000000000000000000000000005f95a1000000000000000000000000000000000000000000000000000000002e90edd000

-----Decoded View---------------
Arg [0] : rate (uint256): 12666
Arg [1] : wallet (address): 0x6fc78dcc8A949d1530035bD577DCB21e9787100e
Arg [2] : tokenWallet (address): 0x6fc78dcc8A949d1530035bD577DCB21e9787100e
Arg [3] : token (address): 0x5D96113baC24d0B24F73d4CBB27b65Ca7E559E10
Arg [4] : cap (uint256): 31580609505763461234801
Arg [5] : capsPerAccount (uint256[4]): 13160000000000000000,10530000000000000000,5260000000000000000,2630000000000000000
Arg [6] : openingTimePhase1 (uint256): 1603382400
Arg [7] : openingTimePhase2 (uint256): 1603468800
Arg [8] : openingTimePhase3 (uint256): 1603555200
Arg [9] : closingTime (uint256): 1603641600
Arg [10] : maxGasPriceWei (uint256): 200000000000

-----Encoded View---------------
14 Constructor Arguments found :
Arg [0] : 000000000000000000000000000000000000000000000000000000000000317a
Arg [1] : 0000000000000000000000006fc78dcc8a949d1530035bd577dcb21e9787100e
Arg [2] : 0000000000000000000000006fc78dcc8a949d1530035bd577dcb21e9787100e
Arg [3] : 0000000000000000000000005d96113bac24d0b24f73d4cbb27b65ca7e559e10
Arg [4] : 0000000000000000000000000000000000000000000006affcff60406b990071
Arg [5] : 000000000000000000000000000000000000000000000000b6a1b6467c240000
Arg [6] : 00000000000000000000000000000000000000000000000092221335acdd0000
Arg [7] : 00000000000000000000000000000000000000000000000048ff46219e8e0000
Arg [8] : 000000000000000000000000000000000000000000000000247fa310cf470000
Arg [9] : 000000000000000000000000000000000000000000000000000000005f91ac80
Arg [10] : 000000000000000000000000000000000000000000000000000000005f92fe00
Arg [11] : 000000000000000000000000000000000000000000000000000000005f944f80
Arg [12] : 000000000000000000000000000000000000000000000000000000005f95a100
Arg [13] : 0000000000000000000000000000000000000000000000000000002e90edd000


Deployed Bytecode Sourcemap

37754:13834:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21836:23;21846:12;:10;:12::i;:::-;21836:9;:23::i;:::-;37754:13834;44900:731;;8:9:-1;5:2;;;30:1;27;20:12;5:2;44900:731:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;44900:731:0;-1:-1:-1;;;;;44900:731:0;;:::i;:::-;;;;;;;;;;;;;;;;;;32688:159;;8:9:-1;5:2;;;30:1;27;20:12;5:2;32688:159:0;;;:::i;49325:129::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49325:129:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;49325:129:0;-1:-1:-1;;;;;49325:129:0;;:::i;:::-;;;;;;;;;;;;;;;;22269:77;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22269:77:0;;;:::i;48834:289::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48834:289:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29742:75;;8:9:-1;5:2;;;30:1;27;20:12;5:2;29742:75:0;;;:::i;43188:94::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;43188:94:0;;;:::i;22414:87::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22414:87:0;;;:::i;32326:192::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;32326:192:0;;;:::i;32145:91::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;32145:91:0;;;:::i;29941:94::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;29941:94:0;;;:::i;22090:89::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22090:89:0;;;:::i;:::-;;;;-1:-1:-1;;;;;22090:89:0;;;;;;;;;;;;;;43313:103;;8:9:-1;5:2;;;30:1;27;20:12;5:2;43313:103:0;;;:::i;49553:110::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49553:110:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;49553:110:0;-1:-1:-1;;;;;49553:110:0;;:::i;35506:140::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;35506:140:0;;;:::i;47557:135::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;47557:135:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;47557:135:0;:::i;45770:274::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;45770:274:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;45770:274:0;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;45770:274:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;45770:274: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;45770:274:0;;-1:-1:-1;45770:274:0;-1:-1:-1;45770:274:0;;;;:::i;34695:79::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;34695:79:0;;;:::i;35061:94::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;35061:94:0;;;:::i;43620:579::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;43620:579:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31984:91;;8:9:-1;5:2;;;30:1;27;20:12;5:2;31984:91:0;;;:::i;44618:138::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;44618:138:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;44618:138:0;-1:-1:-1;;;;;44618:138:0;;:::i;28556:172::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;28556:172:0;;;:::i;28320:91::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;28320:91:0;;;:::i;43424:103::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;43424:103:0;;;:::i;42501:117::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;42501:117:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;42501:117:0;;:::i;46234:1122::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;46234:1122:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;46234:1122:0;-1:-1:-1;;;;;46234:1122:0;;:::i;22766:622::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;22766:622:0;-1:-1:-1;;;;;22766:622:0;;:::i;35801:109::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;35801:109:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;35801:109:0;-1:-1:-1;;;;;35801:109:0;;:::i;44344:120::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;44344:120:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;44344:120:0;-1:-1:-1;;;;;44344:120:0;;:::i;:::-;;;;;;;;;;;;21931:78;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21931:78:0;;;:::i;858:98::-;938:10;858:98;;:::o;22766:622::-;18519:11;;-1:-1:-1;;;18519:11:0;;;;18511:55;;;;;-1:-1:-1;;;18511:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;18658:5;18644:19;;-1:-1:-1;;;;18644:19:0;;;22865:9;22885:44;22906:11;22865:9;22885:20;:44::i;:::-;22991:14;23008:26;23024:9;23008:15;:26::i;:::-;23085:10;;22991:43;;-1:-1:-1;23085:25:0;;23100:9;23085:25;:14;:25;:::i;:::-;23072:10;:38;23123:37;23140:11;23153:6;23123:16;:37::i;:::-;23206:11;-1:-1:-1;;;;;23176:61:0;23192:12;:10;:12::i;:::-;-1:-1:-1;;;;;23176:61:0;;23219:9;23230:6;23176:61;;;;;;;;;;;;;;;;;;;;;;;;23250:46;23273:11;23286:9;23250:22;:46::i;:::-;23309:15;:13;:15::i;:::-;23335:45;23357:11;23370:9;23335:21;:45::i;:::-;-1:-1:-1;;18824:11:0;:18;;-1:-1:-1;;;;18824:18:0;-1:-1:-1;;;18824:18:0;;;-1:-1:-1;22766:622:0:o;44900:731::-;-1:-1:-1;;;;;45007:19:0;;44969:4;45007:19;;;:10;:19;;;;;;;;44969:4;45051:17;:15;:17::i;:::-;45037:31;-1:-1:-1;45155:9:0;45146:5;:18;;;;;;;;;45142:266;;;45215:22;45205:6;:32;;;;;;;;;:85;;;-1:-1:-1;45268:22:0;45258:6;:32;;;;;;;;;45205:85;:138;;;-1:-1:-1;45321:22:0;45311:6;:32;;;;;;;;;45205:138;:191;;;-1:-1:-1;45374:22:0;45364:6;:32;;;;;;;;;45205:191;45181:215;;;;;;45142:266;45498:9;45489:5;:18;;;;;;;;;:42;;;-1:-1:-1;45520:11:0;45511:5;:20;;;;;;;;;45489:42;45485:114;;;45565:22;45555:6;:32;;;;;;;;;;45548:39;;;;;;45485:114;45618:5;45611:12;;;;44900:731;;;;:::o;32688:159::-;32827:12;;32809:15;:30;32688:159;:::o;49325:129::-;-1:-1:-1;;;;;49419:27:0;49392:7;49419:27;;;:14;:27;;;;;;;49325:129::o;22269:77::-;22333:5;;22269:77;:::o;48834:289::-;49036:15;:18;49056;;49076;;49096;;49036;;49056;;49076;;48834:289::o;29742:75::-;29805:4;;29742:75;:::o;43188:94::-;43259:15;;43188:94;:::o;22414:87::-;22483:10;;22414:87;:::o;32326:192::-;32365:4;32463:12;;32444:15;:31;;:66;;;;;32498:12;;32479:15;:31;;32444:66;32437:73;;32326:192;:::o;32145:91::-;32216:12;;32145:91;:::o;29941:94::-;29984:4;30023;;30008:11;:9;:11::i;:::-;:19;;30001:26;;29941:94;:::o;22090:89::-;22164:7;;-1:-1:-1;;;;;22164:7:0;22090:89;:::o;43313:103::-;43390:18;;43313:103;:::o;49553:110::-;-1:-1:-1;;;;;49637:18:0;49610:7;49637:18;;;:9;:18;;;;;;;49553:110::o;35506:140::-;34907:9;:7;:9::i;:::-;34899:54;;;;;-1:-1:-1;;;34899:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;34899:54:0;;;;;;;;;;;;;;;35605:1;35589:6;;35568:40;;-1:-1:-1;;;;;35589:6:0;;;;35568:40;;35605:1;;35568:40;35636:1;35619:19;;-1:-1:-1;;;;;;35619:19:0;;;35506:140::o;47557:135::-;34907:9;:7;:9::i;:::-;34899:54;;;;;-1:-1:-1;;;34899:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;34899:54:0;;;;;;;;;;;;;;;47650:34;;;;;;;;;;;;47669:14;;47650:34;;;;47669:14;;47650:34;47669:14;47650:34;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;47650:18:0;;-1:-1:-1;;47650:34:0:i;:::-;47557:135;:::o;45770:274::-;34907:9;:7;:9::i;:::-;34899:54;;;;;-1:-1:-1;;;34899:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;34899:54:0;;;;;;;;;;;;;;;45880:9;45875:162;45895:19;;;45875:162;;;45962:6;45936:10;:23;45947:8;;45956:1;45947:11;;;;;;;;;;;;;;;;-1:-1:-1;;;;;45947:11:0;45936:23;;-1:-1:-1;45936:23:0;;;;;;;;-1:-1:-1;45936:23:0;:32;;-1:-1:-1;;45936:32:0;;;;;;;;;;;;;;;;46005:8;;46014:1;46005:11;;;;;;;;;;;;;-1:-1:-1;;;;;46005:11:0;-1:-1:-1;;;;;45988:37:0;;46018:6;45988:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;45916:3;;45875:162;;;;45770:274;;;:::o;34695:79::-;34733:7;34760:6;-1:-1:-1;;;;;34760:6:0;34695:79;:::o;35061:94::-;35101:4;35141:6;;-1:-1:-1;;;;;35141:6:0;35125:12;:10;:12::i;:::-;-1:-1:-1;;;;;35125:22:0;;35118:29;;35061:94;:::o;43620:579::-;43668:5;43704:15;43745:13;:11;:13::i;:::-;43734:7;:24;;:56;;;;;43772:18;;43762:7;:28;43734:56;43730:105;;;43814:9;43807:16;;;;;43730:105;43860:18;;43849:7;:29;;:61;;;;;43892:18;;43882:7;:28;43849:61;43845:110;;;43934:9;43927:16;;;;;43845:110;43980:18;;43969:7;:29;;:56;;;;;44012:13;:11;:13::i;:::-;44002:7;:23;43969:56;43965:107;;;44049:11;44042:18;;;;;43965:107;44097:13;:11;:13::i;:::-;44086:7;:24;44082:76;;44134:12;44127:19;;;;;44082:76;44175:16;44168:23;;;43620:579;:::o;31984:91::-;32055:12;;31984:91;:::o;44618:138::-;44675:4;;44699:23;44714:7;44699:14;:23::i;:::-;:49;;;;;;;;;;;44618:138;-1:-1:-1;;44618:138:0:o;28556:172::-;28604:7;28631:89;28640:7;:5;:7::i;:::-;28658:12;;28640:31;;;-1:-1:-1;;;28640:31:0;;-1:-1:-1;;;;;28658:12:0;;;28640:31;;;;;;:17;;;;;;;:31;;;;;;;;;;;;;;;:17;:31;;;5:2:-1;;;;30:1;27;20:12;5:2;28640:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28640:31:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28640:31:0;28673:7;:5;:7::i;:::-;28691:12;;28673:46;;;-1:-1:-1;;;28673:46:0;;-1:-1:-1;;;;;28691:12:0;;;28673:46;;;;28713:4;28673:46;;;;;;:17;;;;;;;:46;;;;;;;;;;;;;;;:17;:46;;;5:2:-1;;;;30:1;27;20:12;5:2;28673:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28673:46:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28673:46:0;28631:8;:89::i;28320:91::-;28391:12;;-1:-1:-1;;;;;28391:12:0;28320:91;:::o;43424:103::-;43501:18;;43424:103;:::o;42501:117::-;34907:9;:7;:9::i;:::-;34899:54;;;;;-1:-1:-1;;;34899:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;34899:54:0;;;;;;;;;;;;;;;42579:31;42595:14;42579:15;:31::i;46234:1122::-;-1:-1:-1;;;;;46339:19:0;;46298:7;46339:19;;;:10;:19;;;;;;;;46450:30;46350:7;46450:21;:30::i;:::-;46446:884;;;46578:11;46557:17;:15;:17::i;:::-;:32;;;;;;;;;46553:88;;;-1:-1:-1;;46610:15:0;;;;;46553:88;46692:22;46682:6;:32;;;;;;;;;:68;;;-1:-1:-1;46728:22:0;46718:6;:32;;;;;;;;;46682:68;46678:134;;;46778:15;46794:1;46778:18;;;46771:25;;;;;46678:134;46861:22;46851:6;:32;;;;;;;;;:68;;;-1:-1:-1;46897:22:0;46887:6;:32;;;;;;;;;46851:68;46847:134;;;46947:15;46963:1;46947:18;;46847:134;47030:22;47020:6;:32;;;;;;;;;:68;;;-1:-1:-1;47066:22:0;47056:6;:32;;;;;;;;;47020:68;47016:134;;;47116:15;47132:1;47116:18;;47016:134;47199:22;47189:6;:32;;;;;;;;;:68;;;-1:-1:-1;47235:22:0;47225:6;:32;;;;;;;;;47189:68;47185:134;;;47285:15;47301:1;47285:18;;47185:134;-1:-1:-1;47347:1:0;;46234:1122;-1:-1:-1;;46234:1122:0:o;35801:109::-;34907:9;:7;:9::i;:::-;34899:54;;;;;-1:-1:-1;;;34899:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;34899:54:0;;;;;;;;;;;;;;;35874:28;35893:8;35874:18;:28::i;44344:120::-;-1:-1:-1;;;;;44437:19:0;44406:11;44437:19;;;:10;:19;;;;;;;;;44344:120::o;21931:78::-;21995:6;;-1:-1:-1;;;;;21995:6:0;21931:78;:::o;51015:570::-;51133:15;;51118:11;:30;;51110:63;;;;;-1:-1:-1;;;51110:63:0;;;;;;;;;;;;-1:-1:-1;;;51110:63:0;;;;;;;;;;;;;;;51186:50;51213:11;51226:9;51186:26;:50::i;:::-;51269:34;51291:11;51269:21;:34::i;:::-;51247:144;;;;-1:-1:-1;;;51247:144:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51470:29;51487:11;51470:16;:29::i;:::-;-1:-1:-1;;;;;51424:27:0;;;;;;:14;:27;;;;;;:42;;51456:9;51424:42;:31;:42;:::i;:::-;:75;;51402:175;;;;-1:-1:-1;;;51402:175:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51015:570;;:::o;26293:122::-;26360:7;26387:20;26401:5;;26387:9;:13;;:20;;;;:::i;:::-;26380:27;26293:122;-1:-1:-1;;26293:122:0:o;4989:181::-;5047:7;5079:5;;;5103:6;;;;5095:46;;;;;-1:-1:-1;;;5095:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;5161:1;4989:181;-1:-1:-1;;;4989:181:0:o;50511:215::-;-1:-1:-1;;;;;50624:22:0;;;;;;:9;:22;;;;;;:39;;50651:11;50624:39;:26;:39;:::i;:::-;-1:-1:-1;;;;;50599:22:0;;;;;;;:9;:22;;;;;:64;;;;50697:6;;50674:44;;50697:6;50706:11;50674:14;:44::i;49878:235::-;49970:52;49999:11;50012:9;49970:28;:52::i;:::-;-1:-1:-1;;;;;50063:27:0;;;;;;:14;:27;;;;;;:42;;50095:9;50063:42;:31;:42;:::i;:::-;-1:-1:-1;;;;;50033:27:0;;;;;;;:14;:27;;;;;:72;;;;-1:-1:-1;49878:235:0:o;26507:80::-;26552:7;;:27;;-1:-1:-1;;;;;26552:7:0;;;;26569:9;26552:27;;;;;:7;:27;:7;:27;26569:9;26552:7;:27;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;47903:786:0;48010:13;:11;:13::i;:::-;47992:15;:31;47984:72;;;;;-1:-1:-1;;;47984:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48072:9;48067:155;48091:21;48087:1;:25;48067:155;;;48162:1;48142:14;48157:1;48142:17;;;;;;;;;;;:21;48134:76;;;;-1:-1:-1;;;48134:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48114:3;;48067:155;;;-1:-1:-1;48260:17:0;;;;48240;;:37;48232:69;;;;;-1:-1:-1;;;48232:69:0;;;;;;;;;;;;-1:-1:-1;;;48232:69:0;;;;;;;;;;;;;;;48340:17;;;;;48320;;;:37;48312:69;;;;;-1:-1:-1;;;48312:69:0;;;;;;;;;;;;-1:-1:-1;;;48312:69:0;;;;;;;;;;;;;;;48420:17;;;;48400;;;;:37;48392:69;;;;;-1:-1:-1;;;48392:69:0;;;;;;;;;;;;-1:-1:-1;;;48392:69:0;;;;;;;;;;;;;;;48474:32;:15;48492:14;48474:32;;:::i;:::-;-1:-1:-1;48553:15:0;:18;48586;;48619;;48652;;48524:157;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47903:786;:::o;27018:106::-;27076:7;27107:1;27103;:5;:13;;27115:1;27103:13;;;-1:-1:-1;27111:1:0;;27096:20;-1:-1:-1;27018:106:0:o;42797:226::-;42891:1;42874:14;:18;42866:55;;;;;-1:-1:-1;;;42866:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;42932:15;:32;;;42980:35;;;;;;;;;;;;;;;;;42797:226;:::o;36016:229::-;-1:-1:-1;;;;;36090:22:0;;36082:73;;;;-1:-1:-1;;;36082:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36192:6;;;36171:38;;-1:-1:-1;;;;;36171:38:0;;;;36192:6;;;36171:38;;;36220:6;:17;;-1:-1:-1;;;;;;36220:17:0;-1:-1:-1;;;;;36220:17:0;;;;;;;;;;36016:229::o;33047:167::-;31198:8;:6;:8::i;:::-;31190:45;;;;;-1:-1:-1;;;31190:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;33156:50;33183:11;33196:9;33156:26;:50::i;6361:471::-;6419:7;6664:6;6660:47;;-1:-1:-1;6694:1:0;6687:8;;6660:47;6731:5;;;6735:1;6731;:5;:1;6755:5;;;;;:10;6747:56;;;;-1:-1:-1;;;6747:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28926:158;29037:12;;29012:64;;-1:-1:-1;;;;;29037:12:0;29051:11;29064;29012:7;:5;:7::i;:::-;-1:-1:-1;;;;;29012:24:0;;:64;;;:24;:64;:::i;30238:240::-;30333:50;30360:11;30373:9;30333:26;:50::i;:::-;30432:4;;30402:26;30418:9;30402:11;:9;:11::i;:::-;:15;:26;:15;:26;:::i;:::-;:34;;30394:76;;;;;-1:-1:-1;;;30394:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;13504:204;13631:68;;;-1:-1:-1;;;;;13631:68:0;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;13631:68:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;13605:95:0;;13624:5;;13605:18;:95::i;23941:380::-;-1:-1:-1;;;;;24044:25:0;;24036:80;;;;-1:-1:-1;;;24036:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24135:14;24127:52;;;;;-1:-1:-1;;;24127:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;15359:1114;15963:27;15971:5;-1:-1:-1;;;;;15963:25:0;;:27::i;:::-;15955:71;;;;;-1:-1:-1;;;15955:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;16100:12;16114:23;16149:5;-1:-1:-1;;;;;16141:19:0;16161:4;16141:25;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;16141:25:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;16099:67:0;;;;16185:7;16177:52;;;;;-1:-1:-1;;;16177:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16246:17;;:21;16242:224;;16388:10;16377:30;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;16377:30:0;16369:85;;;;-1:-1:-1;;;16369:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10349:619;10409:4;10877:20;;10720:66;10917:23;;;;;;:42;;-1:-1:-1;10944:15:0;;;10917:42;10909:51;10349:619;-1:-1:-1;;;;10349:619:0:o;37754:13834::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37754:13834:0;;;-1:-1:-1;37754:13834:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;

Swarm Source

bzzr://6926fb617509bc8881a5ce13c10829db21bff09ac2e105181895d7d9fe2b803e

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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