More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 918 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Unstake | 17727435 | 345 days ago | IN | 0 ETH | 0.00210859 | ||||
Unstake | 17727423 | 345 days ago | IN | 0 ETH | 0.00318339 | ||||
Stake | 17409785 | 390 days ago | IN | 0 ETH | 0.00274178 | ||||
Stake | 17334637 | 401 days ago | IN | 0 ETH | 0.00249272 | ||||
Stake | 17334635 | 401 days ago | IN | 0 ETH | 0.00275455 | ||||
Stake | 17334634 | 401 days ago | IN | 0 ETH | 0.00277687 | ||||
Stake | 17334632 | 401 days ago | IN | 0 ETH | 0.00286839 | ||||
Stake | 17334630 | 401 days ago | IN | 0 ETH | 0.0028501 | ||||
Stake | 17334628 | 401 days ago | IN | 0 ETH | 0.00284019 | ||||
Stake | 17334626 | 401 days ago | IN | 0 ETH | 0.00293307 | ||||
Stake | 17334625 | 401 days ago | IN | 0 ETH | 0.00285215 | ||||
Stake | 17334621 | 401 days ago | IN | 0 ETH | 0.00295289 | ||||
Stake | 17334617 | 401 days ago | IN | 0 ETH | 0.00282704 | ||||
Stake | 17334616 | 401 days ago | IN | 0 ETH | 0.00278247 | ||||
Stake | 17334612 | 401 days ago | IN | 0 ETH | 0.00282941 | ||||
Stake | 17334609 | 401 days ago | IN | 0 ETH | 0.00292318 | ||||
Stake | 17334608 | 401 days ago | IN | 0 ETH | 0.00122806 | ||||
Stake | 17334606 | 401 days ago | IN | 0 ETH | 0.00278789 | ||||
Stake | 17334601 | 401 days ago | IN | 0 ETH | 0.00290754 | ||||
Stake | 17334550 | 401 days ago | IN | 0 ETH | 0.00260773 | ||||
Stake | 17334541 | 401 days ago | IN | 0 ETH | 0.00288845 | ||||
Stake | 17334532 | 401 days ago | IN | 0 ETH | 0.00293102 | ||||
Stake | 17334531 | 401 days ago | IN | 0 ETH | 0.00295137 | ||||
Stake | 17334528 | 401 days ago | IN | 0 ETH | 0.0027588 | ||||
Stake | 17334527 | 401 days ago | IN | 0 ETH | 0.00273018 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
NFTStaking
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-01-15 */ // SPDX-License-Identifier: MIT LICENSE // File: @openzeppelin/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @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] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } // File: @openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // 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/utils/introspection/ERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: @openzeppelin/contracts/token/ERC721/IERC721.sol // OpenZeppelin Contracts (last updated v4.8.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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * 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/token/ERC721/extensions/IERC721Enumerable.sol // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } // File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // 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/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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); /** * @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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount ) external returns (bool); } // File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File: @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/token/ERC721/ERC721.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @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. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256, /* firstTokenId */ uint256 batchSize ) internal virtual { if (batchSize > 1) { if (from != address(0)) { _balances[from] -= batchSize; } if (to != address(0)) { _balances[to] += batchSize; } } } /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual {} } // File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol) pragma solidity ^0.8.0; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev See {ERC721-_beforeTokenTransfer}. */ function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual override { super._beforeTokenTransfer(from, to, firstTokenId, batchSize); if (batchSize > 1) { // Will only trigger during construction. Batch transferring (minting) is not available afterwards. revert("ERC721Enumerable: consecutive transfers not supported"); } uint256 tokenId = firstTokenId; if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } } // File: @openzeppelin/contracts/token/ERC20/ERC20.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer( address from, address to, uint256 amount ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _balances[to] += amount; } emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 amount ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } // File: @openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol) pragma solidity ^0.8.0; /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ abstract contract ERC20Burnable is Context, ERC20 { /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) public virtual { _burn(_msgSender(), amount); } /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) public virtual { _spendAllowance(account, _msgSender(), amount); _burn(account, amount); } } // 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: https://github.com/net2devcrypto/n2dstaking/N2DRewards.sol /* Follow/Subscribe Youtube, Github, IM, Tiktok for more amazing content!! @Net2Dev ███╗░░██╗███████╗████████╗██████╗░██████╗░███████╗██╗░░░██╗ ████╗░██║██╔════╝╚══██╔══╝╚════██╗██╔══██╗██╔════╝██║░░░██║ ██╔██╗██║█████╗░░░░░██║░░░░░███╔═╝██║░░██║█████╗░░╚██╗░██╔╝ ██║╚████║██╔══╝░░░░░██║░░░██╔══╝░░██║░░██║██╔══╝░░░╚████╔╝░ ██║░╚███║███████╗░░░██║░░░███████╗██████╔╝███████╗░░╚██╔╝░░ ╚═╝░░╚══╝╚══════╝░░░╚═╝░░░╚══════╝╚═════╝░╚══════╝░░░╚═╝░░░ THIS CONTRACT IS AVAILABLE FOR EDUCATIONAL PURPOSES ONLY. YOU ARE SOLELY REPONSIBLE FOR ITS USE. I AM NOT RESPONSIBLE FOR ANY OTHER USE. THIS IS TRAINING/EDUCATIONAL MATERIAL. ONLY USE IT IF YOU AGREE TO THE TERMS SPECIFIED ABOVE. */ pragma solidity 0.8.4; contract N2DRewards is ERC20, ERC20Burnable, Ownable { mapping(address => bool) controllers; constructor() ERC20("N2DRewards", "N2DR") { } function mint(address to, uint256 amount) external { require(controllers[msg.sender], "Only controllers can mint"); _mint(to, amount); } function burnFrom(address account, uint256 amount) public override { if (controllers[msg.sender]) { _burn(account, amount); } else { super.burnFrom(account, amount); } } function addController(address controller) external onlyOwner { controllers[controller] = true; } function removeController(address controller) external onlyOwner { controllers[controller] = false; } } // File: contracts/BotzStaking.sol /* Follow/Subscribe Youtube, Github, IM, Tiktok for more amazing content!! @BlockBotz THIS CONTRACT IS AVAILABLE FOR EDUCATIONAL PURPOSES ONLY. YOU ARE SOLELY REPONSIBLE FOR ITS USE. I AM NOT RESPONSIBLE FOR ANY OTHER USE. THIS IS TRAINING/EDUCATIONAL MATERIAL. */ pragma solidity 0.8.4; contract NFTStaking is Ownable, IERC721Receiver { uint256 public totalStaked; // struct to store a stake's token, owner, and earning values struct Stake { uint24 tokenId; uint48 timestamp; address owner; } event NFTStaked(address owner, uint256 tokenId, uint256 value); event NFTUnstaked(address owner, uint256 tokenId, uint256 value); event Claimed(address owner, uint256 amount); // reference to the Block NFT contract ERC721Enumerable nft; N2DRewards token; // maps tokenId to stake mapping(uint256 => Stake) public vault; constructor(ERC721Enumerable _nft, N2DRewards _token) { nft = _nft; token = _token; } function stake(uint256[] calldata tokenIds) external { uint256 tokenId; totalStaked += tokenIds.length; for (uint i = 0; i < tokenIds.length; i++) { tokenId = tokenIds[i]; require(nft.ownerOf(tokenId) == msg.sender, "not your token"); require(vault[tokenId].tokenId == 0, 'already staked'); nft.transferFrom(msg.sender, address(this), tokenId); emit NFTStaked(msg.sender, tokenId, block.timestamp); vault[tokenId] = Stake({ owner: msg.sender, tokenId: uint24(tokenId), timestamp: uint48(block.timestamp) }); } } function _unstakeMany(address account, uint256[] calldata tokenIds) internal { uint256 tokenId; totalStaked -= tokenIds.length; for (uint i = 0; i < tokenIds.length; i++) { tokenId = tokenIds[i]; Stake memory staked = vault[tokenId]; require(staked.owner == msg.sender, "not an owner"); delete vault[tokenId]; emit NFTUnstaked(account, tokenId, block.timestamp); nft.transferFrom(address(this), account, tokenId); } } function claim(uint256[] calldata tokenIds) external { _claim(msg.sender, tokenIds, false); } function claimForAddress(address account, uint256[] calldata tokenIds) external { _claim(account, tokenIds, false); } function unstake(uint256[] calldata tokenIds) external { _claim(msg.sender, tokenIds, true); } // Follow us on @BlockBotz Youtube , @BlockBotzClub Tiktok, @BlockBotzClub Instagram // TOKEN REWARDS CALCULATION // MAKE SURE YOU CHANGE THE VALUE ON BOTH CLAIM AND EARNINGINFO FUNCTIONS. // Find the following line and update accordingly based on how much you want // to reward users with ERC-20 reward tokens. // I hope you get the idea based on the example. // rewardmath = 100 ether .... (This gives 1 token per day per NFT staked to the staker) function _claim(address account, uint256[] calldata tokenIds, bool _unstake) internal { uint256 tokenId; uint256 earned = 0; uint256 rewardmath = 0; for (uint i = 0; i < tokenIds.length; i++) { tokenId = tokenIds[i]; Stake memory staked = vault[tokenId]; require(staked.owner == account, "not an owner"); uint256 stakedAt = staked.timestamp; rewardmath = 100 ether * (block.timestamp - stakedAt) / 86400 ; earned = rewardmath / 100; vault[tokenId] = Stake({ owner: account, tokenId: uint24(tokenId), timestamp: uint48(block.timestamp) }); } if (earned > 0) { token.mint(account, earned); } if (_unstake) { _unstakeMany(account, tokenIds); } emit Claimed(account, earned); } function earningInfo(address account, uint256[] calldata tokenIds) external view returns (uint256[1] memory info) { uint256 tokenId; uint256 earned = 0; uint256 rewardmath = 0; for (uint i = 0; i < tokenIds.length; i++) { tokenId = tokenIds[i]; Stake memory staked = vault[tokenId]; require(staked.owner == account, "not an owner"); uint256 stakedAt = staked.timestamp; rewardmath = 100 ether * (block.timestamp - stakedAt) / 86400; earned = rewardmath / 100; } if (earned > 0) { return [earned]; } } // should never be used inside of transaction because of gas fee function balanceOf(address account) public view returns (uint256) { uint256 balance = 0; uint256 supply = nft.totalSupply(); for(uint i = 1; i <= supply; i++) { if (vault[i].owner == account) { balance += 1; } } return balance; } // should never be used inside of transaction because of gas fee function tokensOfOwner(address account) public view returns (uint256[] memory ownerTokens) { uint256 supply = nft.totalSupply(); uint256[] memory tmp = new uint256[](supply); uint256 index = 0; for(uint tokenId = 1; tokenId <= supply; tokenId++) { if (vault[tokenId].owner == account) { tmp[index] = vault[tokenId].tokenId; index +=1; } } uint256[] memory tokens = new uint256[](index); for(uint i = 0; i < index; i++) { tokens[i] = tmp[i]; } return tokens; } function onERC721Received( address, address from, uint256, bytes calldata ) external pure override returns (bytes4) { require(from == address(0x0), "Cannot send nfts to Vault directly"); return IERC721Receiver.onERC721Received.selector; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract ERC721Enumerable","name":"_nft","type":"address"},{"internalType":"contract N2DRewards","name":"_token","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"NFTStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"NFTUnstaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"claimForAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"earningInfo","outputs":[{"internalType":"uint256[1]","name":"info","type":"uint256[1]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"ownerTokens","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","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":"tokenIds","type":"uint256[]"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"vault","outputs":[{"internalType":"uint24","name":"tokenId","type":"uint24"},{"internalType":"uint48","name":"timestamp","type":"uint48"},{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506040516200251c3803806200251c8339818101604052810190620000379190620001db565b620000576200004b620000e160201b60201c565b620000e960201b60201c565b81600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050620002ac565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050620001be8162000278565b92915050565b600081519050620001d58162000292565b92915050565b60008060408385031215620001ef57600080fd5b6000620001ff85828601620001ad565b92505060206200021285828601620001c4565b9150509250929050565b6000620002298262000258565b9050919050565b60006200023d826200021c565b9050919050565b600062000251826200021c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b620002838162000230565b81146200028f57600080fd5b50565b6200029d8162000244565b8114620002a957600080fd5b50565b61226080620002bc6000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063817b1cd21161008c5780638da5cb5b116100665780638da5cb5b14610226578063c36be35714610244578063e449f34114610260578063f2fde38b1461027c576100cf565b8063817b1cd2146101a657806381a36fb6146101c45780638462151c146101f6576100cf565b80630fbf0a93146100d4578063150b7a02146100f05780636ba4c1381461012057806370a082311461013c578063715018a61461016c5780637e75dd6014610176575b600080fd5b6100ee60048036038101906100e99190611952565b610298565b005b61010a6004803603810190610105919061187a565b61065b565b6040516101179190611cd1565b60405180910390f35b61013a60048036038101906101359190611952565b6106de565b005b61015660048036038101906101519190611828565b6106ef565b6040516101639190611de3565b60405180910390f35b610174610840565b005b610190600480360381019061018b91906118fa565b610854565b60405161019d9190611c94565b60405180910390f35b6101ae610a80565b6040516101bb9190611de3565b60405180910390f35b6101de60048036038101906101d99190611997565b610a86565b6040516101ed93929190611dac565b60405180910390f35b610210600480360381019061020b9190611828565b610af1565b60405161021d9190611caf565b60405180910390f35b61022e610e3b565b60405161023b9190611be2565b60405180910390f35b61025e600480360381019061025991906118fa565b610e64565b005b61027a60048036038101906102759190611952565b610e76565b005b61029660048036038101906102919190611828565b610e87565b005b600082829050600160008282546102af9190611e75565b9250508190555060005b83839050811015610655578383828181106102fd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002013591503373ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff1660e01b81526004016103789190611de3565b60206040518083038186803b15801561039057600080fd5b505afa1580156103a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103c89190611851565b73ffffffffffffffffffffffffffffffffffffffff161461041e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041590611d0c565b60405180910390fd5b60006004600084815260200190815260200160002060000160009054906101000a900462ffffff1662ffffff161461048b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161048290611d8c565b60405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b81526004016104ea93929190611bfd565b600060405180830381600087803b15801561050457600080fd5b505af1158015610518573d6000803e3d6000fd5b505050507f36b3725f1783bad4ff05b7f4c077c3aa68eeb23a4d054ba189db4d01ac278d3933834260405161054f93929190611c5d565b60405180910390a160405180606001604052808362ffffff1681526020014265ffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152506004600084815260200190815260200160002060008201518160000160006101000a81548162ffffff021916908362ffffff16021790555060208201518160000160036101000a81548165ffffffffffff021916908365ffffffffffff16021790555060408201518160000160096101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050808061064d90612013565b9150506102b9565b50505050565b60008073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146106cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c290611d6c565b60405180910390fd5b63150b7a0260e01b905095945050505050565b6106eb3383836000610f0b565b5050565b600080600090506000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561076057600080fd5b505afa158015610774573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061079891906119c0565b90506000600190505b818111610835578473ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060000160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156108225760018361081f9190611e75565b92505b808061082d90612013565b9150506107a1565b508192505050919050565b6108486112da565b6108526000611358565b565b61085c61171e565b600080600090506000805b86869050811015610a52578686828181106108ab577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002013593506000600460008681526020019081526020016000206040518060600160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020016000820160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090508873ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff16146109ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e490611d4c565b60405180910390fd5b6000816020015165ffffffffffff169050620151808142610a0e9190611f56565b68056bc75e2d63100000610a229190611efc565b610a2c9190611ecb565b9350606484610a3b9190611ecb565b945050508080610a4a90612013565b915050610867565b506000821115610a75576040518060200160405280838152509350505050610a79565b5050505b9392505050565b60015481565b60046020528060005260406000206000915090508060000160009054906101000a900462ffffff16908060000160039054906101000a900465ffffffffffff16908060000160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b60606000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b5d57600080fd5b505afa158015610b71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9591906119c0565b905060008167ffffffffffffffff811115610bd9577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051908082528060200260200182016040528015610c075781602001602082028036833780820191505090505b509050600080600190505b838111610d16578573ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060000160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610d03576004600082815260200190815260200160002060000160009054906101000a900462ffffff1662ffffff16838381518110610ce7577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050600182610d009190611e75565b91505b8080610d0e90612013565b915050610c12565b5060008167ffffffffffffffff811115610d59577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051908082528060200260200182016040528015610d875781602001602082028036833780820191505090505b50905060005b82811015610e2e57838181518110610dce577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151828281518110610e0f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010181815250508080610e2690612013565b915050610d8d565b5080945050505050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610e718383836000610f0b565b505050565b610e833383836001610f0b565b5050565b610e8f6112da565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610eff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ef690611cec565b60405180910390fd5b610f0881611358565b50565b600080600090506000805b868690508110156111ec57868682818110610f5a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002013593506000600460008681526020019081526020016000206040518060600160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020016000820160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090508873ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff161461109c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161109390611d4c565b60405180910390fd5b6000816020015165ffffffffffff1690506201518081426110bd9190611f56565b68056bc75e2d631000006110d19190611efc565b6110db9190611ecb565b93506064846110ea9190611ecb565b945060405180606001604052808762ffffff1681526020014265ffffffffffff1681526020018b73ffffffffffffffffffffffffffffffffffffffff168152506004600088815260200190815260200160002060008201518160000160006101000a81548162ffffff021916908362ffffff16021790555060208201518160000160036101000a81548165ffffffffffff021916908365ffffffffffff16021790555060408201518160000160096101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050505080806111e490612013565b915050610f16565b50600082111561128657600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1988846040518363ffffffff1660e01b8152600401611253929190611c34565b600060405180830381600087803b15801561126d57600080fd5b505af1158015611281573d6000803e3d6000fd5b505050505b83156112985761129787878761141c565b5b7fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a87836040516112c9929190611c34565b60405180910390a150505050505050565b6112e2611716565b73ffffffffffffffffffffffffffffffffffffffff16611300610e3b565b73ffffffffffffffffffffffffffffffffffffffff1614611356576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134d90611d2c565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600082829050600160008282546114339190611f56565b9250508190555060005b8383905081101561170f57838382818110611481577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002013591506000600460008481526020019081526020016000206040518060600160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020016000820160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090503373ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff16146115c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ba90611d4c565b60405180910390fd5b60046000848152602001908152602001600020600080820160006101000a81549062ffffff02191690556000820160036101000a81549065ffffffffffff02191690556000820160096101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550507fc486b9458a8637650d84d262414833a5a457bc91ae86b7da110386c8c3fa255b86844260405161166293929190611c5d565b60405180910390a1600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3088866040518463ffffffff1660e01b81526004016116c993929190611bfd565b600060405180830381600087803b1580156116e357600080fd5b505af11580156116f7573d6000803e3d6000fd5b5050505050808061170790612013565b91505061143d565b5050505050565b600033905090565b6040518060200160405280600190602082028036833780820191505090505090565b60008135905061174f816121fc565b92915050565b600081519050611764816121fc565b92915050565b60008083601f84011261177c57600080fd5b8235905067ffffffffffffffff81111561179557600080fd5b6020830191508360208202830111156117ad57600080fd5b9250929050565b60008083601f8401126117c657600080fd5b8235905067ffffffffffffffff8111156117df57600080fd5b6020830191508360018202830111156117f757600080fd5b9250929050565b60008135905061180d81612213565b92915050565b60008151905061182281612213565b92915050565b60006020828403121561183a57600080fd5b600061184884828501611740565b91505092915050565b60006020828403121561186357600080fd5b600061187184828501611755565b91505092915050565b60008060008060006080868803121561189257600080fd5b60006118a088828901611740565b95505060206118b188828901611740565b94505060406118c2888289016117fe565b935050606086013567ffffffffffffffff8111156118df57600080fd5b6118eb888289016117b4565b92509250509295509295909350565b60008060006040848603121561190f57600080fd5b600061191d86828701611740565b935050602084013567ffffffffffffffff81111561193a57600080fd5b6119468682870161176a565b92509250509250925092565b6000806020838503121561196557600080fd5b600083013567ffffffffffffffff81111561197f57600080fd5b61198b8582860161176a565b92509250509250929050565b6000602082840312156119a957600080fd5b60006119b7848285016117fe565b91505092915050565b6000602082840312156119d257600080fd5b60006119e084828501611813565b91505092915050565b60006119f58383611bb5565b60208301905092915050565b611a0a81611f8a565b82525050565b611a1981611e18565b611a238184611e48565b9250611a2e82611dfe565b8060005b83811015611a5f578151611a4687826119e9565b9650611a5183611e2e565b925050600181019050611a32565b505050505050565b6000611a7282611e23565b611a7c8185611e53565b9350611a8783611e08565b8060005b83811015611ab8578151611a9f88826119e9565b9750611aaa83611e3b565b925050600181019050611a8b565b5085935050505092915050565b611ace81611f9c565b82525050565b6000611ae1602683611e64565b9150611aec826120ba565b604082019050919050565b6000611b04600e83611e64565b9150611b0f82612109565b602082019050919050565b6000611b27602083611e64565b9150611b3282612132565b602082019050919050565b6000611b4a600c83611e64565b9150611b558261215b565b602082019050919050565b6000611b6d602283611e64565b9150611b7882612184565b604082019050919050565b6000611b90600e83611e64565b9150611b9b826121d3565b602082019050919050565b611baf81611fe8565b82525050565b611bbe81611ff7565b82525050565b611bcd81611ff7565b82525050565b611bdc81612001565b82525050565b6000602082019050611bf76000830184611a01565b92915050565b6000606082019050611c126000830186611a01565b611c1f6020830185611a01565b611c2c6040830184611bc4565b949350505050565b6000604082019050611c496000830185611a01565b611c566020830184611bc4565b9392505050565b6000606082019050611c726000830186611a01565b611c7f6020830185611bc4565b611c8c6040830184611bc4565b949350505050565b6000602082019050611ca96000830184611a10565b92915050565b60006020820190508181036000830152611cc98184611a67565b905092915050565b6000602082019050611ce66000830184611ac5565b92915050565b60006020820190508181036000830152611d0581611ad4565b9050919050565b60006020820190508181036000830152611d2581611af7565b9050919050565b60006020820190508181036000830152611d4581611b1a565b9050919050565b60006020820190508181036000830152611d6581611b3d565b9050919050565b60006020820190508181036000830152611d8581611b60565b9050919050565b60006020820190508181036000830152611da581611b83565b9050919050565b6000606082019050611dc16000830186611ba6565b611dce6020830185611bd3565b611ddb6040830184611a01565b949350505050565b6000602082019050611df86000830184611bc4565b92915050565b6000819050919050565b6000819050602082019050919050565b600060019050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b6000611e8082611ff7565b9150611e8b83611ff7565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115611ec057611ebf61205c565b5b828201905092915050565b6000611ed682611ff7565b9150611ee183611ff7565b925082611ef157611ef061208b565b5b828204905092915050565b6000611f0782611ff7565b9150611f1283611ff7565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611f4b57611f4a61205c565b5b828202905092915050565b6000611f6182611ff7565b9150611f6c83611ff7565b925082821015611f7f57611f7e61205c565b5b828203905092915050565b6000611f9582611fc8565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062ffffff82169050919050565b6000819050919050565b600065ffffffffffff82169050919050565b600061201e82611ff7565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156120515761205061205c565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f6e6f7420796f757220746f6b656e000000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f6e6f7420616e206f776e65720000000000000000000000000000000000000000600082015250565b7f43616e6e6f742073656e64206e66747320746f205661756c742064697265637460008201527f6c79000000000000000000000000000000000000000000000000000000000000602082015250565b7f616c7265616479207374616b6564000000000000000000000000000000000000600082015250565b61220581611f8a565b811461221057600080fd5b50565b61221c81611ff7565b811461222757600080fd5b5056fea2646970667358221220a8a193886e450304dd0c9300bba957064c414714e3e586b05efe6f1bf933952864736f6c634300080400330000000000000000000000009910c2e45116364a85a2c1704583629349aebf36000000000000000000000000b5e429c69cbbb9c4fa146540a9a4aa039d29bc27
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063817b1cd21161008c5780638da5cb5b116100665780638da5cb5b14610226578063c36be35714610244578063e449f34114610260578063f2fde38b1461027c576100cf565b8063817b1cd2146101a657806381a36fb6146101c45780638462151c146101f6576100cf565b80630fbf0a93146100d4578063150b7a02146100f05780636ba4c1381461012057806370a082311461013c578063715018a61461016c5780637e75dd6014610176575b600080fd5b6100ee60048036038101906100e99190611952565b610298565b005b61010a6004803603810190610105919061187a565b61065b565b6040516101179190611cd1565b60405180910390f35b61013a60048036038101906101359190611952565b6106de565b005b61015660048036038101906101519190611828565b6106ef565b6040516101639190611de3565b60405180910390f35b610174610840565b005b610190600480360381019061018b91906118fa565b610854565b60405161019d9190611c94565b60405180910390f35b6101ae610a80565b6040516101bb9190611de3565b60405180910390f35b6101de60048036038101906101d99190611997565b610a86565b6040516101ed93929190611dac565b60405180910390f35b610210600480360381019061020b9190611828565b610af1565b60405161021d9190611caf565b60405180910390f35b61022e610e3b565b60405161023b9190611be2565b60405180910390f35b61025e600480360381019061025991906118fa565b610e64565b005b61027a60048036038101906102759190611952565b610e76565b005b61029660048036038101906102919190611828565b610e87565b005b600082829050600160008282546102af9190611e75565b9250508190555060005b83839050811015610655578383828181106102fd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002013591503373ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff1660e01b81526004016103789190611de3565b60206040518083038186803b15801561039057600080fd5b505afa1580156103a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103c89190611851565b73ffffffffffffffffffffffffffffffffffffffff161461041e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041590611d0c565b60405180910390fd5b60006004600084815260200190815260200160002060000160009054906101000a900462ffffff1662ffffff161461048b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161048290611d8c565b60405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b81526004016104ea93929190611bfd565b600060405180830381600087803b15801561050457600080fd5b505af1158015610518573d6000803e3d6000fd5b505050507f36b3725f1783bad4ff05b7f4c077c3aa68eeb23a4d054ba189db4d01ac278d3933834260405161054f93929190611c5d565b60405180910390a160405180606001604052808362ffffff1681526020014265ffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152506004600084815260200190815260200160002060008201518160000160006101000a81548162ffffff021916908362ffffff16021790555060208201518160000160036101000a81548165ffffffffffff021916908365ffffffffffff16021790555060408201518160000160096101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050808061064d90612013565b9150506102b9565b50505050565b60008073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146106cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c290611d6c565b60405180910390fd5b63150b7a0260e01b905095945050505050565b6106eb3383836000610f0b565b5050565b600080600090506000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561076057600080fd5b505afa158015610774573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061079891906119c0565b90506000600190505b818111610835578473ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060000160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156108225760018361081f9190611e75565b92505b808061082d90612013565b9150506107a1565b508192505050919050565b6108486112da565b6108526000611358565b565b61085c61171e565b600080600090506000805b86869050811015610a52578686828181106108ab577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002013593506000600460008681526020019081526020016000206040518060600160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020016000820160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090508873ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff16146109ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e490611d4c565b60405180910390fd5b6000816020015165ffffffffffff169050620151808142610a0e9190611f56565b68056bc75e2d63100000610a229190611efc565b610a2c9190611ecb565b9350606484610a3b9190611ecb565b945050508080610a4a90612013565b915050610867565b506000821115610a75576040518060200160405280838152509350505050610a79565b5050505b9392505050565b60015481565b60046020528060005260406000206000915090508060000160009054906101000a900462ffffff16908060000160039054906101000a900465ffffffffffff16908060000160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b60606000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b5d57600080fd5b505afa158015610b71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9591906119c0565b905060008167ffffffffffffffff811115610bd9577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051908082528060200260200182016040528015610c075781602001602082028036833780820191505090505b509050600080600190505b838111610d16578573ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060000160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610d03576004600082815260200190815260200160002060000160009054906101000a900462ffffff1662ffffff16838381518110610ce7577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050600182610d009190611e75565b91505b8080610d0e90612013565b915050610c12565b5060008167ffffffffffffffff811115610d59577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051908082528060200260200182016040528015610d875781602001602082028036833780820191505090505b50905060005b82811015610e2e57838181518110610dce577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151828281518110610e0f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010181815250508080610e2690612013565b915050610d8d565b5080945050505050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610e718383836000610f0b565b505050565b610e833383836001610f0b565b5050565b610e8f6112da565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610eff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ef690611cec565b60405180910390fd5b610f0881611358565b50565b600080600090506000805b868690508110156111ec57868682818110610f5a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002013593506000600460008681526020019081526020016000206040518060600160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020016000820160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090508873ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff161461109c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161109390611d4c565b60405180910390fd5b6000816020015165ffffffffffff1690506201518081426110bd9190611f56565b68056bc75e2d631000006110d19190611efc565b6110db9190611ecb565b93506064846110ea9190611ecb565b945060405180606001604052808762ffffff1681526020014265ffffffffffff1681526020018b73ffffffffffffffffffffffffffffffffffffffff168152506004600088815260200190815260200160002060008201518160000160006101000a81548162ffffff021916908362ffffff16021790555060208201518160000160036101000a81548165ffffffffffff021916908365ffffffffffff16021790555060408201518160000160096101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050505080806111e490612013565b915050610f16565b50600082111561128657600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1988846040518363ffffffff1660e01b8152600401611253929190611c34565b600060405180830381600087803b15801561126d57600080fd5b505af1158015611281573d6000803e3d6000fd5b505050505b83156112985761129787878761141c565b5b7fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a87836040516112c9929190611c34565b60405180910390a150505050505050565b6112e2611716565b73ffffffffffffffffffffffffffffffffffffffff16611300610e3b565b73ffffffffffffffffffffffffffffffffffffffff1614611356576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134d90611d2c565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600082829050600160008282546114339190611f56565b9250508190555060005b8383905081101561170f57838382818110611481577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002013591506000600460008481526020019081526020016000206040518060600160405290816000820160009054906101000a900462ffffff1662ffffff1662ffffff1681526020016000820160039054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020016000820160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090503373ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff16146115c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ba90611d4c565b60405180910390fd5b60046000848152602001908152602001600020600080820160006101000a81549062ffffff02191690556000820160036101000a81549065ffffffffffff02191690556000820160096101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550507fc486b9458a8637650d84d262414833a5a457bc91ae86b7da110386c8c3fa255b86844260405161166293929190611c5d565b60405180910390a1600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3088866040518463ffffffff1660e01b81526004016116c993929190611bfd565b600060405180830381600087803b1580156116e357600080fd5b505af11580156116f7573d6000803e3d6000fd5b5050505050808061170790612013565b91505061143d565b5050505050565b600033905090565b6040518060200160405280600190602082028036833780820191505090505090565b60008135905061174f816121fc565b92915050565b600081519050611764816121fc565b92915050565b60008083601f84011261177c57600080fd5b8235905067ffffffffffffffff81111561179557600080fd5b6020830191508360208202830111156117ad57600080fd5b9250929050565b60008083601f8401126117c657600080fd5b8235905067ffffffffffffffff8111156117df57600080fd5b6020830191508360018202830111156117f757600080fd5b9250929050565b60008135905061180d81612213565b92915050565b60008151905061182281612213565b92915050565b60006020828403121561183a57600080fd5b600061184884828501611740565b91505092915050565b60006020828403121561186357600080fd5b600061187184828501611755565b91505092915050565b60008060008060006080868803121561189257600080fd5b60006118a088828901611740565b95505060206118b188828901611740565b94505060406118c2888289016117fe565b935050606086013567ffffffffffffffff8111156118df57600080fd5b6118eb888289016117b4565b92509250509295509295909350565b60008060006040848603121561190f57600080fd5b600061191d86828701611740565b935050602084013567ffffffffffffffff81111561193a57600080fd5b6119468682870161176a565b92509250509250925092565b6000806020838503121561196557600080fd5b600083013567ffffffffffffffff81111561197f57600080fd5b61198b8582860161176a565b92509250509250929050565b6000602082840312156119a957600080fd5b60006119b7848285016117fe565b91505092915050565b6000602082840312156119d257600080fd5b60006119e084828501611813565b91505092915050565b60006119f58383611bb5565b60208301905092915050565b611a0a81611f8a565b82525050565b611a1981611e18565b611a238184611e48565b9250611a2e82611dfe565b8060005b83811015611a5f578151611a4687826119e9565b9650611a5183611e2e565b925050600181019050611a32565b505050505050565b6000611a7282611e23565b611a7c8185611e53565b9350611a8783611e08565b8060005b83811015611ab8578151611a9f88826119e9565b9750611aaa83611e3b565b925050600181019050611a8b565b5085935050505092915050565b611ace81611f9c565b82525050565b6000611ae1602683611e64565b9150611aec826120ba565b604082019050919050565b6000611b04600e83611e64565b9150611b0f82612109565b602082019050919050565b6000611b27602083611e64565b9150611b3282612132565b602082019050919050565b6000611b4a600c83611e64565b9150611b558261215b565b602082019050919050565b6000611b6d602283611e64565b9150611b7882612184565b604082019050919050565b6000611b90600e83611e64565b9150611b9b826121d3565b602082019050919050565b611baf81611fe8565b82525050565b611bbe81611ff7565b82525050565b611bcd81611ff7565b82525050565b611bdc81612001565b82525050565b6000602082019050611bf76000830184611a01565b92915050565b6000606082019050611c126000830186611a01565b611c1f6020830185611a01565b611c2c6040830184611bc4565b949350505050565b6000604082019050611c496000830185611a01565b611c566020830184611bc4565b9392505050565b6000606082019050611c726000830186611a01565b611c7f6020830185611bc4565b611c8c6040830184611bc4565b949350505050565b6000602082019050611ca96000830184611a10565b92915050565b60006020820190508181036000830152611cc98184611a67565b905092915050565b6000602082019050611ce66000830184611ac5565b92915050565b60006020820190508181036000830152611d0581611ad4565b9050919050565b60006020820190508181036000830152611d2581611af7565b9050919050565b60006020820190508181036000830152611d4581611b1a565b9050919050565b60006020820190508181036000830152611d6581611b3d565b9050919050565b60006020820190508181036000830152611d8581611b60565b9050919050565b60006020820190508181036000830152611da581611b83565b9050919050565b6000606082019050611dc16000830186611ba6565b611dce6020830185611bd3565b611ddb6040830184611a01565b949350505050565b6000602082019050611df86000830184611bc4565b92915050565b6000819050919050565b6000819050602082019050919050565b600060019050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b6000611e8082611ff7565b9150611e8b83611ff7565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115611ec057611ebf61205c565b5b828201905092915050565b6000611ed682611ff7565b9150611ee183611ff7565b925082611ef157611ef061208b565b5b828204905092915050565b6000611f0782611ff7565b9150611f1283611ff7565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611f4b57611f4a61205c565b5b828202905092915050565b6000611f6182611ff7565b9150611f6c83611ff7565b925082821015611f7f57611f7e61205c565b5b828203905092915050565b6000611f9582611fc8565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062ffffff82169050919050565b6000819050919050565b600065ffffffffffff82169050919050565b600061201e82611ff7565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156120515761205061205c565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f6e6f7420796f757220746f6b656e000000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f6e6f7420616e206f776e65720000000000000000000000000000000000000000600082015250565b7f43616e6e6f742073656e64206e66747320746f205661756c742064697265637460008201527f6c79000000000000000000000000000000000000000000000000000000000000602082015250565b7f616c7265616479207374616b6564000000000000000000000000000000000000600082015250565b61220581611f8a565b811461221057600080fd5b50565b61221c81611ff7565b811461222757600080fd5b5056fea2646970667358221220a8a193886e450304dd0c9300bba957064c414714e3e586b05efe6f1bf933952864736f6c63430008040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000009910c2e45116364a85a2c1704583629349aebf36000000000000000000000000b5e429c69cbbb9c4fa146540a9a4aa039d29bc27
-----Decoded View---------------
Arg [0] : _nft (address): 0x9910C2E45116364A85a2C1704583629349aebf36
Arg [1] : _token (address): 0xB5E429C69CBBb9C4FA146540A9A4AA039d29Bc27
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000009910c2e45116364a85a2c1704583629349aebf36
Arg [1] : 000000000000000000000000b5e429c69cbbb9c4fa146540a9a4aa039d29bc27
Deployed Bytecode Sourcemap
83223:5341:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83924:614;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;88259:298;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85034:103;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;87345:280;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;79761:103;;;:::i;:::-;;86679:592;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83278:26;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83772:38;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;87699:554;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;79113:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85143:127;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;85276:104;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80019:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83924:614;83984:15;84021:8;;:15;;84006:11;;:30;;;;;;;:::i;:::-;;;;;;;;84048:6;84043:490;84064:8;;:15;;84060:1;:19;84043:490;;;84105:8;;84114:1;84105:11;;;;;;;;;;;;;;;;;;;;;84095:21;;84157:10;84133:34;;:3;;;;;;;;;;;:11;;;84145:7;84133:20;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:34;;;84125:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;84229:1;84203:5;:14;84209:7;84203:14;;;;;;;;;;;:22;;;;;;;;;;;;:27;;;84195:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;84260:3;;;;;;;;;;;:16;;;84277:10;84297:4;84304:7;84260:52;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84326:47;84336:10;84348:7;84357:15;84326:47;;;;;;;;:::i;:::-;;;;;;;;84401:124;;;;;;;;84462:7;84401:124;;;;;;84499:15;84401:124;;;;;;84425:10;84401:124;;;;;84384:5;:14;84390:7;84384:14;;;;;;;;;;;:141;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84081:3;;;;;:::i;:::-;;;;84043:490;;;;83924:614;;;:::o;88259:298::-;88408:6;88449:3;88433:20;;:4;:20;;;88425:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;88508:41;;;88501:48;;88259:298;;;;;;;:::o;85034:103::-;85096:35;85103:10;85115:8;;85125:5;85096:6;:35::i;:::-;85034:103;;:::o;87345:280::-;87402:7;87418:15;87436:1;87418:19;;87444:14;87461:3;;;;;;;;;;;:15;;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;87444:34;;87489:6;87498:1;87489:10;;87485:114;87506:6;87501:1;:11;87485:114;;87550:7;87532:25;;:5;:8;87538:1;87532:8;;;;;;;;;;;:14;;;;;;;;;;;;:25;;;87528:64;;;87581:1;87570:12;;;;;:::i;:::-;;;87528:64;87514:3;;;;;:::i;:::-;;;;87485:114;;;;87612:7;87605:14;;;;87345:280;;;:::o;79761:103::-;78999:13;:11;:13::i;:::-;79826:30:::1;79853:1;79826:18;:30::i;:::-;79761:103::o:0;86679:592::-;86769:22;;:::i;:::-;86801:15;86824:14;86841:1;86824:18;;86850;86886:6;86881:333;86902:8;;:15;;86898:1;:19;86881:333;;;86943:8;;86952:1;86943:11;;;;;;;;;;;;;;;;;;;;;86933:21;;86963:19;86985:5;:14;86991:7;86985:14;;;;;;;;;;;86963:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87032:7;87016:23;;:6;:12;;;:23;;;87008:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;87065:16;87084:6;:16;;;87065:35;;;;87165:5;87153:8;87135:15;:26;;;;:::i;:::-;87122:9;:40;;;;:::i;:::-;:48;;;;:::i;:::-;87109:61;;87201:3;87188:10;:16;;;;:::i;:::-;87179:25;;86881:333;;86919:3;;;;;:::i;:::-;;;;86881:333;;;;87233:1;87224:6;:10;87220:48;;;87245:15;;;;;;;;87253:6;87245:15;;;;;;;;;;87220:48;86679:592;;;;;;;;;:::o;83278:26::-;;;;:::o;83772:38::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;87699:554::-;87760:28;87799:14;87816:3;;;;;;;;;;;:15;;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;87799:34;;87840:20;87877:6;87863:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87840:44;;87893:13;87921:12;87936:1;87921:16;;87917:181;87950:6;87939:7;:17;87917:181;;88006:7;87982:31;;:5;:14;87988:7;87982:14;;;;;;;;;;;:20;;;;;;;;;;;;:31;;;87978:113;;;88039:5;:14;88045:7;88039:14;;;;;;;;;;;:22;;;;;;;;;;;;88026:35;;:3;88030:5;88026:10;;;;;;;;;;;;;;;;;;;;;:35;;;;;88080:1;88072:9;;;;;:::i;:::-;;;87978:113;87958:9;;;;;:::i;:::-;;;;87917:181;;;;88106:23;88146:5;88132:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88106:46;;88163:6;88159:67;88179:5;88175:1;:9;88159:67;;;88212:3;88216:1;88212:6;;;;;;;;;;;;;;;;;;;;;;88200;88207:1;88200:9;;;;;;;;;;;;;;;;;;;;;:18;;;;;88186:3;;;;;:::i;:::-;;;;88159:67;;;;88241:6;88234:13;;;;;;87699:554;;;:::o;79113:87::-;79159:7;79186:6;;;;;;;;;;;79179:13;;79113:87;:::o;85143:127::-;85232:32;85239:7;85248:8;;85258:5;85232:6;:32::i;:::-;85143:127;;;:::o;85276:104::-;85340:34;85347:10;85359:8;;85369:4;85340:6;:34::i;:::-;85276:104;;:::o;80019:201::-;78999:13;:11;:13::i;:::-;80128:1:::1;80108:22;;:8;:22;;;;80100:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;80184:28;80203:8;80184:18;:28::i;:::-;80019:201:::0;:::o;85848:825::-;85941:15;85963:14;85980:1;85963:18;;85988;86024:6;86019:479;86040:8;;:15;;86036:1;:19;86019:479;;;86081:8;;86090:1;86081:11;;;;;;;;;;;;;;;;;;;;;86071:21;;86101:19;86123:5;:14;86129:7;86123:14;;;;;;;;;;;86101:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86170:7;86154:23;;:6;:12;;;:23;;;86146:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;86203:16;86222:6;:16;;;86203:35;;;;86303:5;86291:8;86273:15;:26;;;;:::i;:::-;86260:9;:40;;;;:::i;:::-;:48;;;;:::i;:::-;86247:61;;86340:3;86327:10;:16;;;;:::i;:::-;86318:25;;86369:121;;;;;;;;86427:7;86369:121;;;;;;86464:15;86369:121;;;;;;86393:7;86369:121;;;;;86352:5;:14;86358:7;86352:14;;;;;;;;;;;:138;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86019:479;;86057:3;;;;;:::i;:::-;;;;86019:479;;;;86517:1;86508:6;:10;86504:60;;;86529:5;;;;;;;;;;;:10;;;86540:7;86549:6;86529:27;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86504:60;86574:8;86570:62;;;86593:31;86606:7;86615:8;;86593:12;:31::i;:::-;86570:62;86643:24;86651:7;86660:6;86643:24;;;;;;;:::i;:::-;;;;;;;;85848:825;;;;;;;:::o;79278:132::-;79353:12;:10;:12::i;:::-;79342:23;;:7;:5;:7::i;:::-;:23;;;79334:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;79278:132::o;80380:191::-;80454:16;80473:6;;;;;;;;;;;80454:25;;80499:8;80490:6;;:17;;;;;;;;;;;;;;;;;;80554:8;80523:40;;80544:8;80523:40;;;;;;;;;;;;80380:191;;:::o;84544:484::-;84628:15;84665:8;;:15;;84650:11;;:30;;;;;;;:::i;:::-;;;;;;;;84692:6;84687:336;84708:8;;:15;;84704:1;:19;84687:336;;;84749:8;;84758:1;84749:11;;;;;;;;;;;;;;;;;;;;;84739:21;;84769:19;84791:5;:14;84797:7;84791:14;;;;;;;;;;;84769:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84838:10;84822:26;;:6;:12;;;:26;;;84814:51;;;;;;;;;;;;:::i;:::-;;;;;;;;;84883:5;:14;84889:7;84883:14;;;;;;;;;;;;84876:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84911:46;84923:7;84932;84941:15;84911:46;;;;;;;;:::i;:::-;;;;;;;;84966:3;;;;;;;;;;;:16;;;84991:4;84998:7;85007;84966:49;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84687:336;84725:3;;;;;:::i;:::-;;;;84687:336;;;;84544:484;;;;:::o;38960:98::-;39013:7;39040:10;39033:17;;38960:98;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:139:1:-;53:5;91:6;78:20;69:29;;107:33;134:5;107:33;:::i;:::-;59:87;;;;:::o;152:143::-;209:5;240:6;234:13;225:22;;256:33;283:5;256:33;:::i;:::-;215:80;;;;:::o;318:367::-;391:8;401:6;451:3;444:4;436:6;432:17;428:27;418:2;;469:1;466;459:12;418:2;505:6;492:20;482:30;;535:18;527:6;524:30;521:2;;;567:1;564;557:12;521:2;604:4;596:6;592:17;580:29;;658:3;650:4;642:6;638:17;628:8;624:32;621:41;618:2;;;675:1;672;665:12;618:2;408:277;;;;;:::o;704:351::-;761:8;771:6;821:3;814:4;806:6;802:17;798:27;788:2;;839:1;836;829:12;788:2;875:6;862:20;852:30;;905:18;897:6;894:30;891:2;;;937:1;934;927:12;891:2;974:4;966:6;962:17;950:29;;1028:3;1020:4;1012:6;1008:17;998:8;994:32;991:41;988:2;;;1045:1;1042;1035:12;988:2;778:277;;;;;:::o;1061:139::-;1107:5;1145:6;1132:20;1123:29;;1161:33;1188:5;1161:33;:::i;:::-;1113:87;;;;:::o;1206:143::-;1263:5;1294:6;1288:13;1279:22;;1310:33;1337:5;1310:33;:::i;:::-;1269:80;;;;:::o;1355:262::-;1414:6;1463:2;1451:9;1442:7;1438:23;1434:32;1431:2;;;1479:1;1476;1469:12;1431:2;1522:1;1547:53;1592:7;1583:6;1572:9;1568:22;1547:53;:::i;:::-;1537:63;;1493:117;1421:196;;;;:::o;1623:284::-;1693:6;1742:2;1730:9;1721:7;1717:23;1713:32;1710:2;;;1758:1;1755;1748:12;1710:2;1801:1;1826:64;1882:7;1873:6;1862:9;1858:22;1826:64;:::i;:::-;1816:74;;1772:128;1700:207;;;;:::o;1913:829::-;2010:6;2018;2026;2034;2042;2091:3;2079:9;2070:7;2066:23;2062:33;2059:2;;;2108:1;2105;2098:12;2059:2;2151:1;2176:53;2221:7;2212:6;2201:9;2197:22;2176:53;:::i;:::-;2166:63;;2122:117;2278:2;2304:53;2349:7;2340:6;2329:9;2325:22;2304:53;:::i;:::-;2294:63;;2249:118;2406:2;2432:53;2477:7;2468:6;2457:9;2453:22;2432:53;:::i;:::-;2422:63;;2377:118;2562:2;2551:9;2547:18;2534:32;2593:18;2585:6;2582:30;2579:2;;;2625:1;2622;2615:12;2579:2;2661:64;2717:7;2708:6;2697:9;2693:22;2661:64;:::i;:::-;2643:82;;;;2505:230;2049:693;;;;;;;;:::o;2748:570::-;2843:6;2851;2859;2908:2;2896:9;2887:7;2883:23;2879:32;2876:2;;;2924:1;2921;2914:12;2876:2;2967:1;2992:53;3037:7;3028:6;3017:9;3013:22;2992:53;:::i;:::-;2982:63;;2938:117;3122:2;3111:9;3107:18;3094:32;3153:18;3145:6;3142:30;3139:2;;;3185:1;3182;3175:12;3139:2;3221:80;3293:7;3284:6;3273:9;3269:22;3221:80;:::i;:::-;3203:98;;;;3065:246;2866:452;;;;;:::o;3324:425::-;3410:6;3418;3467:2;3455:9;3446:7;3442:23;3438:32;3435:2;;;3483:1;3480;3473:12;3435:2;3554:1;3543:9;3539:17;3526:31;3584:18;3576:6;3573:30;3570:2;;;3616:1;3613;3606:12;3570:2;3652:80;3724:7;3715:6;3704:9;3700:22;3652:80;:::i;:::-;3634:98;;;;3497:245;3425:324;;;;;:::o;3755:262::-;3814:6;3863:2;3851:9;3842:7;3838:23;3834:32;3831:2;;;3879:1;3876;3869:12;3831:2;3922:1;3947:53;3992:7;3983:6;3972:9;3968:22;3947:53;:::i;:::-;3937:63;;3893:117;3821:196;;;;:::o;4023:284::-;4093:6;4142:2;4130:9;4121:7;4117:23;4113:32;4110:2;;;4158:1;4155;4148:12;4110:2;4201:1;4226:64;4282:7;4273:6;4262:9;4258:22;4226:64;:::i;:::-;4216:74;;4172:128;4100:207;;;;:::o;4313:179::-;4382:10;4403:46;4445:3;4437:6;4403:46;:::i;:::-;4481:4;4476:3;4472:14;4458:28;;4393:99;;;;:::o;4498:118::-;4585:24;4603:5;4585:24;:::i;:::-;4580:3;4573:37;4563:53;;:::o;4654:694::-;4790:52;4836:5;4790:52;:::i;:::-;4858:84;4935:6;4930:3;4858:84;:::i;:::-;4851:91;;4966:54;5014:5;4966:54;:::i;:::-;5043:7;5074:1;5059:282;5084:6;5081:1;5078:13;5059:282;;;5160:6;5154:13;5187:63;5246:3;5231:13;5187:63;:::i;:::-;5180:70;;5273:58;5324:6;5273:58;:::i;:::-;5263:68;;5119:222;5106:1;5103;5099:9;5094:14;;5059:282;;;5063:14;4766:582;;;;;:::o;5384:732::-;5503:3;5532:54;5580:5;5532:54;:::i;:::-;5602:86;5681:6;5676:3;5602:86;:::i;:::-;5595:93;;5712:56;5762:5;5712:56;:::i;:::-;5791:7;5822:1;5807:284;5832:6;5829:1;5826:13;5807:284;;;5908:6;5902:13;5935:63;5994:3;5979:13;5935:63;:::i;:::-;5928:70;;6021:60;6074:6;6021:60;:::i;:::-;6011:70;;5867:224;5854:1;5851;5847:9;5842:14;;5807:284;;;5811:14;6107:3;6100:10;;5508:608;;;;;;;:::o;6122:115::-;6207:23;6224:5;6207:23;:::i;:::-;6202:3;6195:36;6185:52;;:::o;6243:366::-;6385:3;6406:67;6470:2;6465:3;6406:67;:::i;:::-;6399:74;;6482:93;6571:3;6482:93;:::i;:::-;6600:2;6595:3;6591:12;6584:19;;6389:220;;;:::o;6615:366::-;6757:3;6778:67;6842:2;6837:3;6778:67;:::i;:::-;6771:74;;6854:93;6943:3;6854:93;:::i;:::-;6972:2;6967:3;6963:12;6956:19;;6761:220;;;:::o;6987:366::-;7129:3;7150:67;7214:2;7209:3;7150:67;:::i;:::-;7143:74;;7226:93;7315:3;7226:93;:::i;:::-;7344:2;7339:3;7335:12;7328:19;;7133:220;;;:::o;7359:366::-;7501:3;7522:67;7586:2;7581:3;7522:67;:::i;:::-;7515:74;;7598:93;7687:3;7598:93;:::i;:::-;7716:2;7711:3;7707:12;7700:19;;7505:220;;;:::o;7731:366::-;7873:3;7894:67;7958:2;7953:3;7894:67;:::i;:::-;7887:74;;7970:93;8059:3;7970:93;:::i;:::-;8088:2;8083:3;8079:12;8072:19;;7877:220;;;:::o;8103:366::-;8245:3;8266:67;8330:2;8325:3;8266:67;:::i;:::-;8259:74;;8342:93;8431:3;8342:93;:::i;:::-;8460:2;8455:3;8451:12;8444:19;;8249:220;;;:::o;8475:115::-;8560:23;8577:5;8560:23;:::i;:::-;8555:3;8548:36;8538:52;;:::o;8596:108::-;8673:24;8691:5;8673:24;:::i;:::-;8668:3;8661:37;8651:53;;:::o;8710:118::-;8797:24;8815:5;8797:24;:::i;:::-;8792:3;8785:37;8775:53;;:::o;8834:115::-;8919:23;8936:5;8919:23;:::i;:::-;8914:3;8907:36;8897:52;;:::o;8955:222::-;9048:4;9086:2;9075:9;9071:18;9063:26;;9099:71;9167:1;9156:9;9152:17;9143:6;9099:71;:::i;:::-;9053:124;;;;:::o;9183:442::-;9332:4;9370:2;9359:9;9355:18;9347:26;;9383:71;9451:1;9440:9;9436:17;9427:6;9383:71;:::i;:::-;9464:72;9532:2;9521:9;9517:18;9508:6;9464:72;:::i;:::-;9546;9614:2;9603:9;9599:18;9590:6;9546:72;:::i;:::-;9337:288;;;;;;:::o;9631:332::-;9752:4;9790:2;9779:9;9775:18;9767:26;;9803:71;9871:1;9860:9;9856:17;9847:6;9803:71;:::i;:::-;9884:72;9952:2;9941:9;9937:18;9928:6;9884:72;:::i;:::-;9757:206;;;;;:::o;9969:442::-;10118:4;10156:2;10145:9;10141:18;10133:26;;10169:71;10237:1;10226:9;10222:17;10213:6;10169:71;:::i;:::-;10250:72;10318:2;10307:9;10303:18;10294:6;10250:72;:::i;:::-;10332;10400:2;10389:9;10385:18;10376:6;10332:72;:::i;:::-;10123:288;;;;;;:::o;10417:314::-;10556:4;10594:2;10583:9;10579:18;10571:26;;10607:117;10721:1;10710:9;10706:17;10697:6;10607:117;:::i;:::-;10561:170;;;;:::o;10737:373::-;10880:4;10918:2;10907:9;10903:18;10895:26;;10967:9;10961:4;10957:20;10953:1;10942:9;10938:17;10931:47;10995:108;11098:4;11089:6;10995:108;:::i;:::-;10987:116;;10885:225;;;;:::o;11116:218::-;11207:4;11245:2;11234:9;11230:18;11222:26;;11258:69;11324:1;11313:9;11309:17;11300:6;11258:69;:::i;:::-;11212:122;;;;:::o;11340:419::-;11506:4;11544:2;11533:9;11529:18;11521:26;;11593:9;11587:4;11583:20;11579:1;11568:9;11564:17;11557:47;11621:131;11747:4;11621:131;:::i;:::-;11613:139;;11511:248;;;:::o;11765:419::-;11931:4;11969:2;11958:9;11954:18;11946:26;;12018:9;12012:4;12008:20;12004:1;11993:9;11989:17;11982:47;12046:131;12172:4;12046:131;:::i;:::-;12038:139;;11936:248;;;:::o;12190:419::-;12356:4;12394:2;12383:9;12379:18;12371:26;;12443:9;12437:4;12433:20;12429:1;12418:9;12414:17;12407:47;12471:131;12597:4;12471:131;:::i;:::-;12463:139;;12361:248;;;:::o;12615:419::-;12781:4;12819:2;12808:9;12804:18;12796:26;;12868:9;12862:4;12858:20;12854:1;12843:9;12839:17;12832:47;12896:131;13022:4;12896:131;:::i;:::-;12888:139;;12786:248;;;:::o;13040:419::-;13206:4;13244:2;13233:9;13229:18;13221:26;;13293:9;13287:4;13283:20;13279:1;13268:9;13264:17;13257:47;13321:131;13447:4;13321:131;:::i;:::-;13313:139;;13211:248;;;:::o;13465:419::-;13631:4;13669:2;13658:9;13654:18;13646:26;;13718:9;13712:4;13708:20;13704:1;13693:9;13689:17;13682:47;13746:131;13872:4;13746:131;:::i;:::-;13738:139;;13636:248;;;:::o;13890:434::-;14035:4;14073:2;14062:9;14058:18;14050:26;;14086:69;14152:1;14141:9;14137:17;14128:6;14086:69;:::i;:::-;14165:70;14231:2;14220:9;14216:18;14207:6;14165:70;:::i;:::-;14245:72;14313:2;14302:9;14298:18;14289:6;14245:72;:::i;:::-;14040:284;;;;;;:::o;14330:222::-;14423:4;14461:2;14450:9;14446:18;14438:26;;14474:71;14542:1;14531:9;14527:17;14518:6;14474:71;:::i;:::-;14428:124;;;;:::o;14558:98::-;14623:4;14646:3;14638:11;;14628:28;;;:::o;14662:132::-;14729:4;14752:3;14744:11;;14782:4;14777:3;14773:14;14765:22;;14734:60;;;:::o;14800:104::-;14865:6;14893:4;14883:14;;14872:32;;;:::o;14910:114::-;14977:6;15011:5;15005:12;14995:22;;14984:40;;;:::o;15030:111::-;15098:4;15130;15125:3;15121:14;15113:22;;15103:38;;;:::o;15147:113::-;15217:4;15249;15244:3;15240:14;15232:22;;15222:38;;;:::o;15266:143::-;15363:11;15400:3;15385:18;;15375:34;;;;:::o;15415:184::-;15514:11;15548:6;15543:3;15536:19;15588:4;15583:3;15579:14;15564:29;;15526:73;;;;:::o;15605:169::-;15689:11;15723:6;15718:3;15711:19;15763:4;15758:3;15754:14;15739:29;;15701:73;;;;:::o;15780:305::-;15820:3;15839:20;15857:1;15839:20;:::i;:::-;15834:25;;15873:20;15891:1;15873:20;:::i;:::-;15868:25;;16027:1;15959:66;15955:74;15952:1;15949:81;15946:2;;;16033:18;;:::i;:::-;15946:2;16077:1;16074;16070:9;16063:16;;15824:261;;;;:::o;16091:185::-;16131:1;16148:20;16166:1;16148:20;:::i;:::-;16143:25;;16182:20;16200:1;16182:20;:::i;:::-;16177:25;;16221:1;16211:2;;16226:18;;:::i;:::-;16211:2;16268:1;16265;16261:9;16256:14;;16133:143;;;;:::o;16282:348::-;16322:7;16345:20;16363:1;16345:20;:::i;:::-;16340:25;;16379:20;16397:1;16379:20;:::i;:::-;16374:25;;16567:1;16499:66;16495:74;16492:1;16489:81;16484:1;16477:9;16470:17;16466:105;16463:2;;;16574:18;;:::i;:::-;16463:2;16622:1;16619;16615:9;16604:20;;16330:300;;;;:::o;16636:191::-;16676:4;16696:20;16714:1;16696:20;:::i;:::-;16691:25;;16730:20;16748:1;16730:20;:::i;:::-;16725:25;;16769:1;16766;16763:8;16760:2;;;16774:18;;:::i;:::-;16760:2;16819:1;16816;16812:9;16804:17;;16681:146;;;;:::o;16833:96::-;16870:7;16899:24;16917:5;16899:24;:::i;:::-;16888:35;;16878:51;;;:::o;16935:149::-;16971:7;17011:66;17004:5;17000:78;16989:89;;16979:105;;;:::o;17090:126::-;17127:7;17167:42;17160:5;17156:54;17145:65;;17135:81;;;:::o;17222:91::-;17258:7;17298:8;17291:5;17287:20;17276:31;;17266:47;;;:::o;17319:77::-;17356:7;17385:5;17374:16;;17364:32;;;:::o;17402:97::-;17438:7;17478:14;17471:5;17467:26;17456:37;;17446:53;;;:::o;17505:233::-;17544:3;17567:24;17585:5;17567:24;:::i;:::-;17558:33;;17613:66;17606:5;17603:77;17600:2;;;17683:18;;:::i;:::-;17600:2;17730:1;17723:5;17719:13;17712:20;;17548:190;;;:::o;17744:180::-;17792:77;17789:1;17782:88;17889:4;17886:1;17879:15;17913:4;17910:1;17903:15;17930:180;17978:77;17975:1;17968:88;18075:4;18072:1;18065:15;18099:4;18096:1;18089:15;18116:225;18256:34;18252:1;18244:6;18240:14;18233:58;18325:8;18320:2;18312:6;18308:15;18301:33;18222:119;:::o;18347:164::-;18487:16;18483:1;18475:6;18471:14;18464:40;18453:58;:::o;18517:182::-;18657:34;18653:1;18645:6;18641:14;18634:58;18623:76;:::o;18705:162::-;18845:14;18841:1;18833:6;18829:14;18822:38;18811:56;:::o;18873:221::-;19013:34;19009:1;19001:6;18997:14;18990:58;19082:4;19077:2;19069:6;19065:15;19058:29;18979:115;:::o;19100:164::-;19240:16;19236:1;19228:6;19224:14;19217:40;19206:58;:::o;19270:122::-;19343:24;19361:5;19343:24;:::i;:::-;19336:5;19333:35;19323:2;;19382:1;19379;19372:12;19323:2;19313:79;:::o;19398:122::-;19471:24;19489:5;19471:24;:::i;:::-;19464:5;19461:35;19451:2;;19510:1;19507;19500:12;19451:2;19441:79;:::o
Swarm Source
ipfs://a8a193886e450304dd0c9300bba957064c414714e3e586b05efe6f1bf9339528
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
MATIC | 100.00% | $0.558534 | 0.00000000000000042 | <$0.000001 |
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.