ETH Price: $2,490.82 (-3.16%)

Token

Tejiverse (TEJI)
 

Overview

Max Total Supply

1,000 TEJI

Holders

615

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
24 TEJI
0x47b306c725fe30223663189701e1c336fec2f520
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
Tejiverse

Compiler Version
v0.8.11+commit.d7f03943

Optimization Enabled:
Yes with 512 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-02-26
*/

// File: @openzeppelin/contracts/utils/Strings.sol


// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

// File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol


// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;


/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        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.
            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 if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

// File: @openzeppelin/contracts/utils/Context.sol


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: @openzeppelin/contracts/utils/Address.sol


// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// File: @openzeppelin/contracts/utils/introspection/ERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;


/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;


/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

// File: erc721a/contracts/ERC721A.sol


// Creator: Chiru Labs

pragma solidity ^0.8.4;









error ApprovalCallerNotOwnerNorApproved();
error ApprovalQueryForNonexistentToken();
error ApproveToCaller();
error ApprovalToCurrentOwner();
error BalanceQueryForZeroAddress();
error MintedQueryForZeroAddress();
error BurnedQueryForZeroAddress();
error AuxQueryForZeroAddress();
error MintToZeroAddress();
error MintZeroQuantity();
error OwnerIndexOutOfBounds();
error OwnerQueryForNonexistentToken();
error TokenIndexOutOfBounds();
error TransferCallerNotOwnerNorApproved();
error TransferFromIncorrectOwner();
error TransferToNonERC721ReceiverImplementer();
error TransferToZeroAddress();
error URIQueryForNonexistentToken();

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..).
 *
 * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 *
 * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Compiler will pack this into a single 256bit word.
    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
    }

    // Compiler will pack this into a single 256bit word.
    struct AddressData {
        // Realistically, 2**64-1 is more than enough.
        uint64 balance;
        // Keeps track of mint count with minimal overhead for tokenomics.
        uint64 numberMinted;
        // Keeps track of burn count with minimal overhead for tokenomics.
        uint64 numberBurned;
        // For miscellaneous variable(s) pertaining to the address
        // (e.g. number of whitelist mint slots used).
        // If there are multiple variables, please pack them into a uint64.
        uint64 aux;
    }

    // The tokenId of the next token to be minted.
    uint256 internal _currentIndex;

    // The number of tokens burned.
    uint256 internal _burnCounter;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to ownership details
    // An empty struct value does not necessarily mean the token is unowned. See ownershipOf implementation for details.
    mapping(uint256 => TokenOwnership) internal _ownerships;

    // Mapping owner address to address data
    mapping(address => AddressData) private _addressData;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
        _currentIndex = _startTokenId();
    }

    /**
     * To change the starting tokenId, please override this function.
     */
    function _startTokenId() internal view virtual returns (uint256) {
        return 0;
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     * @dev Burned tokens are calculated here, use _totalMinted() if you want to count just minted tokens.
     */
    function totalSupply() public view returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than _currentIndex - _startTokenId() times
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

    /**
     * Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view returns (uint256) {
        // Counter underflow is impossible as _currentIndex does not decrement,
        // and it is initialized to _startTokenId()
        unchecked {
            return _currentIndex - _startTokenId();
        }
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return uint256(_addressData[owner].balance);
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        if (owner == address(0)) revert MintedQueryForZeroAddress();
        return uint256(_addressData[owner].numberMinted);
    }

    /**
     * Returns the number of tokens burned by or on behalf of `owner`.
     */
    function _numberBurned(address owner) internal view returns (uint256) {
        if (owner == address(0)) revert BurnedQueryForZeroAddress();
        return uint256(_addressData[owner].numberBurned);
    }

    /**
     * Returns the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        if (owner == address(0)) revert AuxQueryForZeroAddress();
        return _addressData[owner].aux;
    }

    /**
     * Sets the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal {
        if (owner == address(0)) revert AuxQueryForZeroAddress();
        _addressData[owner].aux = aux;
    }

    /**
     * Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around in the collection over time.
     */
    function ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr && curr < _currentIndex) {
                TokenOwnership memory ownership = _ownerships[curr];
                if (!ownership.burned) {
                    if (ownership.addr != address(0)) {
                        return ownership;
                    }
                    // Invariant:
                    // There will always be an ownership that has an address and is not burned
                    // before an ownership that does not have an address and is not burned.
                    // Hence, curr will not underflow.
                    while (true) {
                        curr--;
                        ownership = _ownerships[curr];
                        if (ownership.addr != address(0)) {
                            return ownership;
                        }
                    }
                }
            }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view override returns (address) {
        return ownershipOf(tokenId).addr;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        string memory baseURI = _baseURI();
        return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : '';
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return '';
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public override {
        address owner = ERC721A.ownerOf(tokenId);
        if (to == owner) revert ApprovalToCurrentOwner();

        if (_msgSender() != owner && !isApprovedForAll(owner, _msgSender())) {
            revert ApprovalCallerNotOwnerNorApproved();
        }

        _approve(to, tokenId, owner);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public override {
        if (operator == _msgSender()) revert ApproveToCaller();

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, '');
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        _transfer(from, to, tokenId);
        if (to.isContract() && !_checkContractOnERC721Received(from, to, tokenId, _data)) {
            revert TransferToNonERC721ReceiverImplementer();
        }
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        return _startTokenId() <= tokenId && tokenId < _currentIndex &&
            !_ownerships[tokenId].burned;
    }

    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, quantity, '');
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal {
        _mint(to, quantity, _data, true);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _mint(
        address to,
        uint256 quantity,
        bytes memory _data,
        bool safe
    ) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            _addressData[to].balance += uint64(quantity);
            _addressData[to].numberMinted += uint64(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            if (safe && to.isContract()) {
                do {
                    emit Transfer(address(0), to, updatedIndex);
                    if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (updatedIndex != end);
                // Reentrancy protection
                if (_currentIndex != startTokenId) revert();
            } else {
                do {
                    emit Transfer(address(0), to, updatedIndex++);
                } while (updatedIndex != end);
            }
            _currentIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) private {
        TokenOwnership memory prevOwnership = ownershipOf(tokenId);

        bool isApprovedOrOwner = (_msgSender() == prevOwnership.addr ||
            isApprovedForAll(prevOwnership.addr, _msgSender()) ||
            getApproved(tokenId) == _msgSender());

        if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        if (prevOwnership.addr != from) revert TransferFromIncorrectOwner();
        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId, prevOwnership.addr);

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            _addressData[from].balance -= 1;
            _addressData[to].balance += 1;

            _ownerships[tokenId].addr = to;
            _ownerships[tokenId].startTimestamp = uint64(block.timestamp);

            // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            if (_ownerships[nextTokenId].addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId < _currentIndex) {
                    _ownerships[nextTokenId].addr = prevOwnership.addr;
                    _ownerships[nextTokenId].startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

        emit Transfer(from, to, tokenId);
        _afterTokenTransfers(from, to, tokenId, 1);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        TokenOwnership memory prevOwnership = ownershipOf(tokenId);

        _beforeTokenTransfers(prevOwnership.addr, address(0), tokenId, 1);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId, prevOwnership.addr);

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            _addressData[prevOwnership.addr].balance -= 1;
            _addressData[prevOwnership.addr].numberBurned += 1;

            // Keep track of who burned the token, and the timestamp of burning.
            _ownerships[tokenId].addr = prevOwnership.addr;
            _ownerships[tokenId].startTimestamp = uint64(block.timestamp);
            _ownerships[tokenId].burned = true;

            // If the ownership slot of tokenId+1 is not explicitly set, that means the burn initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            if (_ownerships[nextTokenId].addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId < _currentIndex) {
                    _ownerships[nextTokenId].addr = prevOwnership.addr;
                    _ownerships[nextTokenId].startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

        emit Transfer(prevOwnership.addr, address(0), tokenId);
        _afterTokenTransfers(prevOwnership.addr, address(0), tokenId, 1);

        // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
        unchecked {
            _burnCounter++;
        }
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(
        address to,
        uint256 tokenId,
        address owner
    ) private {
        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
            return retval == IERC721Receiver(to).onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

    /**
     * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting.
     * And also called before burning one token.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes
     * minting.
     * And also called after one token has been burned.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
     * transferred to `to`.
     * - When `from` is zero, `tokenId` has been minted for `to`.
     * - When `to` is zero, `tokenId` has been burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}
}

// File: contracts/Tejiverse.sol


pragma solidity 0.8.11;





/*   _____    _ _                           */
/*  |_   _|  (_|_)                          */
/*    | | ___ _ ___   _____ _ __ ___  ___   */
/*    | |/ _ \ | \ \ / / _ \ '__/ __|/ _ \  */
/*    | |  __/ | |\ V /  __/ |  \__ \  __/  */
/*    \_/\___| |_| \_/ \___|_|  |___/\___|  */
/*          _/ |                            */
/*         |__/                             */

/// @title Tejiverse
/// @author naomsa <https://twitter.com/naomsa666>
/// @author Teji <https://twitter.com/0xTeji>
contract Tejiverse is Ownable, ERC721A {
  using Strings for uint256;
  using ECDSA for bytes32;

  /* -------------------------------------------------------------------------- */
  /*                              Metadata Details                              */
  /* -------------------------------------------------------------------------- */

  /// @notice Unrevealed metadata URI.
  string public unrevealedURI;

  /// @notice Metadata base URI.
  string public baseURI;

  /* -------------------------------------------------------------------------- */
  /*                             Marketplace Details                            */
  /* -------------------------------------------------------------------------- */

  /// @notice OpenSea proxy registry.
  address public opensea;

  /// @notice LooksRare marketplace transfer manager.
  address public looksrare;

  /// @notice Check if marketplaces pre-approve is enabled.
  bool public marketplacesApproved;

  /* -------------------------------------------------------------------------- */
  /*                                Sale Details                                */
  /* -------------------------------------------------------------------------- */

  /// @notice Whitelist verified signer address.
  address public signer;

  /// @notice 0 = CLOSED, 1 = WHITELIST, 2 = PUBLIC.
  uint256 public saleState;

  /// @notice address => has minted on presale.
  mapping(address => bool) internal _boughtPresale;

  constructor(string memory newUnrevealedURI, address newSigner) ERC721A("Tejiverse", "TEJI") {
    unrevealedURI = newUnrevealedURI;
    signer = newSigner;

    marketplacesApproved = true;
    opensea = 0xa5409ec958C83C3f309868babACA7c86DCB077c1;
    looksrare = 0xf42aa99F011A1fA7CDA90E5E98b277E306BcA83e;
  }

  /* -------------------------------------------------------------------------- */
  /*                                 Sale Logic                                 */
  /* -------------------------------------------------------------------------- */

  /// @notice Claim one teji.
  function claim() external {
    require(_currentIndex < 1000, "Tejiverse: max supply exceeded");
    if (msg.sender != owner()) {
      require(saleState == 2, "Tejiverse: public sale is not open");
    }

    _safeMint(msg.sender, 1);
  }

  /// @notice Claim one teji with whitelist proof.
  /// @param signature Whitelist proof signature.
  function claimWhitelist(bytes memory signature) external {
    require(_currentIndex < 1000, "Tejiverse: max supply exceeded");
    require(saleState == 1, "Tejiverse: whitelist sale is not open");
    require(!_boughtPresale[msg.sender], "Tejiverse: already claimed");

    bytes32 digest = keccak256(abi.encodePacked(address(this), msg.sender));
    require(digest.toEthSignedMessageHash().recover(signature) == signer, "Tejiverse: invalid signature");

    _boughtPresale[msg.sender] = true;
    _safeMint(msg.sender, 1);
  }

  /* -------------------------------------------------------------------------- */
  /*                                 Owner Logic                                */
  /* -------------------------------------------------------------------------- */

  /// @notice Set unrevealedURI to `newUnrevealedURI`.
  /// @param newUnrevealedURI New unrevealed uri.
  function setUnrevealedURI(string memory newUnrevealedURI) external onlyOwner {
    unrevealedURI = newUnrevealedURI;
  }

  /// @notice Set baseURI to `newBaseURI`.
  /// @param newBaseURI New base uri.
  function setBaseURI(string memory newBaseURI) external onlyOwner {
    baseURI = newBaseURI;
    delete unrevealedURI;
  }

  /// @notice Set `saleState` to `newSaleState`.
  /// @param newSaleState New sale state.
  function setSaleState(uint256 newSaleState) external onlyOwner {
    saleState = newSaleState;
  }

  /// @notice Set `signer` to `newSigner`.
  /// @param newSigner New whitelist signer address.
  function setSigner(address newSigner) external onlyOwner {
    signer = newSigner;
  }

  /// @notice Set `opensea` to `newOpensea` and `looksrare` to `newLooksrare`.
  /// @param newOpensea Opensea's proxy registry contract address.
  /// @param newLooksrare Looksrare's transfer manager contract address.
  function setMarketplaces(address newOpensea, address newLooksrare) external onlyOwner {
    opensea = newOpensea;
    looksrare = newLooksrare;
  }

  /// @notice Toggle pre-approve feature state for sender.
  function toggleMarketplacesApproved() external onlyOwner {
    marketplacesApproved = !marketplacesApproved;
  }

  /* -------------------------------------------------------------------------- */
  /*                                ERC-721 Logic                               */
  /* -------------------------------------------------------------------------- */

  /// @notice See {ERC721-tokenURI}.
  function tokenURI(uint256 id) public view override returns (string memory) {
    require(_exists(id), "ERC721Metadata: query for nonexisting token");

    if (bytes(unrevealedURI).length > 0) return unrevealedURI;
    return string(abi.encodePacked(baseURI, id.toString()));
  }

  /// @notice See {ERC721-isApprovedForAll}.
  /// @dev Modified for opensea and looksrare pre-approve so users can make truly gasless sales.
  function isApprovedForAll(address owner, address operator) public view override returns (bool) {
    if (!marketplacesApproved) return super.isApprovedForAll(owner, operator);

    return
      operator == address(ProxyRegistry(opensea).proxies(owner)) ||
      operator == looksrare ||
      super.isApprovedForAll(owner, operator);
  }
}

contract OwnableDelegateProxy {}

contract ProxyRegistry {
  mapping(address => OwnableDelegateProxy) public proxies;
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"newUnrevealedURI","type":"string"},{"internalType":"address","name":"newSigner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","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":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","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":"approved","type":"bool"}],"name":"ApprovalForAll","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":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"claimWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","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":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"looksrare","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketplacesApproved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"opensea","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","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":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"saleState","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOpensea","type":"address"},{"internalType":"address","name":"newLooksrare","type":"address"}],"name":"setMarketplaces","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newSaleState","type":"uint256"}],"name":"setSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newSigner","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newUnrevealedURI","type":"string"}],"name":"setUnrevealedURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleMarketplacesApproved","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","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":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unrevealedURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b50604051620026e1380380620026e1833981016040819052620000349162000274565b6040518060400160405280600981526020016854656a69766572736560b81b8152506040518060400160405280600481526020016354454a4960e01b8152506200008d620000876200014760201b60201c565b6200014b565b8151620000a29060039060208501906200019b565b508051620000b89060049060208401906200019b565b50600060015550508151620000d59060099060208501906200019b565b50600d80546001600160a01b039092166001600160a01b0319928316179055600c8054600b805490931673a5409ec958c83c3f309868babaca7c86dcb077c1179092557401f42aa99f011a1fa7cda90e5e98b277e306bca83e6001600160a81b031990921691909117905550620003a2565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b828054620001a99062000365565b90600052602060002090601f016020900481019282620001cd576000855562000218565b82601f10620001e857805160ff191683800117855562000218565b8280016001018555821562000218579182015b8281111562000218578251825591602001919060010190620001fb565b50620002269291506200022a565b5090565b5b808211156200022657600081556001016200022b565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b03811681146200026f57600080fd5b919050565b600080604083850312156200028857600080fd5b82516001600160401b0380821115620002a057600080fd5b818501915085601f830112620002b557600080fd5b815181811115620002ca57620002ca62000241565b604051601f8201601f19908116603f01168101908382118183101715620002f557620002f562000241565b816040528281526020935088848487010111156200031257600080fd5b600091505b8282101562000336578482018401518183018501529083019062000317565b82821115620003485760008484830101525b95506200035a91505085820162000257565b925050509250929050565b600181811c908216806200037a57607f821691505b602082108114156200039c57634e487b7160e01b600052602260045260246000fd5b50919050565b61232f80620003b26000396000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c8063603f4d521161010f57806395d89b41116100a2578063c87b56dd11610071578063c87b56dd146103f0578063e985e9c514610403578063f2fde38b14610416578063fe2c7fee1461042957600080fd5b806395d89b41146103af578063a22cb465146103b7578063a8e90b57146103ca578063b88d4fde146103dd57600080fd5b80637035bf18116100de5780637035bf181461037b57806370a0823114610383578063715018a6146103965780638da5cb5b1461039e57600080fd5b8063603f4d52146103445780636352211e1461034d5780636c0360eb146103605780636c19e7831461036857600080fd5b8063238ac9331161018757806342842e0e1161015657806342842e0e146103035780634e71d92d14610316578063511ed3821461031e57806355f804b31461033157600080fd5b8063238ac933146102c257806323b872dd146102d5578063337ac7c4146102e857806333c12e17146102fb57600080fd5b8063084c4088116101c3578063084c408814610271578063095ea7b31461028657806318160ddd146102995780631dd8ce9e146102af57600080fd5b806301ffc9a7146101f5578063026ae1021461021d57806306fdde0314610231578063081812fc14610246575b600080fd5b610208610203366004611d59565b61043c565b60405190151581526020015b60405180910390f35b600c5461020890600160a01b900460ff1681565b61023961048e565b6040516102149190611dce565b610259610254366004611de1565b610520565b6040516001600160a01b039091168152602001610214565b61028461027f366004611de1565b610564565b005b610284610294366004611e0f565b6105b6565b600254600154035b604051908152602001610214565b6102846102bd366004611ee7565b610644565b600d54610259906001600160a01b031681565b6102846102e3366004611f1c565b61088d565b6102846102f6366004611f5d565b610898565b61028461090e565b610284610311366004611f1c565b610977565b610284610992565b600b54610259906001600160a01b031681565b61028461033f366004611f96565b610a61565b6102a1600e5481565b61025961035b366004611de1565b610acc565b610239610ade565b610284610376366004611fdf565b610b6c565b610239610bd6565b6102a1610391366004611fdf565b610be3565b610284610c32565b6000546001600160a01b0316610259565b610239610c84565b6102846103c5366004611ffc565b610c93565b600c54610259906001600160a01b031681565b6102846103eb36600461202f565b610d29565b6102396103fe366004611de1565b610d7a565b610208610411366004611f5d565b610ec0565b610284610424366004611fdf565b610fd4565b610284610437366004611f96565b61108a565b60006001600160e01b031982166380ac58cd60e01b148061046d57506001600160e01b03198216635b5e139f60e01b145b8061048857506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606003805461049d9061209b565b80601f01602080910402602001604051908101604052809291908181526020018280546104c99061209b565b80156105165780601f106104eb57610100808354040283529160200191610516565b820191906000526020600020905b8154815290600101906020018083116104f957829003601f168201915b5050505050905090565b600061052b826110e5565b610548576040516333d1c03960e21b815260040160405180910390fd5b506000908152600760205260409020546001600160a01b031690565b6000546001600160a01b031633146105b15760405162461bcd60e51b815260206004820181905260248201526000805160206122da83398151915260448201526064015b60405180910390fd5b600e55565b60006105c182610acc565b9050806001600160a01b0316836001600160a01b031614156105f65760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b0382161480159061061657506106148133610ec0565b155b15610634576040516367d9dca160e11b815260040160405180910390fd5b61063f838383611111565b505050565b6103e8600154106106975760405162461bcd60e51b815260206004820152601e60248201527f54656a6976657273653a206d617820737570706c79206578636565646564000060448201526064016105a8565b600e546001146106f75760405162461bcd60e51b815260206004820152602560248201527f54656a6976657273653a2077686974656c6973742073616c65206973206e6f746044820152641037b832b760d91b60648201526084016105a8565b336000908152600f602052604090205460ff16156107575760405162461bcd60e51b815260206004820152601a60248201527f54656a6976657273653a20616c726561647920636c61696d656400000000000060448201526064016105a8565b6040516bffffffffffffffffffffffff1930606090811b8216602084015233901b16603482015260009060480160408051601f198184030181529190528051602090910120600d549091506001600160a01b031661080c83610806846040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b9061116d565b6001600160a01b0316146108625760405162461bcd60e51b815260206004820152601c60248201527f54656a6976657273653a20696e76616c6964207369676e61747572650000000060448201526064016105a8565b336000818152600f60205260409020805460ff191660019081179091556108899190611191565b5050565b61063f8383836111ab565b6000546001600160a01b031633146108e05760405162461bcd60e51b815260206004820181905260248201526000805160206122da83398151915260448201526064016105a8565b600b80546001600160a01b039384166001600160a01b031991821617909155600c8054929093169116179055565b6000546001600160a01b031633146109565760405162461bcd60e51b815260206004820181905260248201526000805160206122da83398151915260448201526064016105a8565b600c805460ff60a01b198116600160a01b9182900460ff1615909102179055565b61063f83838360405180602001604052806000815250610d29565b6103e8600154106109e55760405162461bcd60e51b815260206004820152601e60248201527f54656a6976657273653a206d617820737570706c79206578636565646564000060448201526064016105a8565b6000546001600160a01b03163314610a5457600e54600214610a545760405162461bcd60e51b815260206004820152602260248201527f54656a6976657273653a207075626c69632073616c65206973206e6f74206f7060448201526132b760f11b60648201526084016105a8565b610a5f336001611191565b565b6000546001600160a01b03163314610aa95760405162461bcd60e51b815260206004820181905260248201526000805160206122da83398151915260448201526064016105a8565b8051610abc90600a906020840190611c74565b50610ac960096000611cf8565b50565b6000610ad7826113c1565b5192915050565b600a8054610aeb9061209b565b80601f0160208091040260200160405190810160405280929190818152602001828054610b179061209b565b8015610b645780601f10610b3957610100808354040283529160200191610b64565b820191906000526020600020905b815481529060010190602001808311610b4757829003601f168201915b505050505081565b6000546001600160a01b03163314610bb45760405162461bcd60e51b815260206004820181905260248201526000805160206122da83398151915260448201526064016105a8565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b60098054610aeb9061209b565b60006001600160a01b038216610c0c576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b031660009081526006602052604090205467ffffffffffffffff1690565b6000546001600160a01b03163314610c7a5760405162461bcd60e51b815260206004820181905260248201526000805160206122da83398151915260448201526064016105a8565b610a5f60006114dd565b60606004805461049d9061209b565b6001600160a01b038216331415610cbd5760405163b06307db60e01b815260040160405180910390fd5b3360008181526008602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b610d348484846111ab565b6001600160a01b0383163b15158015610d565750610d548484848461152d565b155b15610d74576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b6060610d85826110e5565b610de55760405162461bcd60e51b815260206004820152602b60248201527f4552433732314d657461646174613a20717565727920666f72206e6f6e65786960448201526a39ba34b733903a37b5b2b760a91b60648201526084016105a8565b600060098054610df49061209b565b90501115610e8e5760098054610e099061209b565b80601f0160208091040260200160405190810160405280929190818152602001828054610e359061209b565b8015610e825780601f10610e5757610100808354040283529160200191610e82565b820191906000526020600020905b815481529060010190602001808311610e6557829003601f168201915b50505050509050919050565b600a610e9983611616565b604051602001610eaa9291906120f2565b6040516020818303038152906040529050919050565b600c54600090600160a01b900460ff16610f0357506001600160a01b0382811660009081526008602090815260408083209385168352929052205460ff16610488565b600b5460405163c455279160e01b81526001600160a01b0385811660048301529091169063c455279190602401602060405180830381865afa158015610f4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f719190612199565b6001600160a01b0316826001600160a01b03161480610f9d5750600c546001600160a01b038381169116145b80610fcd57506001600160a01b0380841660009081526008602090815260408083209386168352929052205460ff165b9392505050565b6000546001600160a01b0316331461101c5760405162461bcd60e51b815260206004820181905260248201526000805160206122da83398151915260448201526064016105a8565b6001600160a01b0381166110815760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105a8565b610ac9816114dd565b6000546001600160a01b031633146110d25760405162461bcd60e51b815260206004820181905260248201526000805160206122da83398151915260448201526064016105a8565b8051610889906009906020840190611c74565b600060015482108015610488575050600090815260056020526040902054600160e01b900460ff161590565b60008281526007602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600080600061117c858561172c565b915091506111898161179c565b509392505050565b610889828260405180602001604052806000815250611957565b60006111b6826113c1565b80519091506000906001600160a01b0316336001600160a01b031614806111e4575081516111e49033610ec0565b806111ff5750336111f484610520565b6001600160a01b0316145b90508061121f57604051632ce44b5f60e11b815260040160405180910390fd5b846001600160a01b031682600001516001600160a01b0316146112545760405162a1148160e81b815260040160405180910390fd5b6001600160a01b03841661127b57604051633a954ecd60e21b815260040160405180910390fd5b61128b6000848460000151611111565b6001600160a01b038581166000908152600660209081526040808320805467ffffffffffffffff1980821667ffffffffffffffff92831660001901831617909255898616808652838620805493841693831660019081018416949094179055898652600590945282852080546001600160e01b031916909417600160a01b42909216919091021790925590860180835291205490911661137757600154811015611377578251600082815260056020908152604090912080549186015167ffffffffffffffff16600160a01b026001600160e01b03199092166001600160a01b03909316929092171790555b5082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b5050505050565b6040805160608101825260008082526020820181905291810191909152816001548110156114c457600081815260056020908152604091829020825160608101845290546001600160a01b0381168252600160a01b810467ffffffffffffffff1692820192909252600160e01b90910460ff161515918101829052906114c25780516001600160a01b031615611458579392505050565b5060001901600081815260056020908152604091829020825160608101845290546001600160a01b038116808352600160a01b820467ffffffffffffffff1693830193909352600160e01b900460ff16151592810192909252156114bd579392505050565b611458565b505b604051636f96cda160e11b815260040160405180910390fd5b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906115629033908990889088906004016121b6565b6020604051808303816000875af192505050801561159d575060408051601f3d908101601f1916820190925261159a918101906121f2565b60015b6115f8573d8080156115cb576040519150601f19603f3d011682016040523d82523d6000602084013e6115d0565b606091505b5080516115f0576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b60608161163a5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611664578061164e81612225565b915061165d9050600a83612256565b915061163e565b60008167ffffffffffffffff81111561167f5761167f611e3b565b6040519080825280601f01601f1916602001820160405280156116a9576020820181803683370190505b5090505b841561160e576116be60018361226a565b91506116cb600a86612281565b6116d6906030612295565b60f81b8183815181106116eb576116eb6122ad565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611725600a86612256565b94506116ad565b6000808251604114156117635760208301516040840151606085015160001a61175787828585611964565b94509450505050611795565b82516040141561178d5760208301516040840151611782868383611a51565b935093505050611795565b506000905060025b9250929050565b60008160048111156117b0576117b06122c3565b14156117b95750565b60018160048111156117cd576117cd6122c3565b141561181b5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105a8565b600281600481111561182f5761182f6122c3565b141561187d5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105a8565b6003816004811115611891576118916122c3565b14156118ea5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016105a8565b60048160048111156118fe576118fe6122c3565b1415610ac95760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016105a8565b61063f8383836001611aa3565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561199b5750600090506003611a48565b8460ff16601b141580156119b357508460ff16601c14155b156119c45750600090506004611a48565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611a18573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611a4157600060019250925050611a48565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681611a8760ff86901c601b612295565b9050611a9587828885611964565b935093505050935093915050565b6001546001600160a01b038516611acc57604051622e076360e81b815260040160405180910390fd5b83611aea5760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038516600081815260066020908152604080832080546fffffffffffffffffffffffffffffffff19811667ffffffffffffffff8083168c0181169182176801000000000000000067ffffffffffffffff1990941690921783900481168c01811690920217909155858452600590925290912080546001600160e01b031916909217600160a01b429092169190910217905580808501838015611b9c57506001600160a01b0387163b15155b15611c25575b60405182906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4611bed600088848060010195508861152d565b611c0a576040516368d2bf6b60e11b815260040160405180910390fd5b80821415611ba2578260015414611c2057600080fd5b611c6b565b5b6040516001830192906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a480821415611c26575b506001556113ba565b828054611c809061209b565b90600052602060002090601f016020900481019282611ca25760008555611ce8565b82601f10611cbb57805160ff1916838001178555611ce8565b82800160010185558215611ce8579182015b82811115611ce8578251825591602001919060010190611ccd565b50611cf4929150611d2e565b5090565b508054611d049061209b565b6000825580601f10611d14575050565b601f016020900490600052602060002090810190610ac991905b5b80821115611cf45760008155600101611d2f565b6001600160e01b031981168114610ac957600080fd5b600060208284031215611d6b57600080fd5b8135610fcd81611d43565b60005b83811015611d91578181015183820152602001611d79565b83811115610d745750506000910152565b60008151808452611dba816020860160208601611d76565b601f01601f19169290920160200192915050565b602081526000610fcd6020830184611da2565b600060208284031215611df357600080fd5b5035919050565b6001600160a01b0381168114610ac957600080fd5b60008060408385031215611e2257600080fd5b8235611e2d81611dfa565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115611e6c57611e6c611e3b565b604051601f8501601f19908116603f01168101908282118183101715611e9457611e94611e3b565b81604052809350858152868686011115611ead57600080fd5b858560208301376000602087830101525050509392505050565b600082601f830112611ed857600080fd5b610fcd83833560208501611e51565b600060208284031215611ef957600080fd5b813567ffffffffffffffff811115611f1057600080fd5b61160e84828501611ec7565b600080600060608486031215611f3157600080fd5b8335611f3c81611dfa565b92506020840135611f4c81611dfa565b929592945050506040919091013590565b60008060408385031215611f7057600080fd5b8235611f7b81611dfa565b91506020830135611f8b81611dfa565b809150509250929050565b600060208284031215611fa857600080fd5b813567ffffffffffffffff811115611fbf57600080fd5b8201601f81018413611fd057600080fd5b61160e84823560208401611e51565b600060208284031215611ff157600080fd5b8135610fcd81611dfa565b6000806040838503121561200f57600080fd5b823561201a81611dfa565b915060208301358015158114611f8b57600080fd5b6000806000806080858703121561204557600080fd5b843561205081611dfa565b9350602085013561206081611dfa565b925060408501359150606085013567ffffffffffffffff81111561208357600080fd5b61208f87828801611ec7565b91505092959194509250565b600181811c908216806120af57607f821691505b602082108114156120d057634e487b7160e01b600052602260045260246000fd5b50919050565b600081516120e8818560208601611d76565b9290920192915050565b600080845481600182811c91508083168061210e57607f831692505b602080841082141561212e57634e487b7160e01b86526022600452602486fd5b818015612142576001811461215357612180565b60ff19861689528489019650612180565b60008b81526020902060005b868110156121785781548b82015290850190830161215f565b505084890196505b50505050505061219081856120d6565b95945050505050565b6000602082840312156121ab57600080fd5b8151610fcd81611dfa565b60006001600160a01b038087168352808616602084015250836040830152608060608301526121e86080830184611da2565b9695505050505050565b60006020828403121561220457600080fd5b8151610fcd81611d43565b634e487b7160e01b600052601160045260246000fd5b60006000198214156122395761223961220f565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261226557612265612240565b500490565b60008282101561227c5761227c61220f565b500390565b60008261229057612290612240565b500690565b600082198211156122a8576122a861220f565b500190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fdfe4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a2646970667358221220c49623acfce159438ea9bee66927abbc873325a5e9909ac66a00e32d4bef092664736f6c634300080b003300000000000000000000000000000000000000000000000000000000000000400000000000000000000000007b85fda7524bafcf59d02694dda7f323f75451490000000000000000000000000000000000000000000000000000000000000035697066733a2f2f516d5a6f43617137656d566e6b536672526574566d614448655a6953725439733165516d525748477a387938506d0000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101f05760003560e01c8063603f4d521161010f57806395d89b41116100a2578063c87b56dd11610071578063c87b56dd146103f0578063e985e9c514610403578063f2fde38b14610416578063fe2c7fee1461042957600080fd5b806395d89b41146103af578063a22cb465146103b7578063a8e90b57146103ca578063b88d4fde146103dd57600080fd5b80637035bf18116100de5780637035bf181461037b57806370a0823114610383578063715018a6146103965780638da5cb5b1461039e57600080fd5b8063603f4d52146103445780636352211e1461034d5780636c0360eb146103605780636c19e7831461036857600080fd5b8063238ac9331161018757806342842e0e1161015657806342842e0e146103035780634e71d92d14610316578063511ed3821461031e57806355f804b31461033157600080fd5b8063238ac933146102c257806323b872dd146102d5578063337ac7c4146102e857806333c12e17146102fb57600080fd5b8063084c4088116101c3578063084c408814610271578063095ea7b31461028657806318160ddd146102995780631dd8ce9e146102af57600080fd5b806301ffc9a7146101f5578063026ae1021461021d57806306fdde0314610231578063081812fc14610246575b600080fd5b610208610203366004611d59565b61043c565b60405190151581526020015b60405180910390f35b600c5461020890600160a01b900460ff1681565b61023961048e565b6040516102149190611dce565b610259610254366004611de1565b610520565b6040516001600160a01b039091168152602001610214565b61028461027f366004611de1565b610564565b005b610284610294366004611e0f565b6105b6565b600254600154035b604051908152602001610214565b6102846102bd366004611ee7565b610644565b600d54610259906001600160a01b031681565b6102846102e3366004611f1c565b61088d565b6102846102f6366004611f5d565b610898565b61028461090e565b610284610311366004611f1c565b610977565b610284610992565b600b54610259906001600160a01b031681565b61028461033f366004611f96565b610a61565b6102a1600e5481565b61025961035b366004611de1565b610acc565b610239610ade565b610284610376366004611fdf565b610b6c565b610239610bd6565b6102a1610391366004611fdf565b610be3565b610284610c32565b6000546001600160a01b0316610259565b610239610c84565b6102846103c5366004611ffc565b610c93565b600c54610259906001600160a01b031681565b6102846103eb36600461202f565b610d29565b6102396103fe366004611de1565b610d7a565b610208610411366004611f5d565b610ec0565b610284610424366004611fdf565b610fd4565b610284610437366004611f96565b61108a565b60006001600160e01b031982166380ac58cd60e01b148061046d57506001600160e01b03198216635b5e139f60e01b145b8061048857506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606003805461049d9061209b565b80601f01602080910402602001604051908101604052809291908181526020018280546104c99061209b565b80156105165780601f106104eb57610100808354040283529160200191610516565b820191906000526020600020905b8154815290600101906020018083116104f957829003601f168201915b5050505050905090565b600061052b826110e5565b610548576040516333d1c03960e21b815260040160405180910390fd5b506000908152600760205260409020546001600160a01b031690565b6000546001600160a01b031633146105b15760405162461bcd60e51b815260206004820181905260248201526000805160206122da83398151915260448201526064015b60405180910390fd5b600e55565b60006105c182610acc565b9050806001600160a01b0316836001600160a01b031614156105f65760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b0382161480159061061657506106148133610ec0565b155b15610634576040516367d9dca160e11b815260040160405180910390fd5b61063f838383611111565b505050565b6103e8600154106106975760405162461bcd60e51b815260206004820152601e60248201527f54656a6976657273653a206d617820737570706c79206578636565646564000060448201526064016105a8565b600e546001146106f75760405162461bcd60e51b815260206004820152602560248201527f54656a6976657273653a2077686974656c6973742073616c65206973206e6f746044820152641037b832b760d91b60648201526084016105a8565b336000908152600f602052604090205460ff16156107575760405162461bcd60e51b815260206004820152601a60248201527f54656a6976657273653a20616c726561647920636c61696d656400000000000060448201526064016105a8565b6040516bffffffffffffffffffffffff1930606090811b8216602084015233901b16603482015260009060480160408051601f198184030181529190528051602090910120600d549091506001600160a01b031661080c83610806846040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b9061116d565b6001600160a01b0316146108625760405162461bcd60e51b815260206004820152601c60248201527f54656a6976657273653a20696e76616c6964207369676e61747572650000000060448201526064016105a8565b336000818152600f60205260409020805460ff191660019081179091556108899190611191565b5050565b61063f8383836111ab565b6000546001600160a01b031633146108e05760405162461bcd60e51b815260206004820181905260248201526000805160206122da83398151915260448201526064016105a8565b600b80546001600160a01b039384166001600160a01b031991821617909155600c8054929093169116179055565b6000546001600160a01b031633146109565760405162461bcd60e51b815260206004820181905260248201526000805160206122da83398151915260448201526064016105a8565b600c805460ff60a01b198116600160a01b9182900460ff1615909102179055565b61063f83838360405180602001604052806000815250610d29565b6103e8600154106109e55760405162461bcd60e51b815260206004820152601e60248201527f54656a6976657273653a206d617820737570706c79206578636565646564000060448201526064016105a8565b6000546001600160a01b03163314610a5457600e54600214610a545760405162461bcd60e51b815260206004820152602260248201527f54656a6976657273653a207075626c69632073616c65206973206e6f74206f7060448201526132b760f11b60648201526084016105a8565b610a5f336001611191565b565b6000546001600160a01b03163314610aa95760405162461bcd60e51b815260206004820181905260248201526000805160206122da83398151915260448201526064016105a8565b8051610abc90600a906020840190611c74565b50610ac960096000611cf8565b50565b6000610ad7826113c1565b5192915050565b600a8054610aeb9061209b565b80601f0160208091040260200160405190810160405280929190818152602001828054610b179061209b565b8015610b645780601f10610b3957610100808354040283529160200191610b64565b820191906000526020600020905b815481529060010190602001808311610b4757829003601f168201915b505050505081565b6000546001600160a01b03163314610bb45760405162461bcd60e51b815260206004820181905260248201526000805160206122da83398151915260448201526064016105a8565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b60098054610aeb9061209b565b60006001600160a01b038216610c0c576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b031660009081526006602052604090205467ffffffffffffffff1690565b6000546001600160a01b03163314610c7a5760405162461bcd60e51b815260206004820181905260248201526000805160206122da83398151915260448201526064016105a8565b610a5f60006114dd565b60606004805461049d9061209b565b6001600160a01b038216331415610cbd5760405163b06307db60e01b815260040160405180910390fd5b3360008181526008602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b610d348484846111ab565b6001600160a01b0383163b15158015610d565750610d548484848461152d565b155b15610d74576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b6060610d85826110e5565b610de55760405162461bcd60e51b815260206004820152602b60248201527f4552433732314d657461646174613a20717565727920666f72206e6f6e65786960448201526a39ba34b733903a37b5b2b760a91b60648201526084016105a8565b600060098054610df49061209b565b90501115610e8e5760098054610e099061209b565b80601f0160208091040260200160405190810160405280929190818152602001828054610e359061209b565b8015610e825780601f10610e5757610100808354040283529160200191610e82565b820191906000526020600020905b815481529060010190602001808311610e6557829003601f168201915b50505050509050919050565b600a610e9983611616565b604051602001610eaa9291906120f2565b6040516020818303038152906040529050919050565b600c54600090600160a01b900460ff16610f0357506001600160a01b0382811660009081526008602090815260408083209385168352929052205460ff16610488565b600b5460405163c455279160e01b81526001600160a01b0385811660048301529091169063c455279190602401602060405180830381865afa158015610f4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f719190612199565b6001600160a01b0316826001600160a01b03161480610f9d5750600c546001600160a01b038381169116145b80610fcd57506001600160a01b0380841660009081526008602090815260408083209386168352929052205460ff165b9392505050565b6000546001600160a01b0316331461101c5760405162461bcd60e51b815260206004820181905260248201526000805160206122da83398151915260448201526064016105a8565b6001600160a01b0381166110815760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105a8565b610ac9816114dd565b6000546001600160a01b031633146110d25760405162461bcd60e51b815260206004820181905260248201526000805160206122da83398151915260448201526064016105a8565b8051610889906009906020840190611c74565b600060015482108015610488575050600090815260056020526040902054600160e01b900460ff161590565b60008281526007602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600080600061117c858561172c565b915091506111898161179c565b509392505050565b610889828260405180602001604052806000815250611957565b60006111b6826113c1565b80519091506000906001600160a01b0316336001600160a01b031614806111e4575081516111e49033610ec0565b806111ff5750336111f484610520565b6001600160a01b0316145b90508061121f57604051632ce44b5f60e11b815260040160405180910390fd5b846001600160a01b031682600001516001600160a01b0316146112545760405162a1148160e81b815260040160405180910390fd5b6001600160a01b03841661127b57604051633a954ecd60e21b815260040160405180910390fd5b61128b6000848460000151611111565b6001600160a01b038581166000908152600660209081526040808320805467ffffffffffffffff1980821667ffffffffffffffff92831660001901831617909255898616808652838620805493841693831660019081018416949094179055898652600590945282852080546001600160e01b031916909417600160a01b42909216919091021790925590860180835291205490911661137757600154811015611377578251600082815260056020908152604090912080549186015167ffffffffffffffff16600160a01b026001600160e01b03199092166001600160a01b03909316929092171790555b5082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b5050505050565b6040805160608101825260008082526020820181905291810191909152816001548110156114c457600081815260056020908152604091829020825160608101845290546001600160a01b0381168252600160a01b810467ffffffffffffffff1692820192909252600160e01b90910460ff161515918101829052906114c25780516001600160a01b031615611458579392505050565b5060001901600081815260056020908152604091829020825160608101845290546001600160a01b038116808352600160a01b820467ffffffffffffffff1693830193909352600160e01b900460ff16151592810192909252156114bd579392505050565b611458565b505b604051636f96cda160e11b815260040160405180910390fd5b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906115629033908990889088906004016121b6565b6020604051808303816000875af192505050801561159d575060408051601f3d908101601f1916820190925261159a918101906121f2565b60015b6115f8573d8080156115cb576040519150601f19603f3d011682016040523d82523d6000602084013e6115d0565b606091505b5080516115f0576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b60608161163a5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611664578061164e81612225565b915061165d9050600a83612256565b915061163e565b60008167ffffffffffffffff81111561167f5761167f611e3b565b6040519080825280601f01601f1916602001820160405280156116a9576020820181803683370190505b5090505b841561160e576116be60018361226a565b91506116cb600a86612281565b6116d6906030612295565b60f81b8183815181106116eb576116eb6122ad565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611725600a86612256565b94506116ad565b6000808251604114156117635760208301516040840151606085015160001a61175787828585611964565b94509450505050611795565b82516040141561178d5760208301516040840151611782868383611a51565b935093505050611795565b506000905060025b9250929050565b60008160048111156117b0576117b06122c3565b14156117b95750565b60018160048111156117cd576117cd6122c3565b141561181b5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105a8565b600281600481111561182f5761182f6122c3565b141561187d5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105a8565b6003816004811115611891576118916122c3565b14156118ea5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016105a8565b60048160048111156118fe576118fe6122c3565b1415610ac95760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016105a8565b61063f8383836001611aa3565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561199b5750600090506003611a48565b8460ff16601b141580156119b357508460ff16601c14155b156119c45750600090506004611a48565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611a18573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611a4157600060019250925050611a48565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681611a8760ff86901c601b612295565b9050611a9587828885611964565b935093505050935093915050565b6001546001600160a01b038516611acc57604051622e076360e81b815260040160405180910390fd5b83611aea5760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038516600081815260066020908152604080832080546fffffffffffffffffffffffffffffffff19811667ffffffffffffffff8083168c0181169182176801000000000000000067ffffffffffffffff1990941690921783900481168c01811690920217909155858452600590925290912080546001600160e01b031916909217600160a01b429092169190910217905580808501838015611b9c57506001600160a01b0387163b15155b15611c25575b60405182906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4611bed600088848060010195508861152d565b611c0a576040516368d2bf6b60e11b815260040160405180910390fd5b80821415611ba2578260015414611c2057600080fd5b611c6b565b5b6040516001830192906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a480821415611c26575b506001556113ba565b828054611c809061209b565b90600052602060002090601f016020900481019282611ca25760008555611ce8565b82601f10611cbb57805160ff1916838001178555611ce8565b82800160010185558215611ce8579182015b82811115611ce8578251825591602001919060010190611ccd565b50611cf4929150611d2e565b5090565b508054611d049061209b565b6000825580601f10611d14575050565b601f016020900490600052602060002090810190610ac991905b5b80821115611cf45760008155600101611d2f565b6001600160e01b031981168114610ac957600080fd5b600060208284031215611d6b57600080fd5b8135610fcd81611d43565b60005b83811015611d91578181015183820152602001611d79565b83811115610d745750506000910152565b60008151808452611dba816020860160208601611d76565b601f01601f19169290920160200192915050565b602081526000610fcd6020830184611da2565b600060208284031215611df357600080fd5b5035919050565b6001600160a01b0381168114610ac957600080fd5b60008060408385031215611e2257600080fd5b8235611e2d81611dfa565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115611e6c57611e6c611e3b565b604051601f8501601f19908116603f01168101908282118183101715611e9457611e94611e3b565b81604052809350858152868686011115611ead57600080fd5b858560208301376000602087830101525050509392505050565b600082601f830112611ed857600080fd5b610fcd83833560208501611e51565b600060208284031215611ef957600080fd5b813567ffffffffffffffff811115611f1057600080fd5b61160e84828501611ec7565b600080600060608486031215611f3157600080fd5b8335611f3c81611dfa565b92506020840135611f4c81611dfa565b929592945050506040919091013590565b60008060408385031215611f7057600080fd5b8235611f7b81611dfa565b91506020830135611f8b81611dfa565b809150509250929050565b600060208284031215611fa857600080fd5b813567ffffffffffffffff811115611fbf57600080fd5b8201601f81018413611fd057600080fd5b61160e84823560208401611e51565b600060208284031215611ff157600080fd5b8135610fcd81611dfa565b6000806040838503121561200f57600080fd5b823561201a81611dfa565b915060208301358015158114611f8b57600080fd5b6000806000806080858703121561204557600080fd5b843561205081611dfa565b9350602085013561206081611dfa565b925060408501359150606085013567ffffffffffffffff81111561208357600080fd5b61208f87828801611ec7565b91505092959194509250565b600181811c908216806120af57607f821691505b602082108114156120d057634e487b7160e01b600052602260045260246000fd5b50919050565b600081516120e8818560208601611d76565b9290920192915050565b600080845481600182811c91508083168061210e57607f831692505b602080841082141561212e57634e487b7160e01b86526022600452602486fd5b818015612142576001811461215357612180565b60ff19861689528489019650612180565b60008b81526020902060005b868110156121785781548b82015290850190830161215f565b505084890196505b50505050505061219081856120d6565b95945050505050565b6000602082840312156121ab57600080fd5b8151610fcd81611dfa565b60006001600160a01b038087168352808616602084015250836040830152608060608301526121e86080830184611da2565b9695505050505050565b60006020828403121561220457600080fd5b8151610fcd81611d43565b634e487b7160e01b600052601160045260246000fd5b60006000198214156122395761223961220f565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261226557612265612240565b500490565b60008282101561227c5761227c61220f565b500390565b60008261229057612290612240565b500690565b600082198211156122a8576122a861220f565b500190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fdfe4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a2646970667358221220c49623acfce159438ea9bee66927abbc873325a5e9909ac66a00e32d4bef092664736f6c634300080b0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000000000000000000000000000000000000000000400000000000000000000000007b85fda7524bafcf59d02694dda7f323f75451490000000000000000000000000000000000000000000000000000000000000035697066733a2f2f516d5a6f43617137656d566e6b536672526574566d614448655a6953725439733165516d525748477a387938506d0000000000000000000000

