Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 2,408 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Claim Rewards | 21375540 | 25 days ago | IN | 0 ETH | 0.00104249 | ||||
Claim Rewards | 21349694 | 29 days ago | IN | 0 ETH | 0.00111613 | ||||
Claim Rewards | 21234039 | 45 days ago | IN | 0 ETH | 0.00088674 | ||||
Claim Rewards | 21211920 | 48 days ago | IN | 0 ETH | 0.00083647 | ||||
Batch Stake NFT | 21145479 | 58 days ago | IN | 0 ETH | 0.00090388 | ||||
Batch Stake NFT | 21145470 | 58 days ago | IN | 0 ETH | 0.00086427 | ||||
Batch Unstake NF... | 21099820 | 64 days ago | IN | 0 ETH | 0.00050338 | ||||
Claim Rewards | 21099818 | 64 days ago | IN | 0 ETH | 0.00031874 | ||||
Claim Rewards | 21030422 | 74 days ago | IN | 0 ETH | 0.000871 | ||||
Claim Rewards | 21026004 | 74 days ago | IN | 0 ETH | 0.00042281 | ||||
Claim Rewards | 21004509 | 77 days ago | IN | 0 ETH | 0.00126071 | ||||
Claim Rewards | 21002861 | 77 days ago | IN | 0 ETH | 0.0013624 | ||||
Claim Rewards | 20999559 | 78 days ago | IN | 0 ETH | 0.00083779 | ||||
Claim Rewards | 20966939 | 82 days ago | IN | 0 ETH | 0.00097027 | ||||
Stake NFT | 20965273 | 83 days ago | IN | 0 ETH | 0.00657098 | ||||
Unstake NFT | 20963632 | 83 days ago | IN | 0 ETH | 0.00654754 | ||||
Claim Rewards | 20957868 | 84 days ago | IN | 0 ETH | 0.00145764 | ||||
Claim Rewards | 20954440 | 84 days ago | IN | 0 ETH | 0.00066714 | ||||
Unstake NFT | 20954181 | 84 days ago | IN | 0 ETH | 0.00097721 | ||||
Unstake NFT | 20953214 | 84 days ago | IN | 0 ETH | 0.00152906 | ||||
Claim Rewards | 20952816 | 84 days ago | IN | 0 ETH | 0.00190487 | ||||
Claim Rewards | 20952410 | 84 days ago | IN | 0 ETH | 0.00171149 | ||||
Batch Unstake NF... | 20952031 | 85 days ago | IN | 0 ETH | 0.00151877 | ||||
Claim Rewards | 20951951 | 85 days ago | IN | 0 ETH | 0.00296839 | ||||
Claim Rewards | 20951901 | 85 days ago | IN | 0 ETH | 0.0005736 |
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:
SacredShardStaking
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-12-09 */ // SPDX-License-Identifier: MIT // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File: @openzeppelin/contracts/utils/math/SafeMath.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol) pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } } // File: @openzeppelin/contracts/utils/structs/EnumerableSet.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } } // File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File: @openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol // OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC721Receiver} interface. * * Accepts all token transfers. * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}. */ contract ERC721Holder is IERC721Receiver { /** * @dev See {IERC721Receiver-onERC721Received}. * * Always returns `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address, address, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC721Received.selector; } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } } // File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol // OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/token/ERC721/IERC721.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.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 Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.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 Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { 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 { _transferOwnership(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"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: contracts/SacredShardStaking.sol pragma solidity ^0.8.11; contract SacredShardStaking is ERC721Holder, Ownable { using EnumerableSet for EnumerableSet.UintSet; using ECDSA for bytes32; using SafeMath for uint256; address private systemAddress; struct Staker { EnumerableSet.UintSet tokenIds; uint256 amount; uint256 lastClaimTime; // Timestamp of the last reward claim } struct StakedNft { uint256 timestamp; uint256 stakedTime; uint256 lockedTime; uint256 tier; } struct Collection { IERC721 NFT; uint256 lockTime; uint256 rewardPerDay; // Reward amount per day for each tier uint256 claimCooldown; // Cooldown period between reward claims (in seconds) address rewardTokenAddress; mapping(address => Staker) Stakers; mapping(uint256 => StakedNft) StakedNfts; mapping(uint256 => address) StakerAddresses; } Collection[] public nftPools; mapping(string => bool) public _usedNonces; mapping(uint256 => uint256) public tierRewards; // Mapping to store reward per day for each tier // Server verification event event TierVerified(uint256 indexed poolId, uint256 indexed tokenId, bool isVerified); event Recover(address indexed owner, uint256 indexed amount); constructor() {} event Stake(address indexed owner, uint256 id, uint256 time); event Unstake(address indexed owner, uint256 id, uint256 time); event RewardClaimed(address indexed staker, uint256 amount); function recoverTokens(uint256 _poolId) external onlyOwner { Collection storage pool = nftPools[_poolId]; // Transfer rewards to the staker IERC20 rewardToken = IERC20(pool.rewardTokenAddress); // ERC20 token used for rewards uint256 balance = rewardToken.balanceOf(address(this)); rewardToken.transfer(owner(), balance); emit Recover(address(rewardToken), balance); } function stakeNFT(uint256 _tokenId, uint256 _poolId, uint256 _tier, string memory nonce, bytes32 hash, bytes memory signature) public { require(matchSigner(hash, signature), "please redeem through website"); require(!_usedNonces[nonce], "hash reused"); require(hashTransaction(msg.sender, 1, nonce) == hash, "hash failed"); _usedNonces[nonce] = true; require(_poolId < nftPools.length, "Pool does not exist!"); Collection storage pool = nftPools[_poolId]; require(pool.NFT.balanceOf(msg.sender) >= 1, "Insufficient NFTs"); require(pool.NFT.ownerOf(_tokenId) == msg.sender, "NFT not owned"); pool.Stakers[msg.sender].amount = pool.Stakers[msg.sender].amount.add(1); pool.Stakers[msg.sender].tokenIds.add(_tokenId); StakedNft storage stakedNft = pool.StakedNfts[_tokenId]; stakedNft.lockedTime = block.timestamp.add(pool.lockTime); stakedNft.timestamp = block.timestamp; stakedNft.stakedTime = block.timestamp; stakedNft.tier = _tier; pool.StakerAddresses[_tokenId] = msg.sender; pool.NFT.safeTransferFrom(msg.sender, address(this), _tokenId); emit Stake(msg.sender, _tokenId, block.timestamp); } function batchStakeNFT(uint256[] memory _tokenIds, uint256 _poolId, uint256[] memory _tiers, string memory nonce, bytes32 hash, bytes memory signature) public { require(matchSigner(hash, signature), "please redeem through website"); require(!_usedNonces[nonce], "hash reused"); require(hashTransaction(msg.sender, 1, nonce) == hash, "hash failed"); _usedNonces[nonce] = true; require(_poolId < nftPools.length, "Pool does not exist!"); Collection storage pool = nftPools[_poolId]; require(_tokenIds.length == _tiers.length, "Invalid input"); for (uint256 i = 0; i < _tokenIds.length; i++) { uint256 _tokenId = _tokenIds[i]; uint256 _tier = _tiers[i]; require(pool.NFT.balanceOf(msg.sender) >= 1, "Insufficient NFTs"); require(pool.NFT.ownerOf(_tokenId) == msg.sender, "NFT not owned"); pool.Stakers[msg.sender].amount = pool.Stakers[msg.sender].amount.add(1); pool.Stakers[msg.sender].tokenIds.add(_tokenId); StakedNft storage stakedNft = pool.StakedNfts[_tokenId]; stakedNft.lockedTime = block.timestamp.add(pool.lockTime); stakedNft.timestamp = block.timestamp; stakedNft.stakedTime = block.timestamp; stakedNft.tier = _tier; pool.StakerAddresses[_tokenId] = msg.sender; pool.NFT.safeTransferFrom(msg.sender, address(this), _tokenId); emit Stake(msg.sender, _tokenId, block.timestamp); } } function calculateRewards(uint256 _poolId, address _staker) internal view returns (uint256) { require(_poolId < nftPools.length, "Pool does not exist!"); Collection storage pool = nftPools[_poolId]; Staker storage staker = pool.Stakers[_staker]; uint256 totalRewards = 0; IERC20 rewardToken = IERC20(pool.rewardTokenAddress); uint256 rewardBalance = rewardToken.balanceOf(address(this)); for (uint256 i = 0; i < staker.tokenIds.length(); i++) { uint256 tokenId = staker.tokenIds.at(i); uint256 rewardPerSecond = tierRewards[pool.StakedNfts[tokenId].tier]; uint256 stakingDuration = 0; stakingDuration = block.timestamp.sub(pool.StakedNfts[tokenId].timestamp); uint256 rewards = stakingDuration.mul(rewardPerSecond); totalRewards = totalRewards.add(rewards); } if(rewardBalance < totalRewards){ return rewardBalance; } return totalRewards; } function claimRewards(uint256 _poolId) public { require(_poolId < nftPools.length, "Pool does not exist!"); Collection storage pool = nftPools[_poolId]; Staker storage staker = pool.Stakers[msg.sender]; require(staker.amount > 0, "No staked NFTs"); require(block.timestamp >= staker.lastClaimTime.add(pool.claimCooldown), "Cooldown period not elapsed"); uint256 totalRewards = calculateRewards(_poolId, msg.sender); // Update the timestamp of each staked NFT for (uint256 i = 0; i < staker.tokenIds.length(); i++) { uint256 tokenId = staker.tokenIds.at(i); pool.StakedNfts[tokenId].timestamp = block.timestamp; } staker.lastClaimTime = block.timestamp; // Transfer rewards to the staker IERC20 rewardToken = IERC20(pool.rewardTokenAddress); // ERC20 token used for rewards rewardToken.transfer(msg.sender, totalRewards); staker.lastClaimTime = block.timestamp; emit RewardClaimed(msg.sender, totalRewards); } function unstakeNFT(uint256 _tokenId, uint256 _poolId) public { require(_poolId < nftPools.length, "Pool does not exist!"); Collection storage pool = nftPools[_poolId]; require(block.timestamp >= pool.StakedNfts[_tokenId].lockedTime, "NFT locked for withdrawal"); require(pool.Stakers[msg.sender].amount > 0, "No staked NFTs"); require(pool.StakerAddresses[_tokenId] == msg.sender, "Token not owned"); claimRewards(_poolId); pool.Stakers[msg.sender].amount = pool.Stakers[msg.sender].amount.sub(1); pool.StakerAddresses[_tokenId] = address(0); pool.Stakers[msg.sender].tokenIds.remove(_tokenId); pool.NFT.safeTransferFrom(address(this), msg.sender, _tokenId); emit Unstake(msg.sender, _tokenId, block.timestamp); } function batchUnstakeNFT(uint256[] memory _tokenIds, uint256 _poolId) public { require(_poolId < nftPools.length, "Pool does not exist!"); Collection storage pool = nftPools[_poolId]; claimRewards(_poolId); for (uint256 i = 0; i < _tokenIds.length; i++) { uint256 _tokenId = _tokenIds[i]; require(block.timestamp >= pool.StakedNfts[_tokenId].lockedTime, "NFT locked for withdrawal"); require(pool.Stakers[msg.sender].amount > 0, "No staked NFTs"); require(pool.StakerAddresses[_tokenId] == msg.sender, "Token not owned"); pool.Stakers[msg.sender].amount = pool.Stakers[msg.sender].amount.sub(1); pool.StakerAddresses[_tokenId] = address(0); pool.Stakers[msg.sender].tokenIds.remove(_tokenId); pool.NFT.safeTransferFrom(address(this), msg.sender, _tokenId); emit Unstake(msg.sender, _tokenId, block.timestamp); } } function addPool(address _nftAddress, uint256 _lockTime, uint256 _rewardPerDay, uint256 _claimCooldown, address _rewardTokenAddress) external onlyOwner { Collection storage newCollection = nftPools.push(); newCollection.NFT = IERC721(_nftAddress); newCollection.lockTime = _lockTime; newCollection.rewardPerDay = _rewardPerDay; newCollection.claimCooldown = _claimCooldown; newCollection.rewardTokenAddress = _rewardTokenAddress; } function setTierReward(uint256 _tier, uint256 _rewardPerDay) external onlyOwner { tierRewards[_tier] = _rewardPerDay; } function setSigner(address _signer) external onlyOwner { systemAddress = _signer; } function matchSigner(bytes32 hash, bytes memory signature) public view returns (bool) { return systemAddress == hash.toEthSignedMessageHash().recover(signature); } function hashTransaction( address sender, uint256 amount, string memory nonce ) public view returns (bytes32) { bytes32 hash = keccak256( abi.encodePacked(sender, amount, nonce, address(this)) ); return hash; } function getStakedNft(uint256 _tokenId, uint256 _poolId) public view returns (uint256, uint256, uint256, uint256) { require(_poolId < nftPools.length, "Pool does not exist!"); Collection storage pool = nftPools[_poolId]; StakedNft storage stakedNft = pool.StakedNfts[_tokenId]; return (stakedNft.timestamp, stakedNft.lockedTime, stakedNft.stakedTime, stakedNft.tier); } function calculateEstimatedReward(uint256 _poolId, address _staker) public view returns (uint256) { require(_poolId < nftPools.length, "Pool does not exist!"); Collection storage pool = nftPools[_poolId]; Staker storage staker = pool.Stakers[_staker]; uint256 totalRewards = 0; for (uint256 i = 0; i < staker.tokenIds.length(); i++) { uint256 tokenId = staker.tokenIds.at(i); uint256 rewardPerSecond = tierRewards[pool.StakedNfts[tokenId].tier]; uint256 stakingDuration = 0; stakingDuration = block.timestamp.sub(pool.StakedNfts[tokenId].timestamp); uint256 rewards = stakingDuration.mul(rewardPerSecond); totalRewards = totalRewards.add(rewards); } return totalRewards; } function calculateEstimatedRewardDaily(uint256 _poolId, address _staker) public view returns (uint256) { require(_poolId < nftPools.length, "Pool does not exist!"); Collection storage pool = nftPools[_poolId]; Staker storage staker = pool.Stakers[_staker]; uint256 totalRewards = 0; for (uint256 i = 0; i < staker.tokenIds.length(); i++) { uint256 tokenId = staker.tokenIds.at(i); uint256 rewardPerSecond = tierRewards[pool.StakedNfts[tokenId].tier]; uint256 stakingDuration = 1 days; uint256 rewards = stakingDuration.mul(rewardPerSecond); totalRewards = totalRewards.add(rewards); } return totalRewards; } function getStakerInfo(address _stakerAddress, uint256 _poolId) public view returns (uint256, uint256[] memory) { require(_poolId < nftPools.length, "Pool does not exist"); Collection storage pool = nftPools[_poolId]; Staker storage staker = pool.Stakers[_stakerAddress]; uint256[] memory stakedTokenIds = new uint256[](staker.tokenIds.length()); for (uint256 i = 0; i < staker.tokenIds.length(); i++) { stakedTokenIds[i] = staker.tokenIds.at(i); } return (staker.amount, stakedTokenIds); } function getStakedTokenOwner(uint256 _tokenId, uint256 _poolId) public view returns (address) { require(_poolId < nftPools.length, "Pool does not exist!"); Collection storage pool = nftPools[_poolId]; return pool.StakerAddresses[_tokenId]; } function getPoolSize() public view returns (uint256) { return nftPools.length; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recover","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"Stake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"poolId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isVerified","type":"bool"}],"name":"TierVerified","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"Unstake","type":"event"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"_usedNonces","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nftAddress","type":"address"},{"internalType":"uint256","name":"_lockTime","type":"uint256"},{"internalType":"uint256","name":"_rewardPerDay","type":"uint256"},{"internalType":"uint256","name":"_claimCooldown","type":"uint256"},{"internalType":"address","name":"_rewardTokenAddress","type":"address"}],"name":"addPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"uint256[]","name":"_tiers","type":"uint256[]"},{"internalType":"string","name":"nonce","type":"string"},{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"batchStakeNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"uint256","name":"_poolId","type":"uint256"}],"name":"batchUnstakeNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"address","name":"_staker","type":"address"}],"name":"calculateEstimatedReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"address","name":"_staker","type":"address"}],"name":"calculateEstimatedRewardDaily","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"}],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getPoolSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_poolId","type":"uint256"}],"name":"getStakedNft","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_poolId","type":"uint256"}],"name":"getStakedTokenOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_stakerAddress","type":"address"},{"internalType":"uint256","name":"_poolId","type":"uint256"}],"name":"getStakerInfo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"nonce","type":"string"}],"name":"hashTransaction","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"matchSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"nftPools","outputs":[{"internalType":"contract IERC721","name":"NFT","type":"address"},{"internalType":"uint256","name":"lockTime","type":"uint256"},{"internalType":"uint256","name":"rewardPerDay","type":"uint256"},{"internalType":"uint256","name":"claimCooldown","type":"uint256"},{"internalType":"address","name":"rewardTokenAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"}],"name":"recoverTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tier","type":"uint256"},{"internalType":"uint256","name":"_rewardPerDay","type":"uint256"}],"name":"setTierReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"uint256","name":"_tier","type":"uint256"},{"internalType":"string","name":"nonce","type":"string"},{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"stakeNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tierRewards","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":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_poolId","type":"uint256"}],"name":"unstakeNFT","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061001a3361001f565b61006f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612a3e8061007e6000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c806374fa8998116100c3578063dd8d74d81161007c578063dd8d74d81461034e578063e101487814610361578063e61ea0cf146103a8578063f2fde38b146103bb578063fae35f47146103ce578063ff61db47146103e157600080fd5b806374fa8998146102855780637f5941b4146102985780638da5cb5b146102b95780638da7be7b146102ca578063a6ba55c7146102dd578063ce74f8a81461031b57600080fd5b8063313fb65811610115578063313fb658146101f95780634ecb98e314610224578063556c448d1461023757806367717e2a146102575780636c19e7831461026a578063715018a61461027d57600080fd5b80630962ef791461015d5780630ec75fd314610172578063150b7a021461018557806323845e4b146101c1578063296d2ea7146101d357806330599fc5146101e6575b600080fd5b61017061016b3660046122d5565b6103f4565b005b6101706101803660046123a5565b6105f0565b6101a3610193366004612443565b630a85bd0160e11b949350505050565b6040516001600160e01b031990911681526020015b60405180910390f35b6002545b6040519081526020016101b8565b6101706101e13660046124af565b610a0e565b6101706101f43660046122d5565b610b0f565b61020c610207366004612505565b610c82565b6040516001600160a01b0390911681526020016101b8565b610170610232366004612505565b610cee565b6101c56102453660046122d5565b60046020526000908152604090205481565b6101c5610265366004612527565b610f36565b610170610278366004612580565b610f71565b610170610f9b565b6101c561029336600461259d565b610faf565b6102ab6102a63660046125cd565b611093565b6040516101b89291906125f9565b6000546001600160a01b031661020c565b6101706102d83660046126c7565b6111cd565b61030b6102eb36600461270c565b805160208183018101805160038252928201919093012091525460ff1681565b60405190151581526020016101b8565b61032e610329366004612505565b611453565b6040805194855260208501939093529183015260608201526080016101b8565b61030b61035c366004612749565b6114d5565b61037461036f3660046122d5565b611550565b604080516001600160a01b03968716815260208101959095528401929092526060830152909116608082015260a0016101b8565b6101706103b6366004612790565b61159e565b6101706103c9366004612580565b611a5c565b6101c56103dc36600461259d565b611ad5565b6101706103ef366004612505565b611bc3565b600254811061041e5760405162461bcd60e51b81526004016104159061280c565b60405180910390fd5b6000600282815481106104335761043361283a565b600091825260208083203384526005600890930201918201905260409091206002810154919250906104775760405162461bcd60e51b815260040161041590612850565b6003808301549082015461048a91611bdd565b4210156104d95760405162461bcd60e51b815260206004820152601b60248201527f436f6f6c646f776e20706572696f64206e6f7420656c617073656400000000006044820152606401610415565b60006104e58433611bf0565b905060005b6104f383611d70565b81101561052c5760006105068483611d7a565b6000908152600686016020526040902042905550806105248161288e565b9150506104ea565b5042600383015560048381015460405163a9059cbb60e01b81523392810192909252602482018390526001600160a01b031690819063a9059cbb906044016020604051808303816000875af1158015610589573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ad91906128a7565b5042600384015560405182815233907f106f923f993c2149d49b4255ff723acafa1f2d94393f561d3eda32ae348f72419060200160405180910390a25050505050565b6105fa82826114d5565b6106465760405162461bcd60e51b815260206004820152601d60248201527f706c656173652072656465656d207468726f75676820776562736974650000006044820152606401610415565b60038360405161065691906128f9565b9081526040519081900360200190205460ff16156106a45760405162461bcd60e51b815260206004820152600b60248201526a1a185cda081c995d5cd95960aa1b6044820152606401610415565b816106b133600186610f36565b146106ec5760405162461bcd60e51b815260206004820152600b60248201526a1a185cda0819985a5b195960aa1b6044820152606401610415565b60016003846040516106fe91906128f9565b908152604051908190036020019020805491151560ff19909216919091179055600254851061073f5760405162461bcd60e51b81526004016104159061280c565b6000600286815481106107545761075461283a565b6000918252602090912060089091020180546040516370a0823160e01b81523360048201529192506001916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156107b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d59190612905565b10156108175760405162461bcd60e51b8152602060048201526011602482015270496e73756666696369656e74204e46547360781b6044820152606401610415565b80546040516331a9108f60e11b81526004810189905233916001600160a01b031690636352211e90602401602060405180830381865afa15801561085f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610883919061291e565b6001600160a01b0316146108c95760405162461bcd60e51b815260206004820152600d60248201526c139195081b9bdd081bdddb9959609a1b6044820152606401610415565b3360009081526005820160205260409020600201546108e9906001611bdd565b3360009081526005830160205260409020600281019190915561090c9088611d86565b5060008781526006820160205260409020600182015461092d904290611bdd565b60028201554280825560018201556003810186905560008881526007830160205260409081902080546001600160a01b0319163390811790915583549151632142170760e11b81526001600160a01b0392909216916342842e0e916109989130908d9060040161293b565b600060405180830381600087803b1580156109b257600080fd5b505af11580156109c6573d6000803e3d6000fd5b5050604080518b81524260208201523393507f5af417134f72a9d41143ace85b0a26dce6f550f894f2cbc1eeee8810603d91b692500160405180910390a25050505050505050565b610a16611d92565b600280546001810182556000919091526008027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace810180546001600160a01b039788166001600160a01b0319918216179091557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf8201959095557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad08101939093557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad18301919091557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091018054919093169116179055565b610b17611d92565b600060028281548110610b2c57610b2c61283a565b600091825260208220600460089290920201818101546040516370a0823160e01b815230938101939093529093506001600160a01b0316919082906370a0823190602401602060405180830381865afa158015610b8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb19190612905565b9050816001600160a01b031663a9059cbb610bd46000546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303816000875af1158015610c21573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4591906128a7565b5060405181906001600160a01b038416907f817c5912299b2d8eea4d9429e557c7b42c96a31499b4229932d1f070f068e37a90600090a350505050565b6002546000908210610ca65760405162461bcd60e51b81526004016104159061280c565b600060028381548110610cbb57610cbb61283a565b60009182526020808320878452600760089093020191909101905260409020546001600160a01b03169150505b92915050565b6002548110610d0f5760405162461bcd60e51b81526004016104159061280c565b600060028281548110610d2457610d2461283a565b9060005260206000209060080201905080600601600084815260200190815260200160002060020154421015610d985760405162461bcd60e51b8152602060048201526019602482015278139195081b1bd8dad95908199bdc881dda5d1a191c985dd85b603a1b6044820152606401610415565b336000908152600582016020526040902060020154610dc95760405162461bcd60e51b815260040161041590612850565b60008381526007820160205260409020546001600160a01b03163314610e235760405162461bcd60e51b815260206004820152600f60248201526e151bdad95b881b9bdd081bdddb9959608a1b6044820152606401610415565b610e2c826103f4565b336000908152600582016020526040902060020154610e4c906001611dec565b33600081815260058401602081815260408084206002810196909655888452600787018252832080546001600160a01b0319169055929091529052610e919084611df8565b508054604051632142170760e11b81526001600160a01b03909116906342842e0e90610ec59030903390889060040161293b565b600060405180830381600087803b158015610edf57600080fd5b505af1158015610ef3573d6000803e3d6000fd5b5050604080518681524260208201523393507ff960dbf9e5d0682f7a298ed974e33a28b4464914b7a2bfac12ae419a9afeb28092500160405180910390a2505050565b60008084848430604051602001610f50949392919061295f565b60408051808303601f19018152919052805160209091012095945050505050565b610f79611d92565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b610fa3611d92565b610fad6000611e04565b565b6002546000908310610fd35760405162461bcd60e51b81526004016104159061280c565b600060028481548110610fe857610fe861283a565b600091825260208083206001600160a01b0387168452600560089093020191820190526040822090925090805b61101e83611d70565b8110156110895760006110318483611d7a565b60008181526006870160209081526040808320600301548352600490915281205491925062015180906110648284611e54565b90506110708682611bdd565b95505050505080806110819061288e565b915050611015565b5095945050505050565b60025460009060609083106110e05760405162461bcd60e51b8152602060048201526013602482015272141bdbdb08191bd95cc81b9bdd08195e1a5cdd606a1b6044820152606401610415565b6000600284815481106110f5576110f561283a565b600091825260208083206001600160a01b038916845260056008909302019182019052604082209092509061112982611d70565b67ffffffffffffffff811115611141576111416122ee565b60405190808252806020026020018201604052801561116a578160200160208202803683370190505b50905060005b61117983611d70565b8110156111b95761118a8382611d7a565b82828151811061119c5761119c61283a565b6020908102919091010152806111b18161288e565b915050611170565b5060029091015493509150505b9250929050565b60025481106111ee5760405162461bcd60e51b81526004016104159061280c565b6000600282815481106112035761120361283a565b9060005260206000209060080201905061121c826103f4565b60005b835181101561144d57600084828151811061123c5761123c61283a565b60200260200101519050826006016000828152602001908152602001600020600201544210156112aa5760405162461bcd60e51b8152602060048201526019602482015278139195081b1bd8dad95908199bdc881dda5d1a191c985dd85b603a1b6044820152606401610415565b3360009081526005840160205260409020600201546112db5760405162461bcd60e51b815260040161041590612850565b60008181526007840160205260409020546001600160a01b031633146113355760405162461bcd60e51b815260206004820152600f60248201526e151bdad95b881b9bdd081bdddb9959608a1b6044820152606401610415565b336000908152600584016020526040902060020154611355906001611dec565b33600081815260058601602081815260408084206002810196909655868452600789018252832080546001600160a01b031916905592909152905261139a9082611df8565b508254604051632142170760e11b81526001600160a01b03909116906342842e0e906113ce9030903390869060040161293b565b600060405180830381600087803b1580156113e857600080fd5b505af11580156113fc573d6000803e3d6000fd5b5050604080518481524260208201523393507ff960dbf9e5d0682f7a298ed974e33a28b4464914b7a2bfac12ae419a9afeb28092500160405180910390a250806114458161288e565b91505061121f565b50505050565b600080600080600280549050851061147d5760405162461bcd60e51b81526004016104159061280c565b6000600286815481106114925761149261283a565b6000918252602080832099835260089190910290980160060190975250506040909420805460028201546001830154600390930154919790965091945092509050565b600061153882611532856040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90611e60565b6001546001600160a01b039182169116149392505050565b6002818154811061156057600080fd5b6000918252602090912060089091020180546001820154600283015460038401546004909401546001600160a01b0393841695509193909290911685565b6115a882826114d5565b6115f45760405162461bcd60e51b815260206004820152601d60248201527f706c656173652072656465656d207468726f75676820776562736974650000006044820152606401610415565b60038360405161160491906128f9565b9081526040519081900360200190205460ff16156116525760405162461bcd60e51b815260206004820152600b60248201526a1a185cda081c995d5cd95960aa1b6044820152606401610415565b8161165f33600186610f36565b1461169a5760405162461bcd60e51b815260206004820152600b60248201526a1a185cda0819985a5b195960aa1b6044820152606401610415565b60016003846040516116ac91906128f9565b908152604051908190036020019020805491151560ff1990921691909117905560025485106116ed5760405162461bcd60e51b81526004016104159061280c565b6000600286815481106117025761170261283a565b9060005260206000209060080201905084518751146117535760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081a5b9c1d5d609a1b6044820152606401610415565b60005b8751811015611a525760008882815181106117735761177361283a565b6020026020010151905060008783815181106117915761179161283a565b602090810291909101015184546040516370a0823160e01b81523360048201529192506001916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156117e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180d9190612905565b101561184f5760405162461bcd60e51b8152602060048201526011602482015270496e73756666696369656e74204e46547360781b6044820152606401610415565b83546040516331a9108f60e11b81526004810184905233916001600160a01b031690636352211e90602401602060405180830381865afa158015611897573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118bb919061291e565b6001600160a01b0316146119015760405162461bcd60e51b815260206004820152600d60248201526c139195081b9bdd081bdddb9959609a1b6044820152606401610415565b336000908152600585016020526040902060020154611921906001611bdd565b336000908152600586016020526040902060028101919091556119449083611d86565b50600082815260068501602052604090206001850154611965904290611bdd565b60028201554280825560018201556003810182905560008381526007860160205260409081902080546001600160a01b0319163390811790915586549151632142170760e11b81526001600160a01b0392909216916342842e0e916119d0913090889060040161293b565b600060405180830381600087803b1580156119ea57600080fd5b505af11580156119fe573d6000803e3d6000fd5b5050604080518681524260208201523393507f5af417134f72a9d41143ace85b0a26dce6f550f894f2cbc1eeee8810603d91b692500160405180910390a25050508080611a4a9061288e565b915050611756565b5050505050505050565b611a64611d92565b6001600160a01b038116611ac95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610415565b611ad281611e04565b50565b6002546000908310611af95760405162461bcd60e51b81526004016104159061280c565b600060028481548110611b0e57611b0e61283a565b600091825260208083206001600160a01b0387168452600560089093020191820190526040822090925090805b611b4483611d70565b811015611089576000611b578483611d7a565b60008181526006870160208181526040808420600381015485526004835290842054858552929091525492935091611b90904290611dec565b90506000611b9e8284611e54565b9050611baa8682611bdd565b9550505050508080611bbb9061288e565b915050611b3b565b611bcb611d92565b60009182526004602052604090912055565b6000611be9828461299f565b9392505050565b6002546000908310611c145760405162461bcd60e51b81526004016104159061280c565b600060028481548110611c2957611c2961283a565b600091825260208083206001600160a01b0387811685526008939093020160058101909152604080842060048084015492516370a0823160e01b8152309181019190915292955093921690829082906370a0823190602401602060405180830381865afa158015611c9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc29190612905565b905060005b611cd085611d70565b811015611d4f576000611ce38683611d7a565b60008181526006890160208181526040808420600381015485526004835290842054858552929091525492935091611d1c904290611dec565b90506000611d2a8284611e54565b9050611d368882611bdd565b9750505050508080611d479061288e565b915050611cc7565b5082811015611d64579450610ce89350505050565b50909695505050505050565b6000610ce8825490565b6000611be98383611e84565b6000611be98383611eae565b6000546001600160a01b03163314610fad5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610415565b6000611be982846129b2565b6000611be98383611efd565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000611be982846129c5565b6000806000611e6f8585611ff0565b91509150611e7c81612032565b509392505050565b6000826000018281548110611e9b57611e9b61283a565b9060005260206000200154905092915050565b6000818152600183016020526040812054611ef557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ce8565b506000610ce8565b60008181526001830160205260408120548015611fe6576000611f216001836129b2565b8554909150600090611f35906001906129b2565b9050818114611f9a576000866000018281548110611f5557611f5561283a565b9060005260206000200154905080876000018481548110611f7857611f7861283a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611fab57611fab6129dc565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610ce8565b6000915050610ce8565b60008082516041036120265760208301516040840151606085015160001a61201a878285856121e8565b945094505050506111c6565b506000905060026111c6565b6000816004811115612046576120466129f2565b0361204e5750565b6001816004811115612062576120626129f2565b036120af5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610415565b60028160048111156120c3576120c36129f2565b036121105760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610415565b6003816004811115612124576121246129f2565b0361217c5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610415565b6004816004811115612190576121906129f2565b03611ad25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610415565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561221f57506000905060036122cc565b8460ff16601b1415801561223757508460ff16601c14155b1561224857506000905060046122cc565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561229c573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166122c5576000600192509250506122cc565b9150600090505b94509492505050565b6000602082840312156122e757600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561232d5761232d6122ee565b604052919050565b600082601f83011261234657600080fd5b813567ffffffffffffffff811115612360576123606122ee565b612373601f8201601f1916602001612304565b81815284602083860101111561238857600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156123be57600080fd5b863595506020870135945060408701359350606087013567ffffffffffffffff808211156123eb57600080fd5b6123f78a838b01612335565b94506080890135935060a089013591508082111561241457600080fd5b5061242189828a01612335565b9150509295509295509295565b6001600160a01b0381168114611ad257600080fd5b6000806000806080858703121561245957600080fd5b84356124648161242e565b935060208501356124748161242e565b925060408501359150606085013567ffffffffffffffff81111561249757600080fd5b6124a387828801612335565b91505092959194509250565b600080600080600060a086880312156124c757600080fd5b85356124d28161242e565b945060208601359350604086013592506060860135915060808601356124f78161242e565b809150509295509295909350565b6000806040838503121561251857600080fd5b50508035926020909101359150565b60008060006060848603121561253c57600080fd5b83356125478161242e565b925060208401359150604084013567ffffffffffffffff81111561256a57600080fd5b61257686828701612335565b9150509250925092565b60006020828403121561259257600080fd5b8135611be98161242e565b600080604083850312156125b057600080fd5b8235915060208301356125c28161242e565b809150509250929050565b600080604083850312156125e057600080fd5b82356125eb8161242e565b946020939093013593505050565b6000604082018483526020604081850152818551808452606086019150828701935060005b8181101561263a5784518352938301939183019160010161261e565b5090979650505050505050565b600082601f83011261265857600080fd5b8135602067ffffffffffffffff821115612674576126746122ee565b8160051b612683828201612304565b928352848101820192828101908785111561269d57600080fd5b83870192505b848310156126bc578235825291830191908301906126a3565b979650505050505050565b600080604083850312156126da57600080fd5b823567ffffffffffffffff8111156126f157600080fd5b6126fd85828601612647565b95602094909401359450505050565b60006020828403121561271e57600080fd5b813567ffffffffffffffff81111561273557600080fd5b61274184828501612335565b949350505050565b6000806040838503121561275c57600080fd5b82359150602083013567ffffffffffffffff81111561277a57600080fd5b61278685828601612335565b9150509250929050565b60008060008060008060c087890312156127a957600080fd5b863567ffffffffffffffff808211156127c157600080fd5b6127cd8a838b01612647565b97506020890135965060408901359150808211156127ea57600080fd5b6127f68a838b01612647565b955060608901359150808211156123eb57600080fd5b602080825260149082015273506f6f6c20646f6573206e6f742065786973742160601b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6020808252600e908201526d4e6f207374616b6564204e46547360901b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000600182016128a0576128a0612878565b5060010190565b6000602082840312156128b957600080fd5b81518015158114611be957600080fd5b6000815160005b818110156128ea57602081850181015186830152016128d0565b50600093019283525090919050565b6000611be982846128c9565b60006020828403121561291757600080fd5b5051919050565b60006020828403121561293057600080fd5b8151611be98161242e565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60006bffffffffffffffffffffffff19808760601b16835285601484015261298a60348401866128c9565b60609490941b16835250506014019392505050565b80820180821115610ce857610ce8612878565b81810381811115610ce857610ce8612878565b8082028115828204841417610ce857610ce8612878565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212208f157844ad6899108ff7abc2d28d67aea8c870432a9366f866913a279f4f614464736f6c63430008120033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101585760003560e01c806374fa8998116100c3578063dd8d74d81161007c578063dd8d74d81461034e578063e101487814610361578063e61ea0cf146103a8578063f2fde38b146103bb578063fae35f47146103ce578063ff61db47146103e157600080fd5b806374fa8998146102855780637f5941b4146102985780638da5cb5b146102b95780638da7be7b146102ca578063a6ba55c7146102dd578063ce74f8a81461031b57600080fd5b8063313fb65811610115578063313fb658146101f95780634ecb98e314610224578063556c448d1461023757806367717e2a146102575780636c19e7831461026a578063715018a61461027d57600080fd5b80630962ef791461015d5780630ec75fd314610172578063150b7a021461018557806323845e4b146101c1578063296d2ea7146101d357806330599fc5146101e6575b600080fd5b61017061016b3660046122d5565b6103f4565b005b6101706101803660046123a5565b6105f0565b6101a3610193366004612443565b630a85bd0160e11b949350505050565b6040516001600160e01b031990911681526020015b60405180910390f35b6002545b6040519081526020016101b8565b6101706101e13660046124af565b610a0e565b6101706101f43660046122d5565b610b0f565b61020c610207366004612505565b610c82565b6040516001600160a01b0390911681526020016101b8565b610170610232366004612505565b610cee565b6101c56102453660046122d5565b60046020526000908152604090205481565b6101c5610265366004612527565b610f36565b610170610278366004612580565b610f71565b610170610f9b565b6101c561029336600461259d565b610faf565b6102ab6102a63660046125cd565b611093565b6040516101b89291906125f9565b6000546001600160a01b031661020c565b6101706102d83660046126c7565b6111cd565b61030b6102eb36600461270c565b805160208183018101805160038252928201919093012091525460ff1681565b60405190151581526020016101b8565b61032e610329366004612505565b611453565b6040805194855260208501939093529183015260608201526080016101b8565b61030b61035c366004612749565b6114d5565b61037461036f3660046122d5565b611550565b604080516001600160a01b03968716815260208101959095528401929092526060830152909116608082015260a0016101b8565b6101706103b6366004612790565b61159e565b6101706103c9366004612580565b611a5c565b6101c56103dc36600461259d565b611ad5565b6101706103ef366004612505565b611bc3565b600254811061041e5760405162461bcd60e51b81526004016104159061280c565b60405180910390fd5b6000600282815481106104335761043361283a565b600091825260208083203384526005600890930201918201905260409091206002810154919250906104775760405162461bcd60e51b815260040161041590612850565b6003808301549082015461048a91611bdd565b4210156104d95760405162461bcd60e51b815260206004820152601b60248201527f436f6f6c646f776e20706572696f64206e6f7420656c617073656400000000006044820152606401610415565b60006104e58433611bf0565b905060005b6104f383611d70565b81101561052c5760006105068483611d7a565b6000908152600686016020526040902042905550806105248161288e565b9150506104ea565b5042600383015560048381015460405163a9059cbb60e01b81523392810192909252602482018390526001600160a01b031690819063a9059cbb906044016020604051808303816000875af1158015610589573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ad91906128a7565b5042600384015560405182815233907f106f923f993c2149d49b4255ff723acafa1f2d94393f561d3eda32ae348f72419060200160405180910390a25050505050565b6105fa82826114d5565b6106465760405162461bcd60e51b815260206004820152601d60248201527f706c656173652072656465656d207468726f75676820776562736974650000006044820152606401610415565b60038360405161065691906128f9565b9081526040519081900360200190205460ff16156106a45760405162461bcd60e51b815260206004820152600b60248201526a1a185cda081c995d5cd95960aa1b6044820152606401610415565b816106b133600186610f36565b146106ec5760405162461bcd60e51b815260206004820152600b60248201526a1a185cda0819985a5b195960aa1b6044820152606401610415565b60016003846040516106fe91906128f9565b908152604051908190036020019020805491151560ff19909216919091179055600254851061073f5760405162461bcd60e51b81526004016104159061280c565b6000600286815481106107545761075461283a565b6000918252602090912060089091020180546040516370a0823160e01b81523360048201529192506001916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156107b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d59190612905565b10156108175760405162461bcd60e51b8152602060048201526011602482015270496e73756666696369656e74204e46547360781b6044820152606401610415565b80546040516331a9108f60e11b81526004810189905233916001600160a01b031690636352211e90602401602060405180830381865afa15801561085f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610883919061291e565b6001600160a01b0316146108c95760405162461bcd60e51b815260206004820152600d60248201526c139195081b9bdd081bdddb9959609a1b6044820152606401610415565b3360009081526005820160205260409020600201546108e9906001611bdd565b3360009081526005830160205260409020600281019190915561090c9088611d86565b5060008781526006820160205260409020600182015461092d904290611bdd565b60028201554280825560018201556003810186905560008881526007830160205260409081902080546001600160a01b0319163390811790915583549151632142170760e11b81526001600160a01b0392909216916342842e0e916109989130908d9060040161293b565b600060405180830381600087803b1580156109b257600080fd5b505af11580156109c6573d6000803e3d6000fd5b5050604080518b81524260208201523393507f5af417134f72a9d41143ace85b0a26dce6f550f894f2cbc1eeee8810603d91b692500160405180910390a25050505050505050565b610a16611d92565b600280546001810182556000919091526008027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace810180546001600160a01b039788166001600160a01b0319918216179091557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf8201959095557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad08101939093557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad18301919091557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad29091018054919093169116179055565b610b17611d92565b600060028281548110610b2c57610b2c61283a565b600091825260208220600460089290920201818101546040516370a0823160e01b815230938101939093529093506001600160a01b0316919082906370a0823190602401602060405180830381865afa158015610b8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb19190612905565b9050816001600160a01b031663a9059cbb610bd46000546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303816000875af1158015610c21573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4591906128a7565b5060405181906001600160a01b038416907f817c5912299b2d8eea4d9429e557c7b42c96a31499b4229932d1f070f068e37a90600090a350505050565b6002546000908210610ca65760405162461bcd60e51b81526004016104159061280c565b600060028381548110610cbb57610cbb61283a565b60009182526020808320878452600760089093020191909101905260409020546001600160a01b03169150505b92915050565b6002548110610d0f5760405162461bcd60e51b81526004016104159061280c565b600060028281548110610d2457610d2461283a565b9060005260206000209060080201905080600601600084815260200190815260200160002060020154421015610d985760405162461bcd60e51b8152602060048201526019602482015278139195081b1bd8dad95908199bdc881dda5d1a191c985dd85b603a1b6044820152606401610415565b336000908152600582016020526040902060020154610dc95760405162461bcd60e51b815260040161041590612850565b60008381526007820160205260409020546001600160a01b03163314610e235760405162461bcd60e51b815260206004820152600f60248201526e151bdad95b881b9bdd081bdddb9959608a1b6044820152606401610415565b610e2c826103f4565b336000908152600582016020526040902060020154610e4c906001611dec565b33600081815260058401602081815260408084206002810196909655888452600787018252832080546001600160a01b0319169055929091529052610e919084611df8565b508054604051632142170760e11b81526001600160a01b03909116906342842e0e90610ec59030903390889060040161293b565b600060405180830381600087803b158015610edf57600080fd5b505af1158015610ef3573d6000803e3d6000fd5b5050604080518681524260208201523393507ff960dbf9e5d0682f7a298ed974e33a28b4464914b7a2bfac12ae419a9afeb28092500160405180910390a2505050565b60008084848430604051602001610f50949392919061295f565b60408051808303601f19018152919052805160209091012095945050505050565b610f79611d92565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b610fa3611d92565b610fad6000611e04565b565b6002546000908310610fd35760405162461bcd60e51b81526004016104159061280c565b600060028481548110610fe857610fe861283a565b600091825260208083206001600160a01b0387168452600560089093020191820190526040822090925090805b61101e83611d70565b8110156110895760006110318483611d7a565b60008181526006870160209081526040808320600301548352600490915281205491925062015180906110648284611e54565b90506110708682611bdd565b95505050505080806110819061288e565b915050611015565b5095945050505050565b60025460009060609083106110e05760405162461bcd60e51b8152602060048201526013602482015272141bdbdb08191bd95cc81b9bdd08195e1a5cdd606a1b6044820152606401610415565b6000600284815481106110f5576110f561283a565b600091825260208083206001600160a01b038916845260056008909302019182019052604082209092509061112982611d70565b67ffffffffffffffff811115611141576111416122ee565b60405190808252806020026020018201604052801561116a578160200160208202803683370190505b50905060005b61117983611d70565b8110156111b95761118a8382611d7a565b82828151811061119c5761119c61283a565b6020908102919091010152806111b18161288e565b915050611170565b5060029091015493509150505b9250929050565b60025481106111ee5760405162461bcd60e51b81526004016104159061280c565b6000600282815481106112035761120361283a565b9060005260206000209060080201905061121c826103f4565b60005b835181101561144d57600084828151811061123c5761123c61283a565b60200260200101519050826006016000828152602001908152602001600020600201544210156112aa5760405162461bcd60e51b8152602060048201526019602482015278139195081b1bd8dad95908199bdc881dda5d1a191c985dd85b603a1b6044820152606401610415565b3360009081526005840160205260409020600201546112db5760405162461bcd60e51b815260040161041590612850565b60008181526007840160205260409020546001600160a01b031633146113355760405162461bcd60e51b815260206004820152600f60248201526e151bdad95b881b9bdd081bdddb9959608a1b6044820152606401610415565b336000908152600584016020526040902060020154611355906001611dec565b33600081815260058601602081815260408084206002810196909655868452600789018252832080546001600160a01b031916905592909152905261139a9082611df8565b508254604051632142170760e11b81526001600160a01b03909116906342842e0e906113ce9030903390869060040161293b565b600060405180830381600087803b1580156113e857600080fd5b505af11580156113fc573d6000803e3d6000fd5b5050604080518481524260208201523393507ff960dbf9e5d0682f7a298ed974e33a28b4464914b7a2bfac12ae419a9afeb28092500160405180910390a250806114458161288e565b91505061121f565b50505050565b600080600080600280549050851061147d5760405162461bcd60e51b81526004016104159061280c565b6000600286815481106114925761149261283a565b6000918252602080832099835260089190910290980160060190975250506040909420805460028201546001830154600390930154919790965091945092509050565b600061153882611532856040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90611e60565b6001546001600160a01b039182169116149392505050565b6002818154811061156057600080fd5b6000918252602090912060089091020180546001820154600283015460038401546004909401546001600160a01b0393841695509193909290911685565b6115a882826114d5565b6115f45760405162461bcd60e51b815260206004820152601d60248201527f706c656173652072656465656d207468726f75676820776562736974650000006044820152606401610415565b60038360405161160491906128f9565b9081526040519081900360200190205460ff16156116525760405162461bcd60e51b815260206004820152600b60248201526a1a185cda081c995d5cd95960aa1b6044820152606401610415565b8161165f33600186610f36565b1461169a5760405162461bcd60e51b815260206004820152600b60248201526a1a185cda0819985a5b195960aa1b6044820152606401610415565b60016003846040516116ac91906128f9565b908152604051908190036020019020805491151560ff1990921691909117905560025485106116ed5760405162461bcd60e51b81526004016104159061280c565b6000600286815481106117025761170261283a565b9060005260206000209060080201905084518751146117535760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081a5b9c1d5d609a1b6044820152606401610415565b60005b8751811015611a525760008882815181106117735761177361283a565b6020026020010151905060008783815181106117915761179161283a565b602090810291909101015184546040516370a0823160e01b81523360048201529192506001916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156117e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180d9190612905565b101561184f5760405162461bcd60e51b8152602060048201526011602482015270496e73756666696369656e74204e46547360781b6044820152606401610415565b83546040516331a9108f60e11b81526004810184905233916001600160a01b031690636352211e90602401602060405180830381865afa158015611897573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118bb919061291e565b6001600160a01b0316146119015760405162461bcd60e51b815260206004820152600d60248201526c139195081b9bdd081bdddb9959609a1b6044820152606401610415565b336000908152600585016020526040902060020154611921906001611bdd565b336000908152600586016020526040902060028101919091556119449083611d86565b50600082815260068501602052604090206001850154611965904290611bdd565b60028201554280825560018201556003810182905560008381526007860160205260409081902080546001600160a01b0319163390811790915586549151632142170760e11b81526001600160a01b0392909216916342842e0e916119d0913090889060040161293b565b600060405180830381600087803b1580156119ea57600080fd5b505af11580156119fe573d6000803e3d6000fd5b5050604080518681524260208201523393507f5af417134f72a9d41143ace85b0a26dce6f550f894f2cbc1eeee8810603d91b692500160405180910390a25050508080611a4a9061288e565b915050611756565b5050505050505050565b611a64611d92565b6001600160a01b038116611ac95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610415565b611ad281611e04565b50565b6002546000908310611af95760405162461bcd60e51b81526004016104159061280c565b600060028481548110611b0e57611b0e61283a565b600091825260208083206001600160a01b0387168452600560089093020191820190526040822090925090805b611b4483611d70565b811015611089576000611b578483611d7a565b60008181526006870160208181526040808420600381015485526004835290842054858552929091525492935091611b90904290611dec565b90506000611b9e8284611e54565b9050611baa8682611bdd565b9550505050508080611bbb9061288e565b915050611b3b565b611bcb611d92565b60009182526004602052604090912055565b6000611be9828461299f565b9392505050565b6002546000908310611c145760405162461bcd60e51b81526004016104159061280c565b600060028481548110611c2957611c2961283a565b600091825260208083206001600160a01b0387811685526008939093020160058101909152604080842060048084015492516370a0823160e01b8152309181019190915292955093921690829082906370a0823190602401602060405180830381865afa158015611c9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc29190612905565b905060005b611cd085611d70565b811015611d4f576000611ce38683611d7a565b60008181526006890160208181526040808420600381015485526004835290842054858552929091525492935091611d1c904290611dec565b90506000611d2a8284611e54565b9050611d368882611bdd565b9750505050508080611d479061288e565b915050611cc7565b5082811015611d64579450610ce89350505050565b50909695505050505050565b6000610ce8825490565b6000611be98383611e84565b6000611be98383611eae565b6000546001600160a01b03163314610fad5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610415565b6000611be982846129b2565b6000611be98383611efd565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000611be982846129c5565b6000806000611e6f8585611ff0565b91509150611e7c81612032565b509392505050565b6000826000018281548110611e9b57611e9b61283a565b9060005260206000200154905092915050565b6000818152600183016020526040812054611ef557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ce8565b506000610ce8565b60008181526001830160205260408120548015611fe6576000611f216001836129b2565b8554909150600090611f35906001906129b2565b9050818114611f9a576000866000018281548110611f5557611f5561283a565b9060005260206000200154905080876000018481548110611f7857611f7861283a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611fab57611fab6129dc565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610ce8565b6000915050610ce8565b60008082516041036120265760208301516040840151606085015160001a61201a878285856121e8565b945094505050506111c6565b506000905060026111c6565b6000816004811115612046576120466129f2565b0361204e5750565b6001816004811115612062576120626129f2565b036120af5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610415565b60028160048111156120c3576120c36129f2565b036121105760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610415565b6003816004811115612124576121246129f2565b0361217c5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610415565b6004816004811115612190576121906129f2565b03611ad25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610415565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561221f57506000905060036122cc565b8460ff16601b1415801561223757508460ff16601c14155b1561224857506000905060046122cc565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561229c573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166122c5576000600192509250506122cc565b9150600090505b94509492505050565b6000602082840312156122e757600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561232d5761232d6122ee565b604052919050565b600082601f83011261234657600080fd5b813567ffffffffffffffff811115612360576123606122ee565b612373601f8201601f1916602001612304565b81815284602083860101111561238857600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156123be57600080fd5b863595506020870135945060408701359350606087013567ffffffffffffffff808211156123eb57600080fd5b6123f78a838b01612335565b94506080890135935060a089013591508082111561241457600080fd5b5061242189828a01612335565b9150509295509295509295565b6001600160a01b0381168114611ad257600080fd5b6000806000806080858703121561245957600080fd5b84356124648161242e565b935060208501356124748161242e565b925060408501359150606085013567ffffffffffffffff81111561249757600080fd5b6124a387828801612335565b91505092959194509250565b600080600080600060a086880312156124c757600080fd5b85356124d28161242e565b945060208601359350604086013592506060860135915060808601356124f78161242e565b809150509295509295909350565b6000806040838503121561251857600080fd5b50508035926020909101359150565b60008060006060848603121561253c57600080fd5b83356125478161242e565b925060208401359150604084013567ffffffffffffffff81111561256a57600080fd5b61257686828701612335565b9150509250925092565b60006020828403121561259257600080fd5b8135611be98161242e565b600080604083850312156125b057600080fd5b8235915060208301356125c28161242e565b809150509250929050565b600080604083850312156125e057600080fd5b82356125eb8161242e565b946020939093013593505050565b6000604082018483526020604081850152818551808452606086019150828701935060005b8181101561263a5784518352938301939183019160010161261e565b5090979650505050505050565b600082601f83011261265857600080fd5b8135602067ffffffffffffffff821115612674576126746122ee565b8160051b612683828201612304565b928352848101820192828101908785111561269d57600080fd5b83870192505b848310156126bc578235825291830191908301906126a3565b979650505050505050565b600080604083850312156126da57600080fd5b823567ffffffffffffffff8111156126f157600080fd5b6126fd85828601612647565b95602094909401359450505050565b60006020828403121561271e57600080fd5b813567ffffffffffffffff81111561273557600080fd5b61274184828501612335565b949350505050565b6000806040838503121561275c57600080fd5b82359150602083013567ffffffffffffffff81111561277a57600080fd5b61278685828601612335565b9150509250929050565b60008060008060008060c087890312156127a957600080fd5b863567ffffffffffffffff808211156127c157600080fd5b6127cd8a838b01612647565b97506020890135965060408901359150808211156127ea57600080fd5b6127f68a838b01612647565b955060608901359150808211156123eb57600080fd5b602080825260149082015273506f6f6c20646f6573206e6f742065786973742160601b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6020808252600e908201526d4e6f207374616b6564204e46547360901b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000600182016128a0576128a0612878565b5060010190565b6000602082840312156128b957600080fd5b81518015158114611be957600080fd5b6000815160005b818110156128ea57602081850181015186830152016128d0565b50600093019283525090919050565b6000611be982846128c9565b60006020828403121561291757600080fd5b5051919050565b60006020828403121561293057600080fd5b8151611be98161242e565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60006bffffffffffffffffffffffff19808760601b16835285601484015261298a60348401866128c9565b60609490941b16835250506014019392505050565b80820180821115610ce857610ce8612878565b81810381811115610ce857610ce8612878565b8082028115828204841417610ce857610ce8612878565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212208f157844ad6899108ff7abc2d28d67aea8c870432a9366f866913a279f4f614464736f6c63430008120033
Deployed Bytecode Sourcemap
45409:13070:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51352:1086;;;;;;:::i;:::-;;:::i;:::-;;47405:1276;;;;;;:::i;:::-;;:::i;24625:207::-;;;;;;:::i;:::-;-1:-1:-1;;;24625:207:0;;;;;;;;;;-1:-1:-1;;;;;;2938:33:1;;;2920:52;;2908:2;2893:18;24625:207:0;;;;;;;;58382:94;58453:8;:15;58382:94;;;3129:25:1;;;3117:2;3102:18;58382:94:0;2983:177:1;54278:490:0;;;;;;:::i;:::-;;:::i;46968:429::-;;;;;;:::i;:::-;;:::i;58101:273::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;4181:32:1;;;4163:51;;4151:2;4136:18;58101:273:0;4017:203:1;52446:826:0;;;;;;:::i;:::-;;:::i;46440:46::-;;;;;;:::i;:::-;;;;;;;;;;;;;;55207:279;;;;;;:::i;:::-;;:::i;54917:97::-;;;;;;:::i;:::-;;:::i;44503:103::-;;;:::i;56754:756::-;;;;;;:::i;:::-;;:::i;57518:575::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;43855:87::-;43901:7;43928:6;-1:-1:-1;;;;;43928:6:0;43855:87;;53280:990;;;;;;:::i;:::-;;:::i;46391:42::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8167:14:1;;8160:22;8142:41;;8130:2;8115:18;46391:42:0;8002:187:1;55494:410:0;;;;;;:::i;:::-;;:::i;:::-;;;;8425:25:1;;;8481:2;8466:18;;8459:34;;;;8509:18;;;8502:34;8567:2;8552:18;;8545:34;8412:3;8397:19;55494:410:0;8194:391:1;55022:177:0;;;;;;:::i;:::-;;:::i;46356:28::-;;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;9315:15:1;;;9297:34;;9362:2;9347:18;;9340:34;;;;9390:18;;9383:34;;;;9448:2;9433:18;;9426:34;9497:15;;;9491:3;9476:19;;9469:44;9246:3;9231:19;46356:28:0;8984:535:1;48689:1576:0;;;;;;:::i;:::-;;:::i;44761:201::-;;;;;;:::i;:::-;;:::i;55912:834::-;;;;;;:::i;:::-;;:::i;54776:133::-;;;;;;:::i;:::-;;:::i;51352:1086::-;51427:8;:15;51417:25;;51409:58;;;;-1:-1:-1;;;51409:58:0;;;;;;;:::i;:::-;;;;;;;;;51478:23;51504:8;51513:7;51504:17;;;;;;;;:::i;:::-;;;;;;;;;51569:10;51556:24;;:12;51504:17;;;;;51556:12;;;:24;;;;;;51599:13;;;;51504:17;;-1:-1:-1;51556:24:0;51591:44;;;;-1:-1:-1;;;51591:44:0;;;;;;;:::i;:::-;51698:18;;;;;51673:20;;;;:44;;:24;:44::i;:::-;51654:15;:63;;51646:103;;;;-1:-1:-1;;;51646:103:0;;11688:2:1;51646:103:0;;;11670:21:1;11727:2;11707:18;;;11700:30;11766:29;11746:18;;;11739:57;11813:18;;51646:103:0;11486:351:1;51646:103:0;51762:20;51785:37;51802:7;51811:10;51785:16;:37::i;:::-;51762:60;;51892:9;51887:188;51911:24;:6;:22;:24::i;:::-;51907:1;:28;51887:188;;;51957:15;51975:21;:6;51994:1;51975:18;:21::i;:::-;52011:24;;;;:15;;;:24;;;;;52048:15;52011:52;;-1:-1:-1;51937:3:0;;;;:::i;:::-;;;;51887:188;;;-1:-1:-1;52110:15:0;52087:20;;;:38;52209:23;;;;;52276:46;;-1:-1:-1;;;52276:46:0;;52297:10;52276:46;;;12288:51:1;;;;12355:18;;;12348:34;;;-1:-1:-1;;;;;52209:23:0;;;;52276:20;;12261:18:1;;52276:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;52358:15:0;52335:20;;;:38;52391:39;;3129:25:1;;;52405:10:0;;52391:39;;3117:2:1;3102:18;52391:39:0;;;;;;;51398:1040;;;;51352:1086;:::o;47405:1276::-;47558:28;47570:4;47576:9;47558:11;:28::i;:::-;47550:70;;;;-1:-1:-1;;;47550:70:0;;12877:2:1;47550:70:0;;;12859:21:1;12916:2;12896:18;;;12889:30;12955:31;12935:18;;;12928:59;13004:18;;47550:70:0;12675:353:1;47550:70:0;47640:11;47652:5;47640:18;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;47639:19;47631:43;;;;-1:-1:-1;;;47631:43:0;;13760:2:1;47631:43:0;;;13742:21:1;13799:2;13779:18;;;13772:30;-1:-1:-1;;;13818:18:1;;;13811:41;13869:18;;47631:43:0;13558:335:1;47631:43:0;47734:4;47693:37;47709:10;47721:1;47724:5;47693:15;:37::i;:::-;:45;47685:69;;;;-1:-1:-1;;;47685:69:0;;14100:2:1;47685:69:0;;;14082:21:1;14139:2;14119:18;;;14112:30;-1:-1:-1;;;14158:18:1;;;14151:41;14209:18;;47685:69:0;13898:335:1;47685:69:0;47789:4;47768:11;47780:5;47768:18;;;;;;:::i;:::-;;;;;;;;;;;;;;:25;;;;;-1:-1:-1;;47768:25:0;;;;;;;;;47822:8;:15;47812:25;;47804:58;;;;-1:-1:-1;;;47804:58:0;;;;;;;:::i;:::-;47873:23;47899:8;47908:7;47899:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;47935:8;;:30;;-1:-1:-1;;;47935:30:0;;47954:10;47935:30;;;4163:51:1;47899:17:0;;-1:-1:-1;47969:1:0;;-1:-1:-1;;;;;47935:8:0;;;;:18;;4136::1;;47935:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:35;;47927:65;;;;-1:-1:-1;;;47927:65:0;;14629:2:1;47927:65:0;;;14611:21:1;14668:2;14648:18;;;14641:30;-1:-1:-1;;;14687:18:1;;;14680:47;14744:18;;47927:65:0;14427:341:1;47927:65:0;48011:8;;:26;;-1:-1:-1;;;48011:26:0;;;;;3129:25:1;;;48041:10:0;;-1:-1:-1;;;;;48011:8:0;;:16;;3102:18:1;;48011:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;48011:40:0;;48003:66;;;;-1:-1:-1;;;48003:66:0;;15231:2:1;48003:66:0;;;15213:21:1;15270:2;15250:18;;;15243:30;-1:-1:-1;;;15289:18:1;;;15282:43;15342:18;;48003:66:0;15029:337:1;48003:66:0;48131:10;48118:24;;;;:12;;;:24;;;;;:31;;;:38;;48154:1;48118:35;:38::i;:::-;48097:10;48084:24;;;;:12;;;:24;;;;;:31;;;:72;;;;48167:47;;48205:8;48167:37;:47::i;:::-;-1:-1:-1;48227:27:0;48257:25;;;:15;;;:25;;;;;48336:13;;;;48316:34;;:15;;:19;:34::i;:::-;48293:20;;;:57;48383:15;48361:37;;;48409:20;;;:38;48458:14;;;:22;;;48361:19;48493:30;;;:20;;;:30;;;;;;;:43;;-1:-1:-1;;;;;;48493:43:0;48526:10;48493:43;;;;;;48549:8;;:62;;-1:-1:-1;;;48549:62:0;;-1:-1:-1;;;;;48549:8:0;;;;;:25;;:62;;48595:4;;48514:8;;48549:62;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;48629:44:0;;;15925:25:1;;;48657:15:0;15981:2:1;15966:18;;15959:34;48635:10:0;;-1:-1:-1;48629:44:0;;-1:-1:-1;15898:18:1;48629:44:0;;;;;;;47539:1142;;47405:1276;;;;;;:::o;54278:490::-;43741:13;:11;:13::i;:::-;54476:8:::1;:15:::0;;::::1;::::0;::::1;::::0;;54441:32:::1;54476:15:::0;;;;::::1;;::::0;;::::1;54502:40:::0;;-1:-1:-1;;;;;54502:40:0;;::::1;-1:-1:-1::0;;;;;;54502:40:0;;::::1;;::::0;;;54553:22;;;:34;;;;54598:26;;;:42;;;;54651:27;;;:44;;;;54706:32;;;;:54;;;;;::::1;::::0;::::1;;::::0;;54278:490::o;46968:429::-;43741:13;:11;:13::i;:::-;47038:23:::1;47064:8;47073:7;47064:17;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;47163:23:::1;47064:17;::::0;;;::::1;;47163:23:::0;;::::1;::::0;47250:36:::1;::::0;-1:-1:-1;;;47250:36:0;;47280:4:::1;47250:36:::0;;::::1;4163:51:1::0;;;;47064:17:0;;-1:-1:-1;;;;;;47163:23:0::1;::::0;47064:17;47163:23;;47250:21:::1;::::0;4136:18:1;;47250:36:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47232:54;;47297:11;-1:-1:-1::0;;;;;47297:20:0::1;;47318:7;43901::::0;43928:6;-1:-1:-1;;;;;43928:6:0;;43855:87;47318:7:::1;47297:38;::::0;-1:-1:-1;;;;;;47297:38:0::1;::::0;;;;;;-1:-1:-1;;;;;12306:32:1;;;47297:38:0::1;::::0;::::1;12288:51:1::0;12355:18;;;12348:34;;;12261:18;;47297:38:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;47351:38:0::1;::::0;47381:7;;-1:-1:-1;;;;;47351:38:0;::::1;::::0;::::1;::::0;;;::::1;47027:370;;;46968:429:::0;:::o;58101:273::-;58224:8;:15;58186:7;;58214:25;;58206:58;;;;-1:-1:-1;;;58206:58:0;;;;;;;:::i;:::-;58275:23;58301:8;58310:7;58301:17;;;;;;;;:::i;:::-;;;;;;;;;58336:30;;;:20;58301:17;;;;;58336:20;;;;:30;;;;;;-1:-1:-1;;;;;58336:30:0;;-1:-1:-1;;58101:273:0;;;;;:::o;52446:826::-;52537:8;:15;52527:25;;52519:58;;;;-1:-1:-1;;;52519:58:0;;;;;;;:::i;:::-;52588:23;52614:8;52623:7;52614:17;;;;;;;;:::i;:::-;;;;;;;;;;;52588:43;;52669:4;:15;;:25;52685:8;52669:25;;;;;;;;;;;:36;;;52650:15;:55;;52642:93;;;;-1:-1:-1;;;52642:93:0;;16206:2:1;52642:93:0;;;16188:21:1;16245:2;16225:18;;;16218:30;-1:-1:-1;;;16264:18:1;;;16257:55;16329:18;;52642:93:0;16004:349:1;52642:93:0;52767:10;52788:1;52754:24;;;:12;;;:24;;;;;:31;;;52746:62;;;;-1:-1:-1;;;52746:62:0;;;;;;;:::i;:::-;52827:30;;;;:20;;;:30;;;;;;-1:-1:-1;;;;;52827:30:0;52861:10;52827:44;52819:72;;;;-1:-1:-1;;;52819:72:0;;16560:2:1;52819:72:0;;;16542:21:1;16599:2;16579:18;;;16572:30;-1:-1:-1;;;16618:18:1;;;16611:45;16673:18;;52819:72:0;16358:339:1;52819:72:0;52904:21;52917:7;52904:12;:21::i;:::-;52985:10;52972:24;;;;:12;;;:24;;;;;:31;;;:38;;53008:1;52972:35;:38::i;:::-;52951:10;52938:24;;;;:12;;;:24;;;;;;;;:31;;;:72;;;;53021:30;;;:20;;;:30;;;;:43;;-1:-1:-1;;;;;;53021:43:0;;;53075:24;;;;;;:50;;53042:8;53075:40;:50::i;:::-;-1:-1:-1;53138:8:0;;:62;;-1:-1:-1;;;53138:62:0;;-1:-1:-1;;;;;53138:8:0;;;;:25;;:62;;53172:4;;53179:10;;53191:8;;53138:62;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;53218:46:0;;;15925:25:1;;;53248:15:0;15981:2:1;15966:18;;15959:34;53226:10:0;;-1:-1:-1;53218:46:0;;-1:-1:-1;15898:18:1;53218:46:0;;;;;;;52508:764;52446:826;;:::o;55207:279::-;55328:7;55354:12;55406:6;55414;55422:5;55437:4;55389:54;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;55389:54:0;;;;;;55369:85;;55389:54;55369:85;;;;;55207:279;-1:-1:-1;;;;;55207:279:0:o;54917:97::-;43741:13;:11;:13::i;:::-;54983::::1;:23:::0;;-1:-1:-1;;;;;;54983:23:0::1;-1:-1:-1::0;;;;;54983:23:0;;;::::1;::::0;;;::::1;::::0;;54917:97::o;44503:103::-;43741:13;:11;:13::i;:::-;44568:30:::1;44595:1;44568:18;:30::i;:::-;44503:103::o:0;56754:756::-;56886:8;:15;56848:7;;56876:25;;56868:58;;;;-1:-1:-1;;;56868:58:0;;;;;;;:::i;:::-;56937:23;56963:8;56972:7;56963:17;;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;57015:21:0;;;;:12;56963:17;;;;;57015:12;;;:21;;;;;56963:17;;-1:-1:-1;57015:21:0;56963:17;57094:377;57118:24;:6;:22;:24::i;:::-;57114:1;:28;57094:377;;;57164:15;57182:21;:6;57201:1;57182:18;:21::i;:::-;57218:23;57256:24;;;:15;;;:24;;;;;;;;:29;;;57244:42;;:11;:42;;;;;;57164:39;;-1:-1:-1;57327:6:0;;57368:36;57327:6;57244:42;57368:19;:36::i;:::-;57350:54;-1:-1:-1;57434:25:0;:12;57350:54;57434:16;:25::i;:::-;57419:40;;57149:322;;;;57144:3;;;;;:::i;:::-;;;;57094:377;;;-1:-1:-1;57490:12:0;56754:756;-1:-1:-1;;;;;56754:756:0:o;57518:575::-;57659:8;:15;57603:7;;57612:16;;57649:25;;57641:57;;;;-1:-1:-1;;;57641:57:0;;17411:2:1;57641:57:0;;;17393:21:1;17450:2;17430:18;;;17423:30;-1:-1:-1;;;17469:18:1;;;17462:49;17528:18;;57641:57:0;17209:343:1;57641:57:0;57709:23;57735:8;57744:7;57735:17;;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;57787:28:0;;;;:12;57735:17;;;;;57787:12;;;:28;;;;;57735:17;;-1:-1:-1;57787:28:0;57876:24;57787:28;57876:22;:24::i;:::-;57862:39;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57862:39:0;;57828:73;;57917:9;57912:123;57936:24;:6;:22;:24::i;:::-;57932:1;:28;57912:123;;;58002:21;:6;58021:1;58002:18;:21::i;:::-;57982:14;57997:1;57982:17;;;;;;;;:::i;:::-;;;;;;;;;;:41;57962:3;;;;:::i;:::-;;;;57912:123;;;-1:-1:-1;58055:13:0;;;;;;-1:-1:-1;58070:14:0;-1:-1:-1;;57518:575:0;;;;;;:::o;53280:990::-;53386:8;:15;53376:25;;53368:58;;;;-1:-1:-1;;;53368:58:0;;;;;;;:::i;:::-;53437:23;53463:8;53472:7;53463:17;;;;;;;;:::i;:::-;;;;;;;;;;;53437:43;;53493:21;53506:7;53493:12;:21::i;:::-;53532:9;53527:736;53551:9;:16;53547:1;:20;53527:736;;;53589:16;53608:9;53618:1;53608:12;;;;;;;;:::i;:::-;;;;;;;53589:31;;53662:4;:15;;:25;53678:8;53662:25;;;;;;;;;;;:36;;;53643:15;:55;;53635:93;;;;-1:-1:-1;;;53635:93:0;;16206:2:1;53635:93:0;;;16188:21:1;16245:2;16225:18;;;16218:30;-1:-1:-1;;;16264:18:1;;;16257:55;16329:18;;53635:93:0;16004:349:1;53635:93:0;53764:10;53785:1;53751:24;;;:12;;;:24;;;;;:31;;;53743:62;;;;-1:-1:-1;;;53743:62:0;;;;;;;:::i;:::-;53828:30;;;;:20;;;:30;;;;;;-1:-1:-1;;;;;53828:30:0;53862:10;53828:44;53820:72;;;;-1:-1:-1;;;53820:72:0;;16560:2:1;53820:72:0;;;16542:21:1;16599:2;16579:18;;;16572:30;-1:-1:-1;;;16618:18:1;;;16611:45;16673:18;;53820:72:0;16358:339:1;53820:72:0;53956:10;53943:24;;;;:12;;;:24;;;;;:31;;;:38;;53979:1;53943:35;:38::i;:::-;53922:10;53909:24;;;;:12;;;:24;;;;;;;;:31;;;:72;;;;53996:30;;;:20;;;:30;;;;:43;;-1:-1:-1;;;;;;53996:43:0;;;54054:24;;;;;;:50;;54017:8;54054:40;:50::i;:::-;-1:-1:-1;54121:8:0;;:62;;-1:-1:-1;;;54121:62:0;;-1:-1:-1;;;;;54121:8:0;;;;:25;;:62;;54155:4;;54162:10;;54174:8;;54121:62;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;54205:46:0;;;15925:25:1;;;54235:15:0;15981:2:1;15966:18;;15959:34;54213:10:0;;-1:-1:-1;54205:46:0;;-1:-1:-1;15898:18:1;54205:46:0;;;;;;;-1:-1:-1;53569:3:0;;;;:::i;:::-;;;;53527:736;;;;53357:913;53280:990;;:::o;55494:410::-;55572:7;55581;55590;55599;55637:8;:15;;;;55627:7;:25;55619:58;;;;-1:-1:-1;;;55619:58:0;;;;;;;:::i;:::-;55688:23;55714:8;55723:7;55714:17;;;;;;;;:::i;:::-;;;;;;;;;55772:25;;;55714:17;;;;;;;;55772:15;;:25;;;-1:-1:-1;;55772:25:0;;;;55816:19;;55837:20;;;;55859;;;;55881:14;;;;;55816:19;;55837:20;;-1:-1:-1;55859:20:0;;-1:-1:-1;55881:14:0;-1:-1:-1;55494:410:0;-1:-1:-1;55494:410:0:o;55022:177::-;55102:4;55143:48;55181:9;55143:29;:4;34823:58;;19345:66:1;34823:58:0;;;19333:79:1;19428:12;;;19421:28;;;34690:7:0;;19465:12:1;;34823:58:0;;;;;;;;;;;;34813:69;;;;;;34806:76;;34621:269;;;;55143:29;:37;;:48::i;:::-;55126:13;;-1:-1:-1;;;;;55126:65:0;;;:13;;:65;;55022:177;-1:-1:-1;;;55022:177:0:o;46356:28::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;46356:28:0;;;;-1:-1:-1;46356:28:0;;;;;;;;:::o;48689:1576::-;48867:28;48879:4;48885:9;48867:11;:28::i;:::-;48859:70;;;;-1:-1:-1;;;48859:70:0;;12877:2:1;48859:70:0;;;12859:21:1;12916:2;12896:18;;;12889:30;12955:31;12935:18;;;12928:59;13004:18;;48859:70:0;12675:353:1;48859:70:0;48949:11;48961:5;48949:18;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;48948:19;48940:43;;;;-1:-1:-1;;;48940:43:0;;13760:2:1;48940:43:0;;;13742:21:1;13799:2;13779:18;;;13772:30;-1:-1:-1;;;13818:18:1;;;13811:41;13869:18;;48940:43:0;13558:335:1;48940:43:0;49043:4;49002:37;49018:10;49030:1;49033:5;49002:15;:37::i;:::-;:45;48994:69;;;;-1:-1:-1;;;48994:69:0;;14100:2:1;48994:69:0;;;14082:21:1;14139:2;14119:18;;;14112:30;-1:-1:-1;;;14158:18:1;;;14151:41;14209:18;;48994:69:0;13898:335:1;48994:69:0;49098:4;49077:11;49089:5;49077:18;;;;;;:::i;:::-;;;;;;;;;;;;;;:25;;;;;-1:-1:-1;;49077:25:0;;;;;;;;;49131:8;:15;49121:25;;49113:58;;;;-1:-1:-1;;;49113:58:0;;;;;;;:::i;:::-;49182:23;49208:8;49217:7;49208:17;;;;;;;;:::i;:::-;;;;;;;;;;;49182:43;;49264:6;:13;49244:9;:16;:33;49236:59;;;;-1:-1:-1;;;49236:59:0;;17759:2:1;49236:59:0;;;17741:21:1;17798:2;17778:18;;;17771:30;-1:-1:-1;;;17817:18:1;;;17810:43;17870:18;;49236:59:0;17557:337:1;49236:59:0;49313:9;49308:950;49332:9;:16;49328:1;:20;49308:950;;;49370:16;49389:9;49399:1;49389:12;;;;;;;;:::i;:::-;;;;;;;49370:31;;49416:13;49432:6;49439:1;49432:9;;;;;;;;:::i;:::-;;;;;;;;;;;49466:8;;:30;;-1:-1:-1;;;49466:30:0;;49485:10;49466:30;;;4163:51:1;49432:9:0;;-1:-1:-1;49500:1:0;;-1:-1:-1;;;;;49466:8:0;;;;:18;;4136::1;;49466:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:35;;49458:65;;;;-1:-1:-1;;;49458:65:0;;14629:2:1;49458:65:0;;;14611:21:1;14668:2;14648:18;;;14641:30;-1:-1:-1;;;14687:18:1;;;14680:47;14744:18;;49458:65:0;14427:341:1;49458:65:0;49546:8;;:26;;-1:-1:-1;;;49546:26:0;;;;;3129:25:1;;;49576:10:0;;-1:-1:-1;;;;;49546:8:0;;:16;;3102:18:1;;49546:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;49546:40:0;;49538:66;;;;-1:-1:-1;;;49538:66:0;;15231:2:1;49538:66:0;;;15213:21:1;15270:2;15250:18;;;15243:30;-1:-1:-1;;;15289:18:1;;;15282:43;15342:18;;49538:66:0;15029:337:1;49538:66:0;49668:10;49655:24;;;;:12;;;:24;;;;;:31;;;:38;;49691:1;49655:35;:38::i;:::-;49634:10;49621:24;;;;:12;;;:24;;;;;:31;;;:72;;;;49708:47;;49746:8;49708:37;:47::i;:::-;-1:-1:-1;49772:27:0;49802:25;;;:15;;;:25;;;;;49885:13;;;;49865:34;;:15;;:19;:34::i;:::-;49842:20;;;:57;49936:15;49914:37;;;49966:20;;;:38;50019:14;;;:22;;;49914:19;50058:30;;;:20;;;:30;;;;;;;:43;;-1:-1:-1;;;;;;50058:43:0;50091:10;50058:43;;;;;;50118:8;;:62;;-1:-1:-1;;;50118:62:0;;-1:-1:-1;;;;;50118:8:0;;;;;:25;;:62;;50164:4;;50079:8;;50118:62;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;50202:44:0;;;15925:25:1;;;50230:15:0;15981:2:1;15966:18;;15959:34;50208:10:0;;-1:-1:-1;50202:44:0;;-1:-1:-1;15898:18:1;50202:44:0;;;;;;;49355:903;;;49350:3;;;;;:::i;:::-;;;;49308:950;;;;48848:1417;48689:1576;;;;;;:::o;44761:201::-;43741:13;:11;:13::i;:::-;-1:-1:-1;;;;;44850:22:0;::::1;44842:73;;;::::0;-1:-1:-1;;;44842:73:0;;18101:2:1;44842:73:0::1;::::0;::::1;18083:21:1::0;18140:2;18120:18;;;18113:30;18179:34;18159:18;;;18152:62;-1:-1:-1;;;18230:18:1;;;18223:36;18276:19;;44842:73:0::1;17899:402:1::0;44842:73:0::1;44926:28;44945:8;44926:18;:28::i;:::-;44761:201:::0;:::o;55912:834::-;56039:8;:15;56001:7;;56029:25;;56021:58;;;;-1:-1:-1;;;56021:58:0;;;;;;;:::i;:::-;56090:23;56116:8;56125:7;56116:17;;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;56168:21:0;;;;:12;56116:17;;;;;56168:12;;;:21;;;;;56116:17;;-1:-1:-1;56168:21:0;56116:17;56247:460;56271:24;:6;:22;:24::i;:::-;56267:1;:28;56247:460;;;56317:15;56335:21;:6;56354:1;56335:18;:21::i;:::-;56371:23;56409:24;;;:15;;;:24;;;;;;;;:29;;;;56397:42;;:11;:42;;;;;;56534:24;;;;;;;:34;56317:39;;-1:-1:-1;56397:42:0;56514:55;;:15;;:19;:55::i;:::-;56496:73;-1:-1:-1;56586:15:0;56604:36;56496:73;56624:15;56604:19;:36::i;:::-;56586:54;-1:-1:-1;56670:25:0;:12;56586:54;56670:16;:25::i;:::-;56655:40;;56302:405;;;;56297:3;;;;;:::i;:::-;;;;56247:460;;54776:133;43741:13;:11;:13::i;:::-;54867:18:::1;::::0;;;:11:::1;:18;::::0;;;;;:34;54776:133::o;5805:98::-;5863:7;5890:5;5894:1;5890;:5;:::i;:::-;5883:12;5805:98;-1:-1:-1;;;5805:98:0:o;50273:1071::-;50394:8;:15;50356:7;;50384:25;;50376:58;;;;-1:-1:-1;;;50376:58:0;;;;;;;:::i;:::-;50445:23;50471:8;50480:7;50471:17;;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;50523:21:0;;;;;50471:17;;;;;;50523:12;;;:21;;;;;;;50620:23;;;;;50679:36;;-1:-1:-1;;;50679:36:0;;50709:4;50679:36;;;4163:51:1;;;;50471:17:0;;-1:-1:-1;50523:21:0;50471:17;50620:23;;50471:17;;50620:23;;50679:21;;4136:18:1;;50679:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50655:60;;50745:9;50740:474;50764:24;:6;:22;:24::i;:::-;50760:1;:28;50740:474;;;50810:15;50828:21;:6;50847:1;50828:18;:21::i;:::-;50864:23;50902:24;;;:15;;;:24;;;;;;;;:29;;;;50890:42;;:11;:42;;;;;;51041:24;;;;;;;:34;50810:39;;-1:-1:-1;50890:42:0;51021:55;;:15;;:19;:55::i;:::-;51003:73;-1:-1:-1;51093:15:0;51111:36;51003:73;51131:15;51111:19;:36::i;:::-;51093:54;-1:-1:-1;51177:25:0;:12;51093:54;51177:16;:25::i;:::-;51162:40;;50795:419;;;;50790:3;;;;;:::i;:::-;;;;50740:474;;;;51245:12;51229:13;:28;51226:79;;;51280:13;-1:-1:-1;51273:20:0;;-1:-1:-1;;;;51273:20:0;51226:79;-1:-1:-1;51324:12:0;;50273:1071;-1:-1:-1;;;;;;50273:1071:0:o;21488:114::-;21548:7;21575:19;21583:3;14473:18;;14390:109;21956:137;22027:7;22062:22;22066:3;22078:5;22062:3;:22::i;20726:131::-;20793:4;20817:32;20822:3;20842:5;20817:4;:32::i;44020:132::-;43901:7;43928:6;-1:-1:-1;;;;;43928:6:0;42486:10;44084:23;44076:68;;;;-1:-1:-1;;;44076:68:0;;18638:2:1;44076:68:0;;;18620:21:1;;;18657:18;;;18650:30;18716:34;18696:18;;;18689:62;18768:18;;44076:68:0;18436:356:1;6186:98:0;6244:7;6271:5;6275:1;6271;:5;:::i;21033:137::-;21103:4;21127:35;21135:3;21155:5;21127:7;:35::i;45122:191::-;45196:16;45215:6;;-1:-1:-1;;;;;45232:17:0;;;-1:-1:-1;;;;;;45232:17:0;;;;;;45265:40;;45215:6;;;;;;;45265:40;;45196:16;45265:40;45185:128;45122:191;:::o;6543:98::-;6601:7;6628:5;6632:1;6628;:5;:::i;30819:231::-;30897:7;30918:17;30937:18;30959:27;30970:4;30976:9;30959:10;:27::i;:::-;30917:69;;;;30997:18;31009:5;30997:11;:18::i;:::-;-1:-1:-1;31033:9:0;30819:231;-1:-1:-1;;;30819:231:0:o;14853:120::-;14920:7;14947:3;:11;;14959:5;14947:18;;;;;;;;:::i;:::-;;;;;;;;;14940:25;;14853:120;;;;:::o;12079:414::-;12142:4;14272:19;;;:12;;;:19;;;;;;12159:327;;-1:-1:-1;12202:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;12385:18;;12363:19;;;:12;;;:19;;;;;;:40;;;;12418:11;;12159:327;-1:-1:-1;12469:5:0;12462:12;;12669:1420;12735:4;12874:19;;;:12;;;:19;;;;;;12910:15;;12906:1176;;13285:21;13309:14;13322:1;13309:10;:14;:::i;:::-;13358:18;;13285:38;;-1:-1:-1;13338:17:0;;13358:22;;13379:1;;13358:22;:::i;:::-;13338:42;;13414:13;13401:9;:26;13397:405;;13448:17;13468:3;:11;;13480:9;13468:22;;;;;;;;:::i;:::-;;;;;;;;;13448:42;;13622:9;13593:3;:11;;13605:13;13593:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;13707:23;;;:12;;;:23;;;;;:36;;;13397:405;13883:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;13978:3;:12;;:19;13991:5;13978:19;;;;;;;;;;;13971:26;;;14021:4;14014:11;;;;;;;12906:1176;14065:5;14058:12;;;;;29270:747;29351:7;29360:12;29389:9;:16;29409:2;29389:22;29385:625;;29733:4;29718:20;;29712:27;29783:4;29768:20;;29762:27;29841:4;29826:20;;29820:27;29428:9;29812:36;29884:25;29895:4;29812:36;29712:27;29762;29884:10;:25::i;:::-;29877:32;;;;;;;;;29385:625;-1:-1:-1;29958:1:0;;-1:-1:-1;29962:35:0;29942:56;;27541:643;27619:20;27610:5;:29;;;;;;;;:::i;:::-;;27606:571;;27541:643;:::o;27606:571::-;27717:29;27708:5;:38;;;;;;;;:::i;:::-;;27704:473;;27763:34;;-1:-1:-1;;;27763:34:0;;19954:2:1;27763:34:0;;;19936:21:1;19993:2;19973:18;;;19966:30;20032:26;20012:18;;;20005:54;20076:18;;27763:34:0;19752:348:1;27704:473:0;27828:35;27819:5;:44;;;;;;;;:::i;:::-;;27815:362;;27880:41;;-1:-1:-1;;;27880:41:0;;20307:2:1;27880:41:0;;;20289:21:1;20346:2;20326:18;;;20319:30;20385:33;20365:18;;;20358:61;20436:18;;27880:41:0;20105:355:1;27815:362:0;27952:30;27943:5;:39;;;;;;;;:::i;:::-;;27939:238;;27999:44;;-1:-1:-1;;;27999:44:0;;20667:2:1;27999:44:0;;;20649:21:1;20706:2;20686:18;;;20679:30;20745:34;20725:18;;;20718:62;-1:-1:-1;;;20796:18:1;;;20789:32;20838:19;;27999:44:0;20465:398:1;27939:238:0;28074:30;28065:5;:39;;;;;;;;:::i;:::-;;28061:116;;28121:44;;-1:-1:-1;;;28121:44:0;;21070:2:1;28121:44:0;;;21052:21:1;21109:2;21089:18;;;21082:30;21148:34;21128:18;;;21121:62;-1:-1:-1;;;21199:18:1;;;21192:32;21241:19;;28121:44:0;20868:398:1;32271:1632:0;32402:7;;33336:66;33323:79;;33319:163;;;-1:-1:-1;33435:1:0;;-1:-1:-1;33439:30:0;33419:51;;33319:163;33496:1;:7;;33501:2;33496:7;;:18;;;;;33507:1;:7;;33512:2;33507:7;;33496:18;33492:102;;;-1:-1:-1;33547:1:0;;-1:-1:-1;33551:30:0;33531:51;;33492:102;33708:24;;;33691:14;33708:24;;;;;;;;;21498:25:1;;;21571:4;21559:17;;21539:18;;;21532:45;;;;21593:18;;;21586:34;;;21636:18;;;21629:34;;;33708:24:0;;21470:19:1;;33708:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;33708:24:0;;-1:-1:-1;;33708:24:0;;;-1:-1:-1;;;;;;;33747:20:0;;33743:103;;33800:1;33804:29;33784:50;;;;;;;33743:103;33866:6;-1:-1:-1;33874:20:0;;-1:-1:-1;32271:1632:0;;;;;;;;:::o;14:180:1:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:1;;14:180;-1:-1:-1;14:180:1:o;199:127::-;260:10;255:3;251:20;248:1;241:31;291:4;288:1;281:15;315:4;312:1;305:15;331:275;402:2;396:9;467:2;448:13;;-1:-1:-1;;444:27:1;432:40;;502:18;487:34;;523:22;;;484:62;481:88;;;549:18;;:::i;:::-;585:2;578:22;331:275;;-1:-1:-1;331:275:1:o;611:531::-;654:5;707:3;700:4;692:6;688:17;684:27;674:55;;725:1;722;715:12;674:55;761:6;748:20;787:18;783:2;780:26;777:52;;;809:18;;:::i;:::-;853:55;896:2;877:13;;-1:-1:-1;;873:27:1;902:4;869:38;853:55;:::i;:::-;933:2;924:7;917:19;979:3;972:4;967:2;959:6;955:15;951:26;948:35;945:55;;;996:1;993;986:12;945:55;1061:2;1054:4;1046:6;1042:17;1035:4;1026:7;1022:18;1009:55;1109:1;1084:16;;;1102:4;1080:27;1073:38;;;;1088:7;611:531;-1:-1:-1;;;611:531:1:o;1147:817::-;1270:6;1278;1286;1294;1302;1310;1363:3;1351:9;1342:7;1338:23;1334:33;1331:53;;;1380:1;1377;1370:12;1331:53;1416:9;1403:23;1393:33;;1473:2;1462:9;1458:18;1445:32;1435:42;;1524:2;1513:9;1509:18;1496:32;1486:42;;1579:2;1568:9;1564:18;1551:32;1602:18;1643:2;1635:6;1632:14;1629:34;;;1659:1;1656;1649:12;1629:34;1682:50;1724:7;1715:6;1704:9;1700:22;1682:50;:::i;:::-;1672:60;;1779:3;1768:9;1764:19;1751:33;1741:43;;1837:3;1826:9;1822:19;1809:33;1793:49;;1867:2;1857:8;1854:16;1851:36;;;1883:1;1880;1873:12;1851:36;;1906:52;1950:7;1939:8;1928:9;1924:24;1906:52;:::i;:::-;1896:62;;;1147:817;;;;;;;;:::o;1969:131::-;-1:-1:-1;;;;;2044:31:1;;2034:42;;2024:70;;2090:1;2087;2080:12;2105:666;2200:6;2208;2216;2224;2277:3;2265:9;2256:7;2252:23;2248:33;2245:53;;;2294:1;2291;2284:12;2245:53;2333:9;2320:23;2352:31;2377:5;2352:31;:::i;:::-;2402:5;-1:-1:-1;2459:2:1;2444:18;;2431:32;2472:33;2431:32;2472:33;:::i;:::-;2524:7;-1:-1:-1;2578:2:1;2563:18;;2550:32;;-1:-1:-1;2633:2:1;2618:18;;2605:32;2660:18;2649:30;;2646:50;;;2692:1;2689;2682:12;2646:50;2715;2757:7;2748:6;2737:9;2733:22;2715:50;:::i;:::-;2705:60;;;2105:666;;;;;;;:::o;3165:594::-;3260:6;3268;3276;3284;3292;3345:3;3333:9;3324:7;3320:23;3316:33;3313:53;;;3362:1;3359;3352:12;3313:53;3401:9;3388:23;3420:31;3445:5;3420:31;:::i;:::-;3470:5;-1:-1:-1;3522:2:1;3507:18;;3494:32;;-1:-1:-1;3573:2:1;3558:18;;3545:32;;-1:-1:-1;3624:2:1;3609:18;;3596:32;;-1:-1:-1;3680:3:1;3665:19;;3652:33;3694;3652;3694;:::i;:::-;3746:7;3736:17;;;3165:594;;;;;;;;:::o;3764:248::-;3832:6;3840;3893:2;3881:9;3872:7;3868:23;3864:32;3861:52;;;3909:1;3906;3899:12;3861:52;-1:-1:-1;;3932:23:1;;;4002:2;3987:18;;;3974:32;;-1:-1:-1;3764:248:1:o;4225:525::-;4312:6;4320;4328;4381:2;4369:9;4360:7;4356:23;4352:32;4349:52;;;4397:1;4394;4387:12;4349:52;4436:9;4423:23;4455:31;4480:5;4455:31;:::i;:::-;4505:5;-1:-1:-1;4557:2:1;4542:18;;4529:32;;-1:-1:-1;4612:2:1;4597:18;;4584:32;4639:18;4628:30;;4625:50;;;4671:1;4668;4661:12;4625:50;4694;4736:7;4727:6;4716:9;4712:22;4694:50;:::i;:::-;4684:60;;;4225:525;;;;;:::o;4937:247::-;4996:6;5049:2;5037:9;5028:7;5024:23;5020:32;5017:52;;;5065:1;5062;5055:12;5017:52;5104:9;5091:23;5123:31;5148:5;5123:31;:::i;5189:315::-;5257:6;5265;5318:2;5306:9;5297:7;5293:23;5289:32;5286:52;;;5334:1;5331;5324:12;5286:52;5370:9;5357:23;5347:33;;5430:2;5419:9;5415:18;5402:32;5443:31;5468:5;5443:31;:::i;:::-;5493:5;5483:15;;;5189:315;;;;;:::o;5509:::-;5577:6;5585;5638:2;5626:9;5617:7;5613:23;5609:32;5606:52;;;5654:1;5651;5644:12;5606:52;5693:9;5680:23;5712:31;5737:5;5712:31;:::i;:::-;5762:5;5814:2;5799:18;;;;5786:32;;-1:-1:-1;;;5509:315:1:o;5829:703::-;5999:4;6047:2;6036:9;6032:18;6077:6;6066:9;6059:25;6103:2;6141;6136;6125:9;6121:18;6114:30;6164:6;6199;6193:13;6230:6;6222;6215:22;6268:2;6257:9;6253:18;6246:25;;6306:2;6298:6;6294:15;6280:29;;6327:1;6337:169;6351:6;6348:1;6345:13;6337:169;;;6412:13;;6400:26;;6481:15;;;;6446:12;;;;6373:1;6366:9;6337:169;;;-1:-1:-1;6523:3:1;;5829:703;-1:-1:-1;;;;;;;5829:703:1:o;6537:712::-;6591:5;6644:3;6637:4;6629:6;6625:17;6621:27;6611:55;;6662:1;6659;6652:12;6611:55;6698:6;6685:20;6724:4;6747:18;6743:2;6740:26;6737:52;;;6769:18;;:::i;:::-;6815:2;6812:1;6808:10;6838:28;6862:2;6858;6854:11;6838:28;:::i;:::-;6900:15;;;6970;;;6966:24;;;6931:12;;;;7002:15;;;6999:35;;;7030:1;7027;7020:12;6999:35;7066:2;7058:6;7054:15;7043:26;;7078:142;7094:6;7089:3;7086:15;7078:142;;;7160:17;;7148:30;;7111:12;;;;7198;;;;7078:142;;;7238:5;6537:712;-1:-1:-1;;;;;;;6537:712:1:o;7254:416::-;7347:6;7355;7408:2;7396:9;7387:7;7383:23;7379:32;7376:52;;;7424:1;7421;7414:12;7376:52;7464:9;7451:23;7497:18;7489:6;7486:30;7483:50;;;7529:1;7526;7519:12;7483:50;7552:61;7605:7;7596:6;7585:9;7581:22;7552:61;:::i;:::-;7542:71;7660:2;7645:18;;;;7632:32;;-1:-1:-1;;;;7254:416:1:o;7675:322::-;7744:6;7797:2;7785:9;7776:7;7772:23;7768:32;7765:52;;;7813:1;7810;7803:12;7765:52;7853:9;7840:23;7886:18;7878:6;7875:30;7872:50;;;7918:1;7915;7908:12;7872:50;7941;7983:7;7974:6;7963:9;7959:22;7941:50;:::i;:::-;7931:60;7675:322;-1:-1:-1;;;;7675:322:1:o;8590:389::-;8667:6;8675;8728:2;8716:9;8707:7;8703:23;8699:32;8696:52;;;8744:1;8741;8734:12;8696:52;8780:9;8767:23;8757:33;;8841:2;8830:9;8826:18;8813:32;8868:18;8860:6;8857:30;8854:50;;;8900:1;8897;8890:12;8854:50;8923;8965:7;8956:6;8945:9;8941:22;8923:50;:::i;:::-;8913:60;;;8590:389;;;;;:::o;9524:1133::-;9697:6;9705;9713;9721;9729;9737;9790:3;9778:9;9769:7;9765:23;9761:33;9758:53;;;9807:1;9804;9797:12;9758:53;9847:9;9834:23;9876:18;9917:2;9909:6;9906:14;9903:34;;;9933:1;9930;9923:12;9903:34;9956:61;10009:7;10000:6;9989:9;9985:22;9956:61;:::i;:::-;9946:71;;10064:2;10053:9;10049:18;10036:32;10026:42;;10121:2;10110:9;10106:18;10093:32;10077:48;;10150:2;10140:8;10137:16;10134:36;;;10166:1;10163;10156:12;10134:36;10189:63;10244:7;10233:8;10222:9;10218:24;10189:63;:::i;:::-;10179:73;;10305:2;10294:9;10290:18;10277:32;10261:48;;10334:2;10324:8;10321:16;10318:36;;;10350:1;10347;10340:12;10662:344;10864:2;10846:21;;;10903:2;10883:18;;;10876:30;-1:-1:-1;;;10937:2:1;10922:18;;10915:50;10997:2;10982:18;;10662:344::o;11011:127::-;11072:10;11067:3;11063:20;11060:1;11053:31;11103:4;11100:1;11093:15;11127:4;11124:1;11117:15;11143:338;11345:2;11327:21;;;11384:2;11364:18;;;11357:30;-1:-1:-1;;;11418:2:1;11403:18;;11396:44;11472:2;11457:18;;11143:338::o;11842:127::-;11903:10;11898:3;11894:20;11891:1;11884:31;11934:4;11931:1;11924:15;11958:4;11955:1;11948:15;11974:135;12013:3;12034:17;;;12031:43;;12054:18;;:::i;:::-;-1:-1:-1;12101:1:1;12090:13;;11974:135::o;12393:277::-;12460:6;12513:2;12501:9;12492:7;12488:23;12484:32;12481:52;;;12529:1;12526;12519:12;12481:52;12561:9;12555:16;12614:5;12607:13;12600:21;12593:5;12590:32;12580:60;;12636:1;12633;12626:12;13033:323;13075:3;13113:5;13107:12;13137:1;13147:128;13161:6;13158:1;13155:13;13147:128;;;13258:4;13243:13;;;13239:24;;13233:31;13220:11;;;13213:52;13176:12;13147:128;;;-1:-1:-1;13330:1:1;13294:16;;13319:13;;;-1:-1:-1;13294:16:1;;13033:323;-1:-1:-1;13033:323:1:o;13361:192::-;13492:3;13517:30;13543:3;13535:6;13517:30;:::i;14238:184::-;14308:6;14361:2;14349:9;14340:7;14336:23;14332:32;14329:52;;;14377:1;14374;14367:12;14329:52;-1:-1:-1;14400:16:1;;14238:184;-1:-1:-1;14238:184:1:o;14773:251::-;14843:6;14896:2;14884:9;14875:7;14871:23;14867:32;14864:52;;;14912:1;14909;14902:12;14864:52;14944:9;14938:16;14963:31;14988:5;14963:31;:::i;15371:375::-;-1:-1:-1;;;;;15629:15:1;;;15611:34;;15681:15;;;;15676:2;15661:18;;15654:43;15728:2;15713:18;;15706:34;;;;15561:2;15546:18;;15371:375::o;16702:502::-;16917:3;16949:26;16945:31;17018:2;17009:6;17005:2;17001:15;16997:24;16992:3;16985:37;17052:6;17047:2;17042:3;17038:12;17031:28;17081:39;17116:2;17111:3;17107:12;17099:6;17081:39;:::i;:::-;17151:2;17147:15;;;;17143:24;17129:39;;-1:-1:-1;;17195:2:1;17184:14;;16702:502;-1:-1:-1;;;16702:502:1:o;18306:125::-;18371:9;;;18392:10;;;18389:36;;;18405:18;;:::i;18797:128::-;18864:9;;;18885:11;;;18882:37;;;18899:18;;:::i;18930:168::-;19003:9;;;19034;;19051:15;;;19045:22;;19031:37;19021:71;;19072:18;;:::i;19488:127::-;19549:10;19544:3;19540:20;19537:1;19530:31;19580:4;19577:1;19570:15;19604:4;19601:1;19594:15;19620:127;19681:10;19676:3;19672:20;19669:1;19662:31;19712:4;19709:1;19702:15;19736:4;19733:1;19726:15
Swarm Source
ipfs://8f157844ad6899108ff7abc2d28d67aea8c870432a9366f866913a279f4f6144
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.