More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 630 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Permit Breed | 20786358 | 6 hrs ago | IN | 0 ETH | 0.00306044 | ||||
Permit Breed | 20784750 | 11 hrs ago | IN | 0 ETH | 0.00322495 | ||||
Permit Breed | 20784749 | 11 hrs ago | IN | 0 ETH | 0.00328945 | ||||
Permit Breed | 20784330 | 13 hrs ago | IN | 0 ETH | 0.00278304 | ||||
Permit Breed | 20782102 | 20 hrs ago | IN | 0 ETH | 0.00167902 | ||||
Permit Breed | 20775736 | 41 hrs ago | IN | 0 ETH | 0.00075454 | ||||
Permit Breed | 20774230 | 47 hrs ago | IN | 0 ETH | 0.0011646 | ||||
Permit Breed | 20774170 | 47 hrs ago | IN | 0 ETH | 0.00139936 | ||||
Permit Breed | 20774075 | 47 hrs ago | IN | 0 ETH | 0.00150097 | ||||
Permit Breed | 20773975 | 47 hrs ago | IN | 0 ETH | 0.00098613 | ||||
Permit Breed | 20771961 | 2 days ago | IN | 0 ETH | 0.00373163 | ||||
Permit Breed | 20771305 | 2 days ago | IN | 0 ETH | 0.00313417 | ||||
Permit Breed | 20770940 | 2 days ago | IN | 0 ETH | 0.00271832 | ||||
Permit Breed | 20770571 | 2 days ago | IN | 0 ETH | 0.00093762 | ||||
Permit Breed | 20768588 | 2 days ago | IN | 0 ETH | 0.00039075 | ||||
Permit Breed | 20764545 | 3 days ago | IN | 0 ETH | 0.00130645 | ||||
Permit Breed | 20763935 | 3 days ago | IN | 0 ETH | 0.00287091 | ||||
Permit Breed | 20762309 | 3 days ago | IN | 0 ETH | 0.00237584 | ||||
Permit Breed | 20760945 | 3 days ago | IN | 0 ETH | 0.0001815 | ||||
Permit Breed | 20760747 | 3 days ago | IN | 0 ETH | 0.00032837 | ||||
Permit Breed | 20760702 | 3 days ago | IN | 0 ETH | 0.00044128 | ||||
Permit Breed | 20756409 | 4 days ago | IN | 0 ETH | 0.00038972 | ||||
Permit Breed | 20756401 | 4 days ago | IN | 0 ETH | 0.00035996 | ||||
Permit Breed | 20752743 | 4 days ago | IN | 0 ETH | 0.00021862 | ||||
Permit Breed | 20748136 | 5 days ago | IN | 0 ETH | 0.00022955 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
SNDNFTStake
Compiler Version
v0.8.24+commit.e11b9ed9
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2024-08-28 */ // Sources flattened with hardhat v2.22.2 https://hardhat.org // SPDX-License-Identifier: MIT // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @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; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } } // File @openzeppelin/contracts/access/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; /** * @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. * * The initial owner is set to the address provided by the deployer. 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; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @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 { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling 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 { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _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 @openzeppelin/contracts/utils/introspection/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File @openzeppelin/contracts/token/ERC721/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.20; /** * @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 address zero. * * 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/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol) pragma solidity ^0.8.20; interface IERC5267 { /** * @dev MAY be emitted to signal that the domain could have changed. */ event EIP712DomainChanged(); /** * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 * signature. */ function eip712Domain() external view returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ); } // File @openzeppelin/contracts/utils/math/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol) pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Muldiv operation overflow. */ error MathOverflowedMulDiv(); enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an overflow flag. */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the 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 towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. return a / b; } // (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 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. if (denominator <= prod1) { revert MathOverflowedMulDiv(); } /////////////////////////////////////////////// // 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. uint256 twos = denominator & (0 - denominator); 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 (unsignedRoundsUp(rounding) && 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 * towards zero. * * 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 + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * 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 + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * 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 + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * 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 256, 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 + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } } // File @openzeppelin/contracts/utils/math/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol) pragma solidity ^0.8.20; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @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), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @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) { uint256 localValue = value; bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } 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); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } } // File @openzeppelin/contracts/utils/cryptography/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MessageHashUtils.sol) pragma solidity ^0.8.20; /** * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing. * * The library provides methods for generating a hash of a message that conforms to the * https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712] * specifications. */ library MessageHashUtils { /** * @dev Returns the keccak256 digest of an EIP-191 signed data with version * `0x45` (`personal_sign` messages). * * The digest is calculated by prefixing a bytes32 `messageHash` with * `"\x19Ethereum Signed Message:\n32"` and hashing the result. It corresponds with the * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. * * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with * keccak256, although any bytes32 value can be safely used because the final digest will * be re-hashed. * * See {ECDSA-recover}. */ function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) { /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") // 32 is the bytes-length of messageHash mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20) } } /** * @dev Returns the keccak256 digest of an EIP-191 signed data with version * `0x45` (`personal_sign` messages). * * The digest is calculated by prefixing an arbitrary `message` with * `"\x19Ethereum Signed Message:\n" + len(message)` and hashing the result. It corresponds with the * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. * * See {ECDSA-recover}. */ function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) { return keccak256(bytes.concat("\x19Ethereum Signed Message:\n", bytes(Strings.toString(message.length)), message)); } /** * @dev Returns the keccak256 digest of an EIP-191 signed data with version * `0x00` (data with intended validator). * * The digest is calculated by prefixing an arbitrary `data` with `"\x19\x00"` and the intended * `validator` address. Then hashing the result. * * See {ECDSA-recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked(hex"19_00", validator, data)); } /** * @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`). * * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with * `\x19\x01` and hashing the result. It corresponds to the hash signed by the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712. * * See {ECDSA-recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, hex"19_01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) digest := keccak256(ptr, 0x42) } } } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.20; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(newImplementation.code.length > 0); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/ShortStrings.sol) pragma solidity ^0.8.20; // | string | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | // | length | 0x BB | type ShortString is bytes32; /** * @dev This library provides functions to convert short memory strings * into a `ShortString` type that can be used as an immutable variable. * * Strings of arbitrary length can be optimized using this library if * they are short enough (up to 31 bytes) by packing them with their * length (1 byte) in a single EVM word (32 bytes). Additionally, a * fallback mechanism can be used for every other case. * * Usage example: * * ```solidity * contract Named { * using ShortStrings for *; * * ShortString private immutable _name; * string private _nameFallback; * * constructor(string memory contractName) { * _name = contractName.toShortStringWithFallback(_nameFallback); * } * * function name() external view returns (string memory) { * return _name.toStringWithFallback(_nameFallback); * } * } * ``` */ library ShortStrings { // Used as an identifier for strings longer than 31 bytes. bytes32 private constant FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF; error StringTooLong(string str); error InvalidShortString(); /** * @dev Encode a string of at most 31 chars into a `ShortString`. * * This will trigger a `StringTooLong` error is the input string is too long. */ function toShortString(string memory str) internal pure returns (ShortString) { bytes memory bstr = bytes(str); if (bstr.length > 31) { revert StringTooLong(str); } return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length)); } /** * @dev Decode a `ShortString` back to a "normal" string. */ function toString(ShortString sstr) internal pure returns (string memory) { uint256 len = byteLength(sstr); // using `new string(len)` would work locally but is not memory safe. string memory str = new string(32); /// @solidity memory-safe-assembly assembly { mstore(str, len) mstore(add(str, 0x20), sstr) } return str; } /** * @dev Return the length of a `ShortString`. */ function byteLength(ShortString sstr) internal pure returns (uint256) { uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF; if (result > 31) { revert InvalidShortString(); } return result; } /** * @dev Encode a string into a `ShortString`, or write it to storage if it is too long. */ function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) { if (bytes(value).length < 32) { return toShortString(value); } else { StorageSlot.getStringSlot(store).value = value; return ShortString.wrap(FALLBACK_SENTINEL); } } /** * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}. */ function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) { if (ShortString.unwrap(value) != FALLBACK_SENTINEL) { return toString(value); } else { return store; } } /** * @dev Return the length of a string that was encoded to `ShortString` or written to storage using * {setWithFallback}. * * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of * actual characters as the UTF-8 encoding of a single character can span over multiple bytes. */ function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) { if (ShortString.unwrap(value) != FALLBACK_SENTINEL) { return byteLength(value); } else { return bytes(store).length; } } } // File @openzeppelin/contracts/utils/cryptography/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/EIP712.sol) pragma solidity ^0.8.20; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose * encoding is very generic and therefore its implementation in Solidity is not feasible, thus this contract * does not implement the encoding itself. Protocols need to implement the type-specific encoding they need in order to * produce the hash of their typed data using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain * separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. * * @custom:oz-upgrades-unsafe-allow state-variable-immutable */ abstract contract EIP712 is IERC5267 { using ShortStrings for *; bytes32 private constant TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _cachedDomainSeparator; uint256 private immutable _cachedChainId; address private immutable _cachedThis; bytes32 private immutable _hashedName; bytes32 private immutable _hashedVersion; ShortString private immutable _name; ShortString private immutable _version; string private _nameFallback; string private _versionFallback; /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { _name = name.toShortStringWithFallback(_nameFallback); _version = version.toShortStringWithFallback(_versionFallback); _hashedName = keccak256(bytes(name)); _hashedVersion = keccak256(bytes(version)); _cachedChainId = block.chainid; _cachedDomainSeparator = _buildDomainSeparator(); _cachedThis = address(this); } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _cachedThis && block.chainid == _cachedChainId) { return _cachedDomainSeparator; } else { return _buildDomainSeparator(); } } function _buildDomainSeparator() private view returns (bytes32) { return keccak256(abi.encode(TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev See {IERC-5267}. */ function eip712Domain() public view virtual returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { return ( hex"0f", // 01111 _EIP712Name(), _EIP712Version(), block.chainid, address(this), bytes32(0), new uint256[](0) ); } /** * @dev The name parameter for the EIP712 domain. * * NOTE: By default this function reads _name which is an immutable value. * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). */ // solhint-disable-next-line func-name-mixedcase function _EIP712Name() internal view returns (string memory) { return _name.toStringWithFallback(_nameFallback); } /** * @dev The version parameter for the EIP712 domain. * * NOTE: By default this function reads _version which is an immutable value. * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). */ // solhint-disable-next-line func-name-mixedcase function _EIP712Version() internal view returns (string memory) { return _version.toStringWithFallback(_versionFallback); } } // File @openzeppelin/contracts/token/ERC20/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @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 value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` 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 value) external returns (bool); } // File @openzeppelin/contracts/token/ERC721/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.20; /** * @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/utils/cryptography/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.20; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS } /** * @dev The signature derives the `address(0)`. */ error ECDSAInvalidSignature(); /** * @dev The signature has an invalid length. */ error ECDSAInvalidSignatureLength(uint256 length); /** * @dev The signature has an S value that is in the upper half order. */ error ECDSAInvalidSignatureS(bytes32 s); /** * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not * return address(0) without also returning an error description. Errors are documented using an enum (error type) * and a bytes32 providing additional information about the error. * * If no error is returned, then the address can be used for verification purposes. * * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length)); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature); _throwError(error, errorArg); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) { unchecked { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); // We do not check for an overflow here since the shift operation results in 0 or 1. uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs); _throwError(error, errorArg); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError, bytes32) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n 梅 2 + 1, and for v in (302): v 鈭?{27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS, s); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature, bytes32(0)); } return (signer, RecoverError.NoError, bytes32(0)); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s); _throwError(error, errorArg); return recovered; } /** * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided. */ function _throwError(RecoverError error, bytes32 errorArg) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert ECDSAInvalidSignature(); } else if (error == RecoverError.InvalidSignatureLength) { revert ECDSAInvalidSignatureLength(uint256(errorArg)); } else if (error == RecoverError.InvalidSignatureS) { revert ECDSAInvalidSignatureS(errorArg); } } } // File contracts/SNDNFTStake.sol // Original license: SPDX_License_Identifier: MIT // Compatible with OpenZeppelin Contracts ^5.0.0 pragma solidity ^0.8.20; interface ISNDNFT is IERC721 { function safeMint(address to) external returns (uint256 tokenId); } contract SNDNFTStake is Context, Ownable, IERC721Receiver, EIP712 { using ECDSA for bytes32; ISNDNFT public nft; address public signer; address public treasurer; uint256 public frozenSeconds = 30 * 24 * 60 * 60; // 30 days uint32 public MAXBREED = 7; mapping(uint256 => address) public owners; mapping(uint256 => uint256) public frozens; mapping(address => uint256[]) public stakes; mapping(address => uint256) public nonces; mapping(uint256 => uint32) public breeds; event NftStaked(address staker, uint256 tokenId, uint256 frozen); event NftUnstaked(address owner, uint256 tokenId); event Bred( address recipient, uint256 tokenId, uint256 nft1, uint256 nft2, uint256 nft3 ); struct BreedInfo { address recipient; uint256 nft1; uint256 nft2; uint256 nft3; uint256 nonce; uint32 expired; uint32 num; } bytes32 constant BREEDINFO_TYPEHASH = keccak256( "BreedInfo(address recipient,uint256 nft1,uint256 nft2,uint256 nft3,uint256 nonce,uint32 expired,uint32 num)" ); constructor( address _treasurer, address _signer, address _nft ) Ownable(msg.sender) EIP712("Swords Dungeons NFT Stake", "v1") { nft = ISNDNFT(_nft); treasurer = _treasurer; signer = _signer; } function onERC721Received( address, address from, uint256 tokenId, bytes calldata ) external returns (bytes4) { address sender = _msgSender(); require(sender == address(nft), "must be nft contract"); _stakeNft(from, tokenId); return IERC721Receiver.onERC721Received.selector; } function setMAXBREED(uint32 _max) external onlyOwner { MAXBREED = _max; } function setNFT(address _nft) external onlyOwner { require(_nft != address(0)); nft = ISNDNFT(_nft); } function setFrozenSeconds(uint256 _frozenSeconds) external onlyOwner { frozenSeconds = _frozenSeconds; } function setTreasurer(address _treasurer) external onlyOwner { require(_treasurer != address(0)); treasurer = _treasurer; } function setSigner(address _signer) public onlyOwner { require(_signer != address(0)); signer = _signer; } function _stakeNft(address from, uint256 tokenId) internal { require( owners[tokenId] == address(0) && nft.ownerOf(tokenId) == address(this), "Invalid Stake" ); frozens[tokenId] = block.timestamp + frozenSeconds; owners[tokenId] = from; stakes[from].push(tokenId); emit NftStaked(from, tokenId, frozens[tokenId]); } function unstakeNft(uint256 tokenId, uint32 expired) external { require(expired > block.timestamp, "SNDNFTStake: expired!"); address from = _msgSender(); address owner = owners[tokenId]; require(owner == from, "SNDNFTStake: wrong owner or not staked!"); uint256 frozen = frozens[tokenId]; require( frozen > 0 && block.timestamp >= frozen, "It's not yet unstake time" ); nft.transferFrom(address(this), owner, tokenId); uint256[] memory ids = stakes[owner]; uint256 len = ids.length; uint32 idx = 0; for (uint32 i = 0; i < len; i++) { if (ids[i] == tokenId) { idx = i; break; } } stakes[owner][idx] = stakes[owner][len - 1]; stakes[owner].pop(); delete owners[tokenId]; delete frozens[tokenId]; emit NftUnstaked(owner, tokenId); } function infoOf( uint256 tokenId ) public view returns (address originOwner, uint256 expired) { originOwner = owners[tokenId]; expired = frozens[tokenId]; } function stakesOf( address owner ) public view returns (uint256[] memory tokenIds) { tokenIds = stakes[owner]; } function permitBreed( uint256 nft1, uint256 nft2, uint256 nft3, uint32 num, uint32 expired, bytes memory signature ) external { require(expired > block.timestamp, "SNDNFTStake: expired!"); address recipient = _msgSender(); if ( owners[nft1] != recipient || owners[nft2] != recipient || owners[nft3] != recipient ) { revert("SNDNFTStake: nft not staked or wrong owner!"); } if ( breeds[nft1] >= MAXBREED || breeds[nft2] >= MAXBREED || breeds[nft3] >= MAXBREED ) { revert("SNDNFTStake: over MAXBREED"); } BreedInfo memory info = BreedInfo({ recipient: recipient, nft1: nft1, nft2: nft2, nft3: nft3, nonce: nonces[recipient], expired: expired, num: num }); require(verify(info, signature), "SNDNFTStake: signature is wrong!"); for (uint32 i = 0; i < num; i++) { uint256 tokenId = nft.safeMint(recipient); emit Bred(recipient, tokenId, nft1, nft2, nft3); } nonces[recipient] += 1; breeds[nft1] += 1; breeds[nft2] += 1; breeds[nft3] += 1; } function getNonce(address user) public view returns (uint256 nonce) { nonce = nonces[user]; } function hash(BreedInfo memory info) internal pure returns (bytes32) { return keccak256( abi.encode( BREEDINFO_TYPEHASH, info.recipient, info.nft1, info.nft2, info.nft3, info.nonce, info.expired, info.num ) ); } function verify( BreedInfo memory info, bytes memory signature ) internal view returns (bool) { bytes32 digest = _hashTypedDataV4(hash(info)); address addr = digest.recover(signature); return addr == signer; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_treasurer","type":"address"},{"internalType":"address","name":"_signer","type":"address"},{"internalType":"address","name":"_nft","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ECDSAInvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"ECDSAInvalidSignatureLength","type":"error"},{"inputs":[{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"ECDSAInvalidSignatureS","type":"error"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nft1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nft2","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nft3","type":"uint256"}],"name":"Bred","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"frozen","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"}],"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":[],"name":"MAXBREED","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"breeds","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"frozenSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"frozens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getNonce","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"infoOf","outputs":[{"internalType":"address","name":"originOwner","type":"address"},{"internalType":"uint256","name":"expired","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nft","outputs":[{"internalType":"contract ISNDNFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"owners","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nft1","type":"uint256"},{"internalType":"uint256","name":"nft2","type":"uint256"},{"internalType":"uint256","name":"nft3","type":"uint256"},{"internalType":"uint32","name":"num","type":"uint32"},{"internalType":"uint32","name":"expired","type":"uint32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"permitBreed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_frozenSeconds","type":"uint256"}],"name":"setFrozenSeconds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_max","type":"uint32"}],"name":"setMAXBREED","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nft","type":"address"}],"name":"setNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasurer","type":"address"}],"name":"setTreasurer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"stakesOf","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasurer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint32","name":"expired","type":"uint32"}],"name":"unstakeNft","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
61016060405262278d006006556007805463ffffffff1916811790553480156200002857600080fd5b50604051620020b5380380620020b58339810160408190526200004b91620002ac565b604080518082018252601981527f53776f7264732044756e67656f6e73204e4654205374616b650000000000000060208083019190915282518084019093526002835261763160f01b90830152903380620000c157604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620000cc81620001c3565b50620000da82600162000213565b61012052620000eb81600262000213565b61014052815160208084019190912060e052815190820120610100524660a0526200017960e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c052600380546001600160a01b03199081166001600160a01b039384161790915560058054821694831694909417909355600480549093169116179055620004df565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600060208351101562000233576200022b836200024c565b905062000246565b816200024084826200039d565b5060ff90505b92915050565b600080829050601f815111156200027a578260405163305a27a960e01b8152600401620000b8919062000469565b80516200028782620004ba565b179392505050565b80516001600160a01b0381168114620002a757600080fd5b919050565b600080600060608486031215620002c257600080fd5b620002cd846200028f565b9250620002dd602085016200028f565b9150620002ed604085016200028f565b90509250925092565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200032157607f821691505b6020821081036200034257634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000398576000816000526020600020601f850160051c81016020861015620003735750805b601f850160051c820191505b8181101562000394578281556001016200037f565b5050505b505050565b81516001600160401b03811115620003b957620003b9620002f6565b620003d181620003ca84546200030c565b8462000348565b602080601f831160018114620004095760008415620003f05750858301515b600019600386901b1c1916600185901b17855562000394565b600085815260208120601f198616915b828110156200043a5788860151825594840194600190910190840162000419565b5085821015620004595787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006020808352835180602085015260005b8181101562000499578581018301518582016040015282016200047b565b506000604082860101526040601f19601f8301168501019250505092915050565b80516020808301519190811015620003425760001960209190910360031b1b16919050565b60805160a05160c05160e051610100516101205161014051611b7b6200053a600039600061113a01526000611108015260006113f9015260006113d10152600061132c01526000611356015260006113800152611b7b6000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80636637c3b8116100de57806384b0196e11610097578063e78ef3ff11610071578063e78ef3ff146103fc578063f2fde38b1461040c578063f56e9c661461041f578063fda49eb41461043257600080fd5b806384b0196e146103b05780638da5cb5b146103cb578063b41a6387146103dc57600080fd5b80636637c3b8146102f9578063671d64291461030c5780636c19e7831461031f578063715018a61461033257806378b38f361461033a5780637ecebe001461039057600080fd5b806333b69c4c1161013057806333b69c4c1461028457806347ccca02146102a457806349532418146102b75780634d65b976146102ca578063584b62a1146102d35780635d7e9758146102e657600080fd5b8063025e7c271461017857806303e05b82146101be578063150b7a02146101d3578063238ac933146101ff5780632c0209f5146102125780632d0335ab1461024d575b600080fd5b6101a161018636600461168a565b6008602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101d16101cc3660046116bc565b610445565b005b6101e66101e13660046116f3565b610469565b6040516001600160e01b031990911681526020016101b5565b6004546101a1906001600160a01b031681565b61023861022036600461168a565b600c6020526000908152604090205463ffffffff1681565b60405163ffffffff90911681526020016101b5565b61027661025b366004611792565b6001600160a01b03166000908152600b602052604090205490565b6040519081526020016101b5565b610297610292366004611792565b6104e1565b6040516101b591906117eb565b6003546101a1906001600160a01b031681565b6101d16102c5366004611814565b61054d565b61027660065481565b6102766102e1366004611902565b6109a6565b6101d16102f436600461168a565b6109d7565b6101d161030736600461192e565b6109e4565b6101d161031a366004611792565b610d78565b6101d161032d366004611792565b610db5565b6101d1610df2565b61037161034836600461168a565b6000908152600860209081526040808320546009909252909120546001600160a01b0390911691565b604080516001600160a01b0390931683526020830191909152016101b5565b61027661039e366004611792565b600b6020526000908152604090205481565b6103b8610e06565b6040516101b597969594939291906119a0565b6000546001600160a01b03166101a1565b6102766103ea36600461168a565b60096020526000908152604090205481565b6007546102389063ffffffff1681565b6101d161041a366004611792565b610e4c565b6101d161042d366004611792565b610e8a565b6005546101a1906001600160a01b031681565b61044d610ec7565b6007805463ffffffff191663ffffffff92909216919091179055565b60035460009033906001600160a01b031681146104c45760405162461bcd60e51b81526020600482015260146024820152731b5d5cdd081899481b999d0818dbdb9d1c9858dd60621b60448201526064015b60405180910390fd5b6104ce8686610ef4565b50630a85bd0160e11b9695505050505050565b6001600160a01b0381166000908152600a602090815260409182902080548351818402810184019094528084526060939283018282801561054157602002820191906000526020600020905b81548152602001906001019080831161052d575b50505050509050919050565b428263ffffffff161161059a5760405162461bcd60e51b8152602060048201526015602482015274534e444e46545374616b653a20657870697265642160581b60448201526064016104bb565b60008681526008602052604090205433906001600160a01b0316811415806105dc57506000868152600860205260409020546001600160a01b03828116911614155b8061060157506000858152600860205260409020546001600160a01b03828116911614155b156106625760405162461bcd60e51b815260206004820152602b60248201527f534e444e46545374616b653a206e6674206e6f74207374616b6564206f72207760448201526a726f6e67206f776e65722160a81b60648201526084016104bb565b6007546000888152600c602052604090205463ffffffff91821691161015806106a557506007546000878152600c602052604090205463ffffffff918216911610155b806106ca57506007546000868152600c602052604090205463ffffffff918216911610155b156107175760405162461bcd60e51b815260206004820152601a60248201527f534e444e46545374616b653a206f766572204d4158425245454400000000000060448201526064016104bb565b6040805160e0810182526001600160a01b03831680825260208083018b90528284018a9052606083018990526000918252600b90529190912054608082015263ffffffff80851660a0830152851660c08201526107748184611073565b6107c05760405162461bcd60e51b815260206004820181905260248201527f534e444e46545374616b653a207369676e61747572652069732077726f6e672160448201526064016104bb565b60005b8563ffffffff168163ffffffff1610156108ac576003546040516340d097c360e01b81526001600160a01b03858116600483015260009216906340d097c3906024016020604051808303816000875af1158015610824573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108489190611a10565b604080516001600160a01b0387168152602081018390529081018c9052606081018b9052608081018a90529091507f503a84784644c0f663f06114e7c6f2a39e3927fde8a67ab65a1d949a3d2c087e9060a00160405180910390a1506001016107c3565b506001600160a01b0382166000908152600b602052604081208054600192906108d6908490611a3f565b90915550506000888152600c6020526040812080546001929061090090849063ffffffff16611a52565b82546101009290920a63ffffffff8181021990931691831602179091556000898152600c60205260408120805460019450909261093f91859116611a52565b82546101009290920a63ffffffff8181021990931691831602179091556000888152600c60205260408120805460019450909261097e91859116611a52565b92506101000a81548163ffffffff021916908363ffffffff1602179055505050505050505050565b600a60205281600052604060002081815481106109c257600080fd5b90600052602060002001600091509150505481565b6109df610ec7565b600655565b428163ffffffff1611610a315760405162461bcd60e51b8152602060048201526015602482015274534e444e46545374616b653a20657870697265642160581b60448201526064016104bb565b60008281526008602052604090205433906001600160a01b0316808214610aaa5760405162461bcd60e51b815260206004820152602760248201527f534e444e46545374616b653a2077726f6e67206f776e6572206f72206e6f74206044820152667374616b65642160c81b60648201526084016104bb565b6000848152600960205260409020548015801590610ac85750804210155b610b145760405162461bcd60e51b815260206004820152601960248201527f49742773206e6f742079657420756e7374616b652074696d650000000000000060448201526064016104bb565b6003546040516323b872dd60e01b81523060048201526001600160a01b03848116602483015260448201889052909116906323b872dd90606401600060405180830381600087803b158015610b6857600080fd5b505af1158015610b7c573d6000803e3d6000fd5b505050506001600160a01b0382166000908152600a6020908152604080832080548251818502810185019093528083529192909190830182828015610be057602002820191906000526020600020905b815481526020019060010190808311610bcc575b505050505090506000815190506000805b828163ffffffff161015610c3f5788848263ffffffff1681518110610c1857610c18611a76565b602002602001015103610c2d57809150610c3f565b80610c3781611a8c565b915050610bf1565b506001600160a01b0385166000908152600a60205260409020610c63600184611aaf565b81548110610c7357610c73611a76565b9060005260206000200154600a6000876001600160a01b03166001600160a01b031681526020019081526020016000208263ffffffff1681548110610cba57610cba611a76565b60009182526020808320909101929092556001600160a01b0387168152600a90915260409020805480610cef57610cef611ac2565b60008281526020808220600019908401810183905590920190925589825260088152604080832080546001600160a01b0319169055600982528083209290925581516001600160a01b03881681529081018a90527fe8b40fda281c6bb8d29a090b37522bcc49728e60bf2bbbff36ea712ff1b498a5910160405180910390a15050505050505050565b610d80610ec7565b6001600160a01b038116610d9357600080fd5b600580546001600160a01b0319166001600160a01b0392909216919091179055565b610dbd610ec7565b6001600160a01b038116610dd057600080fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b610dfa610ec7565b610e0460006110b1565b565b600060608060008060006060610e1a611101565b610e22611133565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b610e54610ec7565b6001600160a01b038116610e7e57604051631e4fbdf760e01b8152600060048201526024016104bb565b610e87816110b1565b50565b610e92610ec7565b6001600160a01b038116610ea557600080fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610e045760405163118cdaa760e01b81523360048201526024016104bb565b6000818152600860205260409020546001600160a01b0316158015610f8c57506003546040516331a9108f60e11b81526004810183905230916001600160a01b031690636352211e90602401602060405180830381865afa158015610f5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f819190611ad8565b6001600160a01b0316145b610fc85760405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964205374616b6560981b60448201526064016104bb565b600654610fd59042611a3f565b60008281526009602081815260408084209485556008825280842080546001600160a01b0319166001600160a01b038916908117909155808552600a835281852080546001810182559086528386200187905593869052918152925481519283529282018490528101919091527f2209f5ab1e50b2a6cab82d8f63686a6991f8d51072e1c8c6e752570697c29c469060600160405180910390a15050565b60008061108761108285611160565b61121d565b90506000611095828561124a565b6004546001600160a01b03918216911614925050505b92915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b606061112e7f00000000000000000000000000000000000000000000000000000000000000006001611274565b905090565b606061112e7f00000000000000000000000000000000000000000000000000000000000000006002611274565b60007f59d4e2d4b69257c04c82c4aa35a1c0244e4d511ffbfce11cc13523b585cdeec4826000015183602001518460400151856060015186608001518760a001518860c001516040516020016112009897969594939291909788526001600160a01b0396909616602088015260408701949094526060860192909252608085015260a084015263ffffffff90811660c08401521660e08201526101000190565b604051602081830303815290604052805190602001209050919050565b60006110ab61122a61131f565b8360405161190160f01b8152600281019290925260228201526042902090565b60008060008061125a868661144a565b92509250925061126a8282611497565b5090949350505050565b606060ff831461128e5761128783611554565b90506110ab565b81805461129a90611af5565b80601f01602080910402602001604051908101604052809291908181526020018280546112c690611af5565b80156113135780601f106112e857610100808354040283529160200191611313565b820191906000526020600020905b8154815290600101906020018083116112f657829003601f168201915b505050505090506110ab565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561137857507f000000000000000000000000000000000000000000000000000000000000000046145b156113a257507f000000000000000000000000000000000000000000000000000000000000000090565b61112e604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b600080600083516041036114845760208401516040850151606086015160001a61147688828585611593565b955095509550505050611490565b50508151600091506002905b9250925092565b60008260038111156114ab576114ab611b2f565b036114b4575050565b60018260038111156114c8576114c8611b2f565b036114e65760405163f645eedf60e01b815260040160405180910390fd5b60028260038111156114fa576114fa611b2f565b0361151b5760405163fce698f760e01b8152600481018290526024016104bb565b600382600381111561152f5761152f611b2f565b03611550576040516335e2f38360e21b8152600481018290526024016104bb565b5050565b6060600061156183611662565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08411156115ce5750600091506003905082611658565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015611622573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661164e57506000925060019150829050611658565b9250600091508190505b9450945094915050565b600060ff8216601f8111156110ab57604051632cd44ac360e21b815260040160405180910390fd5b60006020828403121561169c57600080fd5b5035919050565b803563ffffffff811681146116b757600080fd5b919050565b6000602082840312156116ce57600080fd5b6116d7826116a3565b9392505050565b6001600160a01b0381168114610e8757600080fd5b60008060008060006080868803121561170b57600080fd5b8535611716816116de565b94506020860135611726816116de565b935060408601359250606086013567ffffffffffffffff8082111561174a57600080fd5b818801915088601f83011261175e57600080fd5b81358181111561176d57600080fd5b89602082850101111561177f57600080fd5b9699959850939650602001949392505050565b6000602082840312156117a457600080fd5b81356116d7816116de565b60008151808452602080850194506020840160005b838110156117e0578151875295820195908201906001016117c4565b509495945050505050565b6020815260006116d760208301846117af565b634e487b7160e01b600052604160045260246000fd5b60008060008060008060c0878903121561182d57600080fd5b86359550602087013594506040870135935061184b606088016116a3565b9250611859608088016116a3565b915060a087013567ffffffffffffffff8082111561187657600080fd5b818901915089601f83011261188a57600080fd5b81358181111561189c5761189c6117fe565b604051601f8201601f19908116603f011681019083821181831017156118c4576118c46117fe565b816040528281528c60208487010111156118dd57600080fd5b8260208601602083013760006020848301015280955050505050509295509295509295565b6000806040838503121561191557600080fd5b8235611920816116de565b946020939093013593505050565b6000806040838503121561194157600080fd5b82359150611951602084016116a3565b90509250929050565b6000815180845260005b8181101561198057602081850181015186830182015201611964565b506000602082860101526020601f19601f83011685010191505092915050565b60ff60f81b8816815260e0602082015260006119bf60e083018961195a565b82810360408401526119d1818961195a565b606084018890526001600160a01b038716608085015260a0840186905283810360c08501529050611a0281856117af565b9a9950505050505050505050565b600060208284031215611a2257600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156110ab576110ab611a29565b63ffffffff818116838216019080821115611a6f57611a6f611a29565b5092915050565b634e487b7160e01b600052603260045260246000fd5b600063ffffffff808316818103611aa557611aa5611a29565b6001019392505050565b818103818111156110ab576110ab611a29565b634e487b7160e01b600052603160045260246000fd5b600060208284031215611aea57600080fd5b81516116d7816116de565b600181811c90821680611b0957607f821691505b602082108103611b2957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220778a35cfc42fb44d400b3afccd99001337f8a5ef22d22563e28b17547c1d3dd064736f6c634300081800330000000000000000000000005c2f4549ea428012e4aca86a89993032ec822a0d0000000000000000000000001d4f4c4c1247063593256cfa0845a9181d6731b60000000000000000000000004aa33eea4159e7451c63569331c81c143ca2c382
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101735760003560e01c80636637c3b8116100de57806384b0196e11610097578063e78ef3ff11610071578063e78ef3ff146103fc578063f2fde38b1461040c578063f56e9c661461041f578063fda49eb41461043257600080fd5b806384b0196e146103b05780638da5cb5b146103cb578063b41a6387146103dc57600080fd5b80636637c3b8146102f9578063671d64291461030c5780636c19e7831461031f578063715018a61461033257806378b38f361461033a5780637ecebe001461039057600080fd5b806333b69c4c1161013057806333b69c4c1461028457806347ccca02146102a457806349532418146102b75780634d65b976146102ca578063584b62a1146102d35780635d7e9758146102e657600080fd5b8063025e7c271461017857806303e05b82146101be578063150b7a02146101d3578063238ac933146101ff5780632c0209f5146102125780632d0335ab1461024d575b600080fd5b6101a161018636600461168a565b6008602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101d16101cc3660046116bc565b610445565b005b6101e66101e13660046116f3565b610469565b6040516001600160e01b031990911681526020016101b5565b6004546101a1906001600160a01b031681565b61023861022036600461168a565b600c6020526000908152604090205463ffffffff1681565b60405163ffffffff90911681526020016101b5565b61027661025b366004611792565b6001600160a01b03166000908152600b602052604090205490565b6040519081526020016101b5565b610297610292366004611792565b6104e1565b6040516101b591906117eb565b6003546101a1906001600160a01b031681565b6101d16102c5366004611814565b61054d565b61027660065481565b6102766102e1366004611902565b6109a6565b6101d16102f436600461168a565b6109d7565b6101d161030736600461192e565b6109e4565b6101d161031a366004611792565b610d78565b6101d161032d366004611792565b610db5565b6101d1610df2565b61037161034836600461168a565b6000908152600860209081526040808320546009909252909120546001600160a01b0390911691565b604080516001600160a01b0390931683526020830191909152016101b5565b61027661039e366004611792565b600b6020526000908152604090205481565b6103b8610e06565b6040516101b597969594939291906119a0565b6000546001600160a01b03166101a1565b6102766103ea36600461168a565b60096020526000908152604090205481565b6007546102389063ffffffff1681565b6101d161041a366004611792565b610e4c565b6101d161042d366004611792565b610e8a565b6005546101a1906001600160a01b031681565b61044d610ec7565b6007805463ffffffff191663ffffffff92909216919091179055565b60035460009033906001600160a01b031681146104c45760405162461bcd60e51b81526020600482015260146024820152731b5d5cdd081899481b999d0818dbdb9d1c9858dd60621b60448201526064015b60405180910390fd5b6104ce8686610ef4565b50630a85bd0160e11b9695505050505050565b6001600160a01b0381166000908152600a602090815260409182902080548351818402810184019094528084526060939283018282801561054157602002820191906000526020600020905b81548152602001906001019080831161052d575b50505050509050919050565b428263ffffffff161161059a5760405162461bcd60e51b8152602060048201526015602482015274534e444e46545374616b653a20657870697265642160581b60448201526064016104bb565b60008681526008602052604090205433906001600160a01b0316811415806105dc57506000868152600860205260409020546001600160a01b03828116911614155b8061060157506000858152600860205260409020546001600160a01b03828116911614155b156106625760405162461bcd60e51b815260206004820152602b60248201527f534e444e46545374616b653a206e6674206e6f74207374616b6564206f72207760448201526a726f6e67206f776e65722160a81b60648201526084016104bb565b6007546000888152600c602052604090205463ffffffff91821691161015806106a557506007546000878152600c602052604090205463ffffffff918216911610155b806106ca57506007546000868152600c602052604090205463ffffffff918216911610155b156107175760405162461bcd60e51b815260206004820152601a60248201527f534e444e46545374616b653a206f766572204d4158425245454400000000000060448201526064016104bb565b6040805160e0810182526001600160a01b03831680825260208083018b90528284018a9052606083018990526000918252600b90529190912054608082015263ffffffff80851660a0830152851660c08201526107748184611073565b6107c05760405162461bcd60e51b815260206004820181905260248201527f534e444e46545374616b653a207369676e61747572652069732077726f6e672160448201526064016104bb565b60005b8563ffffffff168163ffffffff1610156108ac576003546040516340d097c360e01b81526001600160a01b03858116600483015260009216906340d097c3906024016020604051808303816000875af1158015610824573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108489190611a10565b604080516001600160a01b0387168152602081018390529081018c9052606081018b9052608081018a90529091507f503a84784644c0f663f06114e7c6f2a39e3927fde8a67ab65a1d949a3d2c087e9060a00160405180910390a1506001016107c3565b506001600160a01b0382166000908152600b602052604081208054600192906108d6908490611a3f565b90915550506000888152600c6020526040812080546001929061090090849063ffffffff16611a52565b82546101009290920a63ffffffff8181021990931691831602179091556000898152600c60205260408120805460019450909261093f91859116611a52565b82546101009290920a63ffffffff8181021990931691831602179091556000888152600c60205260408120805460019450909261097e91859116611a52565b92506101000a81548163ffffffff021916908363ffffffff1602179055505050505050505050565b600a60205281600052604060002081815481106109c257600080fd5b90600052602060002001600091509150505481565b6109df610ec7565b600655565b428163ffffffff1611610a315760405162461bcd60e51b8152602060048201526015602482015274534e444e46545374616b653a20657870697265642160581b60448201526064016104bb565b60008281526008602052604090205433906001600160a01b0316808214610aaa5760405162461bcd60e51b815260206004820152602760248201527f534e444e46545374616b653a2077726f6e67206f776e6572206f72206e6f74206044820152667374616b65642160c81b60648201526084016104bb565b6000848152600960205260409020548015801590610ac85750804210155b610b145760405162461bcd60e51b815260206004820152601960248201527f49742773206e6f742079657420756e7374616b652074696d650000000000000060448201526064016104bb565b6003546040516323b872dd60e01b81523060048201526001600160a01b03848116602483015260448201889052909116906323b872dd90606401600060405180830381600087803b158015610b6857600080fd5b505af1158015610b7c573d6000803e3d6000fd5b505050506001600160a01b0382166000908152600a6020908152604080832080548251818502810185019093528083529192909190830182828015610be057602002820191906000526020600020905b815481526020019060010190808311610bcc575b505050505090506000815190506000805b828163ffffffff161015610c3f5788848263ffffffff1681518110610c1857610c18611a76565b602002602001015103610c2d57809150610c3f565b80610c3781611a8c565b915050610bf1565b506001600160a01b0385166000908152600a60205260409020610c63600184611aaf565b81548110610c7357610c73611a76565b9060005260206000200154600a6000876001600160a01b03166001600160a01b031681526020019081526020016000208263ffffffff1681548110610cba57610cba611a76565b60009182526020808320909101929092556001600160a01b0387168152600a90915260409020805480610cef57610cef611ac2565b60008281526020808220600019908401810183905590920190925589825260088152604080832080546001600160a01b0319169055600982528083209290925581516001600160a01b03881681529081018a90527fe8b40fda281c6bb8d29a090b37522bcc49728e60bf2bbbff36ea712ff1b498a5910160405180910390a15050505050505050565b610d80610ec7565b6001600160a01b038116610d9357600080fd5b600580546001600160a01b0319166001600160a01b0392909216919091179055565b610dbd610ec7565b6001600160a01b038116610dd057600080fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b610dfa610ec7565b610e0460006110b1565b565b600060608060008060006060610e1a611101565b610e22611133565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b610e54610ec7565b6001600160a01b038116610e7e57604051631e4fbdf760e01b8152600060048201526024016104bb565b610e87816110b1565b50565b610e92610ec7565b6001600160a01b038116610ea557600080fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610e045760405163118cdaa760e01b81523360048201526024016104bb565b6000818152600860205260409020546001600160a01b0316158015610f8c57506003546040516331a9108f60e11b81526004810183905230916001600160a01b031690636352211e90602401602060405180830381865afa158015610f5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f819190611ad8565b6001600160a01b0316145b610fc85760405162461bcd60e51b815260206004820152600d60248201526c496e76616c6964205374616b6560981b60448201526064016104bb565b600654610fd59042611a3f565b60008281526009602081815260408084209485556008825280842080546001600160a01b0319166001600160a01b038916908117909155808552600a835281852080546001810182559086528386200187905593869052918152925481519283529282018490528101919091527f2209f5ab1e50b2a6cab82d8f63686a6991f8d51072e1c8c6e752570697c29c469060600160405180910390a15050565b60008061108761108285611160565b61121d565b90506000611095828561124a565b6004546001600160a01b03918216911614925050505b92915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b606061112e7f53776f7264732044756e67656f6e73204e4654205374616b65000000000000196001611274565b905090565b606061112e7f76310000000000000000000000000000000000000000000000000000000000026002611274565b60007f59d4e2d4b69257c04c82c4aa35a1c0244e4d511ffbfce11cc13523b585cdeec4826000015183602001518460400151856060015186608001518760a001518860c001516040516020016112009897969594939291909788526001600160a01b0396909616602088015260408701949094526060860192909252608085015260a084015263ffffffff90811660c08401521660e08201526101000190565b604051602081830303815290604052805190602001209050919050565b60006110ab61122a61131f565b8360405161190160f01b8152600281019290925260228201526042902090565b60008060008061125a868661144a565b92509250925061126a8282611497565b5090949350505050565b606060ff831461128e5761128783611554565b90506110ab565b81805461129a90611af5565b80601f01602080910402602001604051908101604052809291908181526020018280546112c690611af5565b80156113135780601f106112e857610100808354040283529160200191611313565b820191906000526020600020905b8154815290600101906020018083116112f657829003601f168201915b505050505090506110ab565b6000306001600160a01b037f000000000000000000000000d88d10c167462998dcd1c2dc51fb984dfce3f83b1614801561137857507f000000000000000000000000000000000000000000000000000000000000000146145b156113a257507fc515d5fb771b4503af32af846a82773296ba20bd32944bdad38189b588c9776f90565b61112e604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f8c41f866b050b1c4f19eab5c408a81d302c23bf749150e64a6026beeada6b467918101919091527f0984d5efd47d99151ae1be065a709e56c602102f24c1abc4008eb3f815a8d21760608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b600080600083516041036114845760208401516040850151606086015160001a61147688828585611593565b955095509550505050611490565b50508151600091506002905b9250925092565b60008260038111156114ab576114ab611b2f565b036114b4575050565b60018260038111156114c8576114c8611b2f565b036114e65760405163f645eedf60e01b815260040160405180910390fd5b60028260038111156114fa576114fa611b2f565b0361151b5760405163fce698f760e01b8152600481018290526024016104bb565b600382600381111561152f5761152f611b2f565b03611550576040516335e2f38360e21b8152600481018290526024016104bb565b5050565b6060600061156183611662565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08411156115ce5750600091506003905082611658565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015611622573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661164e57506000925060019150829050611658565b9250600091508190505b9450945094915050565b600060ff8216601f8111156110ab57604051632cd44ac360e21b815260040160405180910390fd5b60006020828403121561169c57600080fd5b5035919050565b803563ffffffff811681146116b757600080fd5b919050565b6000602082840312156116ce57600080fd5b6116d7826116a3565b9392505050565b6001600160a01b0381168114610e8757600080fd5b60008060008060006080868803121561170b57600080fd5b8535611716816116de565b94506020860135611726816116de565b935060408601359250606086013567ffffffffffffffff8082111561174a57600080fd5b818801915088601f83011261175e57600080fd5b81358181111561176d57600080fd5b89602082850101111561177f57600080fd5b9699959850939650602001949392505050565b6000602082840312156117a457600080fd5b81356116d7816116de565b60008151808452602080850194506020840160005b838110156117e0578151875295820195908201906001016117c4565b509495945050505050565b6020815260006116d760208301846117af565b634e487b7160e01b600052604160045260246000fd5b60008060008060008060c0878903121561182d57600080fd5b86359550602087013594506040870135935061184b606088016116a3565b9250611859608088016116a3565b915060a087013567ffffffffffffffff8082111561187657600080fd5b818901915089601f83011261188a57600080fd5b81358181111561189c5761189c6117fe565b604051601f8201601f19908116603f011681019083821181831017156118c4576118c46117fe565b816040528281528c60208487010111156118dd57600080fd5b8260208601602083013760006020848301015280955050505050509295509295509295565b6000806040838503121561191557600080fd5b8235611920816116de565b946020939093013593505050565b6000806040838503121561194157600080fd5b82359150611951602084016116a3565b90509250929050565b6000815180845260005b8181101561198057602081850181015186830182015201611964565b506000602082860101526020601f19601f83011685010191505092915050565b60ff60f81b8816815260e0602082015260006119bf60e083018961195a565b82810360408401526119d1818961195a565b606084018890526001600160a01b038716608085015260a0840186905283810360c08501529050611a0281856117af565b9a9950505050505050505050565b600060208284031215611a2257600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156110ab576110ab611a29565b63ffffffff818116838216019080821115611a6f57611a6f611a29565b5092915050565b634e487b7160e01b600052603260045260246000fd5b600063ffffffff808316818103611aa557611aa5611a29565b6001019392505050565b818103818111156110ab576110ab611a29565b634e487b7160e01b600052603160045260246000fd5b600060208284031215611aea57600080fd5b81516116d7816116de565b600181811c90821680611b0957607f821691505b602082108103611b2957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220778a35cfc42fb44d400b3afccd99001337f8a5ef22d22563e28b17547c1d3dd064736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005c2f4549ea428012e4aca86a89993032ec822a0d0000000000000000000000001d4f4c4c1247063593256cfa0845a9181d6731b60000000000000000000000004aa33eea4159e7451c63569331c81c143ca2c382
-----Decoded View---------------
Arg [0] : _treasurer (address): 0x5c2f4549ea428012E4AcA86A89993032ec822A0d
Arg [1] : _signer (address): 0x1D4F4c4C1247063593256CfA0845A9181d6731b6
Arg [2] : _nft (address): 0x4AA33EEA4159e7451C63569331C81C143cA2c382
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000005c2f4549ea428012e4aca86a89993032ec822a0d
Arg [1] : 0000000000000000000000001d4f4c4c1247063593256cfa0845a9181d6731b6
Arg [2] : 0000000000000000000000004aa33eea4159e7451c63569331c81c143ca2c382
Deployed Bytecode Sourcemap
63086:6477:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63374:41;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;63374:41:0;;;;;;-1:-1:-1;;;;;363:32:1;;;345:51;;333:2;318:18;63374:41:0;;;;;;;;64926:87;;;;;;:::i;:::-;;:::i;:::-;;64559:359;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;;2003:33:1;;;1985:52;;1973:2;1958:18;64559:359:0;1841:202:1;63216:21:0;;;;;-1:-1:-1;;;;;63216:21:0;;;63569:40;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;2222:10:1;2210:23;;;2192:42;;2180:2;2165:18;63569:40:0;2048:192:1;68720:107:0;;;;;;:::i;:::-;-1:-1:-1;;;;;68807:12:0;68773:13;68807:12;;;:6;:12;;;;;;;68720:107;;;;2643:25:1;;;2631:2;2616:18;68720:107:0;2497:177:1;67189:140:0;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;63191:18::-;;;;;-1:-1:-1;;;;;63191:18:0;;;67337:1375;;;;;;:::i;:::-;;:::i;63275:48::-;;;;;;63471:43;;;;;;:::i;:::-;;:::i;65154:118::-;;;;;;:::i;:::-;;:::i;65996:984::-;;;;;;:::i;:::-;;:::i;65280:146::-;;;;;;:::i;:::-;;:::i;65434:129::-;;;;;;:::i;:::-;;:::i;3571:103::-;;;:::i;66988:193::-;;;;;;:::i;:::-;67058:19;67121:15;;;:6;:15;;;;;;;;;67157:7;:16;;;;;;;-1:-1:-1;;;;;67121:15:0;;;;66988:193;;;;;-1:-1:-1;;;;;5791:32:1;;;5773:51;;5855:2;5840:18;;5833:34;;;;5746:18;66988:193:0;5599:274:1;63521:41:0;;;;;;:::i;:::-;;;;;;;;;;;;;;49232:580;;;:::i;:::-;;;;;;;;;;;;;:::i;2896:87::-;2942:7;2969:6;-1:-1:-1;;;;;2969:6:0;2896:87;;63422:42;;;;;;:::i;:::-;;;;;;;;;;;;;;63341:26;;;;;;;;;3829:220;;;;;;:::i;:::-;;:::i;65021:125::-;;;;;;:::i;:::-;;:::i;63244:24::-;;;;;-1:-1:-1;;;;;63244:24:0;;;64926:87;2782:13;:11;:13::i;:::-;64990:8:::1;:15:::0;;-1:-1:-1;;64990:15:0::1;;::::0;;;::::1;::::0;;;::::1;::::0;;64926:87::o;64559:359::-;64787:3;;64702:6;;930:10;;-1:-1:-1;;;;;64787:3:0;64769:22;;64761:55;;;;-1:-1:-1;;;64761:55:0;;7433:2:1;64761:55:0;;;7415:21:1;7472:2;7452:18;;;7445:30;-1:-1:-1;;;7491:18:1;;;7484:50;7551:18;;64761:55:0;;;;;;;;;64827:24;64837:4;64843:7;64827:9;:24::i;:::-;-1:-1:-1;;;;64869:41:0;64559:359;-1:-1:-1;;;;;;64559:359:0:o;67189:140::-;-1:-1:-1;;;;;67308:13:0;;;;;;:6;:13;;;;;;;;;67297:24;;;;;;;;;;;;;;;;;67259:25;;67297:24;;;67308:13;67297:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67189:140;;;:::o;67337:1375::-;67551:15;67541:7;:25;;;67533:59;;;;-1:-1:-1;;;67533:59:0;;7782:2:1;67533:59:0;;;7764:21:1;7821:2;7801:18;;;7794:30;-1:-1:-1;;;7840:18:1;;;7833:51;7901:18;;67533:59:0;7580:345:1;67533:59:0;67603:17;67664:12;;;:6;:12;;;;;;930:10;;-1:-1:-1;;;;;67664:12:0;:25;;;;:67;;-1:-1:-1;67706:12:0;;;;:6;:12;;;;;;-1:-1:-1;;;;;67706:25:0;;;:12;;:25;;67664:67;:109;;;-1:-1:-1;67748:12:0;;;;:6;:12;;;;;;-1:-1:-1;;;;;67748:25:0;;;:12;;:25;;67664:109;67646:219;;;67800:53;;-1:-1:-1;;;67800:53:0;;8132:2:1;67800:53:0;;;8114:21:1;8171:2;8151:18;;;8144:30;8210:34;8190:18;;;8183:62;-1:-1:-1;;;8261:18:1;;;8254:41;8312:19;;67800:53:0;7930:407:1;67646:219:0;67909:8;;;67893:12;;;:6;:12;;;;;;67909:8;;;;67893:12;;:24;;;:65;;-1:-1:-1;67950:8:0;;;67934:12;;;:6;:12;;;;;;67950:8;;;;67934:12;;:24;;67893:65;:106;;;-1:-1:-1;67991:8:0;;;67975:12;;;:6;:12;;;;;;67991:8;;;;67975:12;;:24;;67893:106;67875:199;;;68026:36;;-1:-1:-1;;;68026:36:0;;8544:2:1;68026:36:0;;;8526:21:1;8583:2;8563:18;;;8556:30;8622:28;8602:18;;;8595:56;8668:18;;68026:36:0;8342:350:1;67875:199:0;68110:225;;;;;;;;-1:-1:-1;;;;;68110:225:0;;;;;;;;;;;;;;;;;;;;;;;;68086:21;68252:17;;;:6;:17;;;;;;;68110:225;;;;;;;;;;;;;;;;;;68354:23;68110:225;68367:9;68354:6;:23::i;:::-;68346:68;;;;-1:-1:-1;;;68346:68:0;;8899:2:1;68346:68:0;;;8881:21:1;;;8918:18;;;8911:30;8977:34;8957:18;;;8950:62;9029:18;;68346:68:0;8697:356:1;68346:68:0;68430:8;68425:163;68448:3;68444:7;;:1;:7;;;68425:163;;;68491:3;;:23;;-1:-1:-1;;;68491:23:0;;-1:-1:-1;;;;;363:32:1;;;68491:23:0;;;345:51:1;68473:15:0;;68491:3;;:12;;318:18:1;;68491:23:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68534:42;;;-1:-1:-1;;;;;9524:32:1;;9506:51;;9588:2;9573:18;;9566:34;;;9616:18;;;9609:34;;;9674:2;9659:18;;9652:34;;;9717:3;9702:19;;9695:35;;;68473:41:0;;-1:-1:-1;68534:42:0;;9493:3:1;9478:19;68534:42:0;;;;;;;-1:-1:-1;68453:3:0;;68425:163;;;-1:-1:-1;;;;;;68598:17:0;;;;;;:6;:17;;;;;:22;;68619:1;;68598:17;:22;;68619:1;;68598:22;:::i;:::-;;;;-1:-1:-1;;68631:12:0;;;;:6;:12;;;;;:17;;68647:1;;68631:12;:17;;68647:1;;68631:17;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68659:12:0;;;:6;:12;;;;;:17;;-1:-1:-1;;;68659:12:0;;:17;;-1:-1:-1;;68659:17:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68687:12:0;;;:6;:12;;;;;:17;;-1:-1:-1;;;68687:12:0;;:17;;-1:-1:-1;;68687:17:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;67522:1190;;67337:1375;;;;;;:::o;63471:43::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;65154:118::-;2782:13;:11;:13::i;:::-;65234::::1;:30:::0;65154:118::o;65996:984::-;66087:15;66077:7;:25;;;66069:59;;;;-1:-1:-1;;;66069:59:0;;7782:2:1;66069:59:0;;;7764:21:1;7821:2;7801:18;;;7794:30;-1:-1:-1;;;7840:18:1;;;7833:51;7901:18;;66069:59:0;7580:345:1;66069:59:0;66139:12;66193:15;;;:6;:15;;;;;;930:10;;-1:-1:-1;;;;;66193:15:0;66227:13;;;66219:65;;;;-1:-1:-1;;;66219:65:0;;10382:2:1;66219:65:0;;;10364:21:1;10421:2;10401:18;;;10394:30;10460:34;10440:18;;;10433:62;-1:-1:-1;;;10511:18:1;;;10504:37;10558:19;;66219:65:0;10180:403:1;66219:65:0;66295:14;66312:16;;;:7;:16;;;;;;66361:10;;;;;:39;;;66394:6;66375:15;:25;;66361:39;66339:114;;;;-1:-1:-1;;;66339:114:0;;10790:2:1;66339:114:0;;;10772:21:1;10829:2;10809:18;;;10802:30;10868:27;10848:18;;;10841:55;10913:18;;66339:114:0;10588:349:1;66339:114:0;66466:3;;:47;;-1:-1:-1;;;66466:47:0;;66491:4;66466:47;;;11182:34:1;-1:-1:-1;;;;;11252:15:1;;;11232:18;;;11225:43;11284:18;;;11277:34;;;66466:3:0;;;;:16;;11117:18:1;;66466:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;66547:13:0;;66524:20;66547:13;;;:6;:13;;;;;;;;66524:36;;;;;;;;;;;;;;;;;;;66547:13;;66524:36;;;66547:13;66524:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66571:11;66585:3;:10;66571:24;;66606:10;66636:8;66631:148;66654:3;66650:1;:7;;;66631:148;;;66693:7;66683:3;66687:1;66683:6;;;;;;;;;;:::i;:::-;;;;;;;:17;66679:89;;66727:1;66721:7;;66747:5;;66679:89;66659:3;;;;:::i;:::-;;;;66631:148;;;-1:-1:-1;;;;;;66810:13:0;;;;;;:6;:13;;;;;66824:7;66830:1;66824:3;:7;:::i;:::-;66810:22;;;;;;;;:::i;:::-;;;;;;;;;66789:6;:13;66796:5;-1:-1:-1;;;;;66789:13:0;-1:-1:-1;;;;;66789:13:0;;;;;;;;;;;;66803:3;66789:18;;;;;;;;;;:::i;:::-;;;;;;;;;;;;:43;;;;-1:-1:-1;;;;;66843:13:0;;;;:6;:13;;;;;;:19;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;66843:19:0;;;;;;;;;;;;;;66880:15;;;:6;:15;;;;;;66873:22;;-1:-1:-1;;;;;;66873:22:0;;;66913:7;:16;;;;;66906:23;;;;66945:27;;-1:-1:-1;;;;;5791:32:1;;5773:51;;5840:18;;;5833:34;;;66945:27:0;;5746:18:1;66945:27:0;;;;;;;66058:922;;;;;;65996:984;;:::o;65280:146::-;2782:13;:11;:13::i;:::-;-1:-1:-1;;;;;65360:24:0;::::1;65352:33;;;::::0;::::1;;65396:9;:22:::0;;-1:-1:-1;;;;;;65396:22:0::1;-1:-1:-1::0;;;;;65396:22:0;;;::::1;::::0;;;::::1;::::0;;65280:146::o;65434:129::-;2782:13;:11;:13::i;:::-;-1:-1:-1;;;;;65506:21:0;::::1;65498:30;;;::::0;::::1;;65539:6;:16:::0;;-1:-1:-1;;;;;;65539:16:0::1;-1:-1:-1::0;;;;;65539:16:0;;;::::1;::::0;;;::::1;::::0;;65434:129::o;3571:103::-;2782:13;:11;:13::i;:::-;3636:30:::1;3663:1;3636:18;:30::i;:::-;3571:103::o:0;49232:580::-;49335:13;49363:18;49396:21;49432:15;49462:25;49502:12;49529:27;49637:13;:11;:13::i;:::-;49665:16;:14;:16::i;:::-;49777;;;49760:1;49777:16;;;;;;;;;-1:-1:-1;;;49584:220:0;;;-1:-1:-1;49584:220:0;;-1:-1:-1;49696:13:0;;-1:-1:-1;49732:4:0;;-1:-1:-1;49760:1:0;-1:-1:-1;49777:16:0;-1:-1:-1;49584:220:0;-1:-1:-1;49232:580:0:o;3829:220::-;2782:13;:11;:13::i;:::-;-1:-1:-1;;;;;3914:22:0;::::1;3910:93;;3960:31;::::0;-1:-1:-1;;;3960:31:0;;3988:1:::1;3960:31;::::0;::::1;345:51:1::0;318:18;;3960:31:0::1;199:203:1::0;3910:93:0::1;4013:28;4032:8;4013:18;:28::i;:::-;3829:220:::0;:::o;65021:125::-;2782:13;:11;:13::i;:::-;-1:-1:-1;;;;;65089:18:0;::::1;65081:27;;;::::0;::::1;;65119:3;:19:::0;;-1:-1:-1;;;;;;65119:19:0::1;-1:-1:-1::0;;;;;65119:19:0;;;::::1;::::0;;;::::1;::::0;;65021:125::o;3061:166::-;2942:7;2969:6;-1:-1:-1;;;;;2969:6:0;930:10;3121:23;3117:103;;3168:40;;-1:-1:-1;;;3168:40:0;;930:10;3168:40;;;345:51:1;318:18;;3168:40:0;199:203:1;65571:417:0;65690:1;65663:15;;;:6;:15;;;;;;-1:-1:-1;;;;;65663:15:0;:29;:87;;;;-1:-1:-1;65713:3:0;;:20;;-1:-1:-1;;;65713:20:0;;;;;2643:25:1;;;65745:4:0;;-1:-1:-1;;;;;65713:3:0;;:11;;2616:18:1;;65713:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;65713:37:0;;65663:87;65641:150;;;;-1:-1:-1;;;65641:150:0;;12383:2:1;65641:150:0;;;12365:21:1;12422:2;12402:18;;;12395:30;-1:-1:-1;;;12441:18:1;;;12434:43;12494:18;;65641:150:0;12181:337:1;65641:150:0;65839:13;;65821:31;;:15;:31;:::i;:::-;65802:16;;;;:7;:16;;;;;;;;:50;;;65863:6;:15;;;;;:22;;-1:-1:-1;;;;;;65863:22:0;-1:-1:-1;;;;;65863:22:0;;;;;;;;65896:12;;;:6;:12;;;;;:26;;-1:-1:-1;65896:26:0;;;;;;;;;;;;;;65963:16;;;;;;;;;65938:42;;12725:51:1;;;12792:18;;;12785:34;;;12835:18;;12828:34;;;;65938:42:0;;12713:2:1;12698:18;65938:42:0;;;;;;;65571:417;;:::o;69296:264::-;69407:4;69424:14;69441:28;69458:10;69463:4;69458;:10::i;:::-;69441:16;:28::i;:::-;69424:45;-1:-1:-1;69480:12:0;69495:25;69424:45;69510:9;69495:14;:25::i;:::-;69546:6;;-1:-1:-1;;;;;69538:14:0;;;69546:6;;69538:14;;-1:-1:-1;;;69296:264:0;;;;;:::o;4209:191::-;4283:16;4302:6;;-1:-1:-1;;;;;4319:17:0;;;-1:-1:-1;;;;;;4319:17:0;;;;;;4352:40;;4302:6;;;;;;;4352:40;;4283:16;4352:40;4272:128;4209:191;:::o;50141:128::-;50187:13;50220:41;:5;50247:13;50220:26;:41::i;:::-;50213:48;;50141:128;:::o;50604:137::-;50653:13;50686:47;:8;50716:16;50686:29;:47::i;68835:453::-;68895:7;64141:144;69037:4;:14;;;69074:4;:9;;;69106:4;:9;;;69138:4;:9;;;69170:4;:10;;;69203:4;:12;;;69238:4;:8;;;68963:302;;;;;;;;;;;;;;13212:25:1;;;-1:-1:-1;;;;;13273:32:1;;;;13268:2;13253:18;;13246:60;13337:2;13322:18;;13315:34;;;;13380:2;13365:18;;13358:34;;;;13423:3;13408:19;;13401:35;13293:3;13452:19;;13445:35;13499:10;13546:15;;;13540:3;13525:19;;13518:44;13599:15;13593:3;13578:19;;13571:44;13199:3;13184:19;;12873:748;68963:302:0;;;;;;;;;;;;;68935:345;;;;;;68915:365;;68835:453;;;:::o;48998:178::-;49075:7;49102:66;49135:20;:18;:20::i;:::-;49157:10;35227:4;35221:11;-1:-1:-1;;;35246:23:0;;35299:4;35290:14;;35283:39;;;;35352:4;35343:14;;35336:34;35409:4;35394:20;;;35022:410;58694:259;58772:7;58793:17;58812:18;58832:16;58852:27;58863:4;58869:9;58852:10;:27::i;:::-;58792:87;;;;;;58890:28;58902:5;58909:8;58890:11;:28::i;:::-;-1:-1:-1;58936:9:0;;58694:259;-1:-1:-1;;;;58694:259:0:o;43111:273::-;43205:13;41057:66;43235:46;;43231:146;;43305:15;43314:5;43305:8;:15::i;:::-;43298:22;;;;43231:146;43360:5;43353:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47899:268;47952:7;47984:4;-1:-1:-1;;;;;47993:11:0;47976:28;;:63;;;;;48025:14;48008:13;:31;47976:63;47972:188;;;-1:-1:-1;48063:22:0;;47899:268::o;47972:188::-;48125:23;48267:80;;;46091:95;48267:80;;;14584:25:1;48289:11:0;14625:18:1;;;14618:34;;;;48302:14:0;14668:18:1;;;14661:34;48318:13:0;14711:18:1;;;14704:34;48341:4:0;14754:19:1;;;14747:61;48230:7:0;;14556:19:1;;48267:80:0;;;;;;;;;;;;48257:91;;;;;;48250:98;;48175:181;;57088:783;57169:7;57178:12;57192:7;57216:9;:16;57236:2;57216:22;57212:652;;57560:4;57545:20;;57539:27;57610:4;57595:20;;57589:27;57668:4;57653:20;;57647:27;57255:9;57639:36;57711:25;57722:4;57639:36;57539:27;57589;57711:10;:25::i;:::-;57704:32;;;;;;;;;;;57212:652;-1:-1:-1;;57834:16:0;;57785:1;;-1:-1:-1;57789:35:0;;57212:652;57088:783;;;;;:::o;62263:542::-;62359:20;62350:5;:29;;;;;;;;:::i;:::-;;62346:452;;62263:542;;:::o;62346:452::-;62457:29;62448:5;:38;;;;;;;;:::i;:::-;;62444:354;;62510:23;;-1:-1:-1;;;62510:23:0;;;;;;;;;;;62444:354;62564:35;62555:5;:44;;;;;;;;:::i;:::-;;62551:247;;62623:46;;-1:-1:-1;;;62623:46:0;;;;;2643:25:1;;;2616:18;;62623:46:0;2497:177:1;62551:247:0;62700:30;62691:5;:39;;;;;;;;:::i;:::-;;62687:111;;62754:32;;-1:-1:-1;;;62754:32:0;;;;;2643:25:1;;;2616:18;;62754:32:0;2497:177:1;62687:111:0;62263:542;;:::o;41766:415::-;41825:13;41851:11;41865:16;41876:4;41865:10;:16::i;:::-;41991:14;;;42002:2;41991:14;;;;;;;;;41851:30;;-1:-1:-1;41971:17:0;;41991:14;;;;;;;;;-1:-1:-1;;;42084:16:0;;;-1:-1:-1;42130:4:0;42121:14;;42114:28;;;;-1:-1:-1;42084:16:0;41766:415::o;60165:1557::-;60296:7;;;61240:66;61227:79;;61223:166;;;-1:-1:-1;61339:1:0;;-1:-1:-1;61343:30:0;;-1:-1:-1;61375:1:0;61323:54;;61223:166;61503:24;;;61486:14;61503:24;;;;;;;;;15046:25:1;;;15119:4;15107:17;;15087:18;;;15080:45;;;;15141:18;;;15134:34;;;15184:18;;;15177:34;;;61503:24:0;;15018:19:1;;61503:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;61503:24:0;;-1:-1:-1;;61503:24:0;;;-1:-1:-1;;;;;;;61542:20:0;;61538:115;;-1:-1:-1;61595:1:0;;-1:-1:-1;61599:29:0;;-1:-1:-1;61595:1:0;;-1:-1:-1;61579:62:0;;61538:115;61673:6;-1:-1:-1;61681:20:0;;-1:-1:-1;61681:20:0;;-1:-1:-1;60165:1557:0;;;;;;;;;:::o;42258:251::-;42319:7;42392:4;42356:40;;42420:2;42411:11;;42407:71;;;42446:20;;-1:-1:-1;;;42446:20:0;;;;;;;;;;;14:180:1;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:1;;14:180;-1:-1:-1;14:180:1:o;407:163::-;474:20;;534:10;523:22;;513:33;;503:61;;560:1;557;550:12;503:61;407:163;;;:::o;575:184::-;633:6;686:2;674:9;665:7;661:23;657:32;654:52;;;702:1;699;692:12;654:52;725:28;743:9;725:28;:::i;:::-;715:38;575:184;-1:-1:-1;;;575:184:1:o;764:131::-;-1:-1:-1;;;;;839:31:1;;829:42;;819:70;;885:1;882;875:12;900:936;997:6;1005;1013;1021;1029;1082:3;1070:9;1061:7;1057:23;1053:33;1050:53;;;1099:1;1096;1089:12;1050:53;1138:9;1125:23;1157:31;1182:5;1157:31;:::i;:::-;1207:5;-1:-1:-1;1264:2:1;1249:18;;1236:32;1277:33;1236:32;1277:33;:::i;:::-;1329:7;-1:-1:-1;1383:2:1;1368:18;;1355:32;;-1:-1:-1;1438:2:1;1423:18;;1410:32;1461:18;1491:14;;;1488:34;;;1518:1;1515;1508:12;1488:34;1556:6;1545:9;1541:22;1531:32;;1601:7;1594:4;1590:2;1586:13;1582:27;1572:55;;1623:1;1620;1613:12;1572:55;1663:2;1650:16;1689:2;1681:6;1678:14;1675:34;;;1705:1;1702;1695:12;1675:34;1750:7;1745:2;1736:6;1732:2;1728:15;1724:24;1721:37;1718:57;;;1771:1;1768;1761:12;1718:57;900:936;;;;-1:-1:-1;900:936:1;;-1:-1:-1;1802:2:1;1794:11;;1824:6;900:936;-1:-1:-1;;;900:936:1:o;2245:247::-;2304:6;2357:2;2345:9;2336:7;2332:23;2328:32;2325:52;;;2373:1;2370;2363:12;2325:52;2412:9;2399:23;2431:31;2456:5;2431:31;:::i;2679:439::-;2732:3;2770:5;2764:12;2797:6;2792:3;2785:19;2823:4;2852;2847:3;2843:14;2836:21;;2891:4;2884:5;2880:16;2914:1;2924:169;2938:6;2935:1;2932:13;2924:169;;;2999:13;;2987:26;;3033:12;;;;3068:15;;;;2960:1;2953:9;2924:169;;;-1:-1:-1;3109:3:1;;2679:439;-1:-1:-1;;;;;2679:439:1:o;3123:261::-;3302:2;3291:9;3284:21;3265:4;3322:56;3374:2;3363:9;3359:18;3351:6;3322:56;:::i;3613:127::-;3674:10;3669:3;3665:20;3662:1;3655:31;3705:4;3702:1;3695:15;3729:4;3726:1;3719:15;3745:1272;3856:6;3864;3872;3880;3888;3896;3949:3;3937:9;3928:7;3924:23;3920:33;3917:53;;;3966:1;3963;3956:12;3917:53;4002:9;3989:23;3979:33;;4059:2;4048:9;4044:18;4031:32;4021:42;;4110:2;4099:9;4095:18;4082:32;4072:42;;4133:37;4166:2;4155:9;4151:18;4133:37;:::i;:::-;4123:47;;4189:38;4222:3;4211:9;4207:19;4189:38;:::i;:::-;4179:48;;4278:3;4267:9;4263:19;4250:33;4302:18;4343:2;4335:6;4332:14;4329:34;;;4359:1;4356;4349:12;4329:34;4397:6;4386:9;4382:22;4372:32;;4442:7;4435:4;4431:2;4427:13;4423:27;4413:55;;4464:1;4461;4454:12;4413:55;4500:2;4487:16;4522:2;4518;4515:10;4512:36;;;4528:18;;:::i;:::-;4603:2;4597:9;4571:2;4657:13;;-1:-1:-1;;4653:22:1;;;4677:2;4649:31;4645:40;4633:53;;;4701:18;;;4721:22;;;4698:46;4695:72;;;4747:18;;:::i;:::-;4787:10;4783:2;4776:22;4822:2;4814:6;4807:18;4862:7;4857:2;4852;4848;4844:11;4840:20;4837:33;4834:53;;;4883:1;4880;4873:12;4834:53;4939:2;4934;4930;4926:11;4921:2;4913:6;4909:15;4896:46;4984:1;4979:2;4974;4966:6;4962:15;4958:24;4951:35;5005:6;4995:16;;;;;;;3745:1272;;;;;;;;:::o;5022:315::-;5090:6;5098;5151:2;5139:9;5130:7;5126:23;5122:32;5119:52;;;5167:1;5164;5157:12;5119:52;5206:9;5193:23;5225:31;5250:5;5225:31;:::i;:::-;5275:5;5327:2;5312:18;;;;5299:32;;-1:-1:-1;;;5022:315:1:o;5342:252::-;5409:6;5417;5470:2;5458:9;5449:7;5445:23;5441:32;5438:52;;;5486:1;5483;5476:12;5438:52;5522:9;5509:23;5499:33;;5551:37;5584:2;5573:9;5569:18;5551:37;:::i;:::-;5541:47;;5342:252;;;;;:::o;5878:423::-;5920:3;5958:5;5952:12;5985:6;5980:3;5973:19;6010:1;6020:162;6034:6;6031:1;6028:13;6020:162;;;6096:4;6152:13;;;6148:22;;6142:29;6124:11;;;6120:20;;6113:59;6049:12;6020:162;;;6024:3;6227:1;6220:4;6211:6;6206:3;6202:16;6198:27;6191:38;6290:4;6283:2;6279:7;6274:2;6266:6;6262:15;6258:29;6253:3;6249:39;6245:50;6238:57;;;5878:423;;;;:::o;6306:920::-;6712:3;6707;6703:13;6695:6;6691:26;6680:9;6673:45;6754:3;6749:2;6738:9;6734:18;6727:31;6654:4;6781:46;6822:3;6811:9;6807:19;6799:6;6781:46;:::i;:::-;6875:9;6867:6;6863:22;6858:2;6847:9;6843:18;6836:50;6909:33;6935:6;6927;6909:33;:::i;:::-;6973:2;6958:18;;6951:34;;;-1:-1:-1;;;;;7022:32:1;;7016:3;7001:19;;6994:61;7042:3;7071:19;;7064:35;;;7136:22;;;7130:3;7115:19;;7108:51;6895:47;-1:-1:-1;7176:44:1;6895:47;7205:6;7176:44;:::i;:::-;7168:52;6306:920;-1:-1:-1;;;;;;;;;;6306:920:1:o;9058:184::-;9128:6;9181:2;9169:9;9160:7;9156:23;9152:32;9149:52;;;9197:1;9194;9187:12;9149:52;-1:-1:-1;9220:16:1;;9058:184;-1:-1:-1;9058:184:1:o;9741:127::-;9802:10;9797:3;9793:20;9790:1;9783:31;9833:4;9830:1;9823:15;9857:4;9854:1;9847:15;9873:125;9938:9;;;9959:10;;;9956:36;;;9972:18;;:::i;10003:172::-;10070:10;10100;;;10112;;;10096:27;;10135:11;;;10132:37;;;10149:18;;:::i;:::-;10132:37;10003:172;;;;:::o;11322:127::-;11383:10;11378:3;11374:20;11371:1;11364:31;11414:4;11411:1;11404:15;11438:4;11435:1;11428:15;11454:201;11492:3;11520:10;11565:2;11558:5;11554:14;11592:2;11583:7;11580:15;11577:41;;11598:18;;:::i;:::-;11647:1;11634:15;;11454:201;-1:-1:-1;;;11454:201:1:o;11660:128::-;11727:9;;;11748:11;;;11745:37;;;11762:18;;:::i;11793:127::-;11854:10;11849:3;11845:20;11842:1;11835:31;11885:4;11882:1;11875:15;11909:4;11906:1;11899:15;11925:251;11995:6;12048:2;12036:9;12027:7;12023:23;12019:32;12016:52;;;12064:1;12061;12054:12;12016:52;12096:9;12090:16;12115:31;12140:5;12115:31;:::i;13626:380::-;13705:1;13701:12;;;;13748;;;13769:61;;13823:4;13815:6;13811:17;13801:27;;13769:61;13876:2;13868:6;13865:14;13845:18;13842:38;13839:161;;13922:10;13917:3;13913:20;13910:1;13903:31;13957:4;13954:1;13947:15;13985:4;13982:1;13975:15;13839:161;;13626:380;;;:::o;14011:127::-;14072:10;14067:3;14063:20;14060:1;14053:31;14103:4;14100:1;14093:15;14127:4;14124:1;14117:15
Swarm Source
ipfs://778a35cfc42fb44d400b3afccd99001337f8a5ef22d22563e28b17547c1d3dd0
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.