Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
Overview
Max Total Supply
0 ETH20AVT
Holders
49
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 ETH20AVTLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Source Code Verified (Exact Match)
Contract Name:
ETH20AVATAR
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-09-08 */ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity 0.8.19; /** * @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; } } /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. 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 { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // 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. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 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 + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } } /** * @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); } } } /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(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) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } } /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } } /// The ERC721 standard allows for self-approvals. /// For performance, this implementation WILL NOT revert for such actions. /// Please add any checks with overrides if desired. abstract contract ERC721 { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CONSTANTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev An account can hold up to 4294967295 tokens. uint256 internal constant _MAX_ACCOUNT_BALANCE = 0xffffffff; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Only the token owner or an approved account can manage the token. error NotOwnerNorApproved(); /// @dev The token does not exist. error TokenDoesNotExist(); /// @dev The token already exists. error TokenAlreadyExists(); /// @dev Cannot query the balance for the zero address. error BalanceQueryForZeroAddress(); /// @dev Cannot mint or transfer to the zero address. error TransferToZeroAddress(); /// @dev The token must be owned by `from`. error TransferFromIncorrectOwner(); /// @dev The recipient's balance has overflowed. error AccountBalanceOverflow(); /// @dev Cannot safely transfer to a contract that does not implement /// the ERC721Receiver interface. error TransferToNonERC721ReceiverImplementer(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* EVENTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Emitted when token `id` is transferred from `from` to `to`. event Transfer(address indexed from, address indexed to, uint256 indexed id); /// @dev Emitted when `owner` enables `account` to manage the `id` token. event Approval(address indexed owner, address indexed account, uint256 indexed id); /// @dev Emitted when `owner` enables or disables `operator` to manage all of their tokens. event ApprovalForAll(address indexed owner, address indexed operator, bool isApproved); /// @dev `keccak256(bytes("Transfer(address,address,uint256)"))`. uint256 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; /// @dev `keccak256(bytes("Approval(address,address,uint256)"))`. uint256 private constant _APPROVAL_EVENT_SIGNATURE = 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925; /// @dev `keccak256(bytes("ApprovalForAll(address,address,bool)"))`. uint256 private constant _APPROVAL_FOR_ALL_EVENT_SIGNATURE = 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* STORAGE */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The ownership data slot of `id` is given by: /// ``` /// mstore(0x00, id) /// mstore(0x1c, _ERC721_MASTER_SLOT_SEED) /// let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) /// ``` /// Bits Layout: // - [0..159] `addr` // - [160..223] `extraData` /// /// The approved address slot is given by: `add(1, ownershipSlot)`. /// /// See: https://notes.ethereum.org/%40vbuterin/verkle_tree_eip /// /// The balance slot of `owner` is given by: /// ``` /// mstore(0x1c, _ERC721_MASTER_SLOT_SEED) /// mstore(0x00, owner) /// let balanceSlot := keccak256(0x0c, 0x1c) /// ``` /// Bits Layout: /// - [0..31] `balance` /// - [32..225] `aux` /// /// The `operator` approval slot of `owner` is given by: /// ``` /// mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator)) /// mstore(0x00, owner) /// let operatorApprovalSlot := keccak256(0x0c, 0x30) /// ``` uint256 private constant _ERC721_MASTER_SLOT_SEED = 0x7d8825530a5a2e7a << 192; /// @dev Pre-shifted and pre-masked constant. uint256 private constant _ERC721_MASTER_SLOT_SEED_MASKED = 0x0a5a2e7a00000000; // Token name string private _name; // Token symbol string private _symbol; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ERC721 METADATA */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the token collection name. function name() public view virtual returns (string memory) { return _name; } /// @dev Returns the token collection symbol. function symbol() public view virtual returns (string memory) { return _symbol; } /// @dev Returns the Uniform Resource Identifier (URI) for token `id`. function tokenURI(uint256 tokenId) public view virtual returns (string memory) { if (!_exists(tokenId)) revert TokenDoesNotExist(); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, "/", _toHexString(address(this)), "/", _toString(tokenId))) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ERC721 */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the owner of token `id`. /// /// Requirements: /// - Token `id` must exist. function ownerOf(uint256 id) public view virtual returns (address result) { result = _ownerOf(id); /// @solidity memory-safe-assembly assembly { if iszero(result) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } } } /// @dev Returns the number of tokens owned by `owner`. /// /// Requirements: /// - `owner` must not be the zero address. function balanceOf(address owner) public view virtual returns (uint256 result) { /// @solidity memory-safe-assembly assembly { // Revert if the `owner` is the zero address. if iszero(owner) { mstore(0x00, 0x8f4eb604) // `BalanceQueryForZeroAddress()`. revert(0x1c, 0x04) } mstore(0x1c, _ERC721_MASTER_SLOT_SEED) mstore(0x00, owner) result := and(sload(keccak256(0x0c, 0x1c)), _MAX_ACCOUNT_BALANCE) } } /// @dev Returns the account approved to managed token `id`. /// /// Requirements: /// - Token `id` must exist. function getApproved(uint256 id) public view virtual returns (address result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) if iszero(shr(96, shl(96, sload(ownershipSlot)))) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } result := sload(add(1, ownershipSlot)) } } /// @dev Sets `account` as the approved account to manage token `id`. /// /// Requirements: /// - Token `id` must exist. /// - The caller must be the owner of the token, /// or an approved operator for the token owner. /// /// Emits a {Approval} event. function approve(address account, uint256 id) public payable virtual { _approve(msg.sender, account, id); } /// @dev Returns whether `operator` is approved to manage the tokens of `owner`. function isApprovedForAll(address owner, address operator) public view virtual returns (bool result) { /// @solidity memory-safe-assembly assembly { mstore(0x1c, operator) mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED) mstore(0x00, owner) result := sload(keccak256(0x0c, 0x30)) } } /// @dev Sets whether `operator` is approved to manage the tokens of the caller. /// /// Emits a {ApprovalForAll} event. function setApprovalForAll(address operator, bool isApproved) public virtual { /// @solidity memory-safe-assembly assembly { // Convert to 0 or 1. isApproved := iszero(iszero(isApproved)) // Update the `isApproved` for (`msg.sender`, `operator`). mstore(0x1c, operator) mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED) mstore(0x00, caller()) sstore(keccak256(0x0c, 0x30), isApproved) // Emit the {ApprovalForAll} event. mstore(0x00, isApproved) log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, caller(), shr(96, shl(96, operator))) } } /// @dev Transfers token `id` from `from` to `to`. /// /// Requirements: /// /// - Token `id` must exist. /// - `from` must be the owner of the token. /// - `to` cannot be the zero address. /// - The caller must be the owner of the token, or be approved to manage the token. /// /// Emits a {Transfer} event. function transferFrom(address from, address to, uint256 id) public payable virtual { _beforeTokenTransfer(from, to, id); /// @solidity memory-safe-assembly assembly { // Clear the upper 96 bits. let bitmaskAddress := shr(96, not(0)) from := and(bitmaskAddress, from) to := and(bitmaskAddress, to) // Load the ownership data. mstore(0x00, id) mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, caller())) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let ownershipPacked := sload(ownershipSlot) let owner := and(bitmaskAddress, ownershipPacked) // Revert if `from` is not the owner, or does not exist. if iszero(mul(owner, eq(owner, from))) { if iszero(owner) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } mstore(0x00, 0xa1148100) // `TransferFromIncorrectOwner()`. revert(0x1c, 0x04) } // Revert if `to` is the zero address. if iszero(to) { mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. revert(0x1c, 0x04) } // Load, check, and update the token approval. { mstore(0x00, from) let approvedAddress := sload(add(1, ownershipSlot)) // Revert if the caller is not the owner, nor approved. if iszero(or(eq(caller(), from), eq(caller(), approvedAddress))) { if iszero(sload(keccak256(0x0c, 0x30))) { mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. revert(0x1c, 0x04) } } // Delete the approved address if any. if approvedAddress { sstore(add(1, ownershipSlot), 0) } } // Update with the new owner. sstore(ownershipSlot, xor(ownershipPacked, xor(from, to))) // Decrement the balance of `from`. { let fromBalanceSlot := keccak256(0x0c, 0x1c) sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1)) } // Increment the balance of `to`. { mstore(0x00, to) let toBalanceSlot := keccak256(0x0c, 0x1c) let toBalanceSlotPacked := add(sload(toBalanceSlot), 1) if iszero(and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE)) { mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. revert(0x1c, 0x04) } sstore(toBalanceSlot, toBalanceSlotPacked) } // Emit the {Transfer} event. log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id) } _afterTokenTransfer(from, to, id); } /// @dev Equivalent to `safeTransferFrom(from, to, id, "")`. function safeTransferFrom(address from, address to, uint256 id) public payable virtual { transferFrom(from, to, id); if (_hasCode(to)) _checkOnERC721Received(from, to, id, ""); } /// @dev Transfers token `id` from `from` to `to`. /// /// Requirements: /// /// - Token `id` must exist. /// - `from` must be the owner of the token. /// - `to` cannot be the zero address. /// - The caller must be the owner of the token, or be approved to manage the token. /// - 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 id, bytes calldata data) public payable virtual { transferFrom(from, to, id); if (_hasCode(to)) _checkOnERC721Received(from, to, id, data); } /// @dev Returns true if this contract implements the interface defined by `interfaceId`. /// See: https://eips.ethereum.org/EIPS/eip-165 /// This function call must use less than 30000 gas. function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) { /// @solidity memory-safe-assembly assembly { let s := shr(224, interfaceId) // ERC165: 0x01ffc9a7, ERC721: 0x80ac58cd, ERC721Metadata: 0x5b5e139f. result := or(or(eq(s, 0x01ffc9a7), eq(s, 0x80ac58cd)), eq(s, 0x5b5e139f)) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL QUERY FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns if token `id` exists. function _exists(uint256 id) internal view virtual returns (bool result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) result := shl(96, sload(add(id, add(id, keccak256(0x00, 0x20))))) } } /// @dev Returns the owner of token `id`. /// Returns the zero address instead of reverting if the token does not exist. function _ownerOf(uint256 id) internal view virtual returns (address result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) result := shr(96, shl(96, sload(add(id, add(id, keccak256(0x00, 0x20)))))) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL DATA HITCHHIKING FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the auxiliary data for `owner`. /// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data. /// Auxiliary data can be set for any address, even if it does not have any tokens. function _getAux(address owner) internal view virtual returns (uint224 result) { /// @solidity memory-safe-assembly assembly { mstore(0x1c, _ERC721_MASTER_SLOT_SEED) mstore(0x00, owner) result := shr(32, sload(keccak256(0x0c, 0x1c))) } } /// @dev Set the auxiliary data for `owner` to `value`. /// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data. /// Auxiliary data can be set for any address, even if it does not have any tokens. function _setAux(address owner, uint224 value) internal virtual { /// @solidity memory-safe-assembly assembly { mstore(0x1c, _ERC721_MASTER_SLOT_SEED) mstore(0x00, owner) let balanceSlot := keccak256(0x0c, 0x1c) let packed := sload(balanceSlot) sstore(balanceSlot, xor(packed, shl(32, xor(value, shr(32, packed))))) } } /// @dev Returns the extra data for token `id`. /// Minting, transferring, burning a token will not change the extra data. /// The extra data can be set on a non existent token. function _getExtraData(uint256 id) internal view virtual returns (uint96 result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) result := shr(160, sload(add(id, add(id, keccak256(0x00, 0x20))))) } } /// @dev Sets the extra data for token `id` to `value`. /// Minting, transferring, burning a token will not change the extra data. /// The extra data can be set on a non existent token. function _setExtraData(uint256 id, uint96 value) internal virtual { /// @solidity memory-safe-assembly assembly { mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let packed := sload(ownershipSlot) sstore(ownershipSlot, xor(packed, shl(160, xor(value, shr(160, packed))))) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL MINT FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Mints token `id` to `to`. /// /// Requirements: /// /// - Token `id` must not exist. /// - `to` cannot be the zero address. /// /// Emits a {Transfer} event. function _mint(address to, uint256 id) internal virtual { _beforeTokenTransfer(address(0), to, id); /// @solidity memory-safe-assembly assembly { // Clear the upper 96 bits. to := shr(96, shl(96, to)) // Revert if `to` is the zero address. if iszero(to) { mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. revert(0x1c, 0x04) } // Load the ownership data. mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let ownershipPacked := sload(ownershipSlot) // Revert if the token already exists. if shl(96, ownershipPacked) { mstore(0x00, 0xc991cbb1) // `TokenAlreadyExists()`. revert(0x1c, 0x04) } // Update with the owner. sstore(ownershipSlot, or(ownershipPacked, to)) // Increment the balance of the owner. { mstore(0x00, to) let balanceSlot := keccak256(0x0c, 0x1c) let balanceSlotPacked := add(sload(balanceSlot), 1) if iszero(and(balanceSlotPacked, _MAX_ACCOUNT_BALANCE)) { mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. revert(0x1c, 0x04) } sstore(balanceSlot, balanceSlotPacked) } // Emit the {Transfer} event. log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, 0, to, id) } _afterTokenTransfer(address(0), to, id); } /// @dev Equivalent to `_safeMint(to, id, "")`. function _safeMint(address to, uint256 id) internal virtual { _safeMint(to, id, ""); } /// @dev Mints token `id` to `to`. /// /// Requirements: /// /// - Token `id` must not exist. /// - `to` cannot be the zero address. /// - If `to` refers to a smart contract, it must implement /// {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. /// /// Emits a {Transfer} event. function _safeMint(address to, uint256 id, bytes memory data) internal virtual { _mint(to, id); if (_hasCode(to)) _checkOnERC721Received(address(0), to, id, data); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL BURN FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Equivalent to `_burn(address(0), id)`. function _burn(uint256 id) internal virtual { _burn(address(0), id); } /// @dev Destroys token `id`, using `by`. /// /// Requirements: /// /// - Token `id` must exist. /// - If `by` is not the zero address, /// it must be the owner of the token, or be approved to manage the token. /// /// Emits a {Transfer} event. function _burn(address by, uint256 id) internal virtual { address owner = ownerOf(id); _beforeTokenTransfer(owner, address(0), id); /// @solidity memory-safe-assembly assembly { // Clear the upper 96 bits. by := shr(96, shl(96, by)) // Load the ownership data. mstore(0x00, id) mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by)) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let ownershipPacked := sload(ownershipSlot) // Reload the owner in case it is changed in `_beforeTokenTransfer`. owner := shr(96, shl(96, ownershipPacked)) // Revert if the token does not exist. if iszero(owner) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } // Load and check the token approval. { mstore(0x00, owner) let approvedAddress := sload(add(1, ownershipSlot)) // If `by` is not the zero address, do the authorization check. // Revert if the `by` is not the owner, nor approved. if iszero(or(iszero(by), or(eq(by, owner), eq(by, approvedAddress)))) { if iszero(sload(keccak256(0x0c, 0x30))) { mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. revert(0x1c, 0x04) } } // Delete the approved address if any. if approvedAddress { sstore(add(1, ownershipSlot), 0) } } // Clear the owner. sstore(ownershipSlot, xor(ownershipPacked, owner)) // Decrement the balance of `owner`. { let balanceSlot := keccak256(0x0c, 0x1c) sstore(balanceSlot, sub(sload(balanceSlot), 1)) } // Emit the {Transfer} event. log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, owner, 0, id) } _afterTokenTransfer(owner, address(0), id); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL APPROVAL FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns whether `account` is the owner of token `id`, or is approved to managed it. /// /// Requirements: /// - Token `id` must exist. function _isApprovedOrOwner(address account, uint256 id) internal view virtual returns (bool result) { /// @solidity memory-safe-assembly assembly { result := 1 // Clear the upper 96 bits. account := shr(96, shl(96, account)) // Load the ownership data. mstore(0x00, id) mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, account)) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let owner := shr(96, shl(96, sload(ownershipSlot))) // Revert if the token does not exist. if iszero(owner) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } // Check if `account` is the `owner`. if iszero(eq(account, owner)) { mstore(0x00, owner) // Check if `account` is approved to if iszero(sload(keccak256(0x0c, 0x30))) { result := eq(account, sload(add(1, ownershipSlot))) } } } } /// @dev Returns the account approved to manage token `id`. /// Returns the zero address instead of reverting if the token does not exist. function _getApproved(uint256 id) internal view virtual returns (address result) { /// @solidity memory-safe-assembly assembly { mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) result := sload(add(1, add(id, add(id, keccak256(0x00, 0x20))))) } } /// @dev Equivalent to `_approve(address(0), account, id)`. function _approve(address account, uint256 id) internal virtual { _approve(address(0), account, id); } /// @dev Sets `account` as the approved account to manage token `id`, using `by`. /// /// Requirements: /// - Token `id` must exist. /// - If `by` is not the zero address, `by` must be the owner /// or an approved operator for the token owner. /// /// Emits a {Transfer} event. function _approve(address by, address account, uint256 id) internal virtual { assembly { // Clear the upper 96 bits. let bitmaskAddress := shr(96, not(0)) account := and(bitmaskAddress, account) by := and(bitmaskAddress, by) // Load the owner of the token. mstore(0x00, id) mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by)) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let owner := and(bitmaskAddress, sload(ownershipSlot)) // Revert if the token does not exist. if iszero(owner) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } // If `by` is not the zero address, do the authorization check. // Revert if `by` is not the owner, nor approved. if iszero(or(iszero(by), eq(by, owner))) { mstore(0x00, owner) if iszero(sload(keccak256(0x0c, 0x30))) { mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. revert(0x1c, 0x04) } } // Sets `account` as the approved account to manage `id`. sstore(add(1, ownershipSlot), account) // Emit the {Approval} event. log4(0x00, 0x00, _APPROVAL_EVENT_SIGNATURE, owner, account, id) } } /// @dev Approve or remove the `operator` as an operator for `by`, /// without authorization checks. /// /// Emits a {ApprovalForAll} event. function _setApprovalForAll(address by, address operator, bool isApproved) internal virtual { /// @solidity memory-safe-assembly assembly { // Clear the upper 96 bits. by := shr(96, shl(96, by)) operator := shr(96, shl(96, operator)) // Convert to 0 or 1. isApproved := iszero(iszero(isApproved)) // Update the `isApproved` for (`by`, `operator`). mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator)) mstore(0x00, by) sstore(keccak256(0x0c, 0x30), isApproved) // Emit the {ApprovalForAll} event. mstore(0x00, isApproved) log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, by, operator) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL TRANSFER FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Equivalent to `_transfer(address(0), from, to, id)`. function _transfer(address from, address to, uint256 id) internal virtual { _transfer(address(0), from, to, id); } /// @dev Transfers token `id` from `from` to `to`. /// /// Requirements: /// /// - Token `id` must exist. /// - `from` must be the owner of the token. /// - `to` cannot be the zero address. /// - If `by` is not the zero address, /// it must be the owner of the token, or be approved to manage the token. /// /// Emits a {Transfer} event. function _transfer(address by, address from, address to, uint256 id) internal virtual { _beforeTokenTransfer(from, to, id); /// @solidity memory-safe-assembly assembly { // Clear the upper 96 bits. let bitmaskAddress := shr(96, not(0)) from := and(bitmaskAddress, from) to := and(bitmaskAddress, to) by := and(bitmaskAddress, by) // Load the ownership data. mstore(0x00, id) mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by)) let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20))) let ownershipPacked := sload(ownershipSlot) let owner := and(bitmaskAddress, ownershipPacked) // Revert if `from` is not the owner, or does not exist. if iszero(mul(owner, eq(owner, from))) { if iszero(owner) { mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`. revert(0x1c, 0x04) } mstore(0x00, 0xa1148100) // `TransferFromIncorrectOwner()`. revert(0x1c, 0x04) } // Revert if `to` is the zero address. if iszero(to) { mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`. revert(0x1c, 0x04) } // Load, check, and update the token approval. { mstore(0x00, from) let approvedAddress := sload(add(1, ownershipSlot)) // If `by` is not the zero address, do the authorization check. // Revert if the `by` is not the owner, nor approved. if iszero(or(iszero(by), or(eq(by, from), eq(by, approvedAddress)))) { if iszero(sload(keccak256(0x0c, 0x30))) { mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`. revert(0x1c, 0x04) } } // Delete the approved address if any. if approvedAddress { sstore(add(1, ownershipSlot), 0) } } // Update with the new owner. sstore(ownershipSlot, xor(ownershipPacked, xor(from, to))) // Decrement the balance of `from`. { let fromBalanceSlot := keccak256(0x0c, 0x1c) sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1)) } // Increment the balance of `to`. { mstore(0x00, to) let toBalanceSlot := keccak256(0x0c, 0x1c) let toBalanceSlotPacked := add(sload(toBalanceSlot), 1) if iszero(and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE)) { mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`. revert(0x1c, 0x04) } sstore(toBalanceSlot, toBalanceSlotPacked) } // Emit the {Transfer} event. log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id) } _afterTokenTransfer(from, to, id); } /// @dev Equivalent to `_safeTransfer(from, to, id, "")`. function _safeTransfer(address from, address to, uint256 id) internal virtual { _safeTransfer(from, to, id, ""); } /// @dev Transfers token `id` from `from` to `to`. /// /// Requirements: /// /// - Token `id` must exist. /// - `from` must be the owner of the token. /// - `to` cannot be the zero address. /// - The caller must be the owner of the token, or be approved to manage the token. /// - If `to` refers to a smart contract, it must implement /// {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. /// /// Emits a {Transfer} event. function _safeTransfer(address from, address to, uint256 id, bytes memory data) internal virtual { _transfer(address(0), from, to, id); if (_hasCode(to)) _checkOnERC721Received(from, to, id, data); } /// @dev Equivalent to `_safeTransfer(by, from, to, id, "")`. function _safeTransfer(address by, address from, address to, uint256 id) internal virtual { _safeTransfer(by, from, to, id, ""); } /// @dev Transfers token `id` from `from` to `to`. /// /// Requirements: /// /// - Token `id` must exist. /// - `from` must be the owner of the token. /// - `to` cannot be the zero address. /// - If `by` is not the zero address, /// it must be the owner of the token, or be approved to manage the token. /// - If `to` refers to a smart contract, it must implement /// {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. /// /// Emits a {Transfer} event. function _safeTransfer(address by, address from, address to, uint256 id, bytes memory data) internal virtual { _transfer(by, from, to, id); if (_hasCode(to)) _checkOnERC721Received(from, to, id, data); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* HOOKS FOR OVERRIDING */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Hook that is called before any token transfers, including minting and burning. function _beforeTokenTransfer(address from, address to, uint256 id) internal virtual {} /// @dev Hook that is called after any token transfers, including minting and burning. function _afterTokenTransfer(address from, address to, uint256 id) internal virtual {} /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PRIVATE HELPERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns if `a` has bytecode of non-zero length. function _hasCode(address a) private view returns (bool result) { /// @solidity memory-safe-assembly assembly { result := extcodesize(a) // Can handle dirty upper bits. } } /// @dev Perform a call to invoke {IERC721Receiver-onERC721Received} on `to`. /// Reverts if the target does not support the function correctly. function _checkOnERC721Received(address from, address to, uint256 id, bytes memory data) private { /// @solidity memory-safe-assembly assembly { // Prepare the calldata. let m := mload(0x40) let onERC721ReceivedSelector := 0x150b7a02 mstore(m, onERC721ReceivedSelector) mstore(add(m, 0x20), caller()) // The `operator`, which is always `msg.sender`. mstore(add(m, 0x40), shr(96, shl(96, from))) mstore(add(m, 0x60), id) mstore(add(m, 0x80), 0x80) let n := mload(data) mstore(add(m, 0xa0), n) if n { pop(staticcall(gas(), 4, add(data, 0x20), n, add(m, 0xc0), n)) } // Revert if the call reverts. if iszero(call(gas(), to, 0, add(m, 0x1c), add(n, 0xa4), m, 0x20)) { if returndatasize() { // Bubble up the revert if the call reverts. returndatacopy(0x00, 0x00, returndatasize()) revert(0x00, returndatasize()) } mstore(m, 0) } // Load the returndata and compare it. if iszero(eq(mload(m), shl(224, onERC721ReceivedSelector))) { mstore(0x00, 0xd1a57ed6) // `TransferToNonERC721ReceiverImplementer()`. revert(0x1c, 0x04) } } } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } /// @dev Returns the hexadecimal representation of `value`. /// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte. function _toHexString(address value) internal pure returns (string memory str) { str = _toHexStringNoPrefix(value); /// @solidity memory-safe-assembly assembly { let strLength := add(mload(str), 2) // Compute the length. mstore(str, 0x3078) // Write the "0x" prefix. str := sub(str, 2) // Move the pointer. mstore(str, strLength) // Write the length. } } /// @dev Returns the hexadecimal representation of `value`. /// The output is encoded using 2 hexadecimal digits per byte. function _toHexStringNoPrefix(address value) internal pure returns (string memory str) { /// @solidity memory-safe-assembly assembly { str := mload(0x40) // Allocate the memory. // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length, // 0x02 bytes for the prefix, and 0x28 bytes for the digits. // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x28) is 0x80. mstore(0x40, add(str, 0x80)) // Store "0123456789abcdef" in scratch space. mstore(0x0f, 0x30313233343536373839616263646566) str := add(str, 2) mstore(str, 40) let o := add(str, 0x20) mstore(add(o, 40), 0) value := shl(96, value) // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. for { let i := 0 } 1 { } { let p := add(o, add(i, i)) let temp := byte(i, value) mstore8(add(p, 1), mload(and(temp, 15))) mstore8(p, mload(shr(4, temp))) i := add(i, 1) if eq(i, 20) { break } } } } } /** * @dev Interface of ERC721ABurnable. */ interface IERC721Burnable { /** * @dev Burns `tokenId`. See {ERC721A-_burn}. * * Requirements: * * - The caller must own `tokenId` or be an approved operator. */ function burn(uint256 tokenId) external; } /** * @title ERC721Burnable. * * @dev ERC721 token that can be irreversibly burned (destroyed). */ abstract contract ERC721Burnable is ERC721, IERC721Burnable { /** * @dev Burns `tokenId`. See {ERC721-_burn}. * * Requirements: * * - The caller must own `tokenId` or be an approved operator. */ function burn(uint256 tokenId) public virtual override { _burn(tokenId); } } /// @notice Based on the reference implementation of the EIP-4494 /// @notice See https://github.com/dievardump/erc721-with-permits and https://eips.ethereum.org/EIPS/eip-4494 /// @author Simon Fremaux (@dievardump) & William SchwabSchwab (@wschwab) interface IERC4494 { function DOMAIN_SEPARATOR() external view returns (bytes32); /// @notice Allows to retrieve current nonce for token /// @param tokenId token id /// @return current token nonce function nonces(uint256 tokenId) external view returns (uint256); /// @notice function to be called by anyone to approve `spender` using a Permit signature /// @dev Anyone can call this to approve `spender`, even a third-party /// @param spender the actor to approve /// @param tokenId the token id /// @param deadline the deadline for the permit to be used /// @param signature permit function permit(address spender, uint256 tokenId, uint256 deadline, bytes memory signature) external; } /// @notice Contract for EIP-712 typed structured data hashing and signing. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/EIP712.sol) /// @author Modified from Solbase (https://github.com/Sol-DAO/solbase/blob/main/src/utils/EIP712.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/EIP712.sol) /// Note, this implementation: /// - Uses `address(this)` for the `verifyingContract` field. /// - Does NOT use the optional EIP-712 salt. /// - Does NOT use any EIP-712 extensions. /// This is for simplicity and to save gas. /// If you need to customize, please fork / modify accordingly. abstract contract EIP712 { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CONSTANTS AND IMMUTABLES */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev `keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")`. bytes32 internal constant _DOMAIN_TYPEHASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f; address private immutable _cachedThis; uint256 private immutable _cachedChainId; bytes32 private immutable _cachedNameHash; bytes32 private immutable _cachedVersionHash; bytes32 private immutable _cachedDomainSeparator; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CONSTRUCTOR */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Cache the hashes for cheaper runtime gas costs. /// In the case of upgradeable contracts (i.e. proxies), /// or if the chain id changes due to a hard fork, /// the domain separator will be seamlessly calculated on-the-fly. constructor() { _cachedThis = address(this); _cachedChainId = block.chainid; (string memory name, string memory version) = _domainNameAndVersion(); bytes32 nameHash = keccak256(bytes(name)); bytes32 versionHash = keccak256(bytes(version)); _cachedNameHash = nameHash; _cachedVersionHash = versionHash; bytes32 separator; /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Load the free memory pointer. mstore(m, _DOMAIN_TYPEHASH) mstore(add(m, 0x20), nameHash) mstore(add(m, 0x40), versionHash) mstore(add(m, 0x60), chainid()) mstore(add(m, 0x80), address()) separator := keccak256(m, 0xa0) } _cachedDomainSeparator = separator; } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* FUNCTIONS TO OVERRIDE */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Please override this function to return the domain name and version. /// ``` /// function _domainNameAndVersion() /// internal /// pure /// virtual /// returns (string memory name, string memory version) /// { /// name = "Solady"; /// version = "1"; /// } /// ``` function _domainNameAndVersion() internal pure virtual returns (string memory name, string memory version); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* HASHING OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the EIP-712 domain separator. function _domainSeparator() internal view virtual returns (bytes32 separator) { separator = _cachedDomainSeparator; if (_cachedDomainSeparatorInvalidated()) { separator = _buildDomainSeparator(); } } /// @dev Returns the hash of the fully encoded EIP-712 message for this domain, /// given `structHash`, as defined in /// https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct. /// /// The hash can be used together with {ECDSA-recover} to obtain the signer of a message: /// ``` /// bytes32 digest = _hashTypedData(keccak256(abi.encode( /// keccak256("Mail(address to,string contents)"), /// mailTo, /// keccak256(bytes(mailContents)) /// ))); /// address signer = ECDSA.recover(digest, signature); /// ``` function _hashTypedData(bytes32 structHash) internal view virtual returns (bytes32 digest) { bytes32 separator = _cachedDomainSeparator; if (_cachedDomainSeparatorInvalidated()) { separator = _buildDomainSeparator(); } /// @solidity memory-safe-assembly assembly { // Compute the digest. mstore(0x00, 0x1901000000000000) // Store "\x19\x01". mstore(0x1a, separator) // Store the domain separator. mstore(0x3a, structHash) // Store the struct hash. digest := keccak256(0x18, 0x42) // Restore the part of the free memory slot that was overwritten. mstore(0x3a, 0) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* EIP-5267 OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev See: https://eips.ethereum.org/EIPS/eip-5267 function eip712Domain() public view virtual returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { fields = hex"0f"; // `0b01111`. (name, version) = _domainNameAndVersion(); chainId = block.chainid; verifyingContract = address(this); salt = salt; // `bytes32(0)`. extensions = extensions; // `new uint256[](0)`. } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PRIVATE HELPERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the EIP-712 domain separator. function _buildDomainSeparator() private view returns (bytes32 separator) { bytes32 nameHash = _cachedNameHash; bytes32 versionHash = _cachedVersionHash; /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Load the free memory pointer. mstore(m, _DOMAIN_TYPEHASH) mstore(add(m, 0x20), nameHash) mstore(add(m, 0x40), versionHash) mstore(add(m, 0x60), chainid()) mstore(add(m, 0x80), address()) separator := keccak256(m, 0xa0) } } /// @dev Returns if the cached domain separator has been invalidated. function _cachedDomainSeparatorInvalidated() private view returns (bool result) { uint256 cachedChainId = _cachedChainId; address cachedThis = _cachedThis; /// @solidity memory-safe-assembly assembly { result := iszero(and(eq(chainid(), cachedChainId), eq(address(), cachedThis))) } } } /// @dev OpenZeppelin's ERC721Upgradeable extended with EIP-4494-compliant permits /// @notice Based on the reference implementation of the EIP-4494 /// @notice See https://github.com/dievardump/erc721-with-permits and https://eips.ethereum.org/EIPS/eip-4494 abstract contract ERC721Permit is IERC4494, EIP712, ERC721 { /// @dev value is equal to keccak256("Permit(address spender,uint256 tokenId,uint256 nonce,uint256 deadline)") bytes32 public constant PERMIT_TYPEHASH = 0x49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad; mapping(uint256 => uint256) internal _nonces; /// @notice Builds the DOMAIN_SEPARATOR (eip712) at time of use /// @dev This is not set as a constant, to ensure that the chainId will change in the event of a chain fork /// @return the DOMAIN_SEPARATOR of eip712 function DOMAIN_SEPARATOR() public view override returns (bytes32) { return _domainSeparator(); } /// @notice Allows to retrieve current nonce for token /// @param tokenId token id /// @return current token nonce function nonces(uint256 tokenId) public view override returns (uint256) { require(_exists(tokenId), "!EXIST"); return _nonces[tokenId]; } /// @notice function to be called by anyone to approve `spender` using a Permit signature /// @dev Anyone can call this to approve `spender`, even a third-party /// @param spender_ the actor to approve /// @param tokenId_ the token id /// @param deadline_ the deadline for the permit to be used /// @param signature_ permit function permit(address spender_, uint256 tokenId_, uint256 deadline_, bytes memory signature_) external override { require(deadline_ >= block.timestamp, "EXPRIED"); bytes32 digest = _buildDigest(spender_, tokenId_, _nonces[tokenId_], deadline_); (address recoveredAddress, ) = ECDSA.tryRecover(digest, signature_); require((recoveredAddress != address(0) && _isApprovedOrOwner(recoveredAddress, tokenId_)), "!PERMIT"); _approve(spender_, tokenId_); } /// @notice Builds the permit digest to sign /// @param spender_ the token spender /// @param tokenId_ the tokenId /// @param nonce_ the nonce to make a permit for /// @param deadline_ the deadline before when the permit can be used /// @return the digest (following eip712) to sign function _buildDigest( address spender_, uint256 tokenId_, uint256 nonce_, uint256 deadline_ ) private view returns (bytes32) { bytes32 structHash = keccak256(abi.encode(PERMIT_TYPEHASH, spender_, tokenId_, nonce_, deadline_)); return _hashTypedData(structHash); } /// @dev helper to easily increment a nonce for a given tokenId /// @param tokenId the tokenId to increment the nonce for function _incrementNonce(uint256 tokenId) internal { assembly { mstore(0x00, tokenId) mstore(0x20, _nonces.slot) let key := keccak256(0x00, 0x40) sstore(key, add(sload(key), 1)) } } function _transfer(address from_, address to_, uint256 tokenId_) internal virtual override { // increment the nonce to be sure it can't be reused _incrementNonce(tokenId_); // do normal transfer super._transfer(from_, to_, tokenId_); } } /** * @dev Interface of IERC721URIStorage. */ interface IERC721URIStorage { event NewBaseTokenURI(string baseTokenURI); function baseURI() external view returns (string memory); } /** * @dev ERC721 token with storage based token URI management. */ abstract contract ERC721URIStorage is IERC721URIStorage, ERC721 { string internal _baseUri; function baseURI() external view override returns (string memory) { return _baseURI(); } function _baseURI() internal view virtual override returns (string memory) { return _baseUri; } function _setBaseURI(string memory baseUri_) internal virtual { _baseUri = baseUri_; emit NewBaseTokenURI(baseUri_); } } interface IPresale { function setMinted(address account_, uint256 quantity_) external; } abstract contract ReentrancyGuard { error ReentrancyGuard__Locked(); uint256 private locked = 1; modifier nonReentrant() virtual { if (locked > 1) revert ReentrancyGuard__Locked(); locked = 2; _; locked = 1; } } library SafeTransferLib { /*////////////////////////////////////////////////////////////// ETH OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferETH(address to, uint256 amount) internal { bool success; /// @solidity memory-safe-assembly assembly { // Transfer the ETH and store if it succeeded or not. success := call(gas(), to, amount, 0, 0, 0, 0) } require(success, "ETH_TRANSFER_FAILED"); } /*////////////////////////////////////////////////////////////// ERC20 OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferFrom(address token, address from, address to, uint256 amount) internal { bool success; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument. mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 100, 0, 32) ) } require(success, "TRANSFER_FROM_FAILED"); } function safeTransfer(address token, address to, uint256 amount) internal { bool success; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "TRANSFER_FAILED"); } function safeApprove(address token, address to, uint256 amount) internal { bool success; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "APPROVE_FAILED"); } } contract ETH20AVATAR is ERC721, ERC721Burnable, ERC721Permit, ERC721URIStorage, Ownable, ReentrancyGuard { uint256 public constant MAX_SUPLLY = 10000; uint256 private _idCounter; address public presaleContract; /** * @dev Initializes the MyBoi NFT. * @param name_ The name of the token. * @param symbol_ The symbol of the token. * @param baseUri_ The base URI for token metadata. */ constructor( address presaleContract_, string memory name_, string memory symbol_, string memory baseUri_ ) ERC721(name_, symbol_) { _setBaseURI(baseUri_); _idCounter = 1; presaleContract = presaleContract_; } /** * @dev Checks if a given token ID exists. * @param tokenId_ The ID of the token to check. * @return A boolean indicating whether the token exists. */ function exists(uint256 tokenId_) external view returns (bool) { return _exists(tokenId_); } /** * @dev Returns the total number of tokens minted. * @return The total number of tokens minted. */ function totalMinted() external view returns (uint256) { return _idCounter - 1; } /** * @dev Sets the base token URI for token metadata. * @param baseTokenURI_ The new base token URI. */ function setBaseTokenURI(string calldata baseTokenURI_) external onlyOwner { _setBaseURI(baseTokenURI_); } function batchMint(uint256 quantity) external nonReentrant { address sender = _msgSender(); IPresale(presaleContract).setMinted(sender, quantity); uint256 tokenId = _idCounter; for (uint i = 0; i < quantity; ) { _safeMint(sender, tokenId); unchecked { ++tokenId; ++i; } } _idCounter = tokenId; } // The following functions are overrides required by Solidity. /** * @dev Transfers the ownership of a token from one address to another. * @param from_ The current owner of the token. * @param to_ The new owner of the token. * @param tokenId_ The ID of the token to transfer. */ function _transfer(address from_, address to_, uint256 tokenId_) internal override(ERC721, ERC721Permit) { super._transfer(from_, to_, tokenId_); } /** * @dev Returns the base URI for token metadata. * @return The base URI for token metadata. */ function _baseURI() internal view virtual override(ERC721, ERC721URIStorage) returns (string memory) { return _baseUri; } /** * @dev Returns the name and version of the ERC712. * @return The name and version of the contract. */ function _domainNameAndVersion() internal pure override returns (string memory, string memory) { return ("ETH20 AVATAR", "1"); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"presaleContract_","type":"address"},{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"string","name":"baseUri_","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountBalanceOverflow","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"NotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ReentrancyGuard__Locked","type":"error"},{"inputs":[],"name":"TokenAlreadyExists","type":"error"},{"inputs":[],"name":"TokenDoesNotExist","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"isApproved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"baseTokenURI","type":"string"}],"name":"NewBaseTokenURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPLLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"batchMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","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":[{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"},{"internalType":"uint256","name":"deadline_","type":"uint256"},{"internalType":"bytes","name":"signature_","type":"bytes"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"presaleContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"isApproved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseTokenURI_","type":"string"}],"name":"setBaseTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
61012060405260016005553480156200001757600080fd5b5060405162002095380380620020958339810160408190526200003a91620002ce565b306080524660a052828260008062000089604080518082018252600c81526b22aa2419181020ab20aa20a960a11b602080830191909152825180840190935260018352603160f81b9083015291565b815160209283012081519183019190912060c082905260e0819052604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8152938401929092529082015246606082015230608082015260a09020610100525060009050620000fb83826200040f565b5060016200010a82826200040f565b50505062000127620001216200016060201b60201c565b62000164565b6200013281620001b6565b5050600160065550600780546001600160a01b0319166001600160a01b039290921691909117905562000510565b3390565b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6003620001c482826200040f565b507fe506a59ac6ac58481e880869f6a02855a0a5cba4f4026cc6ee0af056c7e4283f81604051620001f69190620004db565b60405180910390a150565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620002345781810151838201526020016200021a565b50506000910152565b600082601f8301126200024f57600080fd5b81516001600160401b03808211156200026c576200026c62000201565b604051601f8301601f19908116603f0116810190828211818310171562000297576200029762000201565b81604052838152866020858801011115620002b157600080fd5b620002c484602083016020890162000217565b9695505050505050565b60008060008060808587031215620002e557600080fd5b84516001600160a01b0381168114620002fd57600080fd5b60208601519094506001600160401b03808211156200031b57600080fd5b62000329888389016200023d565b945060408701519150808211156200034057600080fd5b6200034e888389016200023d565b935060608701519150808211156200036557600080fd5b5062000374878288016200023d565b91505092959194509250565b600181811c908216806200039557607f821691505b602082108103620003b657634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200040a57600081815260208120601f850160051c81016020861015620003e55750805b601f850160051c820191505b818110156200040657828155600101620003f1565b5050505b505050565b81516001600160401b038111156200042b576200042b62000201565b62000443816200043c845462000380565b84620003bc565b602080601f8311600181146200047b5760008415620004625750858301515b600019600386901b1c1916600185901b17855562000406565b600085815260208120601f198616915b82811015620004ac578886015182559484019460019091019084016200048b565b5085821015620004cb5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020815260008251806020840152620004fc81604085016020870162000217565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161010051611b396200055c60003960008181610e3701526112cb015260006111c00152600061119a015260006111290152600061114c0152611b396000f3fe6080604052600436106101c25760003560e01c806363d9df85116100f75780638da5cb5b11610095578063b88d4fde11610064578063b88d4fde146104f5578063c87b56dd14610508578063e985e9c514610528578063f2fde38b1461055e57600080fd5b80638da5cb5b1461048d57806395d89b41146104ab578063a22cb465146104c0578063a2309ff8146104e057600080fd5b8063715018a6116100d1578063715018a614610410578063745a41bc146104255780638467be0d1461044557806384b0196e1461046557600080fd5b806363d9df85146103bb5780636c0360eb146103db57806370a08231146103f057600080fd5b806330adf81f1161016457806342966c681161013e57806342966c68146103455780634f558e79146103655780635dfb31ce146103855780636352211e1461039b57600080fd5b806330adf81f146102e95780633644e5151461031d57806342842e0e1461033257600080fd5b8063095ea7b3116101a0578063095ea7b314610273578063141a468c1461028857806323b872dd146102b657806330176e13146102c957600080fd5b806301ffc9a7146101c757806306fdde0314610219578063081812fc1461023b575b600080fd5b3480156101d357600080fd5b506102046101e2366004611527565b6301ffc9a760e09190911c9081146380ac58cd821417635b5e139f9091141790565b60405190151581526020015b60405180910390f35b34801561022557600080fd5b5061022e61057e565b60405161021091906115a1565b34801561024757600080fd5b5061025b6102563660046115b4565b610610565b6040516001600160a01b039091168152602001610210565b6102866102813660046115e4565b610653565b005b34801561029457600080fd5b506102a86102a33660046115b4565b610662565b604051908152602001610210565b6102866102c436600461160e565b6106ba565b3480156102d557600080fd5b506102866102e436600461168c565b6107d1565b3480156102f557600080fd5b506102a87f49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad81565b34801561032957600080fd5b506102a8610818565b61028661034036600461160e565b610827565b34801561035157600080fd5b506102866103603660046115b4565b610854565b34801561037157600080fd5b506102046103803660046115b4565b610860565b34801561039157600080fd5b506102a861271081565b3480156103a757600080fd5b5061025b6103b63660046115b4565b610871565b3480156103c757600080fd5b5060075461025b906001600160a01b031681565b3480156103e757600080fd5b5061022e6108af565b3480156103fc57600080fd5b506102a861040b3660046116ce565b6108b9565b34801561041c57600080fd5b506102866108f4565b34801561043157600080fd5b506102866104403660046116ff565b610908565b34801561045157600080fd5b506102866104603660046115b4565b6109d5565b34801561047157600080fd5b5061047a610a9c565b60405161021097969594939291906117d4565b34801561049957600080fd5b506004546001600160a01b031661025b565b3480156104b757600080fd5b5061022e610afc565b3480156104cc57600080fd5b506102866104db36600461186a565b610b0b565b3480156104ec57600080fd5b506102a8610b61565b6102866105033660046118a6565b610b72565b34801561051457600080fd5b5061022e6105233660046115b4565b610bcd565b34801561053457600080fd5b50610204610543366004611915565b601c52670a5a2e7a000000006008526000526030600c205490565b34801561056a57600080fd5b506102866105793660046116ce565b610c5b565b60606000805461058d90611948565b80601f01602080910402602001604051908101604052809291908181526020018280546105b990611948565b80156106065780601f106105db57610100808354040283529160200191610606565b820191906000526020600020905b8154815290600101906020018083116105e957829003601f168201915b5050505050905090565b6000818152673ec412a9852d173d60c11b601c52602081208201820180546001600160a01b03166106495763ceea21b66000526004601cfd5b6001015492915050565b61065e338383610cd1565b5050565b600061066d82610d72565b6106a75760405162461bcd60e51b81526020600482015260066024820152650851561254d560d21b60448201526064015b60405180910390fd5b5060009081526002602052604090205490565b6000818152673ec412a9852d173d60c11b3317601c52602090208101810180546001600160a01b039485169493841693811691908286148302610718578261070a5763ceea21b66000526004601cfd5b63a11481006000526004601cfd5b8461072b5763ea553b346000526004601cfd5b856000528160010154925082331486331417610759576030600c205461075957634b6e7f186000526004601cfd5b821561076757600082600101555b85851818905550601c600c8181208054600019019055600084905220805460010163ffffffff81166107a1576301336cea6000526004601cfd5b90558082847fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a45b505050565b6107d9610d94565b61065e82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610dee92505050565b6000610822610e35565b905090565b6108328383836106ba565b813b156107cc576107cc83838360405180602001604052806000815250610e6e565b61085d81610ef8565b50565b600061086b82610d72565b92915050565b6000818152673ec412a9852d173d60c11b601c526020902081018101546001600160a01b0316806108aa5763ceea21b66000526004601cfd5b919050565b6060610822610f03565b6000816108ce57638f4eb6046000526004601cfd5b673ec412a9852d173d60c11b601c528160005263ffffffff601c600c2054169050919050565b6108fc610d94565b6109066000610f12565b565b428210156109425760405162461bcd60e51b81526020600482015260076024820152661156141492515160ca1b604482015260640161069e565b60008381526002602052604081205461095f908690869086610f64565b9050600061096d8284610fe7565b5090506001600160a01b0381161580159061098d575061098d818661102c565b6109c35760405162461bcd60e51b81526020600482015260076024820152660854115493525560ca1b604482015260640161069e565b6109cd8686611098565b505050505050565b600160055411156109f95760405163c0d27a9760e01b815260040160405180910390fd5b6002600555600033600754604051634258912560e01b81526001600160a01b03808416600483015260248201869052929350911690634258912590604401600060405180830381600087803b158015610a5157600080fd5b505af1158015610a65573d6000803e3d6000fd5b50506006549150600090505b83811015610a8f57610a8383836110a4565b60019182019101610a71565b5060065550506001600555565b600f60f81b6060806000808083610aea604080518082018252600c81526b22aa2419181020ab20aa20a960a11b602080830191909152825180840190935260018352603160f81b9083015291565b97989097965046955030945091925090565b60606001805461058d90611948565b801515905081601c52670a5a2e7a0000000060085233600052806030600c2055806000528160601b60601c337f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160206000a35050565b600060016006546108229190611982565b610b7d8585856106ba565b833b15610bc657610bc685858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610e6e92505050565b5050505050565b6060610bd882610d72565b610bf55760405163677510db60e11b815260040160405180910390fd5b6000610bff610f03565b90506000815111610c1f5760405180602001604052806000815250610c54565b80610c29306110be565b610c32856110e2565b604051602001610c44939291906119a3565b6040516020818303038152906040525b9392505050565b610c63610d94565b6001600160a01b038116610cc85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161069e565b61085d81610f12565b60001960601c828116925083811693508160005283673ec412a9852d173d60c11b17601c5260206000208201820180548216915081610d185763ceea21b66000526004601cfd5b818514851517610d3e57816000526030600c2054610d3e57634b6e7f186000526004601cfd5b6001018390558183827f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600080a450505050565b6000818152673ec412a9852d173d60c11b601c52602090208101015460601b90565b6004546001600160a01b031633146109065760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161069e565b6003610dfa8282611a43565b507fe506a59ac6ac58481e880869f6a02855a0a5cba4f4026cc6ee0af056c7e4283f81604051610e2a91906115a1565b60405180910390a150565b7f0000000000000000000000000000000000000000000000000000000000000000610e5e611126565b15610e6b57610822611171565b90565b60405163150b7a028082523360208301528560601b60601c604083015283606083015260808083015282518060a08401528015610eb5578060c08401826020870160045afa505b60208360a48301601c860160008a5af1610ede573d15610ed9573d6000803e3d6000fd5b600083525b508060e01b8251146109cd5763d1a57ed66000526004601cfd5b61085d6000826111f9565b60606003805461058d90611948565b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604080517f49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad60208201526001600160a01b03861691810191909152606081018490526080810183905260a08101829052600090819060c001604051602081830303815290604052805190602001209050610fdd816112c7565b9695505050505050565b600080825160410361101d5760208301516040840151606085015160001a61101187828585611328565b94509450505050611025565b506000905060025b9250929050565b60008181526001600160a01b03928316673ec412a9852d173d60c11b8117601c526020909120820182018054919360019216806110715763ceea21b66000526004601cfd5b80851461109057806000526030600c2054611090578160010154851492505b505092915050565b61065e60008383610cd1565b61065e8282604051806020016040528060008152506113ec565b60606110c98261140a565b8051613078825260020160011990910190815292915050565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a9004806110fc5750819003601f19909101908152919050565b467f000000000000000000000000000000000000000000000000000000000000000014307f000000000000000000000000000000000000000000000000000000000000000014161590565b604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81527f000000000000000000000000000000000000000000000000000000000000000060208201527f00000000000000000000000000000000000000000000000000000000000000009181019190915246606082015230608082015260a0902090565b600061120482610871565b90505060008181526001600160a01b03928316673ec412a9852d173d60c11b8117601c52602090912082018201805491938216918261124b5763ceea21b66000526004601cfd5b8260005281600101548086148487141786151761127a576030600c205461127a57634b6e7f186000526004601cfd5b801561128857600083600101555b5082189055601c600c208054600019019055816000827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8280a4505050565b60007f00000000000000000000000000000000000000000000000000000000000000006112f2611126565b15611302576112ff611171565b90505b67190100000000000060005280601a5282603a52604260182091506000603a5250919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561135f57506000905060036113e3565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156113b3573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166113dc576000600192509250506113e3565b9150600090505b94509492505050565b6113f68383611479565b823b156107cc576107cc6000848484610e6e565b60606040519050608081016040526f30313233343536373839616263646566600f526002810190506028815260208101600060288201528260601b925060005b808101820184821a600f81165160018301538060041c518253505060018101906012190161144a575050919050565b6001600160a01b0390911690816114985763ea553b346000526004601cfd5b80600052673ec412a9852d173d60c11b601c5260206000208101810180548060601b156114cd5763c991cbb16000526004601cfd5b831790556000829052601c600c20805460010163ffffffff81166114f9576301336cea6000526004601cfd5b9055808260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a45050565b60006020828403121561153957600080fd5b81356001600160e01b031981168114610c5457600080fd5b60005b8381101561156c578181015183820152602001611554565b50506000910152565b6000815180845261158d816020860160208601611551565b601f01601f19169290920160200192915050565b602081526000610c546020830184611575565b6000602082840312156115c657600080fd5b5035919050565b80356001600160a01b03811681146108aa57600080fd5b600080604083850312156115f757600080fd5b611600836115cd565b946020939093013593505050565b60008060006060848603121561162357600080fd5b61162c846115cd565b925061163a602085016115cd565b9150604084013590509250925092565b60008083601f84011261165c57600080fd5b50813567ffffffffffffffff81111561167457600080fd5b60208301915083602082850101111561102557600080fd5b6000806020838503121561169f57600080fd5b823567ffffffffffffffff8111156116b657600080fd5b6116c28582860161164a565b90969095509350505050565b6000602082840312156116e057600080fd5b610c54826115cd565b634e487b7160e01b600052604160045260246000fd5b6000806000806080858703121561171557600080fd5b61171e856115cd565b93506020850135925060408501359150606085013567ffffffffffffffff8082111561174957600080fd5b818701915087601f83011261175d57600080fd5b81358181111561176f5761176f6116e9565b604051601f8201601f19908116603f01168101908382118183101715611797576117976116e9565b816040528281528a60208487010111156117b057600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60ff60f81b881681526000602060e0818401526117f460e084018a611575565b8381036040850152611806818a611575565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b818110156118585783518352928401929184019160010161183c565b50909c9b505050505050505050505050565b6000806040838503121561187d57600080fd5b611886836115cd565b91506020830135801515811461189b57600080fd5b809150509250929050565b6000806000806000608086880312156118be57600080fd5b6118c7866115cd565b94506118d5602087016115cd565b935060408601359250606086013567ffffffffffffffff8111156118f857600080fd5b6119048882890161164a565b969995985093965092949392505050565b6000806040838503121561192857600080fd5b611931836115cd565b915061193f602084016115cd565b90509250929050565b600181811c9082168061195c57607f821691505b60208210810361197c57634e487b7160e01b600052602260045260246000fd5b50919050565b8181038181111561086b57634e487b7160e01b600052601160045260246000fd5b600084516119b5818460208901611551565b8083019050602f60f81b80825285516119d5816001850160208a01611551565b600192019182015283516119f0816002840160208801611551565b0160020195945050505050565b601f8211156107cc57600081815260208120601f850160051c81016020861015611a245750805b601f850160051c820191505b818110156109cd57828155600101611a30565b815167ffffffffffffffff811115611a5d57611a5d6116e9565b611a7181611a6b8454611948565b846119fd565b602080601f831160018114611aa65760008415611a8e5750858301515b600019600386901b1c1916600185901b1785556109cd565b600085815260208120601f198616915b82811015611ad557888601518255948401946001909101908401611ab6565b5085821015611af35787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220a738f2a03f1e06d7014654e59d2b6af7702dc9f199cfeea9592e8d0fa409800764736f6c6343000813003300000000000000000000000081e9ab34d332b51465fdddbd328fbd3134408892000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000c455448323020415641544152000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084554483230415654000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002368747470733a2f2f6170692e6574683230746f6b656e2e636f6d2f6d657461646174610000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106101c25760003560e01c806363d9df85116100f75780638da5cb5b11610095578063b88d4fde11610064578063b88d4fde146104f5578063c87b56dd14610508578063e985e9c514610528578063f2fde38b1461055e57600080fd5b80638da5cb5b1461048d57806395d89b41146104ab578063a22cb465146104c0578063a2309ff8146104e057600080fd5b8063715018a6116100d1578063715018a614610410578063745a41bc146104255780638467be0d1461044557806384b0196e1461046557600080fd5b806363d9df85146103bb5780636c0360eb146103db57806370a08231146103f057600080fd5b806330adf81f1161016457806342966c681161013e57806342966c68146103455780634f558e79146103655780635dfb31ce146103855780636352211e1461039b57600080fd5b806330adf81f146102e95780633644e5151461031d57806342842e0e1461033257600080fd5b8063095ea7b3116101a0578063095ea7b314610273578063141a468c1461028857806323b872dd146102b657806330176e13146102c957600080fd5b806301ffc9a7146101c757806306fdde0314610219578063081812fc1461023b575b600080fd5b3480156101d357600080fd5b506102046101e2366004611527565b6301ffc9a760e09190911c9081146380ac58cd821417635b5e139f9091141790565b60405190151581526020015b60405180910390f35b34801561022557600080fd5b5061022e61057e565b60405161021091906115a1565b34801561024757600080fd5b5061025b6102563660046115b4565b610610565b6040516001600160a01b039091168152602001610210565b6102866102813660046115e4565b610653565b005b34801561029457600080fd5b506102a86102a33660046115b4565b610662565b604051908152602001610210565b6102866102c436600461160e565b6106ba565b3480156102d557600080fd5b506102866102e436600461168c565b6107d1565b3480156102f557600080fd5b506102a87f49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad81565b34801561032957600080fd5b506102a8610818565b61028661034036600461160e565b610827565b34801561035157600080fd5b506102866103603660046115b4565b610854565b34801561037157600080fd5b506102046103803660046115b4565b610860565b34801561039157600080fd5b506102a861271081565b3480156103a757600080fd5b5061025b6103b63660046115b4565b610871565b3480156103c757600080fd5b5060075461025b906001600160a01b031681565b3480156103e757600080fd5b5061022e6108af565b3480156103fc57600080fd5b506102a861040b3660046116ce565b6108b9565b34801561041c57600080fd5b506102866108f4565b34801561043157600080fd5b506102866104403660046116ff565b610908565b34801561045157600080fd5b506102866104603660046115b4565b6109d5565b34801561047157600080fd5b5061047a610a9c565b60405161021097969594939291906117d4565b34801561049957600080fd5b506004546001600160a01b031661025b565b3480156104b757600080fd5b5061022e610afc565b3480156104cc57600080fd5b506102866104db36600461186a565b610b0b565b3480156104ec57600080fd5b506102a8610b61565b6102866105033660046118a6565b610b72565b34801561051457600080fd5b5061022e6105233660046115b4565b610bcd565b34801561053457600080fd5b50610204610543366004611915565b601c52670a5a2e7a000000006008526000526030600c205490565b34801561056a57600080fd5b506102866105793660046116ce565b610c5b565b60606000805461058d90611948565b80601f01602080910402602001604051908101604052809291908181526020018280546105b990611948565b80156106065780601f106105db57610100808354040283529160200191610606565b820191906000526020600020905b8154815290600101906020018083116105e957829003601f168201915b5050505050905090565b6000818152673ec412a9852d173d60c11b601c52602081208201820180546001600160a01b03166106495763ceea21b66000526004601cfd5b6001015492915050565b61065e338383610cd1565b5050565b600061066d82610d72565b6106a75760405162461bcd60e51b81526020600482015260066024820152650851561254d560d21b60448201526064015b60405180910390fd5b5060009081526002602052604090205490565b6000818152673ec412a9852d173d60c11b3317601c52602090208101810180546001600160a01b039485169493841693811691908286148302610718578261070a5763ceea21b66000526004601cfd5b63a11481006000526004601cfd5b8461072b5763ea553b346000526004601cfd5b856000528160010154925082331486331417610759576030600c205461075957634b6e7f186000526004601cfd5b821561076757600082600101555b85851818905550601c600c8181208054600019019055600084905220805460010163ffffffff81166107a1576301336cea6000526004601cfd5b90558082847fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a45b505050565b6107d9610d94565b61065e82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610dee92505050565b6000610822610e35565b905090565b6108328383836106ba565b813b156107cc576107cc83838360405180602001604052806000815250610e6e565b61085d81610ef8565b50565b600061086b82610d72565b92915050565b6000818152673ec412a9852d173d60c11b601c526020902081018101546001600160a01b0316806108aa5763ceea21b66000526004601cfd5b919050565b6060610822610f03565b6000816108ce57638f4eb6046000526004601cfd5b673ec412a9852d173d60c11b601c528160005263ffffffff601c600c2054169050919050565b6108fc610d94565b6109066000610f12565b565b428210156109425760405162461bcd60e51b81526020600482015260076024820152661156141492515160ca1b604482015260640161069e565b60008381526002602052604081205461095f908690869086610f64565b9050600061096d8284610fe7565b5090506001600160a01b0381161580159061098d575061098d818661102c565b6109c35760405162461bcd60e51b81526020600482015260076024820152660854115493525560ca1b604482015260640161069e565b6109cd8686611098565b505050505050565b600160055411156109f95760405163c0d27a9760e01b815260040160405180910390fd5b6002600555600033600754604051634258912560e01b81526001600160a01b03808416600483015260248201869052929350911690634258912590604401600060405180830381600087803b158015610a5157600080fd5b505af1158015610a65573d6000803e3d6000fd5b50506006549150600090505b83811015610a8f57610a8383836110a4565b60019182019101610a71565b5060065550506001600555565b600f60f81b6060806000808083610aea604080518082018252600c81526b22aa2419181020ab20aa20a960a11b602080830191909152825180840190935260018352603160f81b9083015291565b97989097965046955030945091925090565b60606001805461058d90611948565b801515905081601c52670a5a2e7a0000000060085233600052806030600c2055806000528160601b60601c337f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160206000a35050565b600060016006546108229190611982565b610b7d8585856106ba565b833b15610bc657610bc685858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610e6e92505050565b5050505050565b6060610bd882610d72565b610bf55760405163677510db60e11b815260040160405180910390fd5b6000610bff610f03565b90506000815111610c1f5760405180602001604052806000815250610c54565b80610c29306110be565b610c32856110e2565b604051602001610c44939291906119a3565b6040516020818303038152906040525b9392505050565b610c63610d94565b6001600160a01b038116610cc85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161069e565b61085d81610f12565b60001960601c828116925083811693508160005283673ec412a9852d173d60c11b17601c5260206000208201820180548216915081610d185763ceea21b66000526004601cfd5b818514851517610d3e57816000526030600c2054610d3e57634b6e7f186000526004601cfd5b6001018390558183827f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600080a450505050565b6000818152673ec412a9852d173d60c11b601c52602090208101015460601b90565b6004546001600160a01b031633146109065760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161069e565b6003610dfa8282611a43565b507fe506a59ac6ac58481e880869f6a02855a0a5cba4f4026cc6ee0af056c7e4283f81604051610e2a91906115a1565b60405180910390a150565b7f08460449486f80fb8f43820cd0bb31017393173539fa6bc7d0721841d47f8e42610e5e611126565b15610e6b57610822611171565b90565b60405163150b7a028082523360208301528560601b60601c604083015283606083015260808083015282518060a08401528015610eb5578060c08401826020870160045afa505b60208360a48301601c860160008a5af1610ede573d15610ed9573d6000803e3d6000fd5b600083525b508060e01b8251146109cd5763d1a57ed66000526004601cfd5b61085d6000826111f9565b60606003805461058d90611948565b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604080517f49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad60208201526001600160a01b03861691810191909152606081018490526080810183905260a08101829052600090819060c001604051602081830303815290604052805190602001209050610fdd816112c7565b9695505050505050565b600080825160410361101d5760208301516040840151606085015160001a61101187828585611328565b94509450505050611025565b506000905060025b9250929050565b60008181526001600160a01b03928316673ec412a9852d173d60c11b8117601c526020909120820182018054919360019216806110715763ceea21b66000526004601cfd5b80851461109057806000526030600c2054611090578160010154851492505b505092915050565b61065e60008383610cd1565b61065e8282604051806020016040528060008152506113ec565b60606110c98261140a565b8051613078825260020160011990910190815292915050565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a9004806110fc5750819003601f19909101908152919050565b467f000000000000000000000000000000000000000000000000000000000000000114307f000000000000000000000000ccac2d3d3e42f63a875185c71e0bde6318ec2d5414161590565b604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81527f478afbe3c1b494538cae422e625e9a5660b93570a476df534b896eaf38daadd560208201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc69181019190915246606082015230608082015260a0902090565b600061120482610871565b90505060008181526001600160a01b03928316673ec412a9852d173d60c11b8117601c52602090912082018201805491938216918261124b5763ceea21b66000526004601cfd5b8260005281600101548086148487141786151761127a576030600c205461127a57634b6e7f186000526004601cfd5b801561128857600083600101555b5082189055601c600c208054600019019055816000827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8280a4505050565b60007f08460449486f80fb8f43820cd0bb31017393173539fa6bc7d0721841d47f8e426112f2611126565b15611302576112ff611171565b90505b67190100000000000060005280601a5282603a52604260182091506000603a5250919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561135f57506000905060036113e3565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156113b3573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166113dc576000600192509250506113e3565b9150600090505b94509492505050565b6113f68383611479565b823b156107cc576107cc6000848484610e6e565b60606040519050608081016040526f30313233343536373839616263646566600f526002810190506028815260208101600060288201528260601b925060005b808101820184821a600f81165160018301538060041c518253505060018101906012190161144a575050919050565b6001600160a01b0390911690816114985763ea553b346000526004601cfd5b80600052673ec412a9852d173d60c11b601c5260206000208101810180548060601b156114cd5763c991cbb16000526004601cfd5b831790556000829052601c600c20805460010163ffffffff81166114f9576301336cea6000526004601cfd5b9055808260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a45050565b60006020828403121561153957600080fd5b81356001600160e01b031981168114610c5457600080fd5b60005b8381101561156c578181015183820152602001611554565b50506000910152565b6000815180845261158d816020860160208601611551565b601f01601f19169290920160200192915050565b602081526000610c546020830184611575565b6000602082840312156115c657600080fd5b5035919050565b80356001600160a01b03811681146108aa57600080fd5b600080604083850312156115f757600080fd5b611600836115cd565b946020939093013593505050565b60008060006060848603121561162357600080fd5b61162c846115cd565b925061163a602085016115cd565b9150604084013590509250925092565b60008083601f84011261165c57600080fd5b50813567ffffffffffffffff81111561167457600080fd5b60208301915083602082850101111561102557600080fd5b6000806020838503121561169f57600080fd5b823567ffffffffffffffff8111156116b657600080fd5b6116c28582860161164a565b90969095509350505050565b6000602082840312156116e057600080fd5b610c54826115cd565b634e487b7160e01b600052604160045260246000fd5b6000806000806080858703121561171557600080fd5b61171e856115cd565b93506020850135925060408501359150606085013567ffffffffffffffff8082111561174957600080fd5b818701915087601f83011261175d57600080fd5b81358181111561176f5761176f6116e9565b604051601f8201601f19908116603f01168101908382118183101715611797576117976116e9565b816040528281528a60208487010111156117b057600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60ff60f81b881681526000602060e0818401526117f460e084018a611575565b8381036040850152611806818a611575565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b818110156118585783518352928401929184019160010161183c565b50909c9b505050505050505050505050565b6000806040838503121561187d57600080fd5b611886836115cd565b91506020830135801515811461189b57600080fd5b809150509250929050565b6000806000806000608086880312156118be57600080fd5b6118c7866115cd565b94506118d5602087016115cd565b935060408601359250606086013567ffffffffffffffff8111156118f857600080fd5b6119048882890161164a565b969995985093965092949392505050565b6000806040838503121561192857600080fd5b611931836115cd565b915061193f602084016115cd565b90509250929050565b600181811c9082168061195c57607f821691505b60208210810361197c57634e487b7160e01b600052602260045260246000fd5b50919050565b8181038181111561086b57634e487b7160e01b600052601160045260246000fd5b600084516119b5818460208901611551565b8083019050602f60f81b80825285516119d5816001850160208a01611551565b600192019182015283516119f0816002840160208801611551565b0160020195945050505050565b601f8211156107cc57600081815260208120601f850160051c81016020861015611a245750805b601f850160051c820191505b818110156109cd57828155600101611a30565b815167ffffffffffffffff811115611a5d57611a5d6116e9565b611a7181611a6b8454611948565b846119fd565b602080601f831160018114611aa65760008415611a8e5750858301515b600019600386901b1c1916600185901b1785556109cd565b600085815260208120601f198616915b82811015611ad557888601518255948401946001909101908401611ab6565b5085821015611af35787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220a738f2a03f1e06d7014654e59d2b6af7702dc9f199cfeea9592e8d0fa409800764736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000081e9ab34d332b51465fdddbd328fbd3134408892000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000c455448323020415641544152000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084554483230415654000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002368747470733a2f2f6170692e6574683230746f6b656e2e636f6d2f6d657461646174610000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : presaleContract_ (address): 0x81e9Ab34D332b51465fDDdbd328fbd3134408892
Arg [1] : name_ (string): ETH20 AVATAR
Arg [2] : symbol_ (string): ETH20AVT
Arg [3] : baseUri_ (string): https://api.eth20token.com/metadata
-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 00000000000000000000000081e9ab34d332b51465fdddbd328fbd3134408892
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [4] : 000000000000000000000000000000000000000000000000000000000000000c
Arg [5] : 4554483230204156415441520000000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [7] : 4554483230415654000000000000000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000023
Arg [9] : 68747470733a2f2f6170692e6574683230746f6b656e2e636f6d2f6d65746164
Arg [10] : 6174610000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
92610:2977:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44516:387;;;;;;;;;;-1:-1:-1;44516:387:0;;;;;:::i;:::-;44834:10;44697:3;44693:21;;;;44828:17;;;44853:10;44847:17;;44825:40;44873:10;44867:17;;;44822:63;;44516:387;;;;470:14:1;;463:22;445:41;;433:2;418:18;44516:387:0;;;;;;;;34903:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;37546:553::-;;;;;;;;;;-1:-1:-1;37546:553:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1602:32:1;;;1584:51;;1572:2;1557:18;37546:553:0;1438:203:1;38402:121:0;;;;;;:::i;:::-;;:::i;:::-;;83345:160;;;;;;;;;;-1:-1:-1;83345:160:0;;;;;:::i;:::-;;:::i;:::-;;;2229:25:1;;;2217:2;2202:18;83345:160:0;2083:177:1;40189:3097:0;;;;;;:::i;:::-;;:::i;93993:120::-;;;;;;;;;;-1:-1:-1;93993:120:0;;;;;:::i;:::-;;:::i;82696:108::-;;;;;;;;;;-1:-1:-1;82696:108:0;82738:66;82696:108;;83096:111;;;;;;;;;;;;;:::i;43360:201::-;;;;;;:::i;:::-;;:::i;73158:88::-;;;;;;;;;;-1:-1:-1;73158:88:0;;;;;:::i;:::-;;:::i;93523:106::-;;;;;;;;;;-1:-1:-1;93523:106:0;;;;;:::i;:::-;;:::i;92722:42::-;;;;;;;;;;;;92759:5;92722:42;;36370:341;;;;;;;;;;-1:-1:-1;36370:341:0;;;;;:::i;:::-;;:::i;92804:30::-;;;;;;;;;;-1:-1:-1;92804:30:0;;;;-1:-1:-1;;;;;92804:30:0;;;86090:102;;;;;;;;;;;;;:::i;36861:545::-;;;;;;;;;;-1:-1:-1;36861:545:0;;;;;:::i;:::-;;:::i;2588:103::-;;;;;;;;;;;;;:::i;83867:507::-;;;;;;;;;;-1:-1:-1;83867:507:0;;;;;:::i;:::-;;:::i;94121:429::-;;;;;;;;;;-1:-1:-1;94121:429:0;;;;;:::i;:::-;;:::i;80265:616::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;1947:87::-;;;;;;;;;;-1:-1:-1;2020:6:0;;-1:-1:-1;;;;;2020:6:0;1947:87;;35053:95;;;;;;;;;;;;;:::i;39125:697::-;;;;;;;;;;-1:-1:-1;39125:697:0;;;;;:::i;:::-;;:::i;93762:95::-;;;;;;;;;;;;;:::i;44078:224::-;;;;;;:::i;:::-;;:::i;35232:384::-;;;;;;;;;;-1:-1:-1;35232:384:0;;;;;:::i;:::-;;:::i;38617:364::-;;;;;;;;;;-1:-1:-1;38617:364:0;;;;;:::i;:::-;38804:4;38797:22;38846:31;38840:4;38833:45;38705:11;38892:19;38957:4;38951;38941:21;38935:28;;38617:364;2846:201;;;;;;;;;;-1:-1:-1;2846:201:0;;;;;:::i;:::-;;:::i;34903:91::-;34948:13;34981:5;34974:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34903:91;:::o;37546:553::-;37608:14;37703:16;;;-1:-1:-1;;;37740:4:0;37733:38;37838:4;37822:21;;37814:30;;37806:39;;37885:20;;-1:-1:-1;;;;;37869:38:0;37859:170;;37941:10;37935:4;37928:24;38009:4;38003;37996:18;37859:170;38063:1;38059:21;38053:28;;37546:553;-1:-1:-1;;37546:553:0:o;38402:121::-;38482:33;38491:10;38503:7;38512:2;38482:8;:33::i;:::-;38402:121;;:::o;83345:160::-;83408:7;83436:16;83444:7;83436;:16::i;:::-;83428:35;;;;-1:-1:-1;;;83428:35:0;;8109:2:1;83428:35:0;;;8091:21:1;8148:1;8128:18;;;8121:29;-1:-1:-1;;;8166:18:1;;;8159:36;8212:18;;83428:35:0;;;;;;;;;-1:-1:-1;83481:16:0;;;;:7;:16;;;;;;;83345:160::o;40189:3097::-;40471:1;40619:16;;;-1:-1:-1;;;40691:8:0;40662:38;40656:4;40649:52;40768:4;40752:21;;40744:30;;40736:39;;40812:20;;-1:-1:-1;;;;;40496:25:0;;;;40541:23;;;;40859:36;;;40736:39;41000:15;;;40989:27;;40979:335;;41047:5;41037:149;;41090:10;41084:4;41077:24;41162:4;41156;41149:18;41037:149;41217:10;41211:4;41204:24;41294:4;41288;41281:18;40979:335;41390:2;41380:138;;41426:10;41420:4;41413:24;41498:4;41492;41485:18;41380:138;41624:4;41618;41611:18;41683:13;41680:1;41676:21;41670:28;41647:51;;41835:15;41825:8;41822:29;41815:4;41805:8;41802:18;41799:53;41789:293;;41909:4;41903;41893:21;41887:28;41877:186;;41957:10;41951:4;41944:24;42035:4;42029;42022:18;41877:186;42159:15;42156:93;;;42228:1;42212:13;42209:1;42205:21;42198:32;42156:93;42364:13;;;42343:35;42321:58;;-1:-1:-1;42500:4:0;42494;42484:21;;;42551:22;;-1:-1:-1;;42547:30:0;42523:55;;-1:-1:-1;42673:16:0;;;42728:21;42798:20;;42575:1;42794:28;42875:20;42850:46;;42840:195;;42934:10;42928:4;42921:24;43011:4;43005;42998:18;42840:195;43053:42;;43221:2;43217;43211:4;43184:25;43178:4;;43167:57;43245:33;40189:3097;;;:::o;93993:120::-;1833:13;:11;:13::i;:::-;94079:26:::1;94091:13;;94079:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;94079:11:0::1;::::0;-1:-1:-1;;;94079:26:0:i:1;83096:111::-:0;83154:7;83181:18;:16;:18::i;:::-;83174:25;;83096:111;:::o;43360:201::-;43458:26;43471:4;43477:2;43481;43458:12;:26::i;:::-;66808:14;;43495:58;;;43513:40;43536:4;43542:2;43546;43513:40;;;;;;;;;;;;:22;:40::i;73158:88::-;73224:14;73230:7;73224:5;:14::i;:::-;73158:88;:::o;93523:106::-;93580:4;93604:17;93612:8;93604:7;:17::i;:::-;93597:24;93523:106;-1:-1:-1;;93523:106:0:o;36370:341::-;36428:14;45854:16;;;-1:-1:-1;;;45891:4:0;45884:38;46000:4;45984:21;;45976:30;;45968:39;;45962:46;-1:-1:-1;;;;;45946:64:0;;36555:138;;36605:10;36599:4;36592:24;36673:4;36667;36660:18;36555:138;36370:341;;;:::o;86090:102::-;86141:13;86174:10;:8;:10::i;36861:545::-;36924:14;37088:5;37078:146;;37127:10;37121:4;37114:24;37204:4;37198;37191:18;37078:146;-1:-1:-1;;;37245:4:0;37238:38;37303:5;37297:4;37290:19;37367:20;37359:4;37353;37343:21;37337:28;37333:55;37323:65;;36861:545;;;:::o;2588:103::-;1833:13;:11;:13::i;:::-;2653:30:::1;2680:1;2653:18;:30::i;:::-;2588:103::o:0;83867:507::-;84013:15;84000:9;:28;;83992:48;;;;-1:-1:-1;;;83992:48:0;;8443:2:1;83992:48:0;;;8425:21:1;8482:1;8462:18;;;8455:29;-1:-1:-1;;;8500:18:1;;;8493:37;8547:18;;83992:48:0;8241:330:1;83992:48:0;84053:14;84103:17;;;:7;:17;;;;;;84070:62;;84083:8;;84093;;84122:9;84070:12;:62::i;:::-;84053:79;;84146:24;84176:36;84193:6;84201:10;84176:16;:36::i;:::-;-1:-1:-1;84145:67:0;-1:-1:-1;;;;;;84232:30:0;;;;;;:80;;;84266:46;84285:16;84303:8;84266:18;:46::i;:::-;84223:102;;;;-1:-1:-1;;;84223:102:0;;8778:2:1;84223:102:0;;;8760:21:1;8817:1;8797:18;;;8790:29;-1:-1:-1;;;8835:18:1;;;8828:37;8882:18;;84223:102:0;8576:330:1;84223:102:0;84338:28;84347:8;84357;84338;:28::i;:::-;83981:393;;83867:507;;;;:::o;94121:429::-;86733:1;86724:6;;:10;86720:48;;;86743:25;;-1:-1:-1;;;86743:25:0;;;;;;;;;;;86720:48;86790:1;86781:6;:10;94191:14:::1;736:10:::0;94240:15:::1;::::0;94231:53:::1;::::0;-1:-1:-1;;;94231:53:0;;-1:-1:-1;;;;;9103:32:1;;;94231:53:0::1;::::0;::::1;9085:51:1::0;9152:18;;;9145:34;;;94191:29:0;;-1:-1:-1;94240:15:0;::::1;::::0;94231:35:::1;::::0;9058:18:1;;94231:53:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;94313:10:0::1;::::0;;-1:-1:-1;94295:15:0::1;::::0;-1:-1:-1;94336:176:0::1;94357:8;94353:1;:12;94336:176;;;94384:26;94394:6;94402:7;94384:9;:26::i;:::-;94454:9;::::0;;::::1;::::0;94482:3:::1;94336:176;;;-1:-1:-1::0;94522:10:0::1;:20:::0;-1:-1:-1;;86827:1:0;86818:6;:10;94121:429::o;80265:616::-;-1:-1:-1;;;80396:18:0;;80368:13;;;80396:18;80676:23;95548:28;;;;;;;;;;;-1:-1:-1;;;95548:28:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;95548:28:0;;;;;95442:142;80676:23;80265:616;;80658:41;;;-1:-1:-1;80720:13:0;;-1:-1:-1;80772:4:0;;-1:-1:-1;80265:616:0;;-1:-1:-1;80265:616:0;:::o;35053:95::-;35100:13;35133:7;35126:14;;;;;:::i;39125:697::-;39344:10;39337:18;39330:26;39316:40;;39455:8;39449:4;39442:22;39491:31;39485:4;39478:45;39550:8;39544:4;39537:22;39603:10;39596:4;39590;39580:21;39573:41;39690:10;39684:4;39677:24;39793:8;39789:2;39785:17;39781:2;39777:26;39767:8;39732:33;39726:4;39720;39715:89;39125:697;;:::o;93762:95::-;93808:7;93848:1;93835:10;;:14;;;;:::i;44078:224::-;44197:26;44210:4;44216:2;44220;44197:12;:26::i;:::-;66808:14;;44234:60;;;44252:42;44275:4;44281:2;44285;44289:4;;44252:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44252:22:0;;-1:-1:-1;;;44252:42:0:i;:::-;44078:224;;;;;:::o;35232:384::-;35296:13;35327:16;35335:7;35327;:16::i;:::-;35322:49;;35352:19;;-1:-1:-1;;;35352:19:0;;;;;;;;;;;35322:49;35384:21;35408:10;:8;:10::i;:::-;35384:34;;35473:1;35455:7;35449:21;:25;:159;;;;;;;;;;;;;;;;;35518:7;35532:27;35553:4;35532:12;:27::i;:::-;35566:18;35576:7;35566:9;:18::i;:::-;35501:84;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;35449:159;35429:179;35232:384;-1:-1:-1;;;35232:384:0:o;2846:201::-;1833:13;:11;:13::i;:::-;-1:-1:-1;;;;;2935:22:0;::::1;2927:73;;;::::0;-1:-1:-1;;;2927:73:0;;10626:2:1;2927:73:0::1;::::0;::::1;10608:21:1::0;10665:2;10645:18;;;10638:30;10704:34;10684:18;;;10677:62;-1:-1:-1;;;10755:18:1;;;10748:36;10801:19;;2927:73:0::1;10424:402:1::0;2927:73:0::1;3011:28;3030:8;3011:18;:28::i;57175:1466::-:0;57361:1;57357:6;57353:2;57349:15;57409:7;57393:14;57389:28;57378:39;;57457:2;57441:14;57437:23;57431:29;;57532:2;57526:4;57519:16;57591:2;-1:-1:-1;;;57562:32:0;57556:4;57549:46;57662:4;57656;57646:21;57642:2;57638:30;57634:2;57630:39;57722:13;57716:20;57700:14;57696:41;57683:54;;57813:5;57803:137;;57852:10;57846:4;57839:24;57920:4;57914;57907:18;57803:137;58126:5;58122:2;58119:13;58114:2;58107:10;58104:29;58094:286;;58167:5;58161:4;58154:19;58223:4;58217;58207:21;58201:28;58191:174;;58267:10;58261:4;58254:24;58341:4;58335;58328:18;58191:174;58476:1;58472:21;58465:38;;;58620:2;58495:7;58604:5;58577:25;58571:4;;58560:63;;57175:1466;;;:::o;45242:317::-;45302:11;45394:16;;;-1:-1:-1;;;45431:4:0;45424:38;45532:4;45516:21;;45508:30;;45500:39;45494:46;45490:2;45486:55;;45242:317::o;2112:132::-;2020:6;;-1:-1:-1;;;;;2020:6:0;736:10;2176:23;2168:68;;;;-1:-1:-1;;;2168:68:0;;11033:2:1;2168:68:0;;;11015:21:1;;;11052:18;;;11045:30;11111:34;11091:18;;;11084:62;11163:18;;2168:68:0;10831:356:1;86317:141:0;86390:8;:19;86401:8;86390;:19;:::i;:::-;;86425:25;86441:8;86425:25;;;;;;:::i;:::-;;;;;;;;86317:141;:::o;78313:244::-;78414:22;78451:35;:33;:35::i;:::-;78447:103;;;78515:23;:21;:23::i;78447:103::-;78313:244;:::o;67035:1452::-;67264:4;67258:11;67315:10;67349:24;67346:1;67339:35;67409:8;67402:4;67399:1;67395:12;67388:30;67518:4;67514:2;67510:13;67506:2;67502:22;67495:4;67492:1;67488:12;67481:44;67560:2;67553:4;67550:1;67546:12;67539:24;67598:4;67591;67588:1;67584:12;67577:26;67632:4;67626:11;67672:1;67665:4;67662:1;67658:12;67651:23;67691:1;67688:101;;;67771:1;67764:4;67761:1;67757:12;67754:1;67747:4;67741;67737:15;67734:1;67727:5;67716:57;67712:62;67688:101;67907:4;67904:1;67897:4;67894:1;67890:12;67883:4;67880:1;67876:12;67873:1;67869:2;67862:5;67857:55;67847:355;;67936:16;67933:224;;;68069:16;68063:4;68057;68042:44;68121:16;68115:4;68108:30;67933:224;68185:1;68182;68175:12;67847:355;;68300:24;68295:3;68291:34;68287:1;68281:8;68278:48;68268:201;;68360:10;68354:4;68347:24;68449:4;68443;68436:18;51999:84;52054:21;52068:1;52072:2;52054:5;:21::i;95170:135::-;95256:13;95289:8;95282:15;;;;;:::i;3207:191::-;3300:6;;;-1:-1:-1;;;;;3317:17:0;;;-1:-1:-1;;;;;;3317:17:0;;;;;;;3350:40;;3300:6;;;3317:17;3300:6;;3350:40;;3281:16;;3350:40;3270:128;3207:191;:::o;84695:328::-;84904:66;;;82738;84904;;;13655:25:1;-1:-1:-1;;;;;13716:32:1;;13696:18;;;13689:60;;;;13765:18;;;13758:34;;;13808:18;;;13801:34;;;13851:19;;;13844:35;;;84853:7:0;;;;13627:19:1;;84904:66:0;;;;;;;;;;;;84894:77;;;;;;84873:98;;84989:26;85004:10;84989:14;:26::i;:::-;84982:33;84695:328;-1:-1:-1;;;;;;84695:328:0:o;22270:747::-;22351:7;22360:12;22389:9;:16;22409:2;22389:22;22385:625;;22733:4;22718:20;;22712:27;22783:4;22768:20;;22762:27;22841:4;22826:20;;22820:27;22428:9;22812:36;22884:25;22895:4;22812:36;22712:27;22762;22884:10;:25::i;:::-;22877:32;;;;;;;;;22385:625;-1:-1:-1;22958:1:0;;-1:-1:-1;22962:35:0;22385:625;22270:747;;;;;:::o;55046:1131::-;55134:11;55383:16;;;-1:-1:-1;;;;;55303:25:0;;;-1:-1:-1;;;55426:37:0;;55420:4;55413:51;55531:4;55515:21;;;55507:30;;55499:39;;55581:20;;55303:25;;55236:1;;55565:38;;55669:137;;55718:10;55712:4;55705:24;55786:4;55780;55773:18;55669:137;55893:5;55884:7;55881:18;55871:288;;55933:5;55927:4;55920:19;56043:4;56037;56027:21;56021:28;56011:133;;56109:13;56106:1;56102:21;56096:28;56087:7;56084:41;56074:51;;56011:133;55871:288;;55046:1131;;;;:::o;56731:116::-;56806:33;56823:1;56827:7;56836:2;56806:8;:33::i;50998:100::-;51069:21;51079:2;51083;51069:21;;;;;;;;;;;;:9;:21::i;70498:447::-;70558:17;70594:27;70615:5;70594:20;:27::i;:::-;70721:10;;70784:6;70772:19;;70733:1;70717:18;-1:-1:-1;;70838:11:0;;;70884:22;;;70838:11;70498:447;-1:-1:-1;;70498:447:0:o;68589:1745::-;68654:17;69088:4;69081;69075:11;69071:22;69180:1;69174:4;69167:15;69255:4;69252:1;69248:12;69241:19;;;69337:1;69332:3;69325:14;69441:3;69680:5;69662:428;69728:1;69723:3;69719:11;69712:18;;69899:2;69893:4;69889:13;69885:2;69881:22;69876:3;69868:36;69993:2;69983:13;;70050:25;69662:428;70050:25;-1:-1:-1;70120:13:0;;;-1:-1:-1;;70235:14:0;;;70297:19;;;70235:14;68589:1745;-1:-1:-1;68589:1745:0:o;81898:347::-;82173:9;82013:14;82170:28;82203:9;82059:11;82200:25;82166:60;82159:68;;81898:347::o;81228:587::-;81492:4;81486:11;;81554:16;81544:27;;81332:15;81599:4;81592:12;;81585:30;81380:18;81636:12;;;81629:33;;;;81697:9;81690:4;81683:12;;81676:31;81742:9;81735:4;81728:12;;81721:31;81792:4;81779:18;;;81228:587::o;52383:2204::-;52450:13;52466:11;52474:2;52466:7;:11::i;:::-;52450:27;;-1:-1:-1;52739:4:0;52732:16;;;-1:-1:-1;;;;;52657:20:0;;;-1:-1:-1;;;52775:32:0;;52769:4;52762:46;52875:4;52859:21;;;52851:30;;52843:39;;52919:20;;52657;;53044:33;;;;53143:137;;53192:10;53186:4;53179:24;53260:4;53254;53247:18;53143:137;53377:5;53371:4;53364:19;53437:13;53434:1;53430:21;53424:28;53672:15;53668:2;53665:23;53657:5;53653:2;53650:13;53647:42;53642:2;53635:10;53632:58;53622:298;;53747:4;53741;53731:21;53725:28;53715:186;;53795:10;53789:4;53782:24;53873:4;53867;53860:18;53715:186;53997:15;53994:93;;;54066:1;54050:13;54047:1;54043:21;54036:32;53994:93;-1:-1:-1;54171:27:0;;54149:50;;54317:4;54311;54301:21;54364:18;;-1:-1:-1;;54360:26:0;54340:47;;54513:2;-1:-1:-1;54192:5:0;54476:25;-1:-1:-1;;54459:57:0;40189:3097;;;:::o;79183:728::-;79258:14;79305:22;79342:35;:33;:35::i;:::-;79338:103;;;79406:23;:21;:23::i;:::-;79394:35;;79338:103;79568:18;79562:4;79555:32;79635:9;79629:4;79622:23;79703:10;79697:4;79690:24;79780:4;79774;79764:21;79754:31;;79891:1;79885:4;79878:15;79504:400;79183:728;;;:::o;25203:1477::-;25291:7;;26225:66;26212:79;;26208:163;;;-1:-1:-1;26324:1:0;;-1:-1:-1;26328:30:0;26308:51;;26208:163;26485:24;;;26468:14;26485:24;;;;;;;;;14117:25:1;;;14190:4;14178:17;;14158:18;;;14151:45;;;;14212:18;;;14205:34;;;14255:18;;;14248:34;;;26485:24:0;;14089:19:1;;26485:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;26485:24:0;;-1:-1:-1;;26485:24:0;;;-1:-1:-1;;;;;;;26524:20:0;;26520:103;;26577:1;26581:29;26561:50;;;;;;;26520:103;26643:6;-1:-1:-1;26651:20:0;;-1:-1:-1;25203:1477:0;;;;;;;;:::o;51463:188::-;51553:13;51559:2;51563;51553:5;:13::i;:::-;66808:14;;51577:66;;;51595:48;51626:1;51630:2;51634;51638:4;51595:22;:48::i;71086:1412::-;71154:17;71265:4;71259:11;71252:18;;71598:4;71593:3;71589:14;71583:4;71576:28;71692:34;71686:4;71679:48;71759:1;71754:3;71750:11;71743:18;;71787:2;71782:3;71775:15;71824:4;71819:3;71815:14;71862:1;71857:2;71854:1;71850:10;71843:21;71897:5;71893:2;71889:14;71880:23;;72121:1;72089:391;72201:1;72198;72194:9;72191:1;72187:17;72242:5;72239:1;72234:14;72301:2;72295:4;72291:13;72285:20;72281:1;72278;72274:9;72266:40;72348:4;72345:1;72341:12;72335:19;72332:1;72324:31;-1:-1:-1;;72385:1:0;72378:9;;;-1:-1:-1;;72408:9:0;72089:391;72405:60;72093:44;;71086:1412;;;:::o;49223:1714::-;-1:-1:-1;;;;;49456:20:0;;;;;49542:138;;49588:10;49582:4;49575:24;49660:4;49654;49647:18;49542:138;49748:2;49742:4;49735:16;-1:-1:-1;;;49772:4:0;49765:38;49870:4;49864;49854:21;49850:2;49846:30;49842:2;49838:39;49920:13;49914:20;50011:15;50007:2;50003:24;50000:149;;;50060:10;50054:4;50047:24;50129:4;50123;50116:18;50000:149;50224:23;;50202:46;;50340:4;50333:16;;;50402:4;50396;50386:21;50454:18;;50474:1;50450:26;50527:20;50504:44;;50494:193;;50586:10;50580:4;50573:24;50663:4;50657;50650:18;50494:193;50705:38;;50866:2;50862;50859:1;50832:25;50859:1;;50815:54;38402:121;;:::o;14:286:1:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:1;;209:43;;199:71;;266:1;263;256:12;497:250;582:1;592:113;606:6;603:1;600:13;592:113;;;682:11;;;676:18;663:11;;;656:39;628:2;621:10;592:113;;;-1:-1:-1;;739:1:1;721:16;;714:27;497:250::o;752:271::-;794:3;832:5;826:12;859:6;854:3;847:19;875:76;944:6;937:4;932:3;928:14;921:4;914:5;910:16;875:76;:::i;:::-;1005:2;984:15;-1:-1:-1;;980:29:1;971:39;;;;1012:4;967:50;;752:271;-1:-1:-1;;752:271:1:o;1028:220::-;1177:2;1166:9;1159:21;1140:4;1197:45;1238:2;1227:9;1223:18;1215:6;1197:45;:::i;1253:180::-;1312:6;1365:2;1353:9;1344:7;1340:23;1336:32;1333:52;;;1381:1;1378;1371:12;1333:52;-1:-1:-1;1404:23:1;;1253:180;-1:-1:-1;1253:180:1:o;1646:173::-;1714:20;;-1:-1:-1;;;;;1763:31:1;;1753:42;;1743:70;;1809:1;1806;1799:12;1824:254;1892:6;1900;1953:2;1941:9;1932:7;1928:23;1924:32;1921:52;;;1969:1;1966;1959:12;1921:52;1992:29;2011:9;1992:29;:::i;:::-;1982:39;2068:2;2053:18;;;;2040:32;;-1:-1:-1;;;1824:254:1:o;2265:328::-;2342:6;2350;2358;2411:2;2399:9;2390:7;2386:23;2382:32;2379:52;;;2427:1;2424;2417:12;2379:52;2450:29;2469:9;2450:29;:::i;:::-;2440:39;;2498:38;2532:2;2521:9;2517:18;2498:38;:::i;:::-;2488:48;;2583:2;2572:9;2568:18;2555:32;2545:42;;2265:328;;;;;:::o;2598:348::-;2650:8;2660:6;2714:3;2707:4;2699:6;2695:17;2691:27;2681:55;;2732:1;2729;2722:12;2681:55;-1:-1:-1;2755:20:1;;2798:18;2787:30;;2784:50;;;2830:1;2827;2820:12;2784:50;2867:4;2859:6;2855:17;2843:29;;2919:3;2912:4;2903:6;2895;2891:19;2887:30;2884:39;2881:59;;;2936:1;2933;2926:12;2951:411;3022:6;3030;3083:2;3071:9;3062:7;3058:23;3054:32;3051:52;;;3099:1;3096;3089:12;3051:52;3139:9;3126:23;3172:18;3164:6;3161:30;3158:50;;;3204:1;3201;3194:12;3158:50;3243:59;3294:7;3285:6;3274:9;3270:22;3243:59;:::i;:::-;3321:8;;3217:85;;-1:-1:-1;2951:411:1;-1:-1:-1;;;;2951:411:1:o;3549:186::-;3608:6;3661:2;3649:9;3640:7;3636:23;3632:32;3629:52;;;3677:1;3674;3667:12;3629:52;3700:29;3719:9;3700:29;:::i;3740:127::-;3801:10;3796:3;3792:20;3789:1;3782:31;3832:4;3829:1;3822:15;3856:4;3853:1;3846:15;3872:1132;3967:6;3975;3983;3991;4044:3;4032:9;4023:7;4019:23;4015:33;4012:53;;;4061:1;4058;4051:12;4012:53;4084:29;4103:9;4084:29;:::i;:::-;4074:39;;4160:2;4149:9;4145:18;4132:32;4122:42;;4211:2;4200:9;4196:18;4183:32;4173:42;;4266:2;4255:9;4251:18;4238:32;4289:18;4330:2;4322:6;4319:14;4316:34;;;4346:1;4343;4336:12;4316:34;4384:6;4373:9;4369:22;4359:32;;4429:7;4422:4;4418:2;4414:13;4410:27;4400:55;;4451:1;4448;4441:12;4400:55;4487:2;4474:16;4509:2;4505;4502:10;4499:36;;;4515:18;;:::i;:::-;4590:2;4584:9;4558:2;4644:13;;-1:-1:-1;;4640:22:1;;;4664:2;4636:31;4632:40;4620:53;;;4688:18;;;4708:22;;;4685:46;4682:72;;;4734:18;;:::i;:::-;4774:10;4770:2;4763:22;4809:2;4801:6;4794:18;4849:7;4844:2;4839;4835;4831:11;4827:20;4824:33;4821:53;;;4870:1;4867;4860:12;4821:53;4926:2;4921;4917;4913:11;4908:2;4900:6;4896:15;4883:46;4971:1;4966:2;4961;4953:6;4949:15;4945:24;4938:35;4992:6;4982:16;;;;;;;3872:1132;;;;;;;:::o;5009:1259::-;5415:3;5410;5406:13;5398:6;5394:26;5383:9;5376:45;5357:4;5440:2;5478:3;5473:2;5462:9;5458:18;5451:31;5505:46;5546:3;5535:9;5531:19;5523:6;5505:46;:::i;:::-;5599:9;5591:6;5587:22;5582:2;5571:9;5567:18;5560:50;5633:33;5659:6;5651;5633:33;:::i;:::-;5697:2;5682:18;;5675:34;;;-1:-1:-1;;;;;5746:32:1;;5740:3;5725:19;;5718:61;5766:3;5795:19;;5788:35;;;5860:22;;;5854:3;5839:19;;5832:51;5932:13;;5954:22;;;6030:15;;;;-1:-1:-1;5992:15:1;;;;-1:-1:-1;6073:169:1;6087:6;6084:1;6081:13;6073:169;;;6148:13;;6136:26;;6217:15;;;;6182:12;;;;6109:1;6102:9;6073:169;;;-1:-1:-1;6259:3:1;;5009:1259;-1:-1:-1;;;;;;;;;;;;5009:1259:1:o;6273:347::-;6338:6;6346;6399:2;6387:9;6378:7;6374:23;6370:32;6367:52;;;6415:1;6412;6405:12;6367:52;6438:29;6457:9;6438:29;:::i;:::-;6428:39;;6517:2;6506:9;6502:18;6489:32;6564:5;6557:13;6550:21;6543:5;6540:32;6530:60;;6586:1;6583;6576:12;6530:60;6609:5;6599:15;;;6273:347;;;;;:::o;6625:627::-;6722:6;6730;6738;6746;6754;6807:3;6795:9;6786:7;6782:23;6778:33;6775:53;;;6824:1;6821;6814:12;6775:53;6847:29;6866:9;6847:29;:::i;:::-;6837:39;;6895:38;6929:2;6918:9;6914:18;6895:38;:::i;:::-;6885:48;;6980:2;6969:9;6965:18;6952:32;6942:42;;7035:2;7024:9;7020:18;7007:32;7062:18;7054:6;7051:30;7048:50;;;7094:1;7091;7084:12;7048:50;7133:59;7184:7;7175:6;7164:9;7160:22;7133:59;:::i;:::-;6625:627;;;;-1:-1:-1;6625:627:1;;-1:-1:-1;7211:8:1;;7107:85;6625:627;-1:-1:-1;;;6625:627:1:o;7257:260::-;7325:6;7333;7386:2;7374:9;7365:7;7361:23;7357:32;7354:52;;;7402:1;7399;7392:12;7354:52;7425:29;7444:9;7425:29;:::i;:::-;7415:39;;7473:38;7507:2;7496:9;7492:18;7473:38;:::i;:::-;7463:48;;7257:260;;;;;:::o;7522:380::-;7601:1;7597:12;;;;7644;;;7665:61;;7719:4;7711:6;7707:17;7697:27;;7665:61;7772:2;7764:6;7761:14;7741:18;7738:38;7735:161;;7818:10;7813:3;7809:20;7806:1;7799:31;7853:4;7850:1;7843:15;7881:4;7878:1;7871:15;7735:161;;7522:380;;;:::o;9190:225::-;9257:9;;;9278:11;;;9275:134;;;9331:10;9326:3;9322:20;9319:1;9312:31;9366:4;9363:1;9356:15;9394:4;9391:1;9384:15;9420:999;9849:3;9887:6;9881:13;9903:66;9962:6;9957:3;9950:4;9942:6;9938:17;9903:66;:::i;:::-;10000:6;9995:3;9991:16;9978:29;;-1:-1:-1;;;10052:2:1;10045:5;10038:17;10086:6;10080:13;10102:78;10171:8;10167:1;10160:5;10156:13;10149:4;10141:6;10137:17;10102:78;:::i;:::-;10243:1;10199:20;;10235:10;;;10228:22;10275:13;;10297:75;10275:13;10359:1;10351:10;;10344:4;10332:17;;10297:75;:::i;:::-;10392:17;10411:1;10388:25;;9420:999;-1:-1:-1;;;;;9420:999:1:o;11318:545::-;11420:2;11415:3;11412:11;11409:448;;;11456:1;11481:5;11477:2;11470:17;11526:4;11522:2;11512:19;11596:2;11584:10;11580:19;11577:1;11573:27;11567:4;11563:38;11632:4;11620:10;11617:20;11614:47;;;-1:-1:-1;11655:4:1;11614:47;11710:2;11705:3;11701:12;11698:1;11694:20;11688:4;11684:31;11674:41;;11765:82;11783:2;11776:5;11773:13;11765:82;;;11828:17;;;11809:1;11798:13;11765:82;;12039:1352;12165:3;12159:10;12192:18;12184:6;12181:30;12178:56;;;12214:18;;:::i;:::-;12243:97;12333:6;12293:38;12325:4;12319:11;12293:38;:::i;:::-;12287:4;12243:97;:::i;:::-;12395:4;;12459:2;12448:14;;12476:1;12471:663;;;;13178:1;13195:6;13192:89;;;-1:-1:-1;13247:19:1;;;13241:26;13192:89;-1:-1:-1;;11996:1:1;11992:11;;;11988:24;11984:29;11974:40;12020:1;12016:11;;;11971:57;13294:81;;12441:944;;12471:663;11265:1;11258:14;;;11302:4;11289:18;;-1:-1:-1;;12507:20:1;;;12625:236;12639:7;12636:1;12633:14;12625:236;;;12728:19;;;12722:26;12707:42;;12820:27;;;;12788:1;12776:14;;;;12655:19;;12625:236;;;12629:3;12889:6;12880:7;12877:19;12874:201;;;12950:19;;;12944:26;-1:-1:-1;;13033:1:1;13029:14;;;13045:3;13025:24;13021:37;13017:42;13002:58;12987:74;;12874:201;-1:-1:-1;;;;;13121:1:1;13105:14;;;13101:22;13088:36;;-1:-1:-1;12039:1352:1:o
Swarm Source
ipfs://a738f2a03f1e06d7014654e59d2b6af7702dc9f199cfeea9592e8d0fa4098007
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.