{"file_path":"MainnetArtBlocksAuctions.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: https://github.com/lendroidproject/protocol.2.0/blob/master/LICENSE.md\n\n\n// File: @openzeppelin/contracts/token/ERC20/IERC20.sol\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `recipient`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\n// File: @openzeppelin/contracts/math/SafeMath.sol\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     *\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c >= a, \"SafeMath: addition overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return sub(a, b, \"SafeMath: subtraction overflow\");\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b <= a, errorMessage);\n        uint256 c = a - b;\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     *\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n        // benefit is lost if 'b' is also tested.\n        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n        if (a == 0) {\n            return 0;\n        }\n\n        uint256 c = a * b;\n        require(c / a == b, \"SafeMath: multiplication overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers. Reverts on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        return div(a, b, \"SafeMath: division by zero\");\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b > 0, errorMessage);\n        uint256 c = a / b;\n        // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * Reverts when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        return mod(a, b, \"SafeMath: modulo by zero\");\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * Reverts with custom message when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b != 0, errorMessage);\n        return a % b;\n    }\n}\n\n// File: @openzeppelin/contracts/utils/Address.sol\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n        // for accounts without code, i.e. `keccak256('')`\n        bytes32 codehash;\n        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n        // solhint-disable-next-line no-inline-assembly\n        assembly { codehash := extcodehash(account) }\n        return (codehash != accountHash && codehash != 0x0);\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n        (bool success, ) = recipient.call{ value: amount }(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain`call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n      return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n        return _functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        return _functionCallWithValue(target, data, value, errorMessage);\n    }\n\n    function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n        require(isContract(target), \"Address: call to non-contract\");\n\n        // solhint-disable-next-line avoid-low-level-calls\n        (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                // solhint-disable-next-line no-inline-assembly\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n\n// File: @openzeppelin/contracts/token/ERC20/SafeERC20.sol\n\npragma solidity ^0.7.0;\n\n\n\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using SafeMath for uint256;\n    using Address for address;\n\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(IERC20 token, address spender, uint256 value) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        // solhint-disable-next-line max-line-length\n        require((value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 newAllowance = token.allowance(address(this), spender).add(value);\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        if (returndata.length > 0) { // Return data is optional\n            // solhint-disable-next-line max-line-length\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n\n// File: @chainlink/contracts/src/v0.7/vendor/SafeMathChainlink.sol\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMathChainlink {\n  /**\n    * @dev Returns the addition of two unsigned integers, reverting on\n    * overflow.\n    *\n    * Counterpart to Solidity's `+` operator.\n    *\n    * Requirements:\n    * - Addition cannot overflow.\n    */\n  function add(uint256 a, uint256 b) internal pure returns (uint256) {\n    uint256 c = a + b;\n    require(c >= a, \"SafeMath: addition overflow\");\n\n    return c;\n  }\n\n  /**\n    * @dev Returns the subtraction of two unsigned integers, reverting on\n    * overflow (when the result is negative).\n    *\n    * Counterpart to Solidity's `-` operator.\n    *\n    * Requirements:\n    * - Subtraction cannot overflow.\n    */\n  function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n    require(b <= a, \"SafeMath: subtraction overflow\");\n    uint256 c = a - b;\n\n    return c;\n  }\n\n  /**\n    * @dev Returns the multiplication of two unsigned integers, reverting on\n    * overflow.\n    *\n    * Counterpart to Solidity's `*` operator.\n    *\n    * Requirements:\n    * - Multiplication cannot overflow.\n    */\n  function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n    // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n    // benefit is lost if 'b' is also tested.\n    // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\n    if (a == 0) {\n      return 0;\n    }\n\n    uint256 c = a * b;\n    require(c / a == b, \"SafeMath: multiplication overflow\");\n\n    return c;\n  }\n\n  /**\n    * @dev Returns the integer division of two unsigned integers. Reverts on\n    * division by zero. The result is rounded towards zero.\n    *\n    * Counterpart to Solidity's `/` operator. Note: this function uses a\n    * `revert` opcode (which leaves remaining gas untouched) while Solidity\n    * uses an invalid opcode to revert (consuming all remaining gas).\n    *\n    * Requirements:\n    * - The divisor cannot be zero.\n    */\n  function div(uint256 a, uint256 b) internal pure returns (uint256) {\n    // Solidity only automatically asserts when dividing by 0\n    require(b > 0, \"SafeMath: division by zero\");\n    uint256 c = a / b;\n    // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n    return c;\n  }\n\n  /**\n    * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n    * Reverts when dividing by zero.\n    *\n    * Counterpart to Solidity's `%` operator. This function uses a `revert`\n    * opcode (which leaves remaining gas untouched) while Solidity uses an\n    * invalid opcode to revert (consuming all remaining gas).\n    *\n    * Requirements:\n    * - The divisor cannot be zero.\n    */\n  function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n    require(b != 0, \"SafeMath: modulo by zero\");\n    return a % b;\n  }\n}\n\n// File: @chainlink/contracts/src/v0.7/interfaces/LinkTokenInterface.sol\n\npragma solidity ^0.7.0;\n\ninterface LinkTokenInterface {\n  function allowance(address owner, address spender) external view returns (uint256 remaining);\n  function approve(address spender, uint256 value) external returns (bool success);\n  function balanceOf(address owner) external view returns (uint256 balance);\n  function decimals() external view returns (uint8 decimalPlaces);\n  function decreaseApproval(address spender, uint256 addedValue) external returns (bool success);\n  function increaseApproval(address spender, uint256 subtractedValue) external;\n  function name() external view returns (string memory tokenName);\n  function symbol() external view returns (string memory tokenSymbol);\n  function totalSupply() external view returns (uint256 totalTokensIssued);\n  function transfer(address to, uint256 value) external returns (bool success);\n  function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool success);\n  function transferFrom(address from, address to, uint256 value) external returns (bool success);\n}\n\n// File: contracts/chainlink/VRFRequestIDBase.sol\n\npragma solidity 0.7.5;\n\n\ncontract VRFRequestIDBase {\n\n    /**\n    * @notice returns the seed which is actually input to the VRF coordinator\n    *\n    * @dev To prevent repetition of VRF output due to repetition of the\n    * @dev user-supplied seed, that seed is combined in a hash with the\n    * @dev user-specific nonce, and the address of the consuming contract. The\n    * @dev risk of repetition is mostly mitigated by inclusion of a blockhash in\n    * @dev the final seed, but the nonce does protect against repetition in\n    * @dev requests which are included in a single block.\n    *\n    * @param _userSeed VRF seed input provided by user\n    * @param _requester Address of the requesting contract\n    * @param _nonce User-specific nonce at the time of the request\n    */\n    function makeVRFInputSeed(bytes32 _keyHash, uint256 _userSeed, address _requester, uint256 _nonce)\n    internal pure returns (uint256)\n    {\n        return  uint256(keccak256(abi.encode(_keyHash, _userSeed, _requester, _nonce)));\n    }\n\n    /**\n    * @notice Returns the id for this request\n    * @param _keyHash The serviceAgreement ID to be used for this request\n    * @param _vRFInputSeed The seed to be passed directly to the VRF\n    * @return The id for this request\n    *\n    * @dev Note that _vRFInputSeed is not the seed passed by the consuming\n    * @dev contract, but the one generated by makeVRFInputSeed\n    */\n    function makeRequestId(bytes32 _keyHash, uint256 _vRFInputSeed) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(_keyHash, _vRFInputSeed));\n    }\n}\n\n// File: contracts/chainlink/VRFConsumerBase.sol\n\npragma solidity 0.7.5;\n\n\n\n\n/** ****************************************************************************\n * @notice Interface for contracts using VRF randomness\n * *****************************************************************************\n * @dev PURPOSE\n *\n * @dev Reggie the Random Oracle (not his real job) wants to provide randomness\n * @dev to Vera the verifier in such a way that Vera can be sure he's not\n * @dev making his output up to suit himself. Reggie provides Vera a public key\n * @dev to which he knows the secret key. Each time Vera provides a seed to\n * @dev Reggie, he gives back a value which is computed completely\n * @dev deterministically from the seed and the secret key.\n *\n * @dev Reggie provides a proof by which Vera can verify that the output was\n * @dev correctly computed once Reggie tells it to her, but without that proof,\n * @dev the output is indistinguishable to her from a uniform random sample\n * @dev from the output space.\n *\n * @dev The purpose of this contract is to make it easy for unrelated contracts\n * @dev to talk to Vera the verifier about the work Reggie is doing, to provide\n * @dev simple access to a verifiable source of randomness.\n * *****************************************************************************\n * @dev USAGE\n *\n * @dev Calling contracts must inherit from VRFConsumerInterface, and can\n * @dev initialize VRFConsumerInterface's attributes in their constructor as\n * @dev shown:\n *\n * @dev   contract VRFConsumer {\n * @dev     constuctor(<other arguments>, address _vrfCoordinator, address _link)\n * @dev       VRFConsumerBase(_vrfCoordinator, _link) public {\n * @dev         <initialization with other arguments goes here>\n * @dev       }\n * @dev   }\n *\n * @dev The oracle will have given you an ID for the VRF keypair they have\n * @dev committed to (let's call it keyHash), and have told you the minimum LINK\n * @dev price for VRF service. Make sure your contract has sufficient LINK, and\n * @dev call requestRandomness(keyHash, fee, seed), where seed is the input you\n * @dev want to generate randomness from.\n *\n * @dev Once the VRFCoordinator has received and validated the oracle's response\n * @dev to your request, it will call your contract's fulfillRandomness method.\n *\n * @dev The randomness argument to fulfillRandomness is the actual random value\n * @dev generated from your seed.\n *\n * @dev The requestId argument is generated from the keyHash and the seed by\n * @dev makeRequestId(keyHash, seed). If your contract could have concurrent\n * @dev requests open, you can use the requestId to track which seed is\n * @dev associated with which randomness. See VRFRequestIDBase.sol for more\n * @dev details.\n *\n * @dev Colliding `requestId`s are cryptographically impossible as long as seeds\n * @dev differ. (Which is critical to making unpredictable randomness! See the\n * @dev next section.)\n *\n * *****************************************************************************\n * @dev SECURITY CONSIDERATIONS\n *\n * @dev Since the ultimate input to the VRF is mixed with the block hash of the\n * @dev block in which the request is made, user-provided seeds have no impact\n * @dev on its economic security properties. They are only included for API\n * @dev compatability with previous versions of this contract.\n *\n * @dev Since the block hash of the block which contains the requestRandomness()\n * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful\n * @dev miner could, in principle, fork the blockchain to evict the block\n * @dev containing the request, forcing the request to be included in a\n * @dev different block with a different hash, and therefore a different input\n * @dev to the VRF. However, such an attack would incur a substantial economic\n * @dev cost. This cost scales with the number of blocks the VRF oracle waits\n * @dev until it calls fulfillRandomness().\n */\n // solhint-disable-next-line\nabstract contract VRFConsumerBase is VRFRequestIDBase {\n\n    using SafeMathChainlink for uint256;\n\n    LinkTokenInterface immutable internal LINK;// solhint-disable-line var-name-mixedcase\n    address immutable private vrfCoordinator;\n\n    // solhint-disable-next-line func-visibility\n    constructor(address _vrfCoordinator, address _link) {\n        vrfCoordinator = _vrfCoordinator;\n        LINK = LinkTokenInterface(_link);\n    }\n\n    // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF\n    // proof. rawFulfillRandomness then calls fulfillRandomness, after validating\n    // the origin of the call\n    function rawFulfillRandomness(bytes32 requestId, uint256 randomness) external {\n        require(msg.sender == vrfCoordinator, \"Only VRFCoordinator can fulfill\");\n        fulfillRandomness(requestId, randomness);\n    }\n\n    /**\n    * @notice fulfillRandomness handles the VRF response. Your contract must\n    * @notice implement it.\n    *\n    * @dev The VRFCoordinator expects a calling contract to have a method with\n    * @dev this signature, and will trigger it once it has verified the proof\n    * @dev associated with the randomness (It is triggered via a call to\n    * @dev rawFulfillRandomness, below.)\n    *\n    * @param requestId The Id initially returned by requestRandomness\n    * @param randomness the VRF output\n    */\n    function fulfillRandomness(bytes32 requestId, uint256 randomness) internal virtual;\n\n    /**\n    * @notice requestRandomness initiates a request for VRF output given _seed\n    *\n    * @dev See \"SECURITY CONSIDERATIONS\" above for more information on _seed.\n    *\n    * @dev The fulfillRandomness method receives the output, once it's provided\n    * @dev by the Oracle, and verified by the vrfCoordinator.\n    *\n    * @dev The _keyHash must already be registered with the VRFCoordinator, and\n    * @dev the _fee must exceed the fee specified during registration of the\n    * @dev _keyHash.\n    *\n    * @param _keyHash ID of public key against which randomness is generated\n    * @param _fee The amount of LINK to send with the request\n    * @param _seed seed mixed into the input of the VRF\n    *\n    * @return requestId unique ID for this request\n    *\n    * @dev The returned requestId can be used to distinguish responses to *\n    * @dev concurrent requests. It is passed as the first argument to\n    * @dev fulfillRandomness.\n    */\n    function requestRandomness(bytes32 _keyHash, uint256 _fee, uint256 _seed) internal virtual\n    returns (bytes32 requestId) {\n        LINK.transferAndCall(vrfCoordinator, _fee, abi.encode(_keyHash, _seed));\n        // This is the seed passed to VRFCoordinator. The oracle will mix this with\n        // the hash of the block containing this request to obtain the seed/input\n        // which is finally passed to the VRF cryptographic machinery.\n        uint256 vRFSeed  = makeVRFInputSeed(_keyHash, _seed, address(this), nonces[_keyHash]);\n        // nonces[_keyHash] must stay in sync with\n        // VRFCoordinator.nonces[_keyHash][this], which was incremented by the above\n        // successful LINK.transferAndCall (in VRFCoordinator.randomnessRequest).\n        // This provides protection against the user repeating their input\n        // seed, which would result in a predictable/duplicate output.\n        nonces[_keyHash] = nonces[_keyHash].add(1);\n        return makeRequestId(_keyHash, vRFSeed);\n    }\n\n    // Nonces for each VRF key from which randomness has been requested.\n    //\n    // Must stay in sync with VRFCoordinator[_keyHash][this]\n    mapping(bytes32 /* keyHash */ => uint256 /* nonce */) public nonces;\n\n}\n\n// File: @openzeppelin/contracts/GSN/Context.sol\n\npragma solidity ^0.7.0;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address payable) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes memory) {\n        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n        return msg.data;\n    }\n}\n\n// File: @openzeppelin/contracts/access/Ownable.sol\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\ncontract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor () {\n        address msgSender = _msgSender();\n        _owner = msgSender;\n        emit OwnershipTransferred(address(0), msgSender);\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(_owner == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        emit OwnershipTransferred(_owner, address(0));\n        _owner = address(0);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        emit OwnershipTransferred(_owner, newOwner);\n        _owner = newOwner;\n    }\n}\n\n// File: @openzeppelin/contracts/introspection/IERC165.sol\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n\n// File: @openzeppelin/contracts/token/ERC721/IERC721.sol\n\npragma solidity ^0.7.0;\n\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n    /**\n     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n     */\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n     */\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    /**\n     * @dev Returns the number of tokens in ``owner``'s account.\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    /**\n     * @dev Returns the owner of the `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Transfers `tokenId` token from `from` to `to`.\n     *\n     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n     * The approval is cleared when the token is transferred.\n     *\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n     *\n     * Requirements:\n     *\n     * - The caller must own the token or be an approved operator.\n     * - `tokenId` must exist.\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address to, uint256 tokenId) external;\n\n    /**\n     * @dev Returns the account approved for `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function getApproved(uint256 tokenId) external view returns (address operator);\n\n    /**\n     * @dev Approve or remove `operator` as an operator for the caller.\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n     *\n     * Requirements:\n     *\n     * - The `operator` cannot be the caller.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function setApprovalForAll(address operator, bool _approved) external;\n\n    /**\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n     *\n     * See {setApprovalForAll}\n     */\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n    /**\n      * @dev Safely transfers `tokenId` token from `from` to `to`.\n      *\n      * Requirements:\n      *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n      * - `tokenId` token must exist and be owned by `from`.\n      * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n      * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n      *\n      * Emits a {Transfer} event.\n      */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n\n// File: contracts/auctions/IAuction.sol\n\npragma solidity 0.7.5;\n\n\n/**\n * @dev Required interface of an Auction compliant contract.\n */\ninterface IAuction {\n    // admin functions\n    function setDaoTreasury(address daoTreasuryAddress) external;\n    function setKeyMinter(address keyMinterAddress) external;\n    function setAuctionCurve(address auctionCurveAddress) external;\n    function transferKeyMinterOwnership(address newOwner) external;\n    function escapeHatchERC20(address tokenAddress) external;\n    // end-user functions\n    function totalDefiKeys() external view returns (uint256);\n    function currentPrice() external view returns (uint256);\n}\n\n// File: contracts/auctions/IRandomMinter.sol\n\npragma solidity 0.7.5;\n\n\n/**\n * @dev Required interface of an AuctionTokenProbabilityDistribution compliant contract.\n */\ninterface IRandomMinter {\n    function mintWithRandomness(uint256 randomResult, address to) external returns(\n        address newTokenAddress, uint256 newTokenId, uint256 feePercentage);\n\n    function transferOwnership(address newOwner) external;\n\n    function currentOwner() external view returns (address);\n}\n\n// File: contracts/auctions/Structs.sol\n\npragma solidity 0.7.5;\npragma experimental ABIEncoderV2;\n\n/* solhint-disable */\nstruct DefiKey {\n    uint256 epoch;\n    uint256 amount;\n    uint256 timestamp;\n    address auctionTokenAddress;\n    uint256 auctionTokenId;\n    uint256 feePercentage;\n    address account;\n    bytes32 requestId;\n    uint256 randomness;\n}\n/* solhint-enable */\n\n// File: contracts/auctions/IAuctionCurve.sol\n\npragma solidity 0.7.5;\n\n\n\n/**\n * @dev Required interface of an AuctionCurve compliant contract.\n */\ninterface IAuctionCurve {\n\n    function epochFromTimestamp(uint256 timestamp) external pure returns (uint256);\n\n    function epochStartTimeFromTimestamp(uint256 timestamp) external pure returns (uint256);\n\n    function epochEndTimeFromTimestamp(uint256 timestamp) external pure returns (uint256);\n\n    function currentEpoch() external view returns (uint256);\n\n    function y(DefiKey[] calldata defiKeys) external view returns (uint256 value);\n}\n\n// File: contracts/auctions/BaseAuctions.sol\n\npragma solidity 0.7.5;\n\n\n\n\n\n\n\n\n\n// solhint-disable-next-line\nabstract contract BaseAuctions is IAuction, Ownable {\n\n    using Address for address;\n    using SafeERC20 for IERC20;\n\n    // calulations\n    DefiKey[] public defiKeys;// solhint-disable-line var-name-mixedcase;\n    IAuctionCurve public auctionCurve;\n    IERC20 public purchaseToken;\n    IRandomMinter public keyMinter;\n    // dao\n    address public daoTreasury;\n    // events\n    event PurchaseMade(address indexed account, uint256 indexed epoch, uint256 purchaseAmount);\n\n    function setDaoTreasury(address daoTreasuryAddress) external override onlyOwner {\n        require(daoTreasuryAddress != address(0),\n            \"{setDaoTreasury} : invalid daoTreasuryAddress\");\n        daoTreasury = daoTreasuryAddress;\n    }\n\n    function setKeyMinter(address keyMinterAddress) external override onlyOwner {\n        require(keyMinterAddress != address(0),\n            \"{setKeyMinter} : invalid keyMinterAddress\");\n        keyMinter = IRandomMinter(keyMinterAddress);\n    }\n\n    function transferKeyMinterOwnership(address newOwner) external override onlyOwner {\n        require(newOwner != address(0), \"{transferKeyMinterOwnership} : invalid newOwner\");\n        // transfer ownership of Auction Token Distribution contract to newOwner\n        keyMinter.transferOwnership(newOwner);\n    }\n\n    function setAuctionCurve(address auctionCurveAddress) external override onlyOwner {\n        require(auctionCurveAddress.isContract(), \"{setAuctionCurve} : invalid auctionCurveAddress\");\n        auctionCurve = IAuctionCurve(auctionCurveAddress);\n    }\n\n    /**\n    * @notice Safety function to handle accidental / excess token transfer to the contract\n    */\n    function escapeHatchERC20(address tokenAddress) external override onlyOwner {\n        IERC20 token = IERC20(tokenAddress);\n        token.safeTransfer(owner(), token.balanceOf(address(this)));\n    }\n\n    function totalDefiKeys() external view override returns (uint256) {\n        return defiKeys.length;\n    }\n\n    function currentPrice() public view override returns (uint256) {\n        if ((defiKeys.length > 0) && (defiKeys[defiKeys.length - 1].epoch == auctionCurve.currentEpoch())) {\n            return 0;\n        } else {\n            return auctionCurve.y(defiKeys);\n        }\n    }\n\n}\n\n// File: contracts/auctions/VRFAuctions.sol\n\npragma solidity 0.7.5;\n\n\n\n\n\n// solhint-disable-next-line\nabstract contract VRFAuctions is BaseAuctions, VRFConsumerBase {\n\n    using SafeMath for uint256;\n    using SafeERC20 for IERC20;\n    using Address for address;\n\n    // vrf\n    mapping(bytes32 => uint256) public requestIdToKeyId;\n    bytes32 internal keyHash;\n    uint256 internal fee;\n\n    /**\n     * Constructor inherits VRFConsumerBase\n     */\n    // solhint-disable-next-line func-visibility\n    constructor(address daoTreasuryAddress,\n            address auctionCurveAddress, address purchaseTokenAddress, address keyMinterAddress,\n            address vrfCoordinator, address linkToken, bytes32 vrfKeyHash, uint256 vrfFee\n        )\n        VRFConsumerBase(vrfCoordinator, linkToken) {// solhint-disable-line func-visibility\n            require(daoTreasuryAddress != address(0), \"{VRFAuctions} : invalid daoTreasuryAddress\");\n            require(auctionCurveAddress.isContract(), \"{VRFAuctions} : invalid auctionCurveAddress\");\n            require(purchaseTokenAddress.isContract(), \"{VRFAuctions} : invalid purchaseTokenAddress\");\n            require(keyMinterAddress.isContract(), \"{VRFAuctions} : invalid keyMinterAddress\");\n            daoTreasury = daoTreasuryAddress;\n            auctionCurve = IAuctionCurve(auctionCurveAddress);\n            purchaseToken = IERC20(purchaseTokenAddress);\n            keyMinter = IRandomMinter(keyMinterAddress);\n            // vrf\n            keyHash = vrfKeyHash;\n            fee = vrfFee;\n        }\n\n    function setKeyHash(bytes32 _keyhash) external onlyOwner {\n        keyHash = _keyhash;\n    }\n\n    function setFee(uint256 _fee) external onlyOwner {\n        fee = _fee;\n    }\n\n    function purchase() external {\n        require(keyMinter.currentOwner() == address(this), \"{purchase} : Contract is not owner of keyMinter\");\n        require(LINK.balanceOf(address(this)) >= fee, \"{purchase} : Not enough LINK - fill contract with faucet\");\n        require(currentPrice() > 0, \"{purchase} : Current price is 0\");\n\n        // random number\n        bytes32 requestId = requestRandomness(keyHash, fee, uint256(address(this)));\n        requestIdToKeyId[requestId] = defiKeys.length;\n        DefiKey memory newKey = DefiKey({\n            epoch: auctionCurve.currentEpoch(),\n            amount: auctionCurve.y(defiKeys),\n            timestamp: block.timestamp,// solhint-disable-line not-rely-on-time\n            auctionTokenAddress: address(0),\n            auctionTokenId: 0,\n            feePercentage: 0,\n            account: msg.sender,\n            requestId: requestId,\n            randomness: 0\n        });\n        // save purchase\n        defiKeys.push(newKey);\n        // transfer fee\n        purchaseToken.safeTransferFrom(msg.sender, address(daoTreasury), newKey.amount);\n\n        emit PurchaseMade(msg.sender, newKey.epoch, newKey.amount);\n    }\n\n    function percentageFromRandomness(uint256 randomness) public pure returns (uint256) {\n        return randomness.mod(100);\n    }\n\n    // solhint-disable-next-line no-unused-vars\n    function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {\n        DefiKey storage key = defiKeys[requestIdToKeyId[requestId]];\n        // verify key\n        require(key.requestId == requestId, \"{fulfillRandomness} : requestIds do not match\");\n        // mint nft\n        (address tokenAddress, uint256 tokenId, uint256 feePercentage) = keyMinter.mintWithRandomness(\n            percentageFromRandomness(randomness), key.account);\n        key.auctionTokenAddress = tokenAddress;\n        key.auctionTokenId = tokenId;\n        key.feePercentage = feePercentage;\n        key.randomness = randomness;\n    }\n}\n\n// File: contracts/mocks/artblocks/MainnetArtBlocksAuctions.sol\n\npragma solidity 0.7.5;\n\n\n\ncontract MainnetArtBlocksAuctions is VRFAuctions {\n\n    /**\n     * Constructor inherits VRFAuctions\n     *\n     * Network: Ethereum Mainnet\n     * Chainlink VRF Coordinator address: 0xf0d54349aDdcf704F77AE15b96510dEA15cb7952\n     * LINK token address:                0x514910771AF9Ca656af840dff83E8264EcF986CA\n     * Key Hash: 0xAA77729D3466CA35AE8D28B3BBAC7CC36A5031EFDC430821C02BC31A238AF445\n     *\n     */\n    // solhint-disable-next-line func-visibility\n    constructor(address daoTreasuryAddress,\n            address auctionCurveAddress, address purchaseTokenAddress, address keyMinterAddress)\n        VRFAuctions(daoTreasuryAddress,// solhint-disable-line func-visibility\n            auctionCurveAddress, purchaseTokenAddress, keyMinterAddress,\n            0xf0d54349aDdcf704F77AE15b96510dEA15cb7952,// VRF Coordinator\n            0x514910771AF9Ca656af840dff83E8264EcF986CA,// LINK Token\n            0xAA77729D3466CA35AE8D28B3BBAC7CC36A5031EFDC430821C02BC31A238AF445,// keyHash\n            2 * 10 ** 18// 2 LINK\n            ) {}// solhint-disable-line no-empty-blocks\n\n}","deployed_bytecode":"0x608060405234801561001057600080fd5b50600436106101425760003560e01c80638da5cb5b116100b8578063a124df5d1161007c578063a124df5d1461032b578063a95c4d6214610347578063ef33592e14610365578063f2fde38b1461039d578063f3329376146103b9578063f7b59da1146103d557610142565b80638da5cb5b1461028757806394985ddd146102a557806398544710146102c15780639d1b464a146102dd5780639e317f12146102fb57610142565b80636458265a1161010a5780636458265a146101eb57806364edfbf01461021b578063651bd5261461022557806369fe0e2d14610243578063715018a61461025f57806379022a9f1461026957610142565b80631536a4e4146101475780632918df4c146101655780632ec759c7146101815780633ee9ca5f146101b15780634c195a71146101cd575b600080fd5b61014f6103f1565b60405161015c9190612cc7565b60405180910390f35b61017f600480360381019061017a91906121fb565b610417565b005b61019b6004803603810190610196919061232a565b61054e565b6040516101a89190612efa565b60405180910390f35b6101cb60048036038101906101c691906121fb565b61056b565b005b6101d56106b4565b6040516101e29190612efa565b60405180910390f35b610205600480360381019061020091906122c5565b6106c1565b6040516102129190612efa565b60405180910390f35b6102236106d9565b005b61022d610cfa565b60405161023a9190612cfd565b60405180910390f35b61025d6004803603810190610258919061232a565b610d20565b005b610267610dbf565b005b610271610f12565b60405161027e9190612b7e565b60405180910390f35b61028f610f38565b60405161029c9190612b7e565b60405180910390f35b6102bf60048036038101906102ba91906122ee565b610f61565b005b6102db60048036038101906102d691906122c5565b610ffd565b005b6102e561109c565b6040516102f29190612efa565b60405180910390f35b610315600480360381019061031091906122c5565b611234565b6040516103229190612efa565b60405180910390f35b610345600480360381019061034091906121fb565b61124c565b005b61034f611395565b60405161035c9190612ce2565b60405180910390f35b61037f600480360381019061037a919061232a565b6113bb565b60405161039499989796959493929190612f3e565b60405180910390f35b6103b760048036038101906103b291906121fb565b611459565b005b6103d360048036038101906103ce91906121fb565b61161b565b005b6103ef60048036038101906103ea91906121fb565b6117b0565b005b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61041f611953565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146104ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a390612dfa565b60405180910390fd5b6104cb8173ffffffffffffffffffffffffffffffffffffffff16611908565b61050a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050190612d5a565b60405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600061056460648361195b90919063ffffffff16565b9050919050565b610573611953565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610600576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105f790612dfa565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610670576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066790612eda565b60405180910390fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600180549050905090565b60076020528060005260406000206000915090505481565b3073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b387ef926040518163ffffffff1660e01b815260040160206040518083038186803b15801561075857600080fd5b505afa15801561076c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107909190612224565b73ffffffffffffffffffffffffffffffffffffffff16146107e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107dd90612e7a565b60405180910390fd5b6009547f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016108429190612b7e565b60206040518083038186803b15801561085a57600080fd5b505afa15801561086e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108929190612353565b10156108d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90612d3a565b60405180910390fd5b60006108dd61109c565b1161091d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091490612e3a565b60405180910390fd5b60006109446008546009543073ffffffffffffffffffffffffffffffffffffffff166119a5565b9050600180549050600760008381526020019081526020016000208190555061096b612102565b604051806101200160405280600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663766718086040518163ffffffff1660e01b815260040160206040518083038186803b1580156109df57600080fd5b505afa1580156109f3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a179190612353565b8152602001600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663af51877c60016040518263ffffffff1660e01b8152600401610a789190612c37565b60206040518083038186803b158015610a9057600080fd5b505afa158015610aa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac89190612353565b8152602001428152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020013373ffffffffffffffffffffffffffffffffffffffff16815260200183815260200160008152509050600181908060018154018082558091505060019003906000526020600020906009020160009091909190915060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506080820151816004015560a0820151816005015560c08201518160060160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060e0820151816007015561010082015181600801555050610c9f33600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168360200151600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611b0d909392919063ffffffff16565b80600001513373ffffffffffffffffffffffffffffffffffffffff167fd9a153a14a96b7a32535e39c63c526b4902fdc74c3f65dfbc12f848a3cea48178360200151604051610cee9190612efa565b60405180910390a35050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610d28611953565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610db5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dac90612dfa565b60405180910390fd5b8060098190555050565b610dc7611953565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610e54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4b90612dfa565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b7f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb795273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610fef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fe690612e1a565b60405180910390fd5b610ff98282611b96565b5050565b611005611953565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611092576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108990612dfa565b60405180910390fd5b8060088190555050565b6000806001805490501180156111745750600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663766718086040518163ffffffff1660e01b815260040160206040518083038186803b15801561111557600080fd5b505afa158015611129573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114d9190612353565b6001808080549050038154811061116057fe5b906000526020600020906009020160000154145b156111825760009050611231565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663af51877c60016040518263ffffffff1660e01b81526004016111de9190612c37565b60206040518083038186803b1580156111f657600080fd5b505afa15801561120a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122e9190612353565b90505b90565b60066020528060005260406000206000915090505481565b611254611953565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146112e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d890612dfa565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134890612eba565b60405180910390fd5b80600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600181815481106113cb57600080fd5b90600052602060002090600902016000915090508060000154908060010154908060020154908060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060040154908060050154908060060160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060070154908060080154905089565b611461611953565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146114ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e590612dfa565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561155e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155590612d7a565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611623611953565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146116b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116a790612dfa565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611720576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171790612dda565b60405180910390fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f2fde38b826040518263ffffffff1660e01b815260040161177b9190612b7e565b600060405180830381600087803b15801561179557600080fd5b505af11580156117a9573d6000803e3d6000fd5b5050505050565b6117b8611953565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183c90612dfa565b60405180910390fd5b6000819050611904611855610f38565b8273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161188e9190612b7e565b60206040518083038186803b1580156118a657600080fd5b505afa1580156118ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118de9190612353565b8373ffffffffffffffffffffffffffffffffffffffff16611d5a9092919063ffffffff16565b5050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f915080821415801561194a57506000801b8214155b92505050919050565b600033905090565b600061199d83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250611de0565b905092915050565b60007f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca73ffffffffffffffffffffffffffffffffffffffff16634000aea07f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952858786604051602001611a18929190612c59565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401611a4593929190612bf9565b602060405180830381600087803b158015611a5f57600080fd5b505af1158015611a73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a97919061229c565b506000611ab9858430600660008a815260200190815260200160002054611e3c565b9050611ae260016006600088815260200190815260200160002054611e7890919063ffffffff16565b6006600087815260200190815260200160002081905550611b038582611ecd565b9150509392505050565b611b90846323b872dd60e01b858585604051602401611b2e93929190612b99565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611f00565b50505050565b60006001600760008581526020019081526020016000205481548110611bb857fe5b9060005260206000209060090201905082816007015414611c0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c0590612dba565b60405180910390fd5b6000806000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c48b6ed2611c5a8761054e565b8660060160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401611c9c929190612f15565b606060405180830381600087803b158015611cb657600080fd5b505af1158015611cca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cee919061224d565b925092509250828460030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818460040181905550808460050181905550848460080181905550505050505050565b611ddb8363a9059cbb60e01b8484604051602401611d79929190612bd0565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611f00565b505050565b6000808314158290611e28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e1f9190612d18565b60405180910390fd5b50828481611e3257fe5b0690509392505050565b600084848484604051602001611e559493929190612c82565b6040516020818303038152906040528051906020012060001c9050949350505050565b600080828401905083811015611ec3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eba90612d9a565b60405180910390fd5b8091505092915050565b60008282604051602001611ee2929190612b3b565b60405160208183030381529060405280519060200120905092915050565b6060611f62826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611fc79092919063ffffffff16565b9050600081511115611fc25780806020019051810190611f82919061229c565b611fc1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb890612e9a565b60405180910390fd5b5b505050565b6060611fd68484600085611fdf565b90509392505050565b6060611fea85611908565b612029576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202090612e5a565b60405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040516120539190612b67565b60006040518083038185875af1925050503d8060008114612090576040519150601f19603f3d011682016040523d82523d6000602084013e612095565b606091505b509150915081156120aa5780925050506120fa565b6000815111156120bd5780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120f19190612d18565b60405180910390fd5b949350505050565b604051806101200160405280600081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008019168152602001600081525090565b60008135905061218c816131f1565b92915050565b6000815190506121a1816131f1565b92915050565b6000815190506121b681613208565b92915050565b6000813590506121cb8161321f565b92915050565b6000813590506121e081613236565b92915050565b6000815190506121f581613236565b92915050565b60006020828403121561220d57600080fd5b600061221b8482850161217d565b91505092915050565b60006020828403121561223657600080fd5b600061224484828501612192565b91505092915050565b60008060006060848603121561226257600080fd5b600061227086828701612192565b9350506020612281868287016121e6565b9250506040612292868287016121e6565b9150509250925092565b6000602082840312156122ae57600080fd5b60006122bc848285016121a7565b91505092915050565b6000602082840312156122d757600080fd5b60006122e5848285016121bc565b91505092915050565b6000806040838503121561230157600080fd5b600061230f858286016121bc565b9250506020612320858286016121d1565b9150509250929050565b60006020828403121561233c57600080fd5b600061234a848285016121d1565b91505092915050565b60006020828403121561236557600080fd5b6000612373848285016121e6565b91505092915050565b600061238883836129eb565b6101208301905092915050565b61239e81613080565b82525050565b6123ad81613080565b82525050565b60006123be82612fe0565b6123c8818561300e565b93506123d383612fcb565b8060005b8381101561240357816123ea888261237c565b97506123f583613001565b9250506001810190506123d7565b5085935050505092915050565b6124198161309e565b82525050565b6124288161309e565b82525050565b61243f61243a8261309e565b6131bf565b82525050565b600061245082612feb565b61245a818561301f565b935061246a81856020860161313e565b612473816131d3565b840191505092915050565b600061248982612feb565b6124938185613030565b93506124a381856020860161313e565b80840191505092915050565b6124b8816130d2565b82525050565b6124c7816130f6565b82525050565b6124d68161311a565b82525050565b60006124e782612ff6565b6124f1818561303b565b935061250181856020860161313e565b61250a816131d3565b840191505092915050565b600061252260388361303b565b91507f7b70757263686173657d203a204e6f7420656e6f756768204c494e4b202d206660008301527f696c6c20636f6e747261637420776974682066617563657400000000000000006020830152604082019050919050565b6000612588602f8361303b565b91507f7b73657441756374696f6e43757276657d203a20696e76616c6964206175637460008301527f696f6e43757276654164647265737300000000000000000000000000000000006020830152604082019050919050565b60006125ee60268361303b565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000612654601b8361303b565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b6000612694602d8361303b565b91507f7b66756c66696c6c52616e646f6d6e6573737d203a207265717565737449647360008301527f20646f206e6f74206d61746368000000000000000000000000000000000000006020830152604082019050919050565b60006126fa602f8361303b565b91507f7b7472616e736665724b65794d696e7465724f776e6572736869707d203a206960008301527f6e76616c6964206e65774f776e657200000000000000000000000000000000006020830152604082019050919050565b600061276060208361303b565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b60006127a0601f8361303b565b91507f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c006000830152602082019050919050565b60006127e0601f8361303b565b91507f7b70757263686173657d203a2043757272656e742070726963652069732030006000830152602082019050919050565b6000612820601d8361303b565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b6000612860602f8361303b565b91507f7b70757263686173657d203a20436f6e7472616374206973206e6f74206f776e60008301527f6572206f66206b65794d696e74657200000000000000000000000000000000006020830152604082019050919050565b60006128c6602a8361303b565b91507f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008301527f6f742073756363656564000000000000000000000000000000000000000000006020830152604082019050919050565b600061292c602d8361303b565b91507f7b73657444616f54726561737572797d203a20696e76616c69642064616f547260008301527f65617375727941646472657373000000000000000000000000000000000000006020830152604082019050919050565b600061299260298361303b565b91507f7b7365744b65794d696e7465727d203a20696e76616c6964206b65794d696e7460008301527f65724164647265737300000000000000000000000000000000000000000000006020830152604082019050919050565b61012082016000808301549050612a01816131a5565b612a0e6000860182612b06565b5060018301549050612a1f816131a5565b612a2c6020860182612b06565b5060028301549050612a3d816131a5565b612a4a6040860182612b06565b5060038301549050612a5b81613171565b612a686060860182612395565b5060048301549050612a79816131a5565b612a866080860182612b06565b5060058301549050612a97816131a5565b612aa460a0860182612b06565b5060068301549050612ab581613171565b612ac260c0860182612395565b5060078301549050612ad38161318b565b612ae060e0860182612410565b5060088301549050612af1816131a5565b612aff610100860182612b06565b5050505050565b612b0f816130c8565b82525050565b612b1e816130c8565b82525050565b612b35612b30826130c8565b6131c9565b82525050565b6000612b47828561242e565b602082019150612b578284612b24565b6020820191508190509392505050565b6000612b73828461247e565b915081905092915050565b6000602082019050612b9360008301846123a4565b92915050565b6000606082019050612bae60008301866123a4565b612bbb60208301856123a4565b612bc86040830184612b15565b949350505050565b6000604082019050612be560008301856123a4565b612bf26020830184612b15565b9392505050565b6000606082019050612c0e60008301866123a4565b612c1b6020830185612b15565b8181036040830152612c2d8184612445565b9050949350505050565b60006020820190508181036000830152612c5181846123b3565b905092915050565b6000604082019050612c6e600083018561241f565b612c7b6020830184612b15565b9392505050565b6000608082019050612c97600083018761241f565b612ca46020830186612b15565b612cb160408301856123a4565b612cbe6060830184612b15565b95945050505050565b6000602082019050612cdc60008301846124af565b92915050565b6000602082019050612cf760008301846124be565b92915050565b6000602082019050612d1260008301846124cd565b92915050565b60006020820190508181036000830152612d3281846124dc565b905092915050565b60006020820190508181036000830152612d5381612515565b9050919050565b60006020820190508181036000830152612d738161257b565b9050919050565b60006020820190508181036000830152612d93816125e1565b9050919050565b60006020820190508181036000830152612db381612647565b9050919050565b60006020820190508181036000830152612dd381612687565b9050919050565b60006020820190508181036000830152612df3816126ed565b9050919050565b60006020820190508181036000830152612e1381612753565b9050919050565b60006020820190508181036000830152612e3381612793565b9050919050565b60006020820190508181036000830152612e53816127d3565b9050919050565b60006020820190508181036000830152612e7381612813565b9050919050565b60006020820190508181036000830152612e9381612853565b9050919050565b60006020820190508181036000830152612eb3816128b9565b9050919050565b60006020820190508181036000830152612ed38161291f565b9050919050565b60006020820190508181036000830152612ef381612985565b9050919050565b6000602082019050612f0f6000830184612b15565b92915050565b6000604082019050612f2a6000830185612b15565b612f3760208301846123a4565b9392505050565b600061012082019050612f54600083018c612b15565b612f61602083018b612b15565b612f6e604083018a612b15565b612f7b60608301896123a4565b612f886080830188612b15565b612f9560a0830187612b15565b612fa260c08301866123a4565b612faf60e083018561241f565b612fbd610100830184612b15565b9a9950505050505050505050565b60008190508160005260206000209050919050565b600081549050919050565b600081519050919050565b600081519050919050565b6000600982019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000819050919050565b600061308b826130a8565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006130dd826130e4565b9050919050565b60006130ef826130a8565b9050919050565b600061310182613108565b9050919050565b6000613113826130a8565b9050919050565b60006131258261312c565b9050919050565b6000613137826130a8565b9050919050565b60005b8381101561315c578082015181840152602081019050613141565b8381111561316b576000848401525b50505050565b600061318461317f836131e4565b61304c565b9050919050565b600061319e613199836131e4565b61306c565b9050919050565b60006131b86131b3836131e4565b613076565b9050919050565b6000819050919050565b6000819050919050565b6000601f19601f8301169050919050565b60008160001c9050919050565b6131fa81613080565b811461320557600080fd5b50565b61321181613092565b811461321c57600080fd5b50565b6132288161309e565b811461323357600080fd5b50565b61323f816130c8565b811461324a57600080fd5b5056fea2646970667358221220c57aadc74b40c114ceb7823ff3dd4e73586cdd19f532b899ca1a6c32ef03ef6564736f6c63430007050033","optimization_enabled":false,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"istanbul","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"optimization_runs":null,"sourcify_repo_url":"https://repo.sourcify.dev/contracts/full_match/1/0x6295224c5fC3F2f6E4B1f2E530c9ab8099841bc1/","decoded_constructor_args":[["0x354eB0F1138B821eD4Ed87daeC492D598a1A1a0c",{"internalType":"address","name":"daoTreasuryAddress","type":"address"}],["0xeeC972752645b639f8c618429758eBFA28199088",{"internalType":"address","name":"auctionCurveAddress","type":"address"}],["0x9077F9e1eFE0eA72867ac89046b2a6264CbcaeF5",{"internalType":"address","name":"purchaseTokenAddress","type":"address"}],["0x95004D48437E7D55f81D4fD0a4e24904890838b8",{"internalType":"address","name":"keyMinterAddress","type":"address"}]],"compiler_version":"0.7.5+commit.eb77ed08","is_verified_via_verifier_alliance":false,"verified_at":"2024-08-13T20:13:04.167446Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x60c06040523480156200001157600080fd5b5060405162003aaa38038062003aaa833981810160405281019062000037919062000500565b8383838373f0d54349addcf704f77ae15b96510dea15cb795273514910771af9ca656af840dff83e8264ecf986ca7faa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af44560001b671bc16d674ec8000083836000620000a66200049560201b60201c565b9050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3508173ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b815250508073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250505050600073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16141562000227576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200021e9062000750565b60405180910390fd5b620002538773ffffffffffffffffffffffffffffffffffffffff166200049d60201b620019081760201c565b62000295576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200028c906200070c565b60405180910390fd5b620002c18673ffffffffffffffffffffffffffffffffffffffff166200049d60201b620019081760201c565b62000303576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002fa906200072e565b60405180910390fd5b6200032f8573ffffffffffffffffffffffffffffffffffffffff166200049d60201b620019081760201c565b62000371576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003689062000772565b60405180910390fd5b87600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555086600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160088190555080600981905550505050505050505050505050620007f3565b600033905090565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f9150808214158015620004e057506000801b8214155b92505050919050565b600081519050620004fa81620007d9565b92915050565b600080600080608085870312156200051757600080fd5b60006200052787828801620004e9565b94505060206200053a87828801620004e9565b93505060406200054d87828801620004e9565b92505060606200056087828801620004e9565b91505092959194509250565b60006200057b602b8362000794565b91507f7b56524641756374696f6e737d203a20696e76616c69642061756374696f6e4360008301527f75727665416464726573730000000000000000000000000000000000000000006020830152604082019050919050565b6000620005e3602c8362000794565b91507f7b56524641756374696f6e737d203a20696e76616c696420707572636861736560008301527f546f6b656e4164647265737300000000000000000000000000000000000000006020830152604082019050919050565b60006200064b602a8362000794565b91507f7b56524641756374696f6e737d203a20696e76616c69642064616f547265617360008301527f75727941646472657373000000000000000000000000000000000000000000006020830152604082019050919050565b6000620006b360288362000794565b91507f7b56524641756374696f6e737d203a20696e76616c6964206b65794d696e746560008301527f72416464726573730000000000000000000000000000000000000000000000006020830152604082019050919050565b6000602082019050818103600083015262000727816200056c565b9050919050565b600060208201905081810360008301526200074981620005d4565b9050919050565b600060208201905081810360008301526200076b816200063c565b9050919050565b600060208201905081810360008301526200078d81620006a4565b9050919050565b600082825260208201905092915050565b6000620007b282620007b9565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b620007e481620007a5565b8114620007f057600080fd5b50565b60805160601c60a05160601c6132836200082760003980610f6352806119e55250806107eb52806119a952506132836000f3fe608060405234801561001057600080fd5b50600436106101425760003560e01c80638da5cb5b116100b8578063a124df5d1161007c578063a124df5d1461032b578063a95c4d6214610347578063ef33592e14610365578063f2fde38b1461039d578063f3329376146103b9578063f7b59da1146103d557610142565b80638da5cb5b1461028757806394985ddd146102a557806398544710146102c15780639d1b464a146102dd5780639e317f12146102fb57610142565b80636458265a1161010a5780636458265a146101eb57806364edfbf01461021b578063651bd5261461022557806369fe0e2d14610243578063715018a61461025f57806379022a9f1461026957610142565b80631536a4e4146101475780632918df4c146101655780632ec759c7146101815780633ee9ca5f146101b15780634c195a71146101cd575b600080fd5b61014f6103f1565b60405161015c9190612cc7565b60405180910390f35b61017f600480360381019061017a91906121fb565b610417565b005b61019b6004803603810190610196919061232a565b61054e565b6040516101a89190612efa565b60405180910390f35b6101cb60048036038101906101c691906121fb565b61056b565b005b6101d56106b4565b6040516101e29190612efa565b60405180910390f35b610205600480360381019061020091906122c5565b6106c1565b6040516102129190612efa565b60405180910390f35b6102236106d9565b005b61022d610cfa565b60405161023a9190612cfd565b60405180910390f35b61025d6004803603810190610258919061232a565b610d20565b005b610267610dbf565b005b610271610f12565b60405161027e9190612b7e565b60405180910390f35b61028f610f38565b60405161029c9190612b7e565b60405180910390f35b6102bf60048036038101906102ba91906122ee565b610f61565b005b6102db60048036038101906102d691906122c5565b610ffd565b005b6102e561109c565b6040516102f29190612efa565b60405180910390f35b610315600480360381019061031091906122c5565b611234565b6040516103229190612efa565b60405180910390f35b610345600480360381019061034091906121fb565b61124c565b005b61034f611395565b60405161035c9190612ce2565b60405180910390f35b61037f600480360381019061037a919061232a565b6113bb565b60405161039499989796959493929190612f3e565b60405180910390f35b6103b760048036038101906103b291906121fb565b611459565b005b6103d360048036038101906103ce91906121fb565b61161b565b005b6103ef60048036038101906103ea91906121fb565b6117b0565b005b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61041f611953565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146104ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a390612dfa565b60405180910390fd5b6104cb8173ffffffffffffffffffffffffffffffffffffffff16611908565b61050a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050190612d5a565b60405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600061056460648361195b90919063ffffffff16565b9050919050565b610573611953565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610600576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105f790612dfa565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610670576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066790612eda565b60405180910390fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600180549050905090565b60076020528060005260406000206000915090505481565b3073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b387ef926040518163ffffffff1660e01b815260040160206040518083038186803b15801561075857600080fd5b505afa15801561076c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107909190612224565b73ffffffffffffffffffffffffffffffffffffffff16146107e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107dd90612e7a565b60405180910390fd5b6009547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016108429190612b7e565b60206040518083038186803b15801561085a57600080fd5b505afa15801561086e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108929190612353565b10156108d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90612d3a565b60405180910390fd5b60006108dd61109c565b1161091d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091490612e3a565b60405180910390fd5b60006109446008546009543073ffffffffffffffffffffffffffffffffffffffff166119a5565b9050600180549050600760008381526020019081526020016000208190555061096b612102565b604051806101200160405280600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663766718086040518163ffffffff1660e01b815260040160206040518083038186803b1580156109df57600080fd5b505afa1580156109f3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a179190612353565b8152602001600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663af51877c60016040518263ffffffff1660e01b8152600401610a789190612c37565b60206040518083038186803b158015610a9057600080fd5b505afa158015610aa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac89190612353565b8152602001428152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020013373ffffffffffffffffffffffffffffffffffffffff16815260200183815260200160008152509050600181908060018154018082558091505060019003906000526020600020906009020160009091909190915060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506080820151816004015560a0820151816005015560c08201518160060160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060e0820151816007015561010082015181600801555050610c9f33600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168360200151600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611b0d909392919063ffffffff16565b80600001513373ffffffffffffffffffffffffffffffffffffffff167fd9a153a14a96b7a32535e39c63c526b4902fdc74c3f65dfbc12f848a3cea48178360200151604051610cee9190612efa565b60405180910390a35050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610d28611953565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610db5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dac90612dfa565b60405180910390fd5b8060098190555050565b610dc7611953565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610e54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4b90612dfa565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610fef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fe690612e1a565b60405180910390fd5b610ff98282611b96565b5050565b611005611953565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611092576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108990612dfa565b60405180910390fd5b8060088190555050565b6000806001805490501180156111745750600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663766718086040518163ffffffff1660e01b815260040160206040518083038186803b15801561111557600080fd5b505afa158015611129573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114d9190612353565b6001808080549050038154811061116057fe5b906000526020600020906009020160000154145b156111825760009050611231565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663af51877c60016040518263ffffffff1660e01b81526004016111de9190612c37565b60206040518083038186803b1580156111f657600080fd5b505afa15801561120a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122e9190612353565b90505b90565b60066020528060005260406000206000915090505481565b611254611953565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146112e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d890612dfa565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134890612eba565b60405180910390fd5b80600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600181815481106113cb57600080fd5b90600052602060002090600902016000915090508060000154908060010154908060020154908060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060040154908060050154908060060160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060070154908060080154905089565b611461611953565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146114ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e590612dfa565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561155e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155590612d7a565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611623611953565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146116b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116a790612dfa565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611720576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171790612dda565b60405180910390fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f2fde38b826040518263ffffffff1660e01b815260040161177b9190612b7e565b600060405180830381600087803b15801561179557600080fd5b505af11580156117a9573d6000803e3d6000fd5b5050505050565b6117b8611953565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183c90612dfa565b60405180910390fd5b6000819050611904611855610f38565b8273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161188e9190612b7e565b60206040518083038186803b1580156118a657600080fd5b505afa1580156118ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118de9190612353565b8373ffffffffffffffffffffffffffffffffffffffff16611d5a9092919063ffffffff16565b5050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f915080821415801561194a57506000801b8214155b92505050919050565b600033905090565b600061199d83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250611de0565b905092915050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634000aea07f0000000000000000000000000000000000000000000000000000000000000000858786604051602001611a18929190612c59565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401611a4593929190612bf9565b602060405180830381600087803b158015611a5f57600080fd5b505af1158015611a73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a97919061229c565b506000611ab9858430600660008a815260200190815260200160002054611e3c565b9050611ae260016006600088815260200190815260200160002054611e7890919063ffffffff16565b6006600087815260200190815260200160002081905550611b038582611ecd565b9150509392505050565b611b90846323b872dd60e01b858585604051602401611b2e93929190612b99565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611f00565b50505050565b60006001600760008581526020019081526020016000205481548110611bb857fe5b9060005260206000209060090201905082816007015414611c0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c0590612dba565b60405180910390fd5b6000806000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c48b6ed2611c5a8761054e565b8660060160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401611c9c929190612f15565b606060405180830381600087803b158015611cb657600080fd5b505af1158015611cca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cee919061224d565b925092509250828460030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818460040181905550808460050181905550848460080181905550505050505050565b611ddb8363a9059cbb60e01b8484604051602401611d79929190612bd0565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611f00565b505050565b6000808314158290611e28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e1f9190612d18565b60405180910390fd5b50828481611e3257fe5b0690509392505050565b600084848484604051602001611e559493929190612c82565b6040516020818303038152906040528051906020012060001c9050949350505050565b600080828401905083811015611ec3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eba90612d9a565b60405180910390fd5b8091505092915050565b60008282604051602001611ee2929190612b3b565b60405160208183030381529060405280519060200120905092915050565b6060611f62826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611fc79092919063ffffffff16565b9050600081511115611fc25780806020019051810190611f82919061229c565b611fc1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb890612e9a565b60405180910390fd5b5b505050565b6060611fd68484600085611fdf565b90509392505050565b6060611fea85611908565b612029576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202090612e5a565b60405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040516120539190612b67565b60006040518083038185875af1925050503d8060008114612090576040519150601f19603f3d011682016040523d82523d6000602084013e612095565b606091505b509150915081156120aa5780925050506120fa565b6000815111156120bd5780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120f19190612d18565b60405180910390fd5b949350505050565b604051806101200160405280600081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008019168152602001600081525090565b60008135905061218c816131f1565b92915050565b6000815190506121a1816131f1565b92915050565b6000815190506121b681613208565b92915050565b6000813590506121cb8161321f565b92915050565b6000813590506121e081613236565b92915050565b6000815190506121f581613236565b92915050565b60006020828403121561220d57600080fd5b600061221b8482850161217d565b91505092915050565b60006020828403121561223657600080fd5b600061224484828501612192565b91505092915050565b60008060006060848603121561226257600080fd5b600061227086828701612192565b9350506020612281868287016121e6565b9250506040612292868287016121e6565b9150509250925092565b6000602082840312156122ae57600080fd5b60006122bc848285016121a7565b91505092915050565b6000602082840312156122d757600080fd5b60006122e5848285016121bc565b91505092915050565b6000806040838503121561230157600080fd5b600061230f858286016121bc565b9250506020612320858286016121d1565b9150509250929050565b60006020828403121561233c57600080fd5b600061234a848285016121d1565b91505092915050565b60006020828403121561236557600080fd5b6000612373848285016121e6565b91505092915050565b600061238883836129eb565b6101208301905092915050565b61239e81613080565b82525050565b6123ad81613080565b82525050565b60006123be82612fe0565b6123c8818561300e565b93506123d383612fcb565b8060005b8381101561240357816123ea888261237c565b97506123f583613001565b9250506001810190506123d7565b5085935050505092915050565b6124198161309e565b82525050565b6124288161309e565b82525050565b61243f61243a8261309e565b6131bf565b82525050565b600061245082612feb565b61245a818561301f565b935061246a81856020860161313e565b612473816131d3565b840191505092915050565b600061248982612feb565b6124938185613030565b93506124a381856020860161313e565b80840191505092915050565b6124b8816130d2565b82525050565b6124c7816130f6565b82525050565b6124d68161311a565b82525050565b60006124e782612ff6565b6124f1818561303b565b935061250181856020860161313e565b61250a816131d3565b840191505092915050565b600061252260388361303b565b91507f7b70757263686173657d203a204e6f7420656e6f756768204c494e4b202d206660008301527f696c6c20636f6e747261637420776974682066617563657400000000000000006020830152604082019050919050565b6000612588602f8361303b565b91507f7b73657441756374696f6e43757276657d203a20696e76616c6964206175637460008301527f696f6e43757276654164647265737300000000000000000000000000000000006020830152604082019050919050565b60006125ee60268361303b565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000612654601b8361303b565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b6000612694602d8361303b565b91507f7b66756c66696c6c52616e646f6d6e6573737d203a207265717565737449647360008301527f20646f206e6f74206d61746368000000000000000000000000000000000000006020830152604082019050919050565b60006126fa602f8361303b565b91507f7b7472616e736665724b65794d696e7465724f776e6572736869707d203a206960008301527f6e76616c6964206e65774f776e657200000000000000000000000000000000006020830152604082019050919050565b600061276060208361303b565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b60006127a0601f8361303b565b91507f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c006000830152602082019050919050565b60006127e0601f8361303b565b91507f7b70757263686173657d203a2043757272656e742070726963652069732030006000830152602082019050919050565b6000612820601d8361303b565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b6000612860602f8361303b565b91507f7b70757263686173657d203a20436f6e7472616374206973206e6f74206f776e60008301527f6572206f66206b65794d696e74657200000000000000000000000000000000006020830152604082019050919050565b60006128c6602a8361303b565b91507f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008301527f6f742073756363656564000000000000000000000000000000000000000000006020830152604082019050919050565b600061292c602d8361303b565b91507f7b73657444616f54726561737572797d203a20696e76616c69642064616f547260008301527f65617375727941646472657373000000000000000000000000000000000000006020830152604082019050919050565b600061299260298361303b565b91507f7b7365744b65794d696e7465727d203a20696e76616c6964206b65794d696e7460008301527f65724164647265737300000000000000000000000000000000000000000000006020830152604082019050919050565b61012082016000808301549050612a01816131a5565b612a0e6000860182612b06565b5060018301549050612a1f816131a5565b612a2c6020860182612b06565b5060028301549050612a3d816131a5565b612a4a6040860182612b06565b5060038301549050612a5b81613171565b612a686060860182612395565b5060048301549050612a79816131a5565b612a866080860182612b06565b5060058301549050612a97816131a5565b612aa460a0860182612b06565b5060068301549050612ab581613171565b612ac260c0860182612395565b5060078301549050612ad38161318b565b612ae060e0860182612410565b5060088301549050612af1816131a5565b612aff610100860182612b06565b5050505050565b612b0f816130c8565b82525050565b612b1e816130c8565b82525050565b612b35612b30826130c8565b6131c9565b82525050565b6000612b47828561242e565b602082019150612b578284612b24565b6020820191508190509392505050565b6000612b73828461247e565b915081905092915050565b6000602082019050612b9360008301846123a4565b92915050565b6000606082019050612bae60008301866123a4565b612bbb60208301856123a4565b612bc86040830184612b15565b949350505050565b6000604082019050612be560008301856123a4565b612bf26020830184612b15565b9392505050565b6000606082019050612c0e60008301866123a4565b612c1b6020830185612b15565b8181036040830152612c2d8184612445565b9050949350505050565b60006020820190508181036000830152612c5181846123b3565b905092915050565b6000604082019050612c6e600083018561241f565b612c7b6020830184612b15565b9392505050565b6000608082019050612c97600083018761241f565b612ca46020830186612b15565b612cb160408301856123a4565b612cbe6060830184612b15565b95945050505050565b6000602082019050612cdc60008301846124af565b92915050565b6000602082019050612cf760008301846124be565b92915050565b6000602082019050612d1260008301846124cd565b92915050565b60006020820190508181036000830152612d3281846124dc565b905092915050565b60006020820190508181036000830152612d5381612515565b9050919050565b60006020820190508181036000830152612d738161257b565b9050919050565b60006020820190508181036000830152612d93816125e1565b9050919050565b60006020820190508181036000830152612db381612647565b9050919050565b60006020820190508181036000830152612dd381612687565b9050919050565b60006020820190508181036000830152612df3816126ed565b9050919050565b60006020820190508181036000830152612e1381612753565b9050919050565b60006020820190508181036000830152612e3381612793565b9050919050565b60006020820190508181036000830152612e53816127d3565b9050919050565b60006020820190508181036000830152612e7381612813565b9050919050565b60006020820190508181036000830152612e9381612853565b9050919050565b60006020820190508181036000830152612eb3816128b9565b9050919050565b60006020820190508181036000830152612ed38161291f565b9050919050565b60006020820190508181036000830152612ef381612985565b9050919050565b6000602082019050612f0f6000830184612b15565b92915050565b6000604082019050612f2a6000830185612b15565b612f3760208301846123a4565b9392505050565b600061012082019050612f54600083018c612b15565b612f61602083018b612b15565b612f6e604083018a612b15565b612f7b60608301896123a4565b612f886080830188612b15565b612f9560a0830187612b15565b612fa260c08301866123a4565b612faf60e083018561241f565b612fbd610100830184612b15565b9a9950505050505050505050565b60008190508160005260206000209050919050565b600081549050919050565b600081519050919050565b600081519050919050565b6000600982019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000819050919050565b600061308b826130a8565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006130dd826130e4565b9050919050565b60006130ef826130a8565b9050919050565b600061310182613108565b9050919050565b6000613113826130a8565b9050919050565b60006131258261312c565b9050919050565b6000613137826130a8565b9050919050565b60005b8381101561315c578082015181840152602081019050613141565b8381111561316b576000848401525b50505050565b600061318461317f836131e4565b61304c565b9050919050565b600061319e613199836131e4565b61306c565b9050919050565b60006131b86131b3836131e4565b613076565b9050919050565b6000819050919050565b6000819050919050565b6000601f19601f8301169050919050565b60008160001c9050919050565b6131fa81613080565b811461320557600080fd5b50565b61321181613092565b811461321c57600080fd5b50565b6132288161309e565b811461323357600080fd5b50565b61323f816130c8565b811461324a57600080fd5b5056fea2646970667358221220c57aadc74b40c114ceb7823ff3dd4e73586cdd19f532b899ca1a6c32ef03ef6564736f6c63430007050033000000000000000000000000354eb0f1138b821ed4ed87daec492d598a1a1a0c000000000000000000000000eec972752645b639f8c618429758ebfa281990880000000000000000000000009077f9e1efe0ea72867ac89046b2a6264cbcaef500000000000000000000000095004d48437e7d55f81d4fd0a4e24904890838b8","name":"MainnetArtBlocksAuctions","is_blueprint":false,"license_type":"none","is_fully_verified":true,"is_verified_via_eth_bytecode_db":true,"language":"solidity","evm_version":"istanbul","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":true,"additional_sources":[],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[{"internalType":"address","name":"daoTreasuryAddress","type":"address"},{"internalType":"address","name":"auctionCurveAddress","type":"address"},{"internalType":"address","name":"purchaseTokenAddress","type":"address"},{"internalType":"address","name":"keyMinterAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"purchaseAmount","type":"uint256"}],"name":"PurchaseMade","type":"event"},{"inputs":[],"name":"auctionCurve","outputs":[{"internalType":"contract IAuctionCurve","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"daoTreasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"defiKeys","outputs":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"address","name":"auctionTokenAddress","type":"address"},{"internalType":"uint256","name":"auctionTokenId","type":"uint256"},{"internalType":"uint256","name":"feePercentage","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"uint256","name":"randomness","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"escapeHatchERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"keyMinter","outputs":[{"internalType":"contract IRandomMinter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"randomness","type":"uint256"}],"name":"percentageFromRandomness","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"purchase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"purchaseToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"uint256","name":"randomness","type":"uint256"}],"name":"rawFulfillRandomness","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"requestIdToKeyId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"auctionCurveAddress","type":"address"}],"name":"setAuctionCurve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"daoTreasuryAddress","type":"address"}],"name":"setDaoTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_keyhash","type":"bytes32"}],"name":"setKeyHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"keyMinterAddress","type":"address"}],"name":"setKeyMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalDefiKeys","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferKeyMinterOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":false,"constructor_args":"0x000000000000000000000000354eb0f1138b821ed4ed87daec492d598a1a1a0c000000000000000000000000eec972752645b639f8c618429758ebfa281990880000000000000000000000009077f9e1efe0ea72867ac89046b2a6264cbcaef500000000000000000000000095004d48437e7d55f81d4fd0a4e24904890838b8"}