Overview
ETH Balance
1.343765052551837547 ETH
Eth Value
$3,164.24 (@ $2,354.76/ETH)More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
NFTXInventoryStaking
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-05-02 */ // Sources flattened with hardhat v2.8.2 https://hardhat.org // File contracts/solidity/proxy/IBeacon.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function childImplementation() external view returns (address); function upgradeChildTo(address newImplementation) external; } // File contracts/solidity/interface/INFTXVaultFactory.sol pragma solidity ^0.8.0; interface INFTXVaultFactory is IBeacon { // Read functions. function numVaults() external view returns (uint256); function zapContract() external view returns (address); function feeDistributor() external view returns (address); function eligibilityManager() external view returns (address); function vault(uint256 vaultId) external view returns (address); function allVaults() external view returns (address[] memory); function vaultsForAsset(address asset) external view returns (address[] memory); function isLocked(uint256 id) external view returns (bool); function excludedFromFees(address addr) external view returns (bool); function factoryMintFee() external view returns (uint64); function factoryRandomRedeemFee() external view returns (uint64); function factoryTargetRedeemFee() external view returns (uint64); function factoryRandomSwapFee() external view returns (uint64); function factoryTargetSwapFee() external view returns (uint64); function vaultFees(uint256 vaultId) external view returns (uint256, uint256, uint256, uint256, uint256); event NewFeeDistributor(address oldDistributor, address newDistributor); event NewZapContract(address oldZap, address newZap); event FeeExclusion(address feeExcluded, bool excluded); event NewEligibilityManager(address oldEligManager, address newEligManager); event NewVault(uint256 indexed vaultId, address vaultAddress, address assetAddress); event UpdateVaultFees(uint256 vaultId, uint256 mintFee, uint256 randomRedeemFee, uint256 targetRedeemFee, uint256 randomSwapFee, uint256 targetSwapFee); event DisableVaultFees(uint256 vaultId); event UpdateFactoryFees(uint256 mintFee, uint256 randomRedeemFee, uint256 targetRedeemFee, uint256 randomSwapFee, uint256 targetSwapFee); // Write functions. function __NFTXVaultFactory_init(address _vaultImpl, address _feeDistributor) external; function createVault( string calldata name, string calldata symbol, address _assetAddress, bool is1155, bool allowAllItems ) external returns (uint256); function setFeeDistributor(address _feeDistributor) external; function setEligibilityManager(address _eligibilityManager) external; function setZapContract(address _zapContract) external; function setFeeExclusion(address _excludedAddr, bool excluded) external; function setFactoryFees( uint256 mintFee, uint256 randomRedeemFee, uint256 targetRedeemFee, uint256 randomSwapFee, uint256 targetSwapFee ) external; function setVaultFees( uint256 vaultId, uint256 mintFee, uint256 randomRedeemFee, uint256 targetRedeemFee, uint256 randomSwapFee, uint256 targetSwapFee ) external; function disableVaultFees(uint256 vaultId) external; } // File contracts/solidity/interface/INFTXEligibility.sol pragma solidity ^0.8.0; interface INFTXEligibility { // Read functions. function name() external pure returns (string memory); function finalized() external view returns (bool); function targetAsset() external pure returns (address); function checkAllEligible(uint256[] calldata tokenIds) external view returns (bool); function checkEligible(uint256[] calldata tokenIds) external view returns (bool[] memory); function checkAllIneligible(uint256[] calldata tokenIds) external view returns (bool); function checkIsEligible(uint256 tokenId) external view returns (bool); // Write functions. function __NFTXEligibility_init_bytes(bytes calldata configData) external; function beforeMintHook(uint256[] calldata tokenIds) external; function afterMintHook(uint256[] calldata tokenIds) external; function beforeRedeemHook(uint256[] calldata tokenIds) external; function afterRedeemHook(uint256[] calldata tokenIds) external; } // File contracts/solidity/token/IERC20Upgradeable.sol pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File contracts/solidity/interface/INFTXVault.sol pragma solidity ^0.8.0; interface INFTXVault is IERC20Upgradeable { function manager() external view returns (address); function assetAddress() external view returns (address); function vaultFactory() external view returns (INFTXVaultFactory); function eligibilityStorage() external view returns (INFTXEligibility); function is1155() external view returns (bool); function allowAllItems() external view returns (bool); function enableMint() external view returns (bool); function enableRandomRedeem() external view returns (bool); function enableTargetRedeem() external view returns (bool); function enableRandomSwap() external view returns (bool); function enableTargetSwap() external view returns (bool); function vaultId() external view returns (uint256); function nftIdAt(uint256 holdingsIndex) external view returns (uint256); function allHoldings() external view returns (uint256[] memory); function totalHoldings() external view returns (uint256); function mintFee() external view returns (uint256); function randomRedeemFee() external view returns (uint256); function targetRedeemFee() external view returns (uint256); function randomSwapFee() external view returns (uint256); function targetSwapFee() external view returns (uint256); function vaultFees() external view returns (uint256, uint256, uint256, uint256, uint256); event VaultInit( uint256 indexed vaultId, address assetAddress, bool is1155, bool allowAllItems ); event ManagerSet(address manager); event EligibilityDeployed(uint256 moduleIndex, address eligibilityAddr); // event CustomEligibilityDeployed(address eligibilityAddr); event EnableMintUpdated(bool enabled); event EnableRandomRedeemUpdated(bool enabled); event EnableTargetRedeemUpdated(bool enabled); event EnableRandomSwapUpdated(bool enabled); event EnableTargetSwapUpdated(bool enabled); event Minted(uint256[] nftIds, uint256[] amounts, address to); event Redeemed(uint256[] nftIds, uint256[] specificIds, address to); event Swapped( uint256[] nftIds, uint256[] amounts, uint256[] specificIds, uint256[] redeemedIds, address to ); function __NFTXVault_init( string calldata _name, string calldata _symbol, address _assetAddress, bool _is1155, bool _allowAllItems ) external; function finalizeVault() external; function setVaultMetadata( string memory name_, string memory symbol_ ) external; function setVaultFeatures( bool _enableMint, bool _enableRandomRedeem, bool _enableTargetRedeem, bool _enableRandomSwap, bool _enableTargetSwap ) external; function setFees( uint256 _mintFee, uint256 _randomRedeemFee, uint256 _targetRedeemFee, uint256 _randomSwapFee, uint256 _targetSwapFee ) external; function disableVaultFees() external; // This function allows for an easy setup of any eligibility module contract from the EligibilityManager. // It takes in ABI encoded parameters for the desired module. This is to make sure they can all follow // a similar interface. function deployEligibilityStorage( uint256 moduleIndex, bytes calldata initData ) external returns (address); // The manager has control over options like fees and features function setManager(address _manager) external; function mint( uint256[] calldata tokenIds, uint256[] calldata amounts /* ignored for ERC721 vaults */ ) external returns (uint256); function mintTo( uint256[] calldata tokenIds, uint256[] calldata amounts, /* ignored for ERC721 vaults */ address to ) external returns (uint256); function redeem(uint256 amount, uint256[] calldata specificIds) external returns (uint256[] calldata); function redeemTo( uint256 amount, uint256[] calldata specificIds, address to ) external returns (uint256[] calldata); function swap( uint256[] calldata tokenIds, uint256[] calldata amounts, /* ignored for ERC721 vaults */ uint256[] calldata specificIds ) external returns (uint256[] calldata); function swapTo( uint256[] calldata tokenIds, uint256[] calldata amounts, /* ignored for ERC721 vaults */ uint256[] calldata specificIds, address to ) external returns (uint256[] calldata); function allValidNFTs(uint256[] calldata tokenIds) external view returns (bool); } // File contracts/solidity/interface/INFTXInventoryStaking.sol pragma solidity ^0.8.0; interface INFTXInventoryStaking { function nftxVaultFactory() external view returns (INFTXVaultFactory); function vaultXToken(uint256 vaultId) external view returns (address); function xTokenAddr(address baseToken) external view returns (address); function xTokenShareValue(uint256 vaultId) external view returns (uint256); function __NFTXInventoryStaking_init(address nftxFactory) external; function deployXTokenForVault(uint256 vaultId) external; function receiveRewards(uint256 vaultId, uint256 amount) external returns (bool); function timelockMintFor(uint256 vaultId, uint256 amount, address to, uint256 timelockLength) external returns (uint256); function deposit(uint256 vaultId, uint256 _amount) external; function withdraw(uint256 vaultId, uint256 _share) external; } // File contracts/solidity/token/IERC20Metadata.sol pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20Upgradeable { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File contracts/solidity/util/Address.sol pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File contracts/solidity/util/SafeERC20Upgradeable.sol pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20Upgradeable { using Address for address; function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File contracts/solidity/proxy/Initializable.sol // solhint-disable-next-line compiler-version pragma solidity ^0.8.0; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } } // File contracts/solidity/util/ContextUpgradeable.sol pragma solidity ^0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } uint256[50] private __gap; } // File contracts/solidity/util/OwnableUpgradeable.sol pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal initializer { __Context_init_unchained(); __Ownable_init_unchained(); } function __Ownable_init_unchained() internal initializer { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } uint256[49] private __gap; } // File contracts/solidity/util/PausableUpgradeable.sol pragma solidity ^0.8.0; contract PausableUpgradeable is OwnableUpgradeable { function __Pausable_init() internal initializer { __Ownable_init(); } event SetPaused(uint256 lockId, bool paused); event SetIsGuardian(address addr, bool isGuardian); mapping(address => bool) public isGuardian; mapping(uint256 => bool) public isPaused; // 0 : createVault // 1 : mint // 2 : redeem // 3 : swap // 4 : flashloan function onlyOwnerIfPaused(uint256 lockId) public view virtual { require(!isPaused[lockId] || msg.sender == owner(), "Paused"); } function unpause(uint256 lockId) public virtual onlyOwner { isPaused[lockId] = false; emit SetPaused(lockId, false); } function pause(uint256 lockId) public virtual { require(isGuardian[msg.sender], "Can't pause"); isPaused[lockId] = true; emit SetPaused(lockId, true); } function setIsGuardian(address addr, bool _isGuardian) public virtual onlyOwner { isGuardian[addr] = _isGuardian; emit SetIsGuardian(addr, _isGuardian); } } // File contracts/solidity/util/Create2.sol pragma solidity ^0.8.0; /** * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer. * `CREATE2` can be used to compute in advance the address where a smart * contract will be deployed, which allows for interesting new mechanisms known * as 'counterfactual interactions'. * * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more * information. */ library Create2 { /** * @dev Deploys a contract using `CREATE2`. The address where the contract * will be deployed can be known in advance via {computeAddress}. * * The bytecode for a contract can be obtained from Solidity with * `type(contractName).creationCode`. * * Requirements: * * - `bytecode` must not be empty. * - `salt` must have not been used for `bytecode` already. * - the factory must have a balance of at least `amount`. * - if `amount` is non-zero, `bytecode` must have a `payable` constructor. */ function deploy(uint256 amount, bytes32 salt, bytes memory bytecode) internal returns (address) { address addr; require(address(this).balance >= amount, "Create2: insufficient balance"); require(bytecode.length != 0, "Create2: bytecode length is zero"); // solhint-disable-next-line no-inline-assembly assembly { addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt) } require(addr != address(0), "Create2: Failed on deploy"); return addr; } /** * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the * `bytecodeHash` or `salt` will result in a new destination address. */ function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) { return computeAddress(salt, bytecodeHash, address(this)); } /** * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}. */ function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address) { bytes32 _data = keccak256( abi.encodePacked(bytes1(0xff), deployer, salt, bytecodeHash) ); return address(uint160(uint256(_data))); } } // File contracts/solidity/proxy/UpgradeableBeacon.sol pragma solidity ^0.8.0; /** * @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their * implementation contract, which is where they will delegate all function calls. * * An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon. */ contract UpgradeableBeacon is IBeacon, OwnableUpgradeable { address private _childImplementation; /** * @dev Emitted when the child implementation returned by the beacon is changed. */ event Upgraded(address indexed childImplementation); /** * @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the * beacon. */ function __UpgradeableBeacon__init(address childImplementation_) public initializer { _setChildImplementation(childImplementation_); } /** * @dev Returns the current child implementation address. */ function childImplementation() public view virtual override returns (address) { return _childImplementation; } /** * @dev Upgrades the beacon to a new implementation. * * Emits an {Upgraded} event. * * Requirements: * * - msg.sender must be the owner of the contract. * - `newChildImplementation` must be a contract. */ function upgradeChildTo(address newChildImplementation) public virtual override onlyOwner { _setChildImplementation(newChildImplementation); } /** * @dev Sets the implementation contract address for this beacon * * Requirements: * * - `newChildImplementation` must be a contract. */ function _setChildImplementation(address newChildImplementation) private { require(Address.isContract(newChildImplementation), "UpgradeableBeacon: child implementation is not a contract"); _childImplementation = newChildImplementation; emit Upgraded(newChildImplementation); } } // File contracts/solidity/proxy/Proxy.sol pragma solidity ^0.8.0; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ abstract contract Proxy { /** * @dev Delegates the current call to `implementation`. * * This function does not return to its internall call site, it will return directly to the external caller. */ function _delegate(address implementation) internal virtual { // solhint-disable-next-line no-inline-assembly assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function * and {_fallback} should delegate. */ function _implementation() internal view virtual returns (address); /** * @dev Delegates the current call to the address returned by `_implementation()`. * * This function does not return to its internall call site, it will return directly to the external caller. */ function _fallback() internal virtual { _beforeFallback(); _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback () external payable virtual { _fallback(); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data * is empty. */ receive () external payable virtual { _fallback(); } /** * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback` * call, or as part of the Solidity `fallback` or `receive` functions. * * If overriden should call `super._beforeFallback()`. */ function _beforeFallback() internal virtual { } } // File contracts/solidity/proxy/Create2BeaconProxy.sol pragma solidity ^0.8.0; /** * @dev This contract implements a proxy that gets the implementation address for each call from a {UpgradeableBeacon}. * Slightly modified to allow using beacon proxies with Create2. * * The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't * conflict with the storage layout of the implementation behind the proxy. * * _Available since v3.4._ */ contract Create2BeaconProxy is Proxy { /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 private constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Initializes the proxy with `beacon`. * * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This * will typically be an encoded function call, and allows initializating the storage of the proxy like a Solidity * constructor. * * Requirements: * * - `beacon` must be a contract with the interface {IBeacon}. */ constructor() payable { assert(_BEACON_SLOT == bytes32(uint256(keccak256("eip1967.proxy.beacon")) - 1)); _setBeacon(msg.sender, ""); } /** * @dev Returns the current beacon address. */ function _beacon() internal view virtual returns (address beacon) { bytes32 slot = _BEACON_SLOT; // solhint-disable-next-line no-inline-assembly assembly { beacon := sload(slot) } } /** * @dev Returns the current implementation address of the associated beacon. */ function _implementation() internal view virtual override returns (address) { return IBeacon(_beacon()).childImplementation(); } /** * @dev Changes the proxy to use a new beacon. * * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. * * Requirements: * * - `beacon` must be a contract. * - The implementation returned by `beacon` must be a contract. */ function _setBeacon(address beacon, bytes memory data) internal virtual { require( Address.isContract(beacon), "BeaconProxy: beacon is not a contract" ); require( Address.isContract(IBeacon(beacon).childImplementation()), "BeaconProxy: beacon implementation is not a contract" ); bytes32 slot = _BEACON_SLOT; // solhint-disable-next-line no-inline-assembly assembly { sstore(slot, beacon) } if (data.length > 0) { Address.functionDelegateCall(_implementation(), data, "BeaconProxy: function call failed"); } } } // File contracts/solidity/token/ERC20Upgradeable.sol pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20Metadata { mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal initializer { __Context_init_unchained(); __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer { _name = name_; _symbol = symbol_; } function _setMetadata(string memory name_, string memory symbol_) internal { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); _approve(sender, _msgSender(), currentAllowance - amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); _approve(_msgSender(), spender, currentAllowance - subtractedValue); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); _balances[sender] = senderBalance - amount; _balances[recipient] += amount; emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); _balances[account] = accountBalance - amount; _totalSupply -= amount; emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } uint256[45] private __gap; } // File contracts/solidity/token/XTokenUpgradeable.sol pragma solidity ^0.8.0; // XTokens let uou come in with some vault tokens, and leave with more! The longer you stay, the more vault tokens you get. // // This contract handles swapping to and from xSushi, SushiSwap's staking token. contract XTokenUpgradeable is OwnableUpgradeable, ERC20Upgradeable { using SafeERC20Upgradeable for IERC20Upgradeable; uint256 internal constant MAX_TIMELOCK = 2592000; IERC20Upgradeable public baseToken; mapping(address => uint256) internal timelock; event Timelocked(address user, uint256 until); function __XToken_init(address _baseToken, string memory name, string memory symbol) public initializer { __Ownable_init(); // string memory _name = INFTXInventoryStaking(msg.sender).nftxVaultFactory().vault(); __ERC20_init(name, symbol); baseToken = IERC20Upgradeable(_baseToken); } // Needs to be called BEFORE new base tokens are deposited. function mintXTokens(address account, uint256 _amount, uint256 timelockLength) external onlyOwner returns (uint256) { // Gets the amount of Base Token locked in the contract uint256 totalBaseToken = baseToken.balanceOf(address(this)); // Gets the amount of xTokens in existence uint256 totalShares = totalSupply(); // If no xTokens exist, mint it 1:1 to the amount put in if (totalShares == 0 || totalBaseToken == 0) { _timelockMint(account, _amount, timelockLength); return _amount; } // Calculate and mint the amount of xTokens the base tokens are worth. The ratio will change overtime, as xTokens are burned/minted and base tokens deposited + gained from fees / withdrawn. else { uint256 what = (_amount * totalShares) / totalBaseToken; _timelockMint(account, what, timelockLength); return what; } } function burnXTokens(address who, uint256 _share) external onlyOwner returns (uint256) { // Gets the amount of xToken in existence uint256 totalShares = totalSupply(); // Calculates the amount of base tokens the xToken is worth uint256 what = (_share * baseToken.balanceOf(address(this))) / totalShares; _burn(who, _share); baseToken.safeTransfer(who, what); return what; } function timelockAccount(address account, uint256 timelockLength) public onlyOwner virtual { require(timelockLength < MAX_TIMELOCK, "Too long lock"); uint256 timelockFinish = block.timestamp + timelockLength; if(timelockFinish > timelock[account]){ timelock[account] = timelockFinish; emit Timelocked(account, timelockFinish); } } function _burn(address who, uint256 amount) internal override { require(block.timestamp > timelock[who], "User locked"); super._burn(who, amount); } function timelockUntil(address account) public view returns (uint256) { return timelock[account]; } function _timelockMint(address account, uint256 amount, uint256 timelockLength) internal virtual { timelockAccount(account, timelockLength); _mint(account, amount); } function _transfer(address from, address to, uint256 value) internal override { require(block.timestamp > timelock[from], "User locked"); super._transfer(from, to, value); } } // File contracts/solidity/interface/ITimelockExcludeList.sol pragma solidity ^0.8.0; interface ITimelockExcludeList { function isExcluded(address addr, uint256 vaultId) external view returns (bool); } // File contracts/solidity/NFTXInventoryStaking.sol pragma solidity ^0.8.0; // Author: 0xKiwi. // Pausing codes for inventory staking are: // 10: Deposit contract NFTXInventoryStaking is PausableUpgradeable, UpgradeableBeacon, INFTXInventoryStaking { using SafeERC20Upgradeable for IERC20Upgradeable; // Small locktime to prevent flash deposits. uint256 internal constant DEFAULT_LOCKTIME = 2; bytes internal constant beaconCode = type(Create2BeaconProxy).creationCode; INFTXVaultFactory public override nftxVaultFactory; uint256 public inventoryLockTimeErc20; ITimelockExcludeList public timelockExcludeList; event XTokenCreated(uint256 vaultId, address baseToken, address xToken); event Deposit(uint256 vaultId, uint256 baseTokenAmount, uint256 xTokenAmount, uint256 timelockUntil, address sender); event Withdraw(uint256 vaultId, uint256 baseTokenAmount, uint256 xTokenAmount, address sender); event FeesReceived(uint256 vaultId, uint256 amount); function __NFTXInventoryStaking_init(address _nftxVaultFactory) external virtual override initializer { __Ownable_init(); nftxVaultFactory = INFTXVaultFactory(_nftxVaultFactory); address xTokenImpl = address(new XTokenUpgradeable()); __UpgradeableBeacon__init(xTokenImpl); } modifier onlyAdmin() { require(msg.sender == owner() || msg.sender == nftxVaultFactory.feeDistributor(), "LPStaking: Not authorized"); _; } function setTimelockExcludeList(address addr) external onlyOwner { timelockExcludeList = ITimelockExcludeList(addr); } function setInventoryLockTimeErc20(uint256 time) external onlyOwner { require(time <= 14 days, "Lock too long"); inventoryLockTimeErc20 = time; } function isAddressTimelockExcluded(address addr, uint256 vaultId) public view returns (bool) { if (address(timelockExcludeList) == address(0)) { return false; } else { return timelockExcludeList.isExcluded(addr, vaultId); } } function deployXTokenForVault(uint256 vaultId) public virtual override { address baseToken = nftxVaultFactory.vault(vaultId); address deployedXToken = xTokenAddr(address(baseToken)); if (isContract(deployedXToken)) { return; } address xToken = _deployXToken(baseToken); emit XTokenCreated(vaultId, baseToken, xToken); } function receiveRewards(uint256 vaultId, uint256 amount) external virtual override onlyAdmin returns (bool) { address baseToken = nftxVaultFactory.vault(vaultId); address deployedXToken = xTokenAddr(address(baseToken)); // Don't distribute rewards unless there are people to distribute to. // Also added here if the distribution token is not deployed, just forfeit rewards for now. if (!isContract(deployedXToken) || XTokenUpgradeable(deployedXToken).totalSupply() == 0) { return false; } // We "pull" to the dividend tokens so the fee distributor only needs to approve this contract. IERC20Upgradeable(baseToken).safeTransferFrom(msg.sender, deployedXToken, amount); emit FeesReceived(vaultId, amount); return true; } // Enter staking. Staking, get minted shares and // locks base tokens and mints xTokens. function deposit(uint256 vaultId, uint256 _amount) external virtual override { onlyOwnerIfPaused(10); uint256 timelockTime = isAddressTimelockExcluded(msg.sender, vaultId) ? 0 : inventoryLockTimeErc20; (IERC20Upgradeable baseToken, XTokenUpgradeable xToken, uint256 xTokensMinted) = _timelockMintFor(vaultId, msg.sender, _amount, timelockTime); // Lock the base token in the xtoken contract baseToken.safeTransferFrom(msg.sender, address(xToken), _amount); emit Deposit(vaultId, _amount, xTokensMinted, timelockTime, msg.sender); } function timelockMintFor(uint256 vaultId, uint256 amount, address to, uint256 timelockLength) external virtual override returns (uint256) { onlyOwnerIfPaused(10); require(msg.sender == nftxVaultFactory.zapContract(), "Not staking zap"); require(nftxVaultFactory.excludedFromFees(msg.sender), "Not fee excluded"); // important for math that staking zap is excluded from fees (, , uint256 xTokensMinted) = _timelockMintFor(vaultId, to, amount, timelockLength); emit Deposit(vaultId, amount, xTokensMinted, timelockLength, to); return xTokensMinted; } // Leave the bar. Claim back your tokens. // Unlocks the staked + gained tokens and burns xTokens. function withdraw(uint256 vaultId, uint256 _share) external virtual override { IERC20Upgradeable baseToken = IERC20Upgradeable(nftxVaultFactory.vault(vaultId)); XTokenUpgradeable xToken = XTokenUpgradeable(xTokenAddr(address(baseToken))); uint256 baseTokensRedeemed = xToken.burnXTokens(msg.sender, _share); emit Withdraw(vaultId, baseTokensRedeemed, _share, msg.sender); } function xTokenShareValue(uint256 vaultId) external view virtual override returns (uint256) { IERC20Upgradeable baseToken = IERC20Upgradeable(nftxVaultFactory.vault(vaultId)); XTokenUpgradeable xToken = XTokenUpgradeable(xTokenAddr(address(baseToken))); require(address(xToken) != address(0), "XToken not deployed"); uint256 multiplier = 10 ** 18; return xToken.totalSupply() > 0 ? multiplier * baseToken.balanceOf(address(xToken)) / xToken.totalSupply() : multiplier; } function timelockUntil(uint256 vaultId, address who) external view returns (uint256) { XTokenUpgradeable xToken = XTokenUpgradeable(vaultXToken(vaultId)); return xToken.timelockUntil(who); } function balanceOf(uint256 vaultId, address who) external view returns (uint256) { XTokenUpgradeable xToken = XTokenUpgradeable(vaultXToken(vaultId)); return xToken.balanceOf(who); } // Note: this function does not guarantee the token is deployed, we leave that check to elsewhere to save gas. function xTokenAddr(address baseToken) public view virtual override returns (address) { bytes32 salt = keccak256(abi.encodePacked(baseToken)); address tokenAddr = Create2.computeAddress(salt, keccak256(type(Create2BeaconProxy).creationCode)); return tokenAddr; } function vaultXToken(uint256 vaultId) public view virtual override returns (address) { address baseToken = nftxVaultFactory.vault(vaultId); address xToken = xTokenAddr(baseToken); require(isContract(xToken), "XToken not deployed"); return xToken; } function _timelockMintFor(uint256 vaultId, address account, uint256 _amount, uint256 timelockLength) internal returns (IERC20Upgradeable, XTokenUpgradeable, uint256) { deployXTokenForVault(vaultId); IERC20Upgradeable baseToken = IERC20Upgradeable(nftxVaultFactory.vault(vaultId)); XTokenUpgradeable xToken = XTokenUpgradeable((xTokenAddr(address(baseToken)))); uint256 xTokensMinted = xToken.mintXTokens(account, _amount, timelockLength); return (baseToken, xToken, xTokensMinted); } function _deployXToken(address baseToken) internal returns (address) { string memory symbol = IERC20Metadata(baseToken).symbol(); symbol = string(abi.encodePacked("x", symbol)); bytes32 salt = keccak256(abi.encodePacked(baseToken)); address deployedXToken = Create2.deploy(0, salt, beaconCode); XTokenUpgradeable(deployedXToken).__XToken_init(baseToken, symbol, symbol); return deployedXToken; } function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size != 0; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"baseTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"xTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timelockUntil","type":"uint256"},{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeesReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"bool","name":"isGuardian","type":"bool"}],"name":"SetIsGuardian","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lockId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"SetPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"childImplementation","type":"address"}],"name":"Upgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"baseTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"xTokenAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":false,"internalType":"address","name":"baseToken","type":"address"},{"indexed":false,"internalType":"address","name":"xToken","type":"address"}],"name":"XTokenCreated","type":"event"},{"inputs":[{"internalType":"address","name":"_nftxVaultFactory","type":"address"}],"name":"__NFTXInventoryStaking_init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"childImplementation_","type":"address"}],"name":"__UpgradeableBeacon__init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"address","name":"who","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"childImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"}],"name":"deployXTokenForVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"inventoryLockTimeErc20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"vaultId","type":"uint256"}],"name":"isAddressTimelockExcluded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isGuardian","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nftxVaultFactory","outputs":[{"internalType":"contract INFTXVaultFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"lockId","type":"uint256"}],"name":"onlyOwnerIfPaused","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"lockId","type":"uint256"}],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"receiveRewards","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"}],"name":"setInventoryLockTimeErc20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"_isGuardian","type":"bool"}],"name":"setIsGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setTimelockExcludeList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"timelockExcludeList","outputs":[{"internalType":"contract ITimelockExcludeList","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"timelockLength","type":"uint256"}],"name":"timelockMintFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"address","name":"who","type":"address"}],"name":"timelockUntil","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"lockId","type":"uint256"}],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newChildImplementation","type":"address"}],"name":"upgradeChildTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"}],"name":"vaultXToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"_share","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"baseToken","type":"address"}],"name":"xTokenAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"}],"name":"xTokenShareValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50614f07806100206000396000f3fe60806040523480156200001157600080fd5b5060043610620001f55760003560e01c80637c77b6161162000119578063cda13d6711620000af578063f0f2a4d7116200007a578063f0f2a4d7146200046c578063f2fde38b1462000483578063f36d52da146200049a578063fabc1cbc14620004b157600080fd5b8063cda13d671462000415578063da525716146200042c578063e2bbb158146200043e578063e5956027146200045557600080fd5b806392054f8b11620000f057806392054f8b14620003aa578063a2700d7814620003c1578063bdf2a43c14620003d8578063c23c6da014620003fe57600080fd5b80637c77b616146200036a578063881b2f2d14620003815780638da5cb5b146200039857600080fd5b80633656eec2116200018f5780633a2950af11620001665780633a2950af146200031b5780634363fcd21462000332578063441a3e701462000349578063715018a6146200036057600080fd5b80633656eec214620002e657806337ce42bf14620002fd5780633801daf1146200030757600080fd5b8063136439dd11620001d0578063136439dd14620002795780631f1713fc146200029257806323845fb514620002a95780632699f55a14620002c057600080fd5b8063034fc83c14620001fa5780630c68ba21146200022e57806311ad9d381462000265575b600080fd5b620002116200020b36600462002673565b620004c8565b6040516001600160a01b0390911681526020015b60405180910390f35b620002546200023f36600462002501565b60656020526000908152604090205460ff1681565b604051901515815260200162000225565b606a5462000211906001600160a01b031681565b620002906200028a36600462002673565b620005b9565b005b62000290620002a336600462002501565b62000672565b62000290620002ba3660046200253f565b620006dc565b620002d7620002d1366004620026ee565b6200079b565b60405190815260200162000225565b620002d7620002f7366004620026a5565b620009ef565b620002d760695481565b60685462000211906001600160a01b031681565b620002906200032c36600462002673565b62000a89565b620002d76200034336600462002673565b62000b3f565b620002906200035a366004620026cc565b62000dd1565b6200029062000f55565b620002906200037b36600462002673565b62000ffb565b62000254620003923660046200257c565b62001072565b6033546001600160a01b031662000211565b62000290620003bb36600462002501565b62001138565b62000290620003d236600462002501565b620011b6565b62000254620003e936600462002673565b60666020526000908152604090205460ff1681565b620002d76200040f366004620026a5565b620012d1565b620002116200042636600462002501565b6200132b565b6067546001600160a01b031662000211565b620002906200044f366004620026cc565b620013a9565b620002906200046636600462002501565b6200145d565b620002906200047d36600462002673565b62001520565b620002906200049436600462002501565b6200161f565b62000254620004ab366004620026cc565b62001755565b62000290620004c236600462002673565b620019f2565b6068546040516340d1b7db60e11b81526004810183905260009182916001600160a01b03909116906381a36fb69060240160206040518083038186803b1580156200051257600080fd5b505afa15801562000527573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200054d919062002520565b905060006200055c826200132b565b9050803b620005b25760405162461bcd60e51b815260206004820152601360248201527f58546f6b656e206e6f74206465706c6f7965640000000000000000000000000060448201526064015b60405180910390fd5b9392505050565b3360009081526065602052604090205460ff166200061a5760405162461bcd60e51b815260206004820152600b60248201527f43616e27742070617573650000000000000000000000000000000000000000006044820152606401620005a9565b600081815260666020908152604091829020805460ff191660019081179091558251848152918201527f77f1fcfcce67dc392d64f842056d2ec06c80986c47c910f7e79c5b23a2738d7491015b60405180910390a150565b6033546001600160a01b03163314620006ce5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620005a9565b620006d98162001a9c565b50565b6033546001600160a01b03163314620007385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620005a9565b6001600160a01b038216600081815260656020908152604091829020805460ff19168515159081179091558251938452908301527fd0b6b573d5442f7c29fd50d9735ae341581c25c6ed07748d50eda519f1ffa88a910160405180910390a15050565b6000620007a9600a62000ffb565b606860009054906101000a90046001600160a01b03166001600160a01b0316632549dad96040518163ffffffff1660e01b815260040160206040518083038186803b158015620007f857600080fd5b505afa1580156200080d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000833919062002520565b6001600160a01b0316336001600160a01b031614620008955760405162461bcd60e51b815260206004820152600f60248201527f4e6f74207374616b696e67207a617000000000000000000000000000000000006044820152606401620005a9565b6068546040517fdbe66ca00000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b039091169063dbe66ca09060240160206040518083038186803b158015620008f257600080fd5b505afa15801562000907573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200092d9190620025aa565b6200097b5760405162461bcd60e51b815260206004820152601060248201527f4e6f7420666565206578636c75646564000000000000000000000000000000006044820152606401620005a9565b60006200098b8685878662001b5c565b604080518a8152602081018a9052808201839052606081018890526001600160a01b038916608082015290519194507ff6d712df0bc2e9953a525976e57448a1dcb9b85f49402ab6cce0cea20fc5249c935081900360a0019150a195945050505050565b600080620009fd84620004c8565b6040516370a0823160e01b81526001600160a01b038581166004830152919250908216906370a08231906024015b60206040518083038186803b15801562000a4457600080fd5b505afa15801562000a59573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000a7f91906200268c565b9150505b92915050565b6033546001600160a01b0316331462000ae55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620005a9565b6212750081111562000b3a5760405162461bcd60e51b815260206004820152600d60248201527f4c6f636b20746f6f206c6f6e67000000000000000000000000000000000000006044820152606401620005a9565b606955565b6068546040516340d1b7db60e11b81526004810183905260009182916001600160a01b03909116906381a36fb69060240160206040518083038186803b15801562000b8957600080fd5b505afa15801562000b9e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000bc4919062002520565b9050600062000bd3826200132b565b90506001600160a01b03811662000c2d5760405162461bcd60e51b815260206004820152601360248201527f58546f6b656e206e6f74206465706c6f796564000000000000000000000000006044820152606401620005a9565b6000670de0b6b3a764000090506000826001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801562000c7657600080fd5b505afa15801562000c8b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000cb191906200268c565b1162000cbe578062000dc8565b816001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801562000cf857600080fd5b505afa15801562000d0d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d3391906200268c565b6040516370a0823160e01b81526001600160a01b0384811660048301528516906370a082319060240160206040518083038186803b15801562000d7557600080fd5b505afa15801562000d8a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000db091906200268c565b62000dbc90836200283a565b62000dc8919062002819565b95945050505050565b6068546040516340d1b7db60e11b8152600481018490526000916001600160a01b0316906381a36fb69060240160206040518083038186803b15801562000e1757600080fd5b505afa15801562000e2c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e52919062002520565b9050600062000e61826200132b565b6040517f19e616a3000000000000000000000000000000000000000000000000000000008152336004820152602481018590529091506000906001600160a01b038316906319e616a390604401602060405180830381600087803b15801562000ec957600080fd5b505af115801562000ede573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f0491906200268c565b60408051878152602081018390529081018690523360608201529091507f3049105fcf2a17b0c1862f64c05a6b2df2176ea17686f7cbf2689887594dd2f89060800160405180910390a15050505050565b6033546001600160a01b0316331462000fb15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620005a9565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b60008181526066602052604090205460ff1615806200102457506033546001600160a01b031633145b620006d95760405162461bcd60e51b815260206004820152600660248201527f50617573656400000000000000000000000000000000000000000000000000006044820152606401620005a9565b606a546000906001600160a01b03166200108f5750600062000a83565b606a546040517f81e97b660000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015260248201859052909116906381e97b669060440160206040518083038186803b158015620010f557600080fd5b505afa1580156200110a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620011309190620025aa565b905062000a83565b6033546001600160a01b03163314620011945760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620005a9565b606a80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff1680620011d0575060005460ff16155b620012355760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620005a9565b600054610100900460ff1615801562001258576000805461ffff19166101011790555b6200126262001cb9565b606880546001600160a01b0319166001600160a01b0384161790556040516000906200128e90620024e5565b604051809103906000f080158015620012ab573d6000803e3d6000fd5b509050620012b9816200145d565b508015620012cd576000805461ff00191690555b5050565b600080620012df84620004c8565b6040517fc19ea0530000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301529192509082169063c19ea0539060240162000a2b565b6040516bffffffffffffffffffffffff19606083901b16602082015260009081906034016040516020818303038152906040528051906020012090506000620013a182604051806020016200138090620024f3565b6020820181038252601f19601f820116604052508051906020012062001d84565b949350505050565b620013b5600a62000ffb565b6000620013c3338462001072565b620013d157606954620013d4565b60005b90506000806000620013e98633878762001b5c565b91945092509050620014076001600160a01b03841633848862001df9565b6040805187815260208101879052908101829052606081018590523360808201527ff6d712df0bc2e9953a525976e57448a1dcb9b85f49402ab6cce0cea20fc5249c9060a00160405180910390a1505050505050565b600054610100900460ff168062001477575060005460ff16155b620014dc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620005a9565b600054610100900460ff16158015620014ff576000805461ffff19166101011790555b6200150a8262001a9c565b8015620012cd576000805461ff00191690555050565b6068546040516340d1b7db60e11b8152600481018390526000916001600160a01b0316906381a36fb69060240160206040518083038186803b1580156200156657600080fd5b505afa1580156200157b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620015a1919062002520565b90506000620015b0826200132b565b9050803b15620015bf57505050565b6000620015cc8362001e89565b604080518681526001600160a01b03868116602083015283168183015290519192507fb3f4e35b757d28b36d957b4485e408df4f1b3a43f1fe56a7a74eb66f9904d734919081900360600190a150505050565b6033546001600160a01b031633146200167b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620005a9565b6001600160a01b038116620016f95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401620005a9565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b60006200176a6033546001600160a01b031690565b6001600160a01b0316336001600160a01b03161480620018245750606860009054906101000a90046001600160a01b03166001600160a01b0316630d43e8ad6040518163ffffffff1660e01b815260040160206040518083038186803b158015620017d457600080fd5b505afa158015620017e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200180f919062002520565b6001600160a01b0316336001600160a01b0316145b620018725760405162461bcd60e51b815260206004820152601960248201527f4c505374616b696e673a204e6f7420617574686f72697a6564000000000000006044820152606401620005a9565b6068546040516340d1b7db60e11b8152600481018590526000916001600160a01b0316906381a36fb69060240160206040518083038186803b158015620018b857600080fd5b505afa158015620018cd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018f3919062002520565b9050600062001902826200132b565b9050803b1580620019855750806001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200194857600080fd5b505afa1580156200195d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200198391906200268c565b155b15620019975760009250505062000a83565b620019ae6001600160a01b03831633838762001df9565b60408051868152602081018690527f0299314386021feac38b734d748626da8e75d6abb4e6a897c0f9c8f23ff42715910160405180910390a1506001949350505050565b6033546001600160a01b0316331462001a4e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620005a9565b6000818152606660209081526040808320805460ff191690558051848152918201929092527f77f1fcfcce67dc392d64f842056d2ec06c80986c47c910f7e79c5b23a2738d74910162000667565b803b62001b125760405162461bcd60e51b815260206004820152603960248201527f5570677261646561626c65426561636f6e3a206368696c6420696d706c656d6560448201527f6e746174696f6e206973206e6f74206120636f6e7472616374000000000000006064820152608401620005a9565b606780546001600160a01b0319166001600160a01b0383169081179091556040517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b600080600062001b6c8762001520565b6068546040516340d1b7db60e11b8152600481018990526000916001600160a01b0316906381a36fb69060240160206040518083038186803b15801562001bb257600080fd5b505afa15801562001bc7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001bed919062002520565b9050600062001bfc826200132b565b6040517f7efe41b10000000000000000000000000000000000000000000000000000000081526001600160a01b038a81166004830152602482018a905260448201899052919250600091831690637efe41b190606401602060405180830381600087803b15801562001c6d57600080fd5b505af115801562001c82573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001ca891906200268c565b929a91995091975095505050505050565b600054610100900460ff168062001cd3575060005460ff16155b62001d385760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620005a9565b600054610100900460ff1615801562001d5b576000805461ffff19166101011790555b62001d6562002023565b62001d6f620020d9565b8015620006d9576000805461ff001916905550565b604080517fff000000000000000000000000000000000000000000000000000000000000006020808301919091526bffffffffffffffffffffffff193060601b1660218301526035820185905260558083018590528351808403909101815260759092019092528051910120600090620005b2565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905262001e83908590620021d3565b50505050565b600080826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801562001ec657600080fd5b505afa15801562001edb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262001f059190810190620025c9565b90508060405160200162001f1a91906200277b565b60408051601f19818403018152908290526bffffffffffffffffffffffff19606086901b1660208301529150600090603401604051602081830303815290604052805190602001209050600062001f986000836040518060200162001f7f90620024f3565b601f1982820381018352601f90910116604052620022c4565b6040517f30fe73fd0000000000000000000000000000000000000000000000000000000081529091506001600160a01b038216906330fe73fd9062001fe690889087908190600401620027c2565b600060405180830381600087803b1580156200200157600080fd5b505af115801562002016573d6000803e3d6000fd5b5092979650505050505050565b600054610100900460ff16806200203d575060005460ff16155b620020a25760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620005a9565b600054610100900460ff1615801562001d6f576000805461ffff19166101011790558015620006d9576000805461ff001916905550565b600054610100900460ff1680620020f3575060005460ff16155b620021585760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620005a9565b600054610100900460ff161580156200217b576000805461ffff19166101011790555b603380546001600160a01b0319163390811790915560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015620006d9576000805461ff001916905550565b60006200222a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316620023cc9092919063ffffffff16565b805190915015620022bf57808060200190518101906200224b9190620025aa565b620022bf5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401620005a9565b505050565b60008084471015620023195760405162461bcd60e51b815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401620005a9565b8251620023695760405162461bcd60e51b815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401620005a9565b8383516020850187f590506001600160a01b038116620013a15760405162461bcd60e51b815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401620005a9565b6060620013a1848460008585843b620024285760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620005a9565b600080866001600160a01b031685876040516200244691906200275d565b60006040518083038185875af1925050503d806000811462002485576040519150601f19603f3d011682016040523d82523d6000602084013e6200248a565b606091505b50915091506200249c828286620024a7565b979650505050505050565b60608315620024b8575081620005b2565b825115620024c95782518084602001fd5b8160405162461bcd60e51b8152600401620005a9919062002804565b611df180620028d183390190565b61081080620046c283390190565b60006020828403121562002513578081fd5b8135620005b281620028ab565b60006020828403121562002532578081fd5b8151620005b281620028ab565b6000806040838503121562002552578081fd5b82356200255f81620028ab565b915060208301356200257181620028c1565b809150509250929050565b600080604083850312156200258f578182fd5b82356200259c81620028ab565b946020939093013593505050565b600060208284031215620025bc578081fd5b8151620005b281620028c1565b600060208284031215620025db578081fd5b815167ffffffffffffffff80821115620025f3578283fd5b818401915084601f83011262002607578283fd5b8151818111156200261c576200261c62002895565b604051601f8201601f19908116603f0116810190838211818310171562002647576200264762002895565b8160405282815287602084870101111562002660578586fd5b6200249c83602083016020880162002866565b60006020828403121562002685578081fd5b5035919050565b6000602082840312156200269e578081fd5b5051919050565b60008060408385031215620026b8578182fd5b8235915060208301356200257181620028ab565b60008060408385031215620026df578182fd5b50508035926020909101359150565b6000806000806080858703121562002704578182fd5b843593506020850135925060408501356200271f81620028ab565b9396929550929360600135925050565b600081518084526200274981602086016020860162002866565b601f01601f19169290920160200192915050565b600082516200277181846020870162002866565b9190910192915050565b7f7800000000000000000000000000000000000000000000000000000000000000815260008251620027b581600185016020870162002866565b9190910160010192915050565b6001600160a01b0384168152606060208201526000620027e660608301856200272f565b8281036040840152620027fa81856200272f565b9695505050505050565b602081526000620005b260208301846200272f565b6000826200283557634e487b7160e01b81526012600452602481fd5b500490565b60008160001904831182151516156200286157634e487b7160e01b81526011600452602481fd5b500290565b60005b838110156200288357818101518382015260200162002869565b8381111562001e835750506000910152565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114620006d957600080fd5b8015158114620006d957600080fdfe608060405234801561001057600080fd5b50611dd1806100206000396000f3fe608060405234801561001057600080fd5b506004361061016c5760003560e01c80637efe41b1116100cd578063b068498d11610081578063c55dae6311610066578063c55dae63146102f4578063dd62ed3e14610307578063f2fde38b1461034057600080fd5b8063b068498d146102b8578063c19ea053146102cb57600080fd5b806395d89b41116100b257806395d89b411461028a578063a457c2d714610292578063a9059cbb146102a557600080fd5b80637efe41b1146102525780638da5cb5b1461026557600080fd5b806330fe73fd116101245780633950935111610109578063395093511461020e57806370a0823114610221578063715018a61461024a57600080fd5b806330fe73fd146101ea578063313ce567146101ff57600080fd5b806318160ddd1161015557806318160ddd146101b257806319e616a3146101c457806323b872dd146101d757600080fd5b806306fdde0314610171578063095ea7b31461018f575b600080fd5b610179610353565b6040516101869190611c67565b60405180910390f35b6101a261019d366004611bb8565b6103e5565b6040519015158152602001610186565b6067545b604051908152602001610186565b6101b66101d2366004611bb8565b6103fb565b6101a26101e5366004611b0c565b610528565b6101fd6101f8366004611b47565b6105f0565b005b60405160128152602001610186565b6101a261021c366004611bb8565b6106e0565b6101b661022f366004611ac0565b6001600160a01b031660009081526065602052604090205490565b6101fd610717565b6101b6610260366004611be1565b6107c8565b6033546001600160a01b03165b6040516001600160a01b039091168152602001610186565b610179610903565b6101a26102a0366004611bb8565b610912565b6101a26102b3366004611bb8565b6109c5565b6101fd6102c6366004611bb8565b6109d2565b6101b66102d9366004611ac0565b6001600160a01b031660009081526098602052604090205490565b609754610272906001600160a01b031681565b6101b6610315366004611ada565b6001600160a01b03918216600090815260666020908152604080832093909416825291909152205490565b6101fd61034e366004611ac0565b610b07565b60606068805461036290611d34565b80601f016020809104026020016040519081016040528092919081815260200182805461038e90611d34565b80156103db5780601f106103b0576101008083540402835291602001916103db565b820191906000526020600020905b8154815290600101906020018083116103be57829003601f168201915b5050505050905090565b60006103f2338484610c46565b50600192915050565b6033546000906001600160a01b0316331461045d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b600061046860675490565b6097546040516370a0823160e01b815230600482015291925060009183916001600160a01b0316906370a082319060240160206040518083038186803b1580156104b157600080fd5b505afa1580156104c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e99190611c33565b6104f39086611cd2565b6104fd9190611cb2565b90506105098585610d9f565b609754610520906001600160a01b03168683610e02565b949350505050565b6000610535848484610e82565b6001600160a01b0384166000908152606660209081526040808320338452909152902054828110156105cf5760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610454565b6105e385336105de8685611cf1565b610c46565b60019150505b9392505050565b600054610100900460ff1680610609575060005460ff16155b61066c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff1615801561068e576000805461ffff19166101011790555b610696610ee2565b6106a08383610fa5565b6097805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03861617905580156106da576000805461ff00191690555b50505050565b3360008181526066602090815260408083206001600160a01b038716845290915281205490916103f29185906105de908690611c9a565b6033546001600160a01b031633146107715760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610454565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a36033805473ffffffffffffffffffffffffffffffffffffffff19169055565b6033546000906001600160a01b031633146108255760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610454565b6097546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561086957600080fd5b505afa15801561087d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a19190611c33565b905060006108ae60675490565b90508015806108bb575081155b156108d5576108cb86868661106b565b84925050506105e9565b6000826108e28388611cd2565b6108ec9190611cb2565b90506108f987828761106b565b92506105e9915050565b60606069805461036290611d34565b3360009081526066602090815260408083206001600160a01b0386168452909152812054828110156109ac5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610454565b6109bb33856105de8685611cf1565b5060019392505050565b60006103f2338484610e82565b6033546001600160a01b03163314610a2c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610454565b62278d008110610a7e5760405162461bcd60e51b815260206004820152600d60248201527f546f6f206c6f6e67206c6f636b000000000000000000000000000000000000006044820152606401610454565b6000610a8a8242611c9a565b6001600160a01b038416600090815260986020526040902054909150811115610b02576001600160a01b038316600081815260986020908152604091829020849055815192835282018390527f38f63775093182d55eb9f15cb41c506fd976eadb1b4544ba0aeaed494ee70cde910160405180910390a15b505050565b6033546001600160a01b03163314610b615760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610454565b6001600160a01b038116610bdd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610454565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36033805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6001600160a01b038316610cc15760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b038216610d3d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b0383811660008181526066602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b0382166000908152609860205260409020544211610df45760405162461bcd60e51b815260206004820152600b60248201526a155cd95c881b1bd8dad95960aa1b6044820152606401610454565b610dfe828261107f565b5050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610b02908490611205565b6001600160a01b0383166000908152609860205260409020544211610ed75760405162461bcd60e51b815260206004820152600b60248201526a155cd95c881b1bd8dad95960aa1b6044820152606401610454565b610b028383836112ea565b600054610100900460ff1680610efb575060005460ff16155b610f5e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff16158015610f80576000805461ffff19166101011790555b610f8861150b565b610f906115bc565b8015610fa2576000805461ff00191690555b50565b600054610100900460ff1680610fbe575060005460ff16155b6110215760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff16158015611043576000805461ffff19166101011790555b61104b61150b565b61105583836116be565b8015610b02576000805461ff0019169055505050565b61107583826109d2565b610b02838361179a565b6001600160a01b0382166110fb5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b0382166000908152606560205260409020548181101561118a5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610454565b6111948282611cf1565b6001600160a01b038416600090815260656020526040812091909155606780548492906111c2908490611cf1565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610d92565b600061125a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166118799092919063ffffffff16565b805190915015610b0257808060200190518101906112789190611c13565b610b025760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b0383166113665760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b0382166113e25760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b038316600090815260656020526040902054818110156114715760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610454565b61147b8282611cf1565b6001600160a01b0380861660009081526065602052604080822093909355908516815290812080548492906114b1908490611c9a565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516114fd91815260200190565b60405180910390a350505050565b600054610100900460ff1680611524575060005460ff16155b6115875760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff16158015610f90576000805461ffff19166101011790558015610fa2576000805461ff001916905550565b600054610100900460ff16806115d5575060005460ff16155b6116385760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff1615801561165a576000805461ffff19166101011790555b6033805473ffffffffffffffffffffffffffffffffffffffff19163390811790915560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015610fa2576000805461ff001916905550565b600054610100900460ff16806116d7575060005460ff16155b61173a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff1615801561175c576000805461ffff19166101011790555b825161176f906068906020860190611984565b508151611783906069906020850190611984565b508015610b02576000805461ff0019169055505050565b6001600160a01b0382166117f05760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610454565b80606760008282546118029190611c9a565b90915550506001600160a01b0382166000908152606560205260408120805483929061182f908490611c9a565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6060610520848460008585843b6118d25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610454565b600080866001600160a01b031685876040516118ee9190611c4b565b60006040518083038185875af1925050503d806000811461192b576040519150601f19603f3d011682016040523d82523d6000602084013e611930565b606091505b509150915061194082828661194b565b979650505050505050565b6060831561195a5750816105e9565b82511561196a5782518084602001fd5b8160405162461bcd60e51b81526004016104549190611c67565b82805461199090611d34565b90600052602060002090601f0160209004810192826119b257600085556119f8565b82601f106119cb57805160ff19168380011785556119f8565b828001600101855582156119f8579182015b828111156119f85782518255916020019190600101906119dd565b50611a04929150611a08565b5090565b5b80821115611a045760008155600101611a09565b80356001600160a01b0381168114611a3457600080fd5b919050565b600082601f830112611a49578081fd5b813567ffffffffffffffff80821115611a6457611a64611d85565b604051601f8301601f19908116603f01168101908282118183101715611a8c57611a8c611d85565b81604052838152866020858801011115611aa4578485fd5b8360208701602083013792830160200193909352509392505050565b600060208284031215611ad1578081fd5b6105e982611a1d565b60008060408385031215611aec578081fd5b611af583611a1d565b9150611b0360208401611a1d565b90509250929050565b600080600060608486031215611b20578081fd5b611b2984611a1d565b9250611b3760208501611a1d565b9150604084013590509250925092565b600080600060608486031215611b5b578283fd5b611b6484611a1d565b9250602084013567ffffffffffffffff80821115611b80578384fd5b611b8c87838801611a39565b93506040860135915080821115611ba1578283fd5b50611bae86828701611a39565b9150509250925092565b60008060408385031215611bca578182fd5b611bd383611a1d565b946020939093013593505050565b600080600060608486031215611bf5578283fd5b611bfe84611a1d565b95602085013595506040909401359392505050565b600060208284031215611c24578081fd5b815180151581146105e9578182fd5b600060208284031215611c44578081fd5b5051919050565b60008251611c5d818460208701611d08565b9190910192915050565b6020815260008251806020840152611c86816040850160208701611d08565b601f01601f19169190910160400192915050565b60008219821115611cad57611cad611d6f565b500190565b600082611ccd57634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615611cec57611cec611d6f565b500290565b600082821015611d0357611d03611d6f565b500390565b60005b83811015611d23578181015183820152602001611d0b565b838111156106da5750506000910152565b600181811c90821680611d4857607f821691505b60208210811415611d6957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fdfea264697066735822122040d75194fc955c16ccd88d9d8637a1e44b3af7985d0d846c656af30fa10d873b64736f6c63430008040033608060405261002f60017fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d51610451565b6000805160206107cf8339815191521461005957634e487b7160e01b600052600160045260246000fd5b610078336040518060200160405280600081525061007d60201b60201c565b6104a0565b6100908261023860201b6100291760201c565b6100ef5760405162461bcd60e51b815260206004820152602560248201527f426561636f6e50726f78793a20626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b610172826001600160a01b031663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561012b57600080fd5b505afa15801561013f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016391906103db565b61023860201b6100291760201c565b6101e45760405162461bcd60e51b815260206004820152603460248201527f426561636f6e50726f78793a20626561636f6e20696d706c656d656e7461746960448201527f6f6e206973206e6f74206120636f6e747261637400000000000000000000000060648201526084016100e6565b6000805160206107cf8339815191528281558151156102335761023161020861023e565b836040518060600160405280602181526020016107ef602191396102cb60201b61002f1760201c565b505b505050565b3b151590565b60006102566000805160206107cf8339815191525490565b6001600160a01b031663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561028e57600080fd5b505afa1580156102a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c691906103db565b905090565b6060833b61032a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016100e6565b600080856001600160a01b0316856040516103459190610402565b600060405180830381855af49150503d8060008114610380576040519150601f19603f3d011682016040523d82523d6000602084013e610385565b606091505b5090925090506103968282866103a2565b925050505b9392505050565b606083156103b157508161039b565b8251156103c15782518084602001fd5b8160405162461bcd60e51b81526004016100e6919061041e565b6000602082840312156103ec578081fd5b81516001600160a01b038116811461039b578182fd5b60008251610414818460208701610474565b9190910192915050565b602081526000825180602084015261043d816040850160208701610474565b601f01601f19169190910160400192915050565b60008282101561046f57634e487b7160e01b81526011600452602481fd5b500390565b60005b8381101561048f578181015183820152602001610477565b838111156102315750506000910152565b610320806104af6000396000f3fe60806040523661001357610011610017565b005b6100115b61002761002261012e565b6101da565b565b3b151590565b6060833b6100aa5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516100d2919061026b565b600060405180830381855af49150503d806000811461010d576040519150601f19603f3d011682016040523d82523d6000602084013e610112565b606091505b50915091506101228282866101fe565b925050505b9392505050565b60006101587fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d505490565b73ffffffffffffffffffffffffffffffffffffffff1663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561019d57600080fd5b505afa1580156101b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d59190610237565b905090565b3660008037600080366000845af43d6000803e8080156101f9573d6000f35b3d6000fd5b6060831561020d575081610127565b82511561021d5782518084602001fd5b8160405162461bcd60e51b81526004016100a19190610287565b600060208284031215610248578081fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114610127578182fd5b6000825161027d8184602087016102ba565b9190910192915050565b60208152600082518060208401526102a68160408501602087016102ba565b601f01601f19169190910160400192915050565b60005b838110156102d55781810151838201526020016102bd565b838111156102e4576000848401525b5050505056fea2646970667358221220186f38c9868951054a26d8e78dfc388c93ba31dab42cd0982029e5f5f85fc42164736f6c63430008040033a3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50426561636f6e50726f78793a2066756e6374696f6e2063616c6c206661696c6564a26469706673582212209bee0939b18509884aa33c58a84bbeb7a8061727973ff5e9ca096e155a43b28864736f6c63430008040033
Deployed Bytecode
0x60806040523480156200001157600080fd5b5060043610620001f55760003560e01c80637c77b6161162000119578063cda13d6711620000af578063f0f2a4d7116200007a578063f0f2a4d7146200046c578063f2fde38b1462000483578063f36d52da146200049a578063fabc1cbc14620004b157600080fd5b8063cda13d671462000415578063da525716146200042c578063e2bbb158146200043e578063e5956027146200045557600080fd5b806392054f8b11620000f057806392054f8b14620003aa578063a2700d7814620003c1578063bdf2a43c14620003d8578063c23c6da014620003fe57600080fd5b80637c77b616146200036a578063881b2f2d14620003815780638da5cb5b146200039857600080fd5b80633656eec2116200018f5780633a2950af11620001665780633a2950af146200031b5780634363fcd21462000332578063441a3e701462000349578063715018a6146200036057600080fd5b80633656eec214620002e657806337ce42bf14620002fd5780633801daf1146200030757600080fd5b8063136439dd11620001d0578063136439dd14620002795780631f1713fc146200029257806323845fb514620002a95780632699f55a14620002c057600080fd5b8063034fc83c14620001fa5780630c68ba21146200022e57806311ad9d381462000265575b600080fd5b620002116200020b36600462002673565b620004c8565b6040516001600160a01b0390911681526020015b60405180910390f35b620002546200023f36600462002501565b60656020526000908152604090205460ff1681565b604051901515815260200162000225565b606a5462000211906001600160a01b031681565b620002906200028a36600462002673565b620005b9565b005b62000290620002a336600462002501565b62000672565b62000290620002ba3660046200253f565b620006dc565b620002d7620002d1366004620026ee565b6200079b565b60405190815260200162000225565b620002d7620002f7366004620026a5565b620009ef565b620002d760695481565b60685462000211906001600160a01b031681565b620002906200032c36600462002673565b62000a89565b620002d76200034336600462002673565b62000b3f565b620002906200035a366004620026cc565b62000dd1565b6200029062000f55565b620002906200037b36600462002673565b62000ffb565b62000254620003923660046200257c565b62001072565b6033546001600160a01b031662000211565b62000290620003bb36600462002501565b62001138565b62000290620003d236600462002501565b620011b6565b62000254620003e936600462002673565b60666020526000908152604090205460ff1681565b620002d76200040f366004620026a5565b620012d1565b620002116200042636600462002501565b6200132b565b6067546001600160a01b031662000211565b620002906200044f366004620026cc565b620013a9565b620002906200046636600462002501565b6200145d565b620002906200047d36600462002673565b62001520565b620002906200049436600462002501565b6200161f565b62000254620004ab366004620026cc565b62001755565b62000290620004c236600462002673565b620019f2565b6068546040516340d1b7db60e11b81526004810183905260009182916001600160a01b03909116906381a36fb69060240160206040518083038186803b1580156200051257600080fd5b505afa15801562000527573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200054d919062002520565b905060006200055c826200132b565b9050803b620005b25760405162461bcd60e51b815260206004820152601360248201527f58546f6b656e206e6f74206465706c6f7965640000000000000000000000000060448201526064015b60405180910390fd5b9392505050565b3360009081526065602052604090205460ff166200061a5760405162461bcd60e51b815260206004820152600b60248201527f43616e27742070617573650000000000000000000000000000000000000000006044820152606401620005a9565b600081815260666020908152604091829020805460ff191660019081179091558251848152918201527f77f1fcfcce67dc392d64f842056d2ec06c80986c47c910f7e79c5b23a2738d7491015b60405180910390a150565b6033546001600160a01b03163314620006ce5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620005a9565b620006d98162001a9c565b50565b6033546001600160a01b03163314620007385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620005a9565b6001600160a01b038216600081815260656020908152604091829020805460ff19168515159081179091558251938452908301527fd0b6b573d5442f7c29fd50d9735ae341581c25c6ed07748d50eda519f1ffa88a910160405180910390a15050565b6000620007a9600a62000ffb565b606860009054906101000a90046001600160a01b03166001600160a01b0316632549dad96040518163ffffffff1660e01b815260040160206040518083038186803b158015620007f857600080fd5b505afa1580156200080d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000833919062002520565b6001600160a01b0316336001600160a01b031614620008955760405162461bcd60e51b815260206004820152600f60248201527f4e6f74207374616b696e67207a617000000000000000000000000000000000006044820152606401620005a9565b6068546040517fdbe66ca00000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b039091169063dbe66ca09060240160206040518083038186803b158015620008f257600080fd5b505afa15801562000907573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200092d9190620025aa565b6200097b5760405162461bcd60e51b815260206004820152601060248201527f4e6f7420666565206578636c75646564000000000000000000000000000000006044820152606401620005a9565b60006200098b8685878662001b5c565b604080518a8152602081018a9052808201839052606081018890526001600160a01b038916608082015290519194507ff6d712df0bc2e9953a525976e57448a1dcb9b85f49402ab6cce0cea20fc5249c935081900360a0019150a195945050505050565b600080620009fd84620004c8565b6040516370a0823160e01b81526001600160a01b038581166004830152919250908216906370a08231906024015b60206040518083038186803b15801562000a4457600080fd5b505afa15801562000a59573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000a7f91906200268c565b9150505b92915050565b6033546001600160a01b0316331462000ae55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620005a9565b6212750081111562000b3a5760405162461bcd60e51b815260206004820152600d60248201527f4c6f636b20746f6f206c6f6e67000000000000000000000000000000000000006044820152606401620005a9565b606955565b6068546040516340d1b7db60e11b81526004810183905260009182916001600160a01b03909116906381a36fb69060240160206040518083038186803b15801562000b8957600080fd5b505afa15801562000b9e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000bc4919062002520565b9050600062000bd3826200132b565b90506001600160a01b03811662000c2d5760405162461bcd60e51b815260206004820152601360248201527f58546f6b656e206e6f74206465706c6f796564000000000000000000000000006044820152606401620005a9565b6000670de0b6b3a764000090506000826001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801562000c7657600080fd5b505afa15801562000c8b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000cb191906200268c565b1162000cbe578062000dc8565b816001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801562000cf857600080fd5b505afa15801562000d0d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d3391906200268c565b6040516370a0823160e01b81526001600160a01b0384811660048301528516906370a082319060240160206040518083038186803b15801562000d7557600080fd5b505afa15801562000d8a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000db091906200268c565b62000dbc90836200283a565b62000dc8919062002819565b95945050505050565b6068546040516340d1b7db60e11b8152600481018490526000916001600160a01b0316906381a36fb69060240160206040518083038186803b15801562000e1757600080fd5b505afa15801562000e2c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e52919062002520565b9050600062000e61826200132b565b6040517f19e616a3000000000000000000000000000000000000000000000000000000008152336004820152602481018590529091506000906001600160a01b038316906319e616a390604401602060405180830381600087803b15801562000ec957600080fd5b505af115801562000ede573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f0491906200268c565b60408051878152602081018390529081018690523360608201529091507f3049105fcf2a17b0c1862f64c05a6b2df2176ea17686f7cbf2689887594dd2f89060800160405180910390a15050505050565b6033546001600160a01b0316331462000fb15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620005a9565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b60008181526066602052604090205460ff1615806200102457506033546001600160a01b031633145b620006d95760405162461bcd60e51b815260206004820152600660248201527f50617573656400000000000000000000000000000000000000000000000000006044820152606401620005a9565b606a546000906001600160a01b03166200108f5750600062000a83565b606a546040517f81e97b660000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015260248201859052909116906381e97b669060440160206040518083038186803b158015620010f557600080fd5b505afa1580156200110a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620011309190620025aa565b905062000a83565b6033546001600160a01b03163314620011945760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620005a9565b606a80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff1680620011d0575060005460ff16155b620012355760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620005a9565b600054610100900460ff1615801562001258576000805461ffff19166101011790555b6200126262001cb9565b606880546001600160a01b0319166001600160a01b0384161790556040516000906200128e90620024e5565b604051809103906000f080158015620012ab573d6000803e3d6000fd5b509050620012b9816200145d565b508015620012cd576000805461ff00191690555b5050565b600080620012df84620004c8565b6040517fc19ea0530000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301529192509082169063c19ea0539060240162000a2b565b6040516bffffffffffffffffffffffff19606083901b16602082015260009081906034016040516020818303038152906040528051906020012090506000620013a182604051806020016200138090620024f3565b6020820181038252601f19601f820116604052508051906020012062001d84565b949350505050565b620013b5600a62000ffb565b6000620013c3338462001072565b620013d157606954620013d4565b60005b90506000806000620013e98633878762001b5c565b91945092509050620014076001600160a01b03841633848862001df9565b6040805187815260208101879052908101829052606081018590523360808201527ff6d712df0bc2e9953a525976e57448a1dcb9b85f49402ab6cce0cea20fc5249c9060a00160405180910390a1505050505050565b600054610100900460ff168062001477575060005460ff16155b620014dc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620005a9565b600054610100900460ff16158015620014ff576000805461ffff19166101011790555b6200150a8262001a9c565b8015620012cd576000805461ff00191690555050565b6068546040516340d1b7db60e11b8152600481018390526000916001600160a01b0316906381a36fb69060240160206040518083038186803b1580156200156657600080fd5b505afa1580156200157b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620015a1919062002520565b90506000620015b0826200132b565b9050803b15620015bf57505050565b6000620015cc8362001e89565b604080518681526001600160a01b03868116602083015283168183015290519192507fb3f4e35b757d28b36d957b4485e408df4f1b3a43f1fe56a7a74eb66f9904d734919081900360600190a150505050565b6033546001600160a01b031633146200167b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620005a9565b6001600160a01b038116620016f95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401620005a9565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b60006200176a6033546001600160a01b031690565b6001600160a01b0316336001600160a01b03161480620018245750606860009054906101000a90046001600160a01b03166001600160a01b0316630d43e8ad6040518163ffffffff1660e01b815260040160206040518083038186803b158015620017d457600080fd5b505afa158015620017e9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200180f919062002520565b6001600160a01b0316336001600160a01b0316145b620018725760405162461bcd60e51b815260206004820152601960248201527f4c505374616b696e673a204e6f7420617574686f72697a6564000000000000006044820152606401620005a9565b6068546040516340d1b7db60e11b8152600481018590526000916001600160a01b0316906381a36fb69060240160206040518083038186803b158015620018b857600080fd5b505afa158015620018cd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018f3919062002520565b9050600062001902826200132b565b9050803b1580620019855750806001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200194857600080fd5b505afa1580156200195d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200198391906200268c565b155b15620019975760009250505062000a83565b620019ae6001600160a01b03831633838762001df9565b60408051868152602081018690527f0299314386021feac38b734d748626da8e75d6abb4e6a897c0f9c8f23ff42715910160405180910390a1506001949350505050565b6033546001600160a01b0316331462001a4e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620005a9565b6000818152606660209081526040808320805460ff191690558051848152918201929092527f77f1fcfcce67dc392d64f842056d2ec06c80986c47c910f7e79c5b23a2738d74910162000667565b803b62001b125760405162461bcd60e51b815260206004820152603960248201527f5570677261646561626c65426561636f6e3a206368696c6420696d706c656d6560448201527f6e746174696f6e206973206e6f74206120636f6e7472616374000000000000006064820152608401620005a9565b606780546001600160a01b0319166001600160a01b0383169081179091556040517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b600080600062001b6c8762001520565b6068546040516340d1b7db60e11b8152600481018990526000916001600160a01b0316906381a36fb69060240160206040518083038186803b15801562001bb257600080fd5b505afa15801562001bc7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001bed919062002520565b9050600062001bfc826200132b565b6040517f7efe41b10000000000000000000000000000000000000000000000000000000081526001600160a01b038a81166004830152602482018a905260448201899052919250600091831690637efe41b190606401602060405180830381600087803b15801562001c6d57600080fd5b505af115801562001c82573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001ca891906200268c565b929a91995091975095505050505050565b600054610100900460ff168062001cd3575060005460ff16155b62001d385760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620005a9565b600054610100900460ff1615801562001d5b576000805461ffff19166101011790555b62001d6562002023565b62001d6f620020d9565b8015620006d9576000805461ff001916905550565b604080517fff000000000000000000000000000000000000000000000000000000000000006020808301919091526bffffffffffffffffffffffff193060601b1660218301526035820185905260558083018590528351808403909101815260759092019092528051910120600090620005b2565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905262001e83908590620021d3565b50505050565b600080826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801562001ec657600080fd5b505afa15801562001edb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262001f059190810190620025c9565b90508060405160200162001f1a91906200277b565b60408051601f19818403018152908290526bffffffffffffffffffffffff19606086901b1660208301529150600090603401604051602081830303815290604052805190602001209050600062001f986000836040518060200162001f7f90620024f3565b601f1982820381018352601f90910116604052620022c4565b6040517f30fe73fd0000000000000000000000000000000000000000000000000000000081529091506001600160a01b038216906330fe73fd9062001fe690889087908190600401620027c2565b600060405180830381600087803b1580156200200157600080fd5b505af115801562002016573d6000803e3d6000fd5b5092979650505050505050565b600054610100900460ff16806200203d575060005460ff16155b620020a25760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620005a9565b600054610100900460ff1615801562001d6f576000805461ffff19166101011790558015620006d9576000805461ff001916905550565b600054610100900460ff1680620020f3575060005460ff16155b620021585760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620005a9565b600054610100900460ff161580156200217b576000805461ffff19166101011790555b603380546001600160a01b0319163390811790915560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015620006d9576000805461ff001916905550565b60006200222a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316620023cc9092919063ffffffff16565b805190915015620022bf57808060200190518101906200224b9190620025aa565b620022bf5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401620005a9565b505050565b60008084471015620023195760405162461bcd60e51b815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401620005a9565b8251620023695760405162461bcd60e51b815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401620005a9565b8383516020850187f590506001600160a01b038116620013a15760405162461bcd60e51b815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401620005a9565b6060620013a1848460008585843b620024285760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620005a9565b600080866001600160a01b031685876040516200244691906200275d565b60006040518083038185875af1925050503d806000811462002485576040519150601f19603f3d011682016040523d82523d6000602084013e6200248a565b606091505b50915091506200249c828286620024a7565b979650505050505050565b60608315620024b8575081620005b2565b825115620024c95782518084602001fd5b8160405162461bcd60e51b8152600401620005a9919062002804565b611df180620028d183390190565b61081080620046c283390190565b60006020828403121562002513578081fd5b8135620005b281620028ab565b60006020828403121562002532578081fd5b8151620005b281620028ab565b6000806040838503121562002552578081fd5b82356200255f81620028ab565b915060208301356200257181620028c1565b809150509250929050565b600080604083850312156200258f578182fd5b82356200259c81620028ab565b946020939093013593505050565b600060208284031215620025bc578081fd5b8151620005b281620028c1565b600060208284031215620025db578081fd5b815167ffffffffffffffff80821115620025f3578283fd5b818401915084601f83011262002607578283fd5b8151818111156200261c576200261c62002895565b604051601f8201601f19908116603f0116810190838211818310171562002647576200264762002895565b8160405282815287602084870101111562002660578586fd5b6200249c83602083016020880162002866565b60006020828403121562002685578081fd5b5035919050565b6000602082840312156200269e578081fd5b5051919050565b60008060408385031215620026b8578182fd5b8235915060208301356200257181620028ab565b60008060408385031215620026df578182fd5b50508035926020909101359150565b6000806000806080858703121562002704578182fd5b843593506020850135925060408501356200271f81620028ab565b9396929550929360600135925050565b600081518084526200274981602086016020860162002866565b601f01601f19169290920160200192915050565b600082516200277181846020870162002866565b9190910192915050565b7f7800000000000000000000000000000000000000000000000000000000000000815260008251620027b581600185016020870162002866565b9190910160010192915050565b6001600160a01b0384168152606060208201526000620027e660608301856200272f565b8281036040840152620027fa81856200272f565b9695505050505050565b602081526000620005b260208301846200272f565b6000826200283557634e487b7160e01b81526012600452602481fd5b500490565b60008160001904831182151516156200286157634e487b7160e01b81526011600452602481fd5b500290565b60005b838110156200288357818101518382015260200162002869565b8381111562001e835750506000910152565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114620006d957600080fd5b8015158114620006d957600080fdfe608060405234801561001057600080fd5b50611dd1806100206000396000f3fe608060405234801561001057600080fd5b506004361061016c5760003560e01c80637efe41b1116100cd578063b068498d11610081578063c55dae6311610066578063c55dae63146102f4578063dd62ed3e14610307578063f2fde38b1461034057600080fd5b8063b068498d146102b8578063c19ea053146102cb57600080fd5b806395d89b41116100b257806395d89b411461028a578063a457c2d714610292578063a9059cbb146102a557600080fd5b80637efe41b1146102525780638da5cb5b1461026557600080fd5b806330fe73fd116101245780633950935111610109578063395093511461020e57806370a0823114610221578063715018a61461024a57600080fd5b806330fe73fd146101ea578063313ce567146101ff57600080fd5b806318160ddd1161015557806318160ddd146101b257806319e616a3146101c457806323b872dd146101d757600080fd5b806306fdde0314610171578063095ea7b31461018f575b600080fd5b610179610353565b6040516101869190611c67565b60405180910390f35b6101a261019d366004611bb8565b6103e5565b6040519015158152602001610186565b6067545b604051908152602001610186565b6101b66101d2366004611bb8565b6103fb565b6101a26101e5366004611b0c565b610528565b6101fd6101f8366004611b47565b6105f0565b005b60405160128152602001610186565b6101a261021c366004611bb8565b6106e0565b6101b661022f366004611ac0565b6001600160a01b031660009081526065602052604090205490565b6101fd610717565b6101b6610260366004611be1565b6107c8565b6033546001600160a01b03165b6040516001600160a01b039091168152602001610186565b610179610903565b6101a26102a0366004611bb8565b610912565b6101a26102b3366004611bb8565b6109c5565b6101fd6102c6366004611bb8565b6109d2565b6101b66102d9366004611ac0565b6001600160a01b031660009081526098602052604090205490565b609754610272906001600160a01b031681565b6101b6610315366004611ada565b6001600160a01b03918216600090815260666020908152604080832093909416825291909152205490565b6101fd61034e366004611ac0565b610b07565b60606068805461036290611d34565b80601f016020809104026020016040519081016040528092919081815260200182805461038e90611d34565b80156103db5780601f106103b0576101008083540402835291602001916103db565b820191906000526020600020905b8154815290600101906020018083116103be57829003601f168201915b5050505050905090565b60006103f2338484610c46565b50600192915050565b6033546000906001600160a01b0316331461045d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b600061046860675490565b6097546040516370a0823160e01b815230600482015291925060009183916001600160a01b0316906370a082319060240160206040518083038186803b1580156104b157600080fd5b505afa1580156104c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e99190611c33565b6104f39086611cd2565b6104fd9190611cb2565b90506105098585610d9f565b609754610520906001600160a01b03168683610e02565b949350505050565b6000610535848484610e82565b6001600160a01b0384166000908152606660209081526040808320338452909152902054828110156105cf5760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610454565b6105e385336105de8685611cf1565b610c46565b60019150505b9392505050565b600054610100900460ff1680610609575060005460ff16155b61066c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff1615801561068e576000805461ffff19166101011790555b610696610ee2565b6106a08383610fa5565b6097805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03861617905580156106da576000805461ff00191690555b50505050565b3360008181526066602090815260408083206001600160a01b038716845290915281205490916103f29185906105de908690611c9a565b6033546001600160a01b031633146107715760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610454565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a36033805473ffffffffffffffffffffffffffffffffffffffff19169055565b6033546000906001600160a01b031633146108255760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610454565b6097546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561086957600080fd5b505afa15801561087d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a19190611c33565b905060006108ae60675490565b90508015806108bb575081155b156108d5576108cb86868661106b565b84925050506105e9565b6000826108e28388611cd2565b6108ec9190611cb2565b90506108f987828761106b565b92506105e9915050565b60606069805461036290611d34565b3360009081526066602090815260408083206001600160a01b0386168452909152812054828110156109ac5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610454565b6109bb33856105de8685611cf1565b5060019392505050565b60006103f2338484610e82565b6033546001600160a01b03163314610a2c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610454565b62278d008110610a7e5760405162461bcd60e51b815260206004820152600d60248201527f546f6f206c6f6e67206c6f636b000000000000000000000000000000000000006044820152606401610454565b6000610a8a8242611c9a565b6001600160a01b038416600090815260986020526040902054909150811115610b02576001600160a01b038316600081815260986020908152604091829020849055815192835282018390527f38f63775093182d55eb9f15cb41c506fd976eadb1b4544ba0aeaed494ee70cde910160405180910390a15b505050565b6033546001600160a01b03163314610b615760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610454565b6001600160a01b038116610bdd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610454565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36033805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6001600160a01b038316610cc15760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b038216610d3d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b0383811660008181526066602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b0382166000908152609860205260409020544211610df45760405162461bcd60e51b815260206004820152600b60248201526a155cd95c881b1bd8dad95960aa1b6044820152606401610454565b610dfe828261107f565b5050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610b02908490611205565b6001600160a01b0383166000908152609860205260409020544211610ed75760405162461bcd60e51b815260206004820152600b60248201526a155cd95c881b1bd8dad95960aa1b6044820152606401610454565b610b028383836112ea565b600054610100900460ff1680610efb575060005460ff16155b610f5e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff16158015610f80576000805461ffff19166101011790555b610f8861150b565b610f906115bc565b8015610fa2576000805461ff00191690555b50565b600054610100900460ff1680610fbe575060005460ff16155b6110215760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff16158015611043576000805461ffff19166101011790555b61104b61150b565b61105583836116be565b8015610b02576000805461ff0019169055505050565b61107583826109d2565b610b02838361179a565b6001600160a01b0382166110fb5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b0382166000908152606560205260409020548181101561118a5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610454565b6111948282611cf1565b6001600160a01b038416600090815260656020526040812091909155606780548492906111c2908490611cf1565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610d92565b600061125a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166118799092919063ffffffff16565b805190915015610b0257808060200190518101906112789190611c13565b610b025760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b0383166113665760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b0382166113e25760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610454565b6001600160a01b038316600090815260656020526040902054818110156114715760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610454565b61147b8282611cf1565b6001600160a01b0380861660009081526065602052604080822093909355908516815290812080548492906114b1908490611c9a565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516114fd91815260200190565b60405180910390a350505050565b600054610100900460ff1680611524575060005460ff16155b6115875760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff16158015610f90576000805461ffff19166101011790558015610fa2576000805461ff001916905550565b600054610100900460ff16806115d5575060005460ff16155b6116385760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff1615801561165a576000805461ffff19166101011790555b6033805473ffffffffffffffffffffffffffffffffffffffff19163390811790915560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015610fa2576000805461ff001916905550565b600054610100900460ff16806116d7575060005460ff16155b61173a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610454565b600054610100900460ff1615801561175c576000805461ffff19166101011790555b825161176f906068906020860190611984565b508151611783906069906020850190611984565b508015610b02576000805461ff0019169055505050565b6001600160a01b0382166117f05760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610454565b80606760008282546118029190611c9a565b90915550506001600160a01b0382166000908152606560205260408120805483929061182f908490611c9a565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6060610520848460008585843b6118d25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610454565b600080866001600160a01b031685876040516118ee9190611c4b565b60006040518083038185875af1925050503d806000811461192b576040519150601f19603f3d011682016040523d82523d6000602084013e611930565b606091505b509150915061194082828661194b565b979650505050505050565b6060831561195a5750816105e9565b82511561196a5782518084602001fd5b8160405162461bcd60e51b81526004016104549190611c67565b82805461199090611d34565b90600052602060002090601f0160209004810192826119b257600085556119f8565b82601f106119cb57805160ff19168380011785556119f8565b828001600101855582156119f8579182015b828111156119f85782518255916020019190600101906119dd565b50611a04929150611a08565b5090565b5b80821115611a045760008155600101611a09565b80356001600160a01b0381168114611a3457600080fd5b919050565b600082601f830112611a49578081fd5b813567ffffffffffffffff80821115611a6457611a64611d85565b604051601f8301601f19908116603f01168101908282118183101715611a8c57611a8c611d85565b81604052838152866020858801011115611aa4578485fd5b8360208701602083013792830160200193909352509392505050565b600060208284031215611ad1578081fd5b6105e982611a1d565b60008060408385031215611aec578081fd5b611af583611a1d565b9150611b0360208401611a1d565b90509250929050565b600080600060608486031215611b20578081fd5b611b2984611a1d565b9250611b3760208501611a1d565b9150604084013590509250925092565b600080600060608486031215611b5b578283fd5b611b6484611a1d565b9250602084013567ffffffffffffffff80821115611b80578384fd5b611b8c87838801611a39565b93506040860135915080821115611ba1578283fd5b50611bae86828701611a39565b9150509250925092565b60008060408385031215611bca578182fd5b611bd383611a1d565b946020939093013593505050565b600080600060608486031215611bf5578283fd5b611bfe84611a1d565b95602085013595506040909401359392505050565b600060208284031215611c24578081fd5b815180151581146105e9578182fd5b600060208284031215611c44578081fd5b5051919050565b60008251611c5d818460208701611d08565b9190910192915050565b6020815260008251806020840152611c86816040850160208701611d08565b601f01601f19169190910160400192915050565b60008219821115611cad57611cad611d6f565b500190565b600082611ccd57634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615611cec57611cec611d6f565b500290565b600082821015611d0357611d03611d6f565b500390565b60005b83811015611d23578181015183820152602001611d0b565b838111156106da5750506000910152565b600181811c90821680611d4857607f821691505b60208210811415611d6957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fdfea264697066735822122040d75194fc955c16ccd88d9d8637a1e44b3af7985d0d846c656af30fa10d873b64736f6c63430008040033608060405261002f60017fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d51610451565b6000805160206107cf8339815191521461005957634e487b7160e01b600052600160045260246000fd5b610078336040518060200160405280600081525061007d60201b60201c565b6104a0565b6100908261023860201b6100291760201c565b6100ef5760405162461bcd60e51b815260206004820152602560248201527f426561636f6e50726f78793a20626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b610172826001600160a01b031663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561012b57600080fd5b505afa15801561013f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016391906103db565b61023860201b6100291760201c565b6101e45760405162461bcd60e51b815260206004820152603460248201527f426561636f6e50726f78793a20626561636f6e20696d706c656d656e7461746960448201527f6f6e206973206e6f74206120636f6e747261637400000000000000000000000060648201526084016100e6565b6000805160206107cf8339815191528281558151156102335761023161020861023e565b836040518060600160405280602181526020016107ef602191396102cb60201b61002f1760201c565b505b505050565b3b151590565b60006102566000805160206107cf8339815191525490565b6001600160a01b031663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561028e57600080fd5b505afa1580156102a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c691906103db565b905090565b6060833b61032a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016100e6565b600080856001600160a01b0316856040516103459190610402565b600060405180830381855af49150503d8060008114610380576040519150601f19603f3d011682016040523d82523d6000602084013e610385565b606091505b5090925090506103968282866103a2565b925050505b9392505050565b606083156103b157508161039b565b8251156103c15782518084602001fd5b8160405162461bcd60e51b81526004016100e6919061041e565b6000602082840312156103ec578081fd5b81516001600160a01b038116811461039b578182fd5b60008251610414818460208701610474565b9190910192915050565b602081526000825180602084015261043d816040850160208701610474565b601f01601f19169190910160400192915050565b60008282101561046f57634e487b7160e01b81526011600452602481fd5b500390565b60005b8381101561048f578181015183820152602001610477565b838111156102315750506000910152565b610320806104af6000396000f3fe60806040523661001357610011610017565b005b6100115b61002761002261012e565b6101da565b565b3b151590565b6060833b6100aa5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516100d2919061026b565b600060405180830381855af49150503d806000811461010d576040519150601f19603f3d011682016040523d82523d6000602084013e610112565b606091505b50915091506101228282866101fe565b925050505b9392505050565b60006101587fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d505490565b73ffffffffffffffffffffffffffffffffffffffff1663da5257166040518163ffffffff1660e01b815260040160206040518083038186803b15801561019d57600080fd5b505afa1580156101b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d59190610237565b905090565b3660008037600080366000845af43d6000803e8080156101f9573d6000f35b3d6000fd5b6060831561020d575081610127565b82511561021d5782518084602001fd5b8160405162461bcd60e51b81526004016100a19190610287565b600060208284031215610248578081fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114610127578182fd5b6000825161027d8184602087016102ba565b9190910192915050565b60208152600082518060208401526102a68160408501602087016102ba565b601f01601f19169190910160400192915050565b60005b838110156102d55781810151838201526020016102bd565b838111156102e4576000848401525b5050505056fea2646970667358221220186f38c9868951054a26d8e78dfc388c93ba31dab42cd0982029e5f5f85fc42164736f6c63430008040033a3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50426561636f6e50726f78793a2066756e6374696f6e2063616c6c206661696c6564a26469706673582212209bee0939b18509884aa33c58a84bbeb7a8061727973ff5e9ca096e155a43b28864736f6c63430008040033
Deployed Bytecode Sourcemap
59197:8206:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65674:289;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;5774:55:1;;;5756:74;;5744:2;5729:18;65674:289:0;;;;;;;;31922:42;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;7904:14:1;;7897:22;7879:41;;7867:2;7852:18;31922:42:0;7834:92:1;59645:47:0;;;;;-1:-1:-1;;;;;59645:47:0;;;32451:184;;;;;;:::i;:::-;;:::i;:::-;;36840:156;;;;;;:::i;:::-;;:::i;32643:177::-;;;;;;:::i;:::-;;:::i;63111:609::-;;;;;;:::i;:::-;;:::i;:::-;;;15083:25:1;;;15071:2;15056:18;63111:609:0;15038:76:1;65039:205:0;;;;;;:::i;:::-;;:::i;59601:37::-;;;;;;59542:50;;;;;-1:-1:-1;;;;;59542:50:0;;;60696:168;;;;;;:::i;:::-;;:::i;64260:550::-;;;;;;:::i;:::-;;:::i;63837:416::-;;;;;;:::i;:::-;;:::i;30983:148::-;;;:::i;32119:143::-;;;;;;:::i;:::-;;:::i;60872:283::-;;;;;;:::i;:::-;;:::i;30332:87::-;30405:6;;-1:-1:-1;;;;;30405:6:0;30332:87;;60556:132;;;;;;:::i;:::-;;:::i;60063:315::-;;;;;;:::i;:::-;;:::i;31971:40::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;64818:213;;;;;;:::i;:::-;;:::i;65368:294::-;;;;;;:::i;:::-;;:::i;36440:124::-;36536:20;;-1:-1:-1;;;;;36536:20:0;36440:124;;62509:594;;;;;;:::i;:::-;;:::i;36203:148::-;;;;;;:::i;:::-;;:::i;61163:395::-;;;;;;:::i;:::-;;:::i;31286:244::-;;;;;;:::i;:::-;;:::i;61566:836::-;;;;;;:::i;:::-;;:::i;32270:173::-;;;;;;:::i;:::-;;:::i;65674:289::-;65790:16;;:31;;-1:-1:-1;;;65790:31:0;;;;;15083:25:1;;;65750:7:0;;;;-1:-1:-1;;;;;65790:16:0;;;;:22;;15056:18:1;;65790:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65770:51;;65832:14;65849:21;65860:9;65849:10;:21::i;:::-;65832:38;-1:-1:-1;67344:20:0;;65881:50;;;;-1:-1:-1;;;65881:50:0;;10330:2:1;65881:50:0;;;10312:21:1;10369:2;10349:18;;;10342:30;10408:21;10388:18;;;10381:49;10447:18;;65881:50:0;;;;;;;;;65949:6;65674:289;-1:-1:-1;;;65674:289:0:o;32451:184::-;32527:10;32516:22;;;;:10;:22;;;;;;;;32508:46;;;;-1:-1:-1;;;32508:46:0;;10678:2:1;32508:46:0;;;10660:21:1;10717:2;10697:18;;;10690:30;10756:13;10736:18;;;10729:41;10787:18;;32508:46:0;10650:161:1;32508:46:0;32565:16;;;;:8;:16;;;;;;;;;:23;;-1:-1:-1;;32565:23:0;32584:4;32565:23;;;;;;32604;;15690:25:1;;;15731:18;;;15724:50;32604:23:0;;15663:18:1;32604:23:0;;;;;;;;32451:184;:::o;36840:156::-;30405:6;;-1:-1:-1;;;;;30405:6:0;28715:10;30552:23;30544:68;;;;-1:-1:-1;;;30544:68:0;;12962:2:1;30544:68:0;;;12944:21:1;;;12981:18;;;12974:30;13040:34;13020:18;;;13013:62;13092:18;;30544:68:0;12934:182:1;30544:68:0;36941:47:::1;36965:22;36941:23;:47::i;:::-;36840:156:::0;:::o;32643:177::-;30405:6;;-1:-1:-1;;;;;30405:6:0;28715:10;30552:23;30544:68;;;;-1:-1:-1;;;30544:68:0;;12962:2:1;30544:68:0;;;12944:21:1;;;12981:18;;;12974:30;13040:34;13020:18;;;13013:62;13092:18;;30544:68:0;12934:182:1;30544:68:0;-1:-1:-1;;;;;32734:16:0;::::1;;::::0;;;:10:::1;:16;::::0;;;;;;;;:30;;-1:-1:-1;;32734:30:0::1;::::0;::::1;;::::0;;::::1;::::0;;;32780:32;;6412:74:1;;;6502:18;;;6495:50;32780:32:0::1;::::0;6385:18:1;32780:32:0::1;;;;;;;32643:177:::0;;:::o;63111:609::-;63240:7;63260:21;63278:2;63260:17;:21::i;:::-;63314:16;;;;;;;;;-1:-1:-1;;;;;63314:16:0;-1:-1:-1;;;;;63314:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;63300:44:0;:10;-1:-1:-1;;;;;63300:44:0;;63292:72;;;;-1:-1:-1;;;63292:72:0;;13668:2:1;63292:72:0;;;13650:21:1;13707:2;13687:18;;;13680:30;13746:17;13726:18;;;13719:45;13781:18;;63292:72:0;13640:165:1;63292:72:0;63383:16;;:45;;;;;63417:10;63383:45;;;5756:74:1;-1:-1:-1;;;;;63383:16:0;;;;:33;;5729:18:1;;63383:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63375:74;;;;-1:-1:-1;;;63375:74:0;;13323:2:1;63375:74:0;;;13305:21:1;13362:2;13342:18;;;13335:30;13401:18;13381;;;13374:46;13437:18;;63375:74:0;13295:166:1;63375:74:0;63528:21;63553:53;63570:7;63579:2;63583:6;63591:14;63553:16;:53::i;:::-;63622:59;;;16742:25:1;;;16798:2;16783:18;;16776:34;;;16826:18;;;16819:34;;;16884:2;16869:18;;16862:34;;;-1:-1:-1;;;;;16933:55:1;;16927:3;16912:19;;16905:84;63622:59:0;;16819:34:1;;-1:-1:-1;63622:59:0;;-1:-1:-1;63622:59:0;;;16729:3:1;63622:59:0;;-1:-1:-1;63622:59:0;63699:13;63111:609;-1:-1:-1;;;;;63111:609:0:o;65039:205::-;65111:7;65131:24;65176:20;65188:7;65176:11;:20::i;:::-;65215:21;;-1:-1:-1;;;65215:21:0;;-1:-1:-1;;;;;5774:55:1;;;65215:21:0;;;5756:74:1;65131:66:0;;-1:-1:-1;65215:16:0;;;;;;5729:18:1;;65215:21:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65208:28;;;65039:205;;;;;:::o;60696:168::-;30405:6;;-1:-1:-1;;;;;30405:6:0;28715:10;30552:23;30544:68;;;;-1:-1:-1;;;30544:68:0;;12962:2:1;30544:68:0;;;12944:21:1;;;12981:18;;;12974:30;13040:34;13020:18;;;13013:62;13092:18;;30544:68:0;12934:182:1;30544:68:0;60791:7:::1;60783:4;:15;;60775:41;;;::::0;-1:-1:-1;;;60775:41:0;;12620:2:1;60775:41:0::1;::::0;::::1;12602:21:1::0;12659:2;12639:18;;;12632:30;12698:15;12678:18;;;12671:43;12731:18;;60775:41:0::1;12592:163:1::0;60775:41:0::1;60827:22;:29:::0;60696:168::o;64260:550::-;64411:16;;:31;;-1:-1:-1;;;64411:31:0;;;;;15083:25:1;;;64343:7:0;;;;-1:-1:-1;;;;;64411:16:0;;;;:22;;15056:18:1;;64411:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64363:80;;64454:24;64499:30;64518:9;64499:10;:30::i;:::-;64454:76;-1:-1:-1;;;;;;64549:29:0;;64541:61;;;;-1:-1:-1;;;64541:61:0;;10330:2:1;64541:61:0;;;10312:21:1;10369:2;10349:18;;;10342:30;10408:21;10388:18;;;10381:49;10447:18;;64541:61:0;10302:169:1;64541:61:0;64615:18;64636:8;64615:29;;64685:1;64662:6;-1:-1:-1;;;;;64662:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:24;:140;;64792:10;64662:140;;;64755:6;-1:-1:-1;;;;;64755:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64716:36;;-1:-1:-1;;;64716:36:0;;-1:-1:-1;;;;;5774:55:1;;;64716:36:0;;;5756:74:1;64716:19:0;;;;;5729:18:1;;64716:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64703:49;;:10;:49;:::i;:::-;:72;;;;:::i;:::-;64655:147;64260:550;-1:-1:-1;;;;;64260:550:0:o;63837:416::-;63973:16;;:31;;-1:-1:-1;;;63973:31:0;;;;;15083:25:1;;;63925:27:0;;-1:-1:-1;;;;;63973:16:0;;:22;;15056:18:1;;63973:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63925:80;;64016:24;64061:30;64080:9;64061:10;:30::i;:::-;64134:38;;;;;64153:10;64134:38;;;7238:74:1;7328:18;;;7321:34;;;64016:76:0;;-1:-1:-1;64105:26:0;;-1:-1:-1;;;;;64134:18:0;;;;;7211::1;;64134:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64188:57;;;16269:25:1;;;16325:2;16310:18;;16303:34;;;16353:18;;;16346:34;;;64234:10:0;16411:2:1;16396:18;;16389:83;64105:67:0;;-1:-1:-1;64188:57:0;;16256:3:1;16241:19;64188:57:0;;;;;;;63837:416;;;;;:::o;30983:148::-;30405:6;;-1:-1:-1;;;;;30405:6:0;28715:10;30552:23;30544:68;;;;-1:-1:-1;;;30544:68:0;;12962:2:1;30544:68:0;;;12944:21:1;;;12981:18;;;12974:30;13040:34;13020:18;;;13013:62;13092:18;;30544:68:0;12934:182:1;30544:68:0;31074:6:::1;::::0;31053:40:::1;::::0;31090:1:::1;::::0;-1:-1:-1;;;;;31074:6:0::1;::::0;31053:40:::1;::::0;31090:1;;31053:40:::1;31104:6;:19:::0;;-1:-1:-1;;;;;;31104:19:0::1;::::0;;30983:148::o;32119:143::-;32202:16;;;;:8;:16;;;;;;;;32201:17;;:42;;-1:-1:-1;30405:6:0;;-1:-1:-1;;;;;30405:6:0;32222:10;:21;32201:42;32193:61;;;;-1:-1:-1;;;32193:61:0;;8874:2:1;32193:61:0;;;8856:21:1;8913:1;8893:18;;;8886:29;8951:8;8931:18;;;8924:36;8977:18;;32193:61:0;8846:155:1;60872:283:0;60988:19;;60959:4;;-1:-1:-1;;;;;60988:19:0;60976:172;;-1:-1:-1;61046:5:0;61039:12;;60976:172;61091:19;;:45;;;;;-1:-1:-1;;;;;7256:55:1;;;61091:45:0;;;7238:74:1;7328:18;;;7321:34;;;61091:19:0;;;;:30;;7211:18:1;;61091:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61084:52;;;;60556:132;30405:6;;-1:-1:-1;;;;;30405:6:0;28715:10;30552:23;30544:68;;;;-1:-1:-1;;;30544:68:0;;12962:2:1;30544:68:0;;;12944:21:1;;;12981:18;;;12974:30;13040:34;13020:18;;;13013:62;13092:18;;30544:68:0;12934:182:1;30544:68:0;60632:19:::1;:48:::0;;-1:-1:-1;;;;;;60632:48:0::1;-1:-1:-1::0;;;;;60632:48:0;;;::::1;::::0;;;::::1;::::0;;60556:132::o;60063:315::-;27456:13;;;;;;;;:30;;-1:-1:-1;27474:12:0;;;;27473:13;27456:30;27448:89;;;;-1:-1:-1;;;27448:89:0;;11425:2:1;27448:89:0;;;11407:21:1;11464:2;11444:18;;;11437:30;11503:34;11483:18;;;11476:62;-1:-1:-1;;;11554:18:1;;;11547:44;11608:19;;27448:89:0;11397:236:1;27448:89:0;27550:19;27573:13;;;;;;27572:14;27597:101;;;;27632:13;:20;;-1:-1:-1;;27667:19:0;;;;;27597:101;60176:16:::1;:14;:16::i;:::-;60203;:55:::0;;-1:-1:-1;;;;;;60203:55:0::1;-1:-1:-1::0;;;;;60203:55:0;::::1;;::::0;;60298:23:::1;::::0;-1:-1:-1;;60298:23:0::1;::::0;::::1;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;60269:53;;60333:37;60359:10;60333:25;:37::i;:::-;27710:1;27728:14:::0;27724:68;;;27775:5;27759:21;;-1:-1:-1;;27759:21:0;;;27724:68;60063:315;;:::o;64818:213::-;64894:7;64914:24;64959:20;64971:7;64959:11;:20::i;:::-;64998:25;;;;;-1:-1:-1;;;;;5774:55:1;;;64998:25:0;;;5756:74:1;64914:66:0;;-1:-1:-1;64998:20:0;;;;;;5729:18:1;;64998:25:0;5711:125:1;65368:294:0;65490:27;;-1:-1:-1;;4324:2:1;4320:15;;;4316:53;65490:27:0;;;4304:66:1;65445:7:0;;;;4386:12:1;;65490:27:0;;;;;;;;;;;;65480:38;;;;;;65465:53;;65529:17;65549:78;65572:4;65588:37;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;65578:48;;;;;;65549:22;:78::i;:::-;65529:98;65368:294;-1:-1:-1;;;;65368:294:0:o;62509:594::-;62597:21;62615:2;62597:17;:21::i;:::-;62631:20;62654:46;62680:10;62692:7;62654:25;:46::i;:::-;:75;;62707:22;;62654:75;;;62703:1;62654:75;62631:98;;62743:27;62772:24;62798:21;62823:60;62840:7;62849:10;62861:7;62870:12;62823:16;:60::i;:::-;62742:141;;-1:-1:-1;62742:141:0;-1:-1:-1;62742:141:0;-1:-1:-1;62949:64:0;-1:-1:-1;;;;;62949:26:0;;62976:10;62742:141;63005:7;62949:26;:64::i;:::-;63029:66;;;16742:25:1;;;16798:2;16783:18;;16776:34;;;16826:18;;;16819:34;;;16884:2;16869:18;;16862:34;;;63084:10:0;16927:3:1;16912:19;;16905:84;63029:66:0;;16729:3:1;16714:19;63029:66:0;;;;;;;62509:594;;;;;;:::o;36203:148::-;27456:13;;;;;;;;:30;;-1:-1:-1;27474:12:0;;;;27473:13;27456:30;27448:89;;;;-1:-1:-1;;;27448:89:0;;11425:2:1;27448:89:0;;;11407:21:1;11464:2;11444:18;;;11437:30;11503:34;11483:18;;;11476:62;-1:-1:-1;;;11554:18:1;;;11547:44;11608:19;;27448:89:0;11397:236:1;27448:89:0;27550:19;27573:13;;;;;;27572:14;27597:101;;;;27632:13;:20;;-1:-1:-1;;27667:19:0;;;;;27597:101;36298:45:::1;36322:20;36298:23;:45::i;:::-;27728:14:::0;27724:68;;;27775:5;27759:21;;-1:-1:-1;;27759:21:0;;;36203:148;;:::o;61163:395::-;61265:16;;:31;;-1:-1:-1;;;61265:31:0;;;;;15083:25:1;;;61245:17:0;;-1:-1:-1;;;;;61265:16:0;;:22;;15056:18:1;;61265:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61245:51;;61307:22;61332:30;61351:9;61332:10;:30::i;:::-;61307:55;-1:-1:-1;67344:20:0;;67383:9;61375:65;;61422:7;;61163:395;:::o;61375:65::-;61452:14;61469:24;61483:9;61469:13;:24::i;:::-;61509:41;;;15321:25:1;;;-1:-1:-1;;;;;15443:15:1;;;15438:2;15423:18;;15416:43;15495:15;;15475:18;;;15468:43;61509:41:0;;15495:15:1;;-1:-1:-1;61509:41:0;;;;;;15309:2:1;61509:41:0;;;61163:395;;;;:::o;31286:244::-;30405:6;;-1:-1:-1;;;;;30405:6:0;28715:10;30552:23;30544:68;;;;-1:-1:-1;;;30544:68:0;;12962:2:1;30544:68:0;;;12944:21:1;;;12981:18;;;12974:30;13040:34;13020:18;;;13013:62;13092:18;;30544:68:0;12934:182:1;30544:68:0;-1:-1:-1;;;;;31375:22:0;::::1;31367:73;;;::::0;-1:-1:-1;;;31367:73:0;;9569:2:1;31367:73:0::1;::::0;::::1;9551:21:1::0;9608:2;9588:18;;;9581:30;9647:34;9627:18;;;9620:62;9718:8;9698:18;;;9691:36;9744:19;;31367:73:0::1;9541:228:1::0;31367:73:0::1;31477:6;::::0;31456:38:::1;::::0;-1:-1:-1;;;;;31456:38:0;;::::1;::::0;31477:6:::1;::::0;31456:38:::1;::::0;31477:6:::1;::::0;31456:38:::1;31505:6;:17:::0;;-1:-1:-1;;;;;;31505:17:0::1;-1:-1:-1::0;;;;;31505:17:0;;;::::1;::::0;;;::::1;::::0;;31286:244::o;61566:836::-;61668:4;60440:7;30405:6;;-1:-1:-1;;;;;30405:6:0;;30332:87;60440:7;-1:-1:-1;;;;;60426:21:0;:10;-1:-1:-1;;;;;60426:21:0;;:72;;;;60465:16;;;;;;;;;-1:-1:-1;;;;;60465:16:0;-1:-1:-1;;;;;60465:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;60451:47:0;:10;-1:-1:-1;;;;;60451:47:0;;60426:72;60418:110;;;;-1:-1:-1;;;60418:110:0;;9976:2:1;60418:110:0;;;9958:21:1;10015:2;9995:18;;;9988:30;10054:27;10034:18;;;10027:55;10099:18;;60418:110:0;9948:175:1;60418:110:0;61705:16:::1;::::0;:31:::1;::::0;-1:-1:-1;;;61705:31:0;;::::1;::::0;::::1;15083:25:1::0;;;61685:17:0::1;::::0;-1:-1:-1;;;;;61705:16:0::1;::::0;:22:::1;::::0;15056:18:1;;61705:31:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61685:51;;61747:22;61772:30;61791:9;61772:10;:30::i;:::-;61747:55:::0;-1:-1:-1;67344:20:0;;67383:9;;62007:83:::1;;;62056:14;-1:-1:-1::0;;;;;62038:45:0::1;;:47;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:52:::0;62007:83:::1;62003:128;;;62114:5;62107:12;;;;;;62003:128;62246:81;-1:-1:-1::0;;;;;62246:45:0;::::1;62292:10;62304:14:::0;62320:6;62246:45:::1;:81::i;:::-;62343:29;::::0;;15959:25:1;;;16015:2;16000:18;;15993:34;;;62343:29:0::1;::::0;15932:18:1;62343:29:0::1;;;;;;;-1:-1:-1::0;62390:4:0::1;::::0;61566:836;-1:-1:-1;;;;61566:836:0:o;32270:173::-;30405:6;;-1:-1:-1;;;;;30405:6:0;28715:10;30552:23;30544:68;;;;-1:-1:-1;;;30544:68:0;;12962:2:1;30544:68:0;;;12944:21:1;;;12981:18;;;12974:30;13040:34;13020:18;;;13013:62;13092:18;;30544:68:0;12934:182:1;30544:68:0;32390:5:::1;32371:16:::0;;;:8:::1;:16;::::0;;;;;;;:24;;-1:-1:-1;;32371:24:0::1;::::0;;32411;;15690:25:1;;;15731:18;;;15724:50;;;;32411:24:0::1;::::0;15663:18:1;32411:24:0::1;15645:135:1::0;37185:308:0;15150:20;;37269:112;;;;-1:-1:-1;;;37269:112:0;;11840:2:1;37269:112:0;;;11822:21:1;11879:2;11859:18;;;11852:30;11918:34;11898:18;;;11891:62;11989:27;11969:18;;;11962:55;12034:19;;37269:112:0;11812:247:1;37269:112:0;37392:20;:45;;-1:-1:-1;;;;;;37392:45:0;-1:-1:-1;;;;;37392:45:0;;;;;;;;37453:32;;;;-1:-1:-1;;37453:32:0;37185:308;:::o;65972:535::-;66091:17;66110;66129:7;66149:29;66170:7;66149:20;:29::i;:::-;66237:16;;:31;;-1:-1:-1;;;66237:31:0;;;;;15083:25:1;;;66189:27:0;;-1:-1:-1;;;;;66237:16:0;;:22;;15056:18:1;;66237:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66189:80;;66280:24;66326:30;66345:9;66326:10;:30::i;:::-;66395:52;;;;;-1:-1:-1;;;;;7586:55:1;;;66395:52:0;;;7568:74:1;7658:18;;;7651:34;;;7701:18;;;7694:34;;;66280:78:0;;-1:-1:-1;66371:21:0;;66395:18;;;;;7541::1;;66395:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66466:9;;66477:6;;-1:-1:-1;66466:9:0;;-1:-1:-1;65972:535:0;-1:-1:-1;;;;;;65972:535:0:o;29918:129::-;27456:13;;;;;;;;:30;;-1:-1:-1;27474:12:0;;;;27473:13;27456:30;27448:89;;;;-1:-1:-1;;;27448:89:0;;11425:2:1;27448:89:0;;;11407:21:1;11464:2;11444:18;;;11437:30;11503:34;11483:18;;;11476:62;-1:-1:-1;;;11554:18:1;;;11547:44;11608:19;;27448:89:0;11397:236:1;27448:89:0;27550:19;27573:13;;;;;;27572:14;27597:101;;;;27632:13;:20;;-1:-1:-1;;27667:19:0;;;;;27597:101;29976:26:::1;:24;:26::i;:::-;30013;:24;:26::i;:::-;27728:14:::0;27724:68;;;27775:5;27759:21;;-1:-1:-1;;27759:21:0;;;29918:129;:::o;34641:167::-;35218:60;;;35235:12;35218:60;;;;4620:92:1;;;;-1:-1:-1;;34794:4:0;4749:2:1;4745:15;4741:53;4728:11;;;4721:74;4811:12;;;4804:28;;;4848:12;;;;4841:28;;;35218:60:0;;;;;;;;;;4885:12:1;;;;35218:60:0;;;35194:95;;;;;34724:7;;34751:49;35057:290;22870:216;23009:68;;;-1:-1:-1;;;;;6122:15:1;;;23009:68:0;;;6104:34:1;6174:15;;6154:18;;;6147:43;6206:18;;;;6199:34;;;23009:68:0;;;;;;;;;;6016:18:1;;;;23009:68:0;;;;;;;;;;23032:27;23009:68;;;22982:96;;23002:5;;22982:19;:96::i;:::-;22870:216;;;;:::o;66515:454::-;66575:7;66595:20;66633:9;-1:-1:-1;;;;;66618:32:0;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;66618:34:0;;;;;;;;;;;;:::i;:::-;66595:57;;66701:6;66679:29;;;;;;;;:::i;:::-;;;;-1:-1:-1;;66679:29:0;;;;;;;;;;-1:-1:-1;;4324:2:1;4320:15;;;4316:53;66679:29:0;66745:27;;4304:66:1;66679:29:0;-1:-1:-1;66720:12:0;;4386::1;;66745:27:0;;;;;;;;;;;;66735:38;;;;;;66720:53;;66784:22;66809:35;66824:1;66827:4;59496:37;;;;;;;;:::i;:::-;-1:-1:-1;;59496:37:0;;;;;;;;;;;;;;66809:14;:35::i;:::-;66855:74;;;;;66784:60;;-1:-1:-1;;;;;;66855:47:0;;;;;:74;;66903:9;;66914:6;;;;66855:74;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66947:14:0;;66515:454;-1:-1:-1;;;;;;;66515:454:0:o;28564:65::-;27456:13;;;;;;;;:30;;-1:-1:-1;27474:12:0;;;;27473:13;27456:30;27448:89;;;;-1:-1:-1;;;27448:89:0;;11425:2:1;27448:89:0;;;11407:21:1;11464:2;11444:18;;;11437:30;11503:34;11483:18;;;11476:62;-1:-1:-1;;;11554:18:1;;;11547:44;11608:19;;27448:89:0;11397:236:1;27448:89:0;27550:19;27573:13;;;;;;27572:14;27597:101;;;;27632:13;:20;;-1:-1:-1;;27667:19:0;;;;;27724:68;;;;27775:5;27759:21;;-1:-1:-1;;27759:21:0;;;28564:65;:::o;30055:196::-;27456:13;;;;;;;;:30;;-1:-1:-1;27474:12:0;;;;27473:13;27456:30;27448:89;;;;-1:-1:-1;;;27448:89:0;;11425:2:1;27448:89:0;;;11407:21:1;11464:2;11444:18;;;11437:30;11503:34;11483:18;;;11476:62;-1:-1:-1;;;11554:18:1;;;11547:44;11608:19;;27448:89:0;11397:236:1;27448:89:0;27550:19;27573:13;;;;;;27572:14;27597:101;;;;27632:13;:20;;-1:-1:-1;;27667:19:0;;;;;27597:101;30166:6:::1;:18:::0;;-1:-1:-1;;;;;;30166:18:0::1;28715:10:::0;30166:18;;::::1;::::0;;;30200:43:::1;::::0;28715:10;;30123:17:::1;::::0;30200:43:::1;::::0;30123:17;;30200:43:::1;27710:1;27728:14:::0;27724:68;;;27775:5;27759:21;;-1:-1:-1;;27759:21:0;;;30055:196;:::o;25163:772::-;25598:23;25624:69;25652:4;25624:69;;;;;;;;;;;;;;;;;25632:5;-1:-1:-1;;;;;25624:27:0;;;:69;;;;;:::i;:::-;25708:17;;25598:95;;-1:-1:-1;25708:21:0;25704:224;;25850:10;25839:30;;;;;;;;;;;;:::i;:::-;25831:85;;;;-1:-1:-1;;;25831:85:0;;14370:2:1;25831:85:0;;;14352:21:1;14409:2;14389:18;;;14382:30;14448:34;14428:18;;;14421:62;14519:12;14499:18;;;14492:40;14549:19;;25831:85:0;14342:232:1;25831:85:0;25163:772;;;:::o;33886:545::-;33973:7;33993:12;34049:6;34024:21;:31;;34016:73;;;;-1:-1:-1;;;34016:73:0;;14781:2:1;34016:73:0;;;14763:21:1;14820:2;14800:18;;;14793:30;14859:31;14839:18;;;14832:59;14908:18;;34016:73:0;14753:179:1;34016:73:0;34108:15;;34100:65;;;;-1:-1:-1;;;34100:65:0;;9208:2:1;34100:65:0;;;9190:21:1;;;9227:18;;;9220:30;9286:34;9266:18;;;9259:62;9338:18;;34100:65:0;9180:182:1;34100:65:0;34319:4;34308:8;34302:15;34295:4;34285:8;34281:19;34273:6;34265:59;34257:67;-1:-1:-1;;;;;;34353:18:0;;34345:56;;;;-1:-1:-1;;;34345:56:0;;12266:2:1;34345:56:0;;;12248:21:1;12305:2;12285:18;;;12278:30;12344:27;12324:18;;;12317:55;12389:18;;34345:56:0;12238:175:1;17701:195:0;17804:12;17836:52;17858:6;17866:4;17872:1;17875:12;17804;15150:20;;18997:60;;;;-1:-1:-1;;;18997:60:0;;14012:2:1;18997:60:0;;;13994:21:1;14051:2;14031:18;;;14024:30;14090:31;14070:18;;;14063:59;14139:18;;18997:60:0;13984:179:1;18997:60:0;19131:12;19145:23;19172:6;-1:-1:-1;;;;;19172:11:0;19192:5;19200:4;19172:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19130:75;;;;19223:52;19241:7;19250:10;19262:12;19223:17;:52::i;:::-;19216:59;18753:530;-1:-1:-1;;;;;;;18753:530:0:o;21293:742::-;21408:12;21437:7;21433:595;;;-1:-1:-1;21468:10:0;21461:17;;21433:595;21582:17;;:21;21578:439;;21845:10;21839:17;21906:15;21893:10;21889:2;21885:19;21878:44;21793:148;21988:12;21981:20;;-1:-1:-1;;;21981:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;:::o;:::-;;;;;;;;:::o;14:257:1:-;73:6;126:2;114:9;105:7;101:23;97:32;94:2;;;147:6;139;132:22;94:2;191:9;178:23;210:31;235:5;210:31;:::i;276:261::-;346:6;399:2;387:9;378:7;374:23;370:32;367:2;;;420:6;412;405:22;367:2;457:9;451:16;476:31;501:5;476:31;:::i;542:392::-;607:6;615;668:2;656:9;647:7;643:23;639:32;636:2;;;689:6;681;674:22;636:2;733:9;720:23;752:31;777:5;752:31;:::i;:::-;802:5;-1:-1:-1;859:2:1;844:18;;831:32;872:30;831:32;872:30;:::i;:::-;921:7;911:17;;;626:308;;;;;:::o;939:325::-;1007:6;1015;1068:2;1056:9;1047:7;1043:23;1039:32;1036:2;;;1089:6;1081;1074:22;1036:2;1133:9;1120:23;1152:31;1177:5;1152:31;:::i;:::-;1202:5;1254:2;1239:18;;;;1226:32;;-1:-1:-1;;;1026:238:1:o;1269:255::-;1336:6;1389:2;1377:9;1368:7;1364:23;1360:32;1357:2;;;1410:6;1402;1395:22;1357:2;1447:9;1441:16;1466:28;1488:5;1466:28;:::i;1529:924::-;1609:6;1662:2;1650:9;1641:7;1637:23;1633:32;1630:2;;;1683:6;1675;1668:22;1630:2;1721:9;1715:16;1750:18;1791:2;1783:6;1780:14;1777:2;;;1812:6;1804;1797:22;1777:2;1855:6;1844:9;1840:22;1830:32;;1900:7;1893:4;1889:2;1885:13;1881:27;1871:2;;1927:6;1919;1912:22;1871:2;1961;1955:9;1983:2;1979;1976:10;1973:2;;;1989:18;;:::i;:::-;2064:2;2058:9;2032:2;2118:13;;-1:-1:-1;;2114:22:1;;;2138:2;2110:31;2106:40;2094:53;;;2162:18;;;2182:22;;;2159:46;2156:2;;;2208:18;;:::i;:::-;2248:10;2244:2;2237:22;2283:2;2275:6;2268:18;2323:7;2318:2;2313;2309;2305:11;2301:20;2298:33;2295:2;;;2349:6;2341;2334:22;2295:2;2367:55;2419:2;2414;2406:6;2402:15;2397:2;2393;2389:11;2367:55;:::i;2458:190::-;2517:6;2570:2;2558:9;2549:7;2545:23;2541:32;2538:2;;;2591:6;2583;2576:22;2538:2;-1:-1:-1;2619:23:1;;2528:120;-1:-1:-1;2528:120:1:o;2653:194::-;2723:6;2776:2;2764:9;2755:7;2751:23;2747:32;2744:2;;;2797:6;2789;2782:22;2744:2;-1:-1:-1;2825:16:1;;2734:113;-1:-1:-1;2734:113:1:o;2852:325::-;2920:6;2928;2981:2;2969:9;2960:7;2956:23;2952:32;2949:2;;;3002:6;2994;2987:22;2949:2;3043:9;3030:23;3020:33;;3103:2;3092:9;3088:18;3075:32;3116:31;3141:5;3116:31;:::i;3182:258::-;3250:6;3258;3311:2;3299:9;3290:7;3286:23;3282:32;3279:2;;;3332:6;3324;3317:22;3279:2;-1:-1:-1;;3360:23:1;;;3430:2;3415:18;;;3402:32;;-1:-1:-1;3269:171:1:o;3445:462::-;3531:6;3539;3547;3555;3608:3;3596:9;3587:7;3583:23;3579:33;3576:2;;;3630:6;3622;3615:22;3576:2;3671:9;3658:23;3648:33;;3728:2;3717:9;3713:18;3700:32;3690:42;;3782:2;3771:9;3767:18;3754:32;3795:31;3820:5;3795:31;:::i;:::-;3566:341;;;;-1:-1:-1;3845:5:1;;3897:2;3882:18;3869:32;;-1:-1:-1;;3566:341:1:o;3912:258::-;3954:3;3992:5;3986:12;4019:6;4014:3;4007:19;4035:63;4091:6;4084:4;4079:3;4075:14;4068:4;4061:5;4057:16;4035:63;:::i;:::-;4152:2;4131:15;-1:-1:-1;;4127:29:1;4118:39;;;;4159:4;4114:50;;3962:208;-1:-1:-1;;3962:208:1:o;4908:274::-;5037:3;5075:6;5069:13;5091:53;5137:6;5132:3;5125:4;5117:6;5113:17;5091:53;:::i;:::-;5160:16;;;;;5045:137;-1:-1:-1;;5045:137:1:o;5187:418::-;5449:3;5444;5437:16;5419:3;5482:6;5476:13;5498:61;5552:6;5548:1;5543:3;5539:11;5532:4;5524:6;5520:17;5498:61;:::i;:::-;5579:16;;;;5597:1;5575:24;;5427:178;-1:-1:-1;;5427:178:1:o;6556:503::-;-1:-1:-1;;;;;6785:6:1;6781:55;6770:9;6763:74;6873:2;6868;6857:9;6853:18;6846:30;6744:4;6899:45;6940:2;6929:9;6925:18;6917:6;6899:45;:::i;:::-;6992:9;6984:6;6980:22;6975:2;6964:9;6960:18;6953:50;7020:33;7046:6;7038;7020:33;:::i;:::-;7012:41;6753:306;-1:-1:-1;;;;;;6753:306:1:o;8447:220::-;8596:2;8585:9;8578:21;8559:4;8616:45;8657:2;8646:9;8642:18;8634:6;8616:45;:::i;17000:274::-;17040:1;17066;17056:2;;-1:-1:-1;;;17098:1:1;17091:88;17202:4;17199:1;17192:15;17230:4;17227:1;17220:15;17056:2;-1:-1:-1;17259:9:1;;17046:228::o;17279:334::-;17319:7;17385:1;17381;17377:6;17373:14;17370:1;17367:21;17362:1;17355:9;17348:17;17344:45;17341:2;;;-1:-1:-1;;;17419:7:1;17412:94;17529:4;17526:1;17519:15;17563:4;17554:7;17547:21;17341:2;-1:-1:-1;17598:9:1;;17331:282::o;17618:258::-;17690:1;17700:113;17714:6;17711:1;17708:13;17700:113;;;17790:11;;;17784:18;17771:11;;;17764:39;17736:2;17729:10;17700:113;;;17831:6;17828:1;17825:13;17822:2;;;-1:-1:-1;;17866:1:1;17848:16;;17841:27;17671:205::o;17881:184::-;-1:-1:-1;;;17930:1:1;17923:88;18030:4;18027:1;18020:15;18054:4;18051:1;18044:15;18070:154;-1:-1:-1;;;;;18149:5:1;18145:54;18138:5;18135:65;18125:2;;18214:1;18211;18204:12;18229:118;18315:5;18308:13;18301:21;18294:5;18291:32;18281:2;;18337:1;18334;18327:12
Swarm Source
ipfs://9bee0939b18509884aa33c58a84bbeb7a8061727973ff5e9ca096e155a43b288
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $2,354.78 | 1.3438 | $3,164.27 |
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.