-----Decoded View---------------
Arg [0] : newUnrevealedURI (string): ipfs://QmZoCaq7emVnkSfrRetVmaDHeZiSrT9s1eQmRWHGz8y8Pm
Arg [1] : newSigner (address): 0x7b85FDa7524BAfCf59d02694DdA7F323F7545149

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 0000000000000000000000007b85fda7524bafcf59d02694dda7f323f7545149
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000035
Arg [3] : 697066733a2f2f516d5a6f43617137656d566e6b536672526574566d61444865
Arg [4] : 5a6953725439733165516d525748477a387938506d0000000000000000000000


Deployed Bytecode Sourcemap

55849:5755:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37806:305;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;37806:305:0;;;;;;;;56812:32;;;;;-1:-1:-1;;;56812:32:0;;;;;;41191:100;;;:::i;:::-;;;;;;;:::i;42694:204::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1714:55:1;;;1696:74;;1684:2;1669:18;42694:204:0;1550:226:1;59676:100:0;;;;;;:::i;:::-;;:::i;:::-;;42257:371;;;;;;:::i;:::-;;:::i;37055:303::-;37309:12;;37293:13;;:28;37055:303;;;2406:25:1;;;2394:2;2379:18;37055:303:0;2260:177:1;58336:538:0;;;;;;:::i;:::-;;:::i;57155:21::-;;;;;-1:-1:-1;;;;;57155:21:0;;;43551:170;;;;;;:::i;:::-;;:::i;60196:150::-;;;;;;:::i;:::-;;:::i;60412:114::-;;;:::i;43792:185::-;;;;;;:::i;:::-;;:::i;57981:246::-;;;:::i;56636:22::-;;;;;-1:-1:-1;;;;;56636:22:0;;;59452:125;;;;;;:::i;:::-;;:::i;57237:24::-;;;;;;41000:124;;;;;;:::i;:::-;;:::i;56315:21::-;;;:::i;59880:88::-;;;;;;:::i;:::-;;:::i;56247:27::-;;;:::i;38175:206::-;;;;;;:::i;:::-;;:::i;14264:103::-;;;:::i;13613:87::-;13659:7;13686:6;-1:-1:-1;;;;;13686:6:0;13613:87;;41360:104;;;:::i;42970:279::-;;;;;;:::i;:::-;;:::i;56720:24::-;;;;;-1:-1:-1;;;;;56720:24:0;;;44048:369;;;;;;:::i;:::-;;:::i;60824:283::-;;;;;;:::i;:::-;;:::i;61257:344::-;;;;;;:::i;:::-;;:::i;14522:201::-;;;;;;:::i;:::-;;:::i;59241:122::-;;;;;;:::i;:::-;;:::i;37806:305::-;37908:4;-1:-1:-1;;;;;;37945:40:0;;-1:-1:-1;;;37945:40:0;;:105;;-1:-1:-1;;;;;;;38002:48:0;;-1:-1:-1;;;38002:48:0;37945:105;:158;;;-1:-1:-1;;;;;;;;;;26506:40:0;;;38067:36;37925:178;37806:305;-1:-1:-1;;37806:305:0:o;41191:100::-;41245:13;41278:5;41271:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41191:100;:::o;42694:204::-;42762:7;42787:16;42795:7;42787;:16::i;:::-;42782:64;;42812:34;;-1:-1:-1;;;42812:34:0;;;;;;;;;;;42782:64;-1:-1:-1;42866:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;42866:24:0;;42694:204::o;59676:100::-;13659:7;13686:6;-1:-1:-1;;;;;13686:6:0;12417:10;13833:23;13825:68;;;;-1:-1:-1;;;13825:68:0;;6999:2:1;13825:68:0;;;6981:21:1;;;7018:18;;;7011:30;-1:-1:-1;;;;;;;;;;;7057:18:1;;;7050:62;7129:18;;13825:68:0;;;;;;;;;59746:9:::1;:24:::0;59676:100::o;42257:371::-;42330:13;42346:24;42362:7;42346:15;:24::i;:::-;42330:40;;42391:5;-1:-1:-1;;;;;42385:11:0;:2;-1:-1:-1;;;;;42385:11:0;;42381:48;;;42405:24;;-1:-1:-1;;;42405:24:0;;;;;;;;;;;42381:48;12417:10;-1:-1:-1;;;;;42446:21:0;;;;;;:63;;-1:-1:-1;42472:37:0;42489:5;12417:10;61257:344;:::i;42472:37::-;42471:38;42446:63;42442:138;;;42533:35;;-1:-1:-1;;;42533:35:0;;;;;;;;;;;42442:138;42592:28;42601:2;42605:7;42614:5;42592:8;:28::i;:::-;42319:309;42257:371;;:::o;58336:538::-;58424:4;58408:13;;:20;58400:63;;;;-1:-1:-1;;;58400:63:0;;7360:2:1;58400:63:0;;;7342:21:1;7399:2;7379:18;;;7372:30;7438:32;7418:18;;;7411:60;7488:18;;58400:63:0;7158:354:1;58400:63:0;58478:9;;58491:1;58478:14;58470:64;;;;-1:-1:-1;;;58470:64:0;;7719:2:1;58470:64:0;;;7701:21:1;7758:2;7738:18;;;7731:30;7797:34;7777:18;;;7770:62;-1:-1:-1;;;7848:18:1;;;7841:35;7893:19;;58470:64:0;7517:401:1;58470:64:0;58565:10;58550:26;;;;:14;:26;;;;;;;;58549:27;58541:66;;;;-1:-1:-1;;;58541:66:0;;8125:2:1;58541:66:0;;;8107:21:1;8164:2;8144:18;;;8137:30;8203:28;8183:18;;;8176:56;8249:18;;58541:66:0;7923:350:1;58541:66:0;58643:43;;-1:-1:-1;;58668:4:0;8505:2:1;8501:15;;;8497:24;;58643:43:0;;;8485:37:1;58675:10:0;8556:15:1;;8552:24;8538:12;;;8531:46;58616:14:0;;8593:12:1;;58643:43:0;;;-1:-1:-1;;58643:43:0;;;;;;;;;58633:54;;58643:43;58633:54;;;;58756:6;;58633:54;;-1:-1:-1;;;;;;58756:6:0;58702:50;58742:9;58702:31;58633:54;10545:58;;12217:66:1;10545:58:0;;;12205:79:1;12300:12;;;12293:28;;;10412:7:0;;12337:12:1;;10545:58:0;;;;;;;;;;;;10535:69;;;;;;10528:76;;10343:269;;;;58702:31;:39;;:50::i;:::-;-1:-1:-1;;;;;58702:60:0;;58694:101;;;;-1:-1:-1;;;58694:101:0;;8818:2:1;58694:101:0;;;8800:21:1;8857:2;8837:18;;;8830:30;8896;8876:18;;;8869:58;8944:18;;58694:101:0;8616:352:1;58694:101:0;58819:10;58804:26;;;;:14;:26;;;;;:33;;-1:-1:-1;;58804:33:0;58833:4;58804:33;;;;;;58844:24;;58819:10;58844:9;:24::i;:::-;58393:481;58336:538;:::o;43551:170::-;43685:28;43695:4;43701:2;43705:7;43685:9;:28::i;60196:150::-;13659:7;13686:6;-1:-1:-1;;;;;13686:6:0;12417:10;13833:23;13825:68;;;;-1:-1:-1;;;13825:68:0;;6999:2:1;13825:68:0;;;6981:21:1;;;7018:18;;;7011:30;-1:-1:-1;;;;;;;;;;;7057:18:1;;;7050:62;7129:18;;13825:68:0;6797:356:1;13825:68:0;60289:7:::1;:20:::0;;-1:-1:-1;;;;;60289:20:0;;::::1;-1:-1:-1::0;;;;;;60289:20:0;;::::1;;::::0;;;60316:9:::1;:24:::0;;;;;::::1;::::0;::::1;;::::0;;60196:150::o;60412:114::-;13659:7;13686:6;-1:-1:-1;;;;;13686:6:0;12417:10;13833:23;13825:68;;;;-1:-1:-1;;;13825:68:0;;6999:2:1;13825:68:0;;;6981:21:1;;;7018:18;;;7011:30;-1:-1:-1;;;;;;;;;;;7057:18:1;;;7050:62;7129:18;;13825:68:0;6797:356:1;13825:68:0;60500:20:::1;::::0;;-1:-1:-1;;;;60476:44:0;::::1;-1:-1:-1::0;;;60500:20:0;;;::::1;;;60499:21;60476:44:::0;;::::1;;::::0;;60412:114::o;43792:185::-;43930:39;43947:4;43953:2;43957:7;43930:39;;;;;;;;;;;;:16;:39::i;57981:246::-;58038:4;58022:13;;:20;58014:63;;;;-1:-1:-1;;;58014:63:0;;7360:2:1;58014:63:0;;;7342:21:1;7399:2;7379:18;;;7372:30;7438:32;7418:18;;;7411:60;7488:18;;58014:63:0;7158:354:1;58014:63:0;13659:7;13686:6;-1:-1:-1;;;;;13686:6:0;58088:10;:21;58084:105;;58128:9;;58141:1;58128:14;58120:61;;;;-1:-1:-1;;;58120:61:0;;9175:2:1;58120:61:0;;;9157:21:1;9214:2;9194:18;;;9187:30;9253:34;9233:18;;;9226:62;-1:-1:-1;;;9304:18:1;;;9297:32;9346:19;;58120:61:0;8973:398:1;58120:61:0;58197:24;58207:10;58219:1;58197:9;:24::i;:::-;57981:246::o;59452:125::-;13659:7;13686:6;-1:-1:-1;;;;;13686:6:0;12417:10;13833:23;13825:68;;;;-1:-1:-1;;;13825:68:0;;6999:2:1;13825:68:0;;;6981:21:1;;;7018:18;;;7011:30;-1:-1:-1;;;;;;;;;;;7057:18:1;;;7050:62;7129:18;;13825:68:0;6797:356:1;13825:68:0;59524:20;;::::1;::::0;:7:::1;::::0;:20:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;59551:20:0::1;59558:13;;59551:20;:::i;:::-;59452:125:::0;:::o;41000:124::-;41064:7;41091:20;41103:7;41091:11;:20::i;:::-;:25;;41000:124;-1:-1:-1;;41000:124:0:o;56315:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;59880:88::-;13659:7;13686:6;-1:-1:-1;;;;;13686:6:0;12417:10;13833:23;13825:68;;;;-1:-1:-1;;;13825:68:0;;6999:2:1;13825:68:0;;;6981:21:1;;;7018:18;;;7011:30;-1:-1:-1;;;;;;;;;;;7057:18:1;;;7050:62;7129:18;;13825:68:0;6797:356:1;13825:68:0;59944:6:::1;:18:::0;;-1:-1:-1;;;;;;59944:18:0::1;-1:-1:-1::0;;;;;59944:18:0;;;::::1;::::0;;;::::1;::::0;;59880:88::o;56247:27::-;;;;;;;:::i;38175:206::-;38239:7;-1:-1:-1;;;;;38263:19:0;;38259:60;;38291:28;;-1:-1:-1;;;38291:28:0;;;;;;;;;;;38259:60;-1:-1:-1;;;;;;38345:19:0;;;;;:12;:19;;;;;:27;;;;38175:206::o;14264:103::-;13659:7;13686:6;-1:-1:-1;;;;;13686:6:0;12417:10;13833:23;13825:68;;;;-1:-1:-1;;;13825:68:0;;6999:2:1;13825:68:0;;;6981:21:1;;;7018:18;;;7011:30;-1:-1:-1;;;;;;;;;;;7057:18:1;;;7050:62;7129:18;;13825:68:0;6797:356:1;13825:68:0;14329:30:::1;14356:1;14329:18;:30::i;41360:104::-:0;41416:13;41449:7;41442:14;;;;;:::i;42970:279::-;-1:-1:-1;;;;;43061:24:0;;12417:10;43061:24;43057:54;;;43094:17;;-1:-1:-1;;;43094:17:0;;;;;;;;;;;43057:54;12417:10;43124:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;43124:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;43124:53:0;;;;;;;;;;43193:48;;540:41:1;;;43124:42:0;;12417:10;43193:48;;513:18:1;43193:48:0;;;;;;;42970:279;;:::o;44048:369::-;44215:28;44225:4;44231:2;44235:7;44215:9;:28::i;:::-;-1:-1:-1;;;;;44258:13:0;;16609:19;:23;;44258:76;;;;;44278:56;44309:4;44315:2;44319:7;44328:5;44278:30;:56::i;:::-;44277:57;44258:76;44254:156;;;44358:40;;-1:-1:-1;;;44358:40:0;;;;;;;;;;;44254:156;44048:369;;;;:::o;60824:283::-;60884:13;60914:11;60922:2;60914:7;:11::i;:::-;60906:67;;;;-1:-1:-1;;;60906:67:0;;9578:2:1;60906:67:0;;;9560:21:1;9617:2;9597:18;;;9590:30;9656:34;9636:18;;;9629:62;-1:-1:-1;;;9707:18:1;;;9700:41;9758:19;;60906:67:0;9376:407:1;60906:67:0;61016:1;60992:13;60986:27;;;;;:::i;:::-;;;:31;60982:57;;;61026:13;61019:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60824:283;;;:::o;60982:57::-;61077:7;61086:13;:2;:11;:13::i;:::-;61060:40;;;;;;;;;:::i;:::-;;;;;;;;;;;;;61046:55;;60824:283;;;:::o;61257:344::-;61364:20;;61346:4;;-1:-1:-1;;;61364:20:0;;;;61359:73;;-1:-1:-1;;;;;;43441:25:0;;;43417:4;43441:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;61386:46;;61359:73;61489:7;;61475:37;;-1:-1:-1;;;61475:37:0;;-1:-1:-1;;;;;1714:55:1;;;61475:37:0;;;1696:74:1;61489:7:0;;;;61475:30;;1669:18:1;;61475:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;61455:58:0;:8;-1:-1:-1;;;;;61455:58:0;;:90;;;-1:-1:-1;61536:9:0;;-1:-1:-1;;;;;61524:21:0;;;61536:9;;61524:21;61455:90;:140;;;-1:-1:-1;;;;;;43441:25:0;;;43417:4;43441:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;61556:39;61441:154;61257:344;-1:-1:-1;;;61257:344:0:o;14522:201::-;13659:7;13686:6;-1:-1:-1;;;;;13686:6:0;12417:10;13833:23;13825:68;;;;-1:-1:-1;;;13825:68:0;;6999:2:1;13825:68:0;;;6981:21:1;;;7018:18;;;7011:30;-1:-1:-1;;;;;;;;;;;7057:18:1;;;7050:62;7129:18;;13825:68:0;6797:356:1;13825:68:0;-1:-1:-1;;;;;14611:22:0;::::1;14603:73;;;::::0;-1:-1:-1;;;14603:73:0;;11770:2:1;14603:73:0::1;::::0;::::1;11752:21:1::0;11809:2;11789:18;;;11782:30;11848:34;11828:18;;;11821:62;-1:-1:-1;;;11899:18:1;;;11892:36;11945:19;;14603:73:0::1;11568:402:1::0;14603:73:0::1;14687:28;14706:8;14687:18;:28::i;59241:122::-:0;13659:7;13686:6;-1:-1:-1;;;;;13686:6:0;12417:10;13833:23;13825:68;;;;-1:-1:-1;;;13825:68:0;;6999:2:1;13825:68:0;;;6981:21:1;;;7018:18;;;7011:30;-1:-1:-1;;;;;;;;;;;7057:18:1;;;7050:62;7129:18;;13825:68:0;6797:356:1;13825:68:0;59325:32;;::::1;::::0;:13:::1;::::0;:32:::1;::::0;::::1;::::0;::::1;:::i;44672:187::-:0;44729:4;44793:13;;44783:7;:23;44753:98;;;;-1:-1:-1;;44824:20:0;;;;:11;:20;;;;;:27;-1:-1:-1;;;44824:27:0;;;;44823:28;;44672:187::o;52283:196::-;52398:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;52398:29:0;-1:-1:-1;;;;;52398:29:0;;;;;;;;;52443:28;;52398:24;;52443:28;;;;;;;52283:196;;;:::o;6541:231::-;6619:7;6640:17;6659:18;6681:27;6692:4;6698:9;6681:10;:27::i;:::-;6639:69;;;;6719:18;6731:5;6719:11;:18::i;:::-;-1:-1:-1;6755:9:0;6541:231;-1:-1:-1;;;6541:231:0:o;44867:104::-;44936:27;44946:2;44950:8;44936:27;;;;;;;;;;;;:9;:27::i;47785:2112::-;47900:35;47938:20;47950:7;47938:11;:20::i;:::-;48013:18;;47900:58;;-1:-1:-1;47971:22:0;;-1:-1:-1;;;;;47997:34:0;12417:10;-1:-1:-1;;;;;47997:34:0;;:101;;;-1:-1:-1;48065:18:0;;48048:50;;12417:10;61257:344;:::i;48048:50::-;47997:154;;;-1:-1:-1;12417:10:0;48115:20;48127:7;48115:11;:20::i;:::-;-1:-1:-1;;;;;48115:36:0;;47997:154;47971:181;;48170:17;48165:66;;48196:35;;-1:-1:-1;;;48196:35:0;;;;;;;;;;;48165:66;48268:4;-1:-1:-1;;;;;48246:26:0;:13;:18;;;-1:-1:-1;;;;;48246:26:0;;48242:67;;48281:28;;-1:-1:-1;;;48281:28:0;;;;;;;;;;;48242:67;-1:-1:-1;;;;;48324:16:0;;48320:52;;48349:23;;-1:-1:-1;;;48349:23:0;;;;;;;;;;;48320:52;48493:49;48510:1;48514:7;48523:13;:18;;;48493:8;:49::i;:::-;-1:-1:-1;;;;;48838:18:0;;;;;;;:12;:18;;;;;;;;:31;;-1:-1:-1;;48838:31:0;;;;;;;-1:-1:-1;;48838:31:0;;;;;;;48884:16;;;;;;;;;:29;;;;;;;;-1:-1:-1;48884:29:0;;;;;;;;;;;48930:20;;;:11;:20;;;;;;:30;;-1:-1:-1;;;;;;48975:61:0;;;;-1:-1:-1;;;49020:15:0;48975:61;;;;;;;;;;;49310:11;;;49340:24;;;;;:29;49310:11;;49340:29;49336:445;;49565:13;;49551:11;:27;49547:219;;;49635:18;;;49603:24;;;:11;:24;;;;;;;;:50;;49718:28;;;;49676:70;;-1:-1:-1;;;49676:70:0;-1:-1:-1;;;;;;49676:70:0;;;-1:-1:-1;;;;;49603:50:0;;;49676:70;;;;;;;49547:219;48813:979;49828:7;49824:2;-1:-1:-1;;;;;49809:27:0;49818:4;-1:-1:-1;;;;;49809:27:0;;;;;;;;;;;49847:42;47889:2008;;47785:2112;;;:::o;39830:1108::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;39940:7:0;40023:13;;40016:4;:20;39985:886;;;40057:31;40091:17;;;:11;:17;;;;;;;;;40057:51;;;;;;;;;-1:-1:-1;;;;;40057:51:0;;;;-1:-1:-1;;;40057:51:0;;;;;;;;;;;-1:-1:-1;;;40057:51:0;;;;;;;;;;;;;;40127:729;;40177:14;;-1:-1:-1;;;;;40177:28:0;;40173:101;;40241:9;39830:1108;-1:-1:-1;;;39830:1108:0:o;40173:101::-;-1:-1:-1;;;40616:6:0;40661:17;;;;:11;:17;;;;;;;;;40649:29;;;;;;;;;-1:-1:-1;;;;;40649:29:0;;;;;-1:-1:-1;;;40649:29:0;;;;;;;;;;;-1:-1:-1;;;40649:29:0;;;;;;;;;;;;;40709:28;40705:109;;40777:9;39830:1108;-1:-1:-1;;;39830:1108:0:o;40705:109::-;40576:261;;;40038:833;39985:886;40899:31;;-1:-1:-1;;;40899:31:0;;;;;;;;;;;14883:191;14957:16;14976:6;;-1:-1:-1;;;;;14993:17:0;;;-1:-1:-1;;;;;;14993:17:0;;;;;;15026:40;;14976:6;;;;;;;15026:40;;14957:16;15026:40;14946:128;14883:191;:::o;52971:667::-;53155:72;;-1:-1:-1;;;53155:72:0;;53134:4;;-1:-1:-1;;;;;53155:36:0;;;;;:72;;12417:10;;53206:4;;53212:7;;53221:5;;53155:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53155:72:0;;;;;;;;-1:-1:-1;;53155:72:0;;;;;;;;;;;;:::i;:::-;;;53151:480;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53389:13:0;;53385:235;;53435:40;;-1:-1:-1;;;53435:40:0;;;;;;;;;;;53385:235;53578:6;53572:13;53563:6;53559:2;53555:15;53548:38;53151:480;-1:-1:-1;;;;;;53274:55:0;-1:-1:-1;;;53274:55:0;;-1:-1:-1;53151:480:0;52971:667;;;;;;:::o;365:723::-;421:13;642:10;638:53;;-1:-1:-1;;669:10:0;;;;;;;;;;;;-1:-1:-1;;;669:10:0;;;;;365:723::o;638:53::-;716:5;701:12;757:78;764:9;;757:78;;790:8;;;;:::i;:::-;;-1:-1:-1;813:10:0;;-1:-1:-1;821:2:0;813:10;;:::i;:::-;;;757:78;;;845:19;877:6;867:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;867:17:0;;845:39;;895:154;902:10;;895:154;;929:11;939:1;929:11;;:::i;:::-;;-1:-1:-1;998:10:0;1006:2;998:5;:10;:::i;:::-;985:24;;:2;:24;:::i;:::-;972:39;;955:6;962;955:14;;;;;;;;:::i;:::-;;;;:56;;;;;;;;;;-1:-1:-1;1026:11:0;1035:2;1026:11;;:::i;:::-;;;895:154;;4431:1308;4512:7;4521:12;4746:9;:16;4766:2;4746:22;4742:990;;;5042:4;5027:20;;5021:27;5092:4;5077:20;;5071:27;5150:4;5135:20;;5129:27;4785:9;5121:36;5193:25;5204:4;5121:36;5021:27;5071;5193:10;:25::i;:::-;5186:32;;;;;;;;;4742:990;5240:9;:16;5260:2;5240:22;5236:496;;;5515:4;5500:20;;5494:27;5566:4;5551:20;;5545:27;5608:23;5619:4;5494:27;5545;5608:10;:23::i;:::-;5601:30;;;;;;;;5236:496;-1:-1:-1;5680:1:0;;-1:-1:-1;5684:35:0;5236:496;4431:1308;;;;;:::o;2702:643::-;2780:20;2771:5;:29;;;;;;;;:::i;:::-;;2767:571;;;2702:643;:::o;2767:571::-;2878:29;2869:5;:38;;;;;;;;:::i;:::-;;2865:473;;;2924:34;;-1:-1:-1;;;2924:34:0;;14517:2:1;2924:34:0;;;14499:21:1;14556:2;14536:18;;;14529:30;14595:26;14575:18;;;14568:54;14639:18;;2924:34:0;14315:348:1;2865:473:0;2989:35;2980:5;:44;;;;;;;;:::i;:::-;;2976:362;;;3041:41;;-1:-1:-1;;;3041:41:0;;14870:2:1;3041:41:0;;;14852:21:1;14909:2;14889:18;;;14882:30;14948:33;14928:18;;;14921:61;14999:18;;3041:41:0;14668:355:1;2976:362:0;3113:30;3104:5;:39;;;;;;;;:::i;:::-;;3100:238;;;3160:44;;-1:-1:-1;;;3160:44:0;;15230:2:1;3160:44:0;;;15212:21:1;15269:2;15249:18;;;15242:30;15308:34;15288:18;;;15281:62;-1:-1:-1;;;15359:18:1;;;15352:32;15401:19;;3160:44:0;15028:398:1;3100:238:0;3235:30;3226:5;:39;;;;;;;;:::i;:::-;;3222:116;;;3282:44;;-1:-1:-1;;;3282:44:0;;15633:2:1;3282:44:0;;;15615:21:1;15672:2;15652:18;;;15645:30;15711:34;15691:18;;;15684:62;-1:-1:-1;;;15762:18:1;;;15755:32;15804:19;;3282:44:0;15431:398:1;45334:163:0;45457:32;45463:2;45467:8;45477:5;45484:4;45457:5;:32::i;7993:1632::-;8124:7;;9058:66;9045:79;;9041:163;;;-1:-1:-1;9157:1:0;;-1:-1:-1;9161:30:0;9141:51;;9041:163;9218:1;:7;;9223:2;9218:7;;:18;;;;;9229:1;:7;;9234:2;9229:7;;9218:18;9214:102;;;-1:-1:-1;9269:1:0;;-1:-1:-1;9273:30:0;9253:51;;9214:102;9430:24;;;9413:14;9430:24;;;;;;;;;16061:25:1;;;16134:4;16122:17;;16102:18;;;16095:45;;;;16156:18;;;16149:34;;;16199:18;;;16192:34;;;9430:24:0;;16033:19:1;;9430:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;9430:24:0;;-1:-1:-1;;9430:24:0;;;-1:-1:-1;;;;;;;9469:20:0;;9465:103;;9522:1;9526:29;9506:50;;;;;;;9465:103;9588:6;-1:-1:-1;9596:20:0;;-1:-1:-1;7993:1632:0;;;;;;;;:::o;7035:344::-;7149:7;;7208:66;7195:80;;7149:7;7302:25;7318:3;7303:18;;;7325:2;7302:25;:::i;:::-;7286:42;;7346:25;7357:4;7363:1;7366;7369;7346:10;:25::i;:::-;7339:32;;;;;;7035:344;;;;;;:::o;45756:1775::-;45918:13;;-1:-1:-1;;;;;45946:16:0;;45942:48;;45971:19;;-1:-1:-1;;;45971:19:0;;;;;;;;;;;45942:48;46005:13;46001:44;;46027:18;;-1:-1:-1;;;46027:18:0;;;;;;;;;;;46001:44;-1:-1:-1;;;;;46396:16:0;;;;;;:12;:16;;;;;;;;:44;;-1:-1:-1;;46455:49:0;;46396:44;;;;;;;;46455:49;;;;-1:-1:-1;;46396:44:0;;;;;;46455:49;;;;;;;;;;;;;;;;46521:25;;;:11;:25;;;;;;:35;;-1:-1:-1;;;;;;46571:66:0;;;;-1:-1:-1;;;46621:15:0;46571:66;;;;;;;;;;46521:25;46718:23;;;46762:4;:23;;;;-1:-1:-1;;;;;;46770:13:0;;16609:19;:23;;46770:15;46758:641;;;46806:314;46837:38;;46862:12;;-1:-1:-1;;;;;46837:38:0;;;46854:1;;46837:38;;46854:1;;46837:38;46903:69;46942:1;46946:2;46950:14;;;;;;46966:5;46903:30;:69::i;:::-;46898:174;;47008:40;;-1:-1:-1;;;47008:40:0;;;;;;;;;;;46898:174;47115:3;47099:12;:19;;46806:314;;47201:12;47184:13;;:29;47180:43;;47215:8;;;47180:43;46758:641;;;47264:120;47295:40;;47320:14;;;;;-1:-1:-1;;;;;47295:40:0;;;47312:1;;47295:40;;47312:1;;47295:40;47379:3;47363:12;:19;;47264:120;;46758:641;-1:-1:-1;47413:13:0;:28;47463:60;44048:369;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:1;822:16;;815:27;592:258::o;855:269::-;908:3;946:5;940:12;973:6;968:3;961:19;989:63;1045:6;1038:4;1033:3;1029:14;1022:4;1015:5;1011:16;989:63;:::i;:::-;1106:2;1085:15;-1:-1:-1;;1081:29:1;1072:39;;;;1113:4;1068:50;;855:269;-1:-1:-1;;855:269:1:o;1129:231::-;1278:2;1267:9;1260:21;1241:4;1298:56;1350:2;1339:9;1335:18;1327:6;1298:56;:::i;1365:180::-;1424:6;1477:2;1465:9;1456:7;1452:23;1448:32;1445:52;;;1493:1;1490;1483:12;1445:52;-1:-1:-1;1516:23:1;;1365:180;-1:-1:-1;1365:180:1:o;1781:154::-;-1:-1:-1;;;;;1860:5:1;1856:54;1849:5;1846:65;1836:93;;1925:1;1922;1915:12;1940:315;2008:6;2016;2069:2;2057:9;2048:7;2044:23;2040:32;2037:52;;;2085:1;2082;2075:12;2037:52;2124:9;2111:23;2143:31;2168:5;2143:31;:::i;:::-;2193:5;2245:2;2230:18;;;;2217:32;;-1:-1:-1;;;1940:315:1:o;2442:127::-;2503:10;2498:3;2494:20;2491:1;2484:31;2534:4;2531:1;2524:15;2558:4;2555:1;2548:15;2574:631;2638:5;2668:18;2709:2;2701:6;2698:14;2695:40;;;2715:18;;:::i;:::-;2790:2;2784:9;2758:2;2844:15;;-1:-1:-1;;2840:24:1;;;2866:2;2836:33;2832:42;2820:55;;;2890:18;;;2910:22;;;2887:46;2884:72;;;2936:18;;:::i;:::-;2976:10;2972:2;2965:22;3005:6;2996:15;;3035:6;3027;3020:22;3075:3;3066:6;3061:3;3057:16;3054:25;3051:45;;;3092:1;3089;3082:12;3051:45;3142:6;3137:3;3130:4;3122:6;3118:17;3105:44;3197:1;3190:4;3181:6;3173;3169:19;3165:30;3158:41;;;;2574:631;;;;;:::o;3210:220::-;3252:5;3305:3;3298:4;3290:6;3286:17;3282:27;3272:55;;3323:1;3320;3313:12;3272:55;3345:79;3420:3;3411:6;3398:20;3391:4;3383:6;3379:17;3345:79;:::i;3435:320::-;3503:6;3556:2;3544:9;3535:7;3531:23;3527:32;3524:52;;;3572:1;3569;3562:12;3524:52;3612:9;3599:23;3645:18;3637:6;3634:30;3631:50;;;3677:1;3674;3667:12;3631:50;3700:49;3741:7;3732:6;3721:9;3717:22;3700:49;:::i;3760:456::-;3837:6;3845;3853;3906:2;3894:9;3885:7;3881:23;3877:32;3874:52;;;3922:1;3919;3912:12;3874:52;3961:9;3948:23;3980:31;4005:5;3980:31;:::i;:::-;4030:5;-1:-1:-1;4087:2:1;4072:18;;4059:32;4100:33;4059:32;4100:33;:::i;:::-;3760:456;;4152:7;;-1:-1:-1;;;4206:2:1;4191:18;;;;4178:32;;3760:456::o;4221:388::-;4289:6;4297;4350:2;4338:9;4329:7;4325:23;4321:32;4318:52;;;4366:1;4363;4356:12;4318:52;4405:9;4392:23;4424:31;4449:5;4424:31;:::i;:::-;4474:5;-1:-1:-1;4531:2:1;4516:18;;4503:32;4544:33;4503:32;4544:33;:::i;:::-;4596:7;4586:17;;;4221:388;;;;;:::o;4614:450::-;4683:6;4736:2;4724:9;4715:7;4711:23;4707:32;4704:52;;;4752:1;4749;4742:12;4704:52;4792:9;4779:23;4825:18;4817:6;4814:30;4811:50;;;4857:1;4854;4847:12;4811:50;4880:22;;4933:4;4925:13;;4921:27;-1:-1:-1;4911:55:1;;4962:1;4959;4952:12;4911:55;4985:73;5050:7;5045:2;5032:16;5027:2;5023;5019:11;4985:73;:::i;5069:247::-;5128:6;5181:2;5169:9;5160:7;5156:23;5152:32;5149:52;;;5197:1;5194;5187:12;5149:52;5236:9;5223:23;5255:31;5280:5;5255:31;:::i;5321:416::-;5386:6;5394;5447:2;5435:9;5426:7;5422:23;5418:32;5415:52;;;5463:1;5460;5453:12;5415:52;5502:9;5489:23;5521:31;5546:5;5521:31;:::i;:::-;5571:5;-1:-1:-1;5628:2:1;5613:18;;5600:32;5670:15;;5663:23;5651:36;;5641:64;;5701:1;5698;5691:12;5742:665;5837:6;5845;5853;5861;5914:3;5902:9;5893:7;5889:23;5885:33;5882:53;;;5931:1;5928;5921:12;5882:53;5970:9;5957:23;5989:31;6014:5;5989:31;:::i;:::-;6039:5;-1:-1:-1;6096:2:1;6081:18;;6068:32;6109:33;6068:32;6109:33;:::i;:::-;6161:7;-1:-1:-1;6215:2:1;6200:18;;6187:32;;-1:-1:-1;6270:2:1;6255:18;;6242:32;6297:18;6286:30;;6283:50;;;6329:1;6326;6319:12;6283:50;6352:49;6393:7;6384:6;6373:9;6369:22;6352:49;:::i;:::-;6342:59;;;5742:665;;;;;;;:::o;6412:380::-;6491:1;6487:12;;;;6534;;;6555:61;;6609:4;6601:6;6597:17;6587:27;;6555:61;6662:2;6654:6;6651:14;6631:18;6628:38;6625:161;;;6708:10;6703:3;6699:20;6696:1;6689:31;6743:4;6740:1;6733:15;6771:4;6768:1;6761:15;6625:161;;6412:380;;;:::o;9914:185::-;9956:3;9994:5;9988:12;10009:52;10054:6;10049:3;10042:4;10035:5;10031:16;10009:52;:::i;:::-;10077:16;;;;;9914:185;-1:-1:-1;;9914:185:1:o;10104:1174::-;10280:3;10309:1;10342:6;10336:13;10372:3;10394:1;10422:9;10418:2;10414:18;10404:28;;10482:2;10471:9;10467:18;10504;10494:61;;10548:4;10540:6;10536:17;10526:27;;10494:61;10574:2;10622;10614:6;10611:14;10591:18;10588:38;10585:165;;;-1:-1:-1;;;10649:33:1;;10705:4;10702:1;10695:15;10735:4;10656:3;10723:17;10585:165;10766:18;10793:104;;;;10911:1;10906:320;;;;10759:467;;10793:104;-1:-1:-1;;10826:24:1;;10814:37;;10871:16;;;;-1:-1:-1;10793:104:1;;10906:320;9861:1;9854:14;;;9898:4;9885:18;;11001:1;11015:165;11029:6;11026:1;11023:13;11015:165;;;11107:14;;11094:11;;;11087:35;11150:16;;;;11044:10;;11015:165;;;11019:3;;11209:6;11204:3;11200:16;11193:23;;10759:467;;;;;;;11242:30;11268:3;11260:6;11242:30;:::i;:::-;11235:37;10104:1174;-1:-1:-1;;;;;10104:1174:1:o;11283:280::-;11382:6;11435:2;11423:9;11414:7;11410:23;11406:32;11403:52;;;11451:1;11448;11441:12;11403:52;11483:9;11477:16;11502:31;11527:5;11502:31;:::i;12360:523::-;12554:4;-1:-1:-1;;;;;12664:2:1;12656:6;12652:15;12641:9;12634:34;12716:2;12708:6;12704:15;12699:2;12688:9;12684:18;12677:43;;12756:6;12751:2;12740:9;12736:18;12729:34;12799:3;12794:2;12783:9;12779:18;12772:31;12820:57;12872:3;12861:9;12857:19;12849:6;12820:57;:::i;:::-;12812:65;12360:523;-1:-1:-1;;;;;;12360:523:1:o;12888:249::-;12957:6;13010:2;12998:9;12989:7;12985:23;12981:32;12978:52;;;13026:1;13023;13016:12;12978:52;13058:9;13052:16;13077:30;13101:5;13077:30;:::i;13142:127::-;13203:10;13198:3;13194:20;13191:1;13184:31;13234:4;13231:1;13224:15;13258:4;13255:1;13248:15;13274:135;13313:3;-1:-1:-1;;13334:17:1;;13331:43;;;13354:18;;:::i;:::-;-1:-1:-1;13401:1:1;13390:13;;13274:135::o;13414:127::-;13475:10;13470:3;13466:20;13463:1;13456:31;13506:4;13503:1;13496:15;13530:4;13527:1;13520:15;13546:120;13586:1;13612;13602:35;;13617:18;;:::i;:::-;-1:-1:-1;13651:9:1;;13546:120::o;13671:125::-;13711:4;13739:1;13736;13733:8;13730:34;;;13744:18;;:::i;:::-;-1:-1:-1;13781:9:1;;13671:125::o;13801:112::-;13833:1;13859;13849:35;;13864:18;;:::i;:::-;-1:-1:-1;13898:9:1;;13801:112::o;13918:128::-;13958:3;13989:1;13985:6;13982:1;13979:13;13976:39;;;13995:18;;:::i;:::-;-1:-1:-1;14031:9:1;;13918:128::o;14051:127::-;14112:10;14107:3;14103:20;14100:1;14093:31;14143:4;14140:1;14133:15;14167:4;14164:1;14157:15;14183:127;14244:10;14239:3;14235:20;14232:1;14225:31;14275:4;14272:1;14265:15;14299:4;14296:1;14289:15

Swarm Source

ipfs://c49623acfce159438ea9bee66927abbc873325a5e9909ac66a00e32d4bef0926
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.