ETH Price: $3,429.08 (+4.36%)

Token

!fundrop Stickers ()
 

Overview

Max Total Supply

120,557

Holders

115,778

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
0x7b6e1ecc0c2cc9a2646aec1a53ee0f7782cb0053
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:
Stickers

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 250000 runs

Other Settings:
paris EvmVersion
File 1 of 8 : Stickers.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;

import {ECDSA} from "solady/utils/ECDSA.sol";
import {Ownable} from "solady/auth/Ownable.sol";
import {ERC1155} from "solmate/tokens/ERC1155.sol";

import {IERC165} from "openzeppelin/utils/introspection/IERC165.sol";
import {IERC1155} from "openzeppelin/token/ERC1155/IERC1155.sol";
import "fundrop/IMetadataRenderer.sol";
import "fundrop/IERC4906.sol";

contract Stickers is ERC1155, Ownable {
    address public signer;
    address public metadataRenderer;
    uint256 public mintEnd;
    mapping(bytes32 => bool) _hasMinted;

    error InvalidSignature();
    error MintClosed();
    error MintedAlready();

    constructor() {
        _initializeOwner(tx.origin);
    }

    function name() public view virtual returns (string memory) {
        return "!fundrop Stickers";
    }

    function _packRecipientAndRound(address _address, uint16 _round) internal pure returns (bytes32) {
        return (bytes32(uint256(uint160(_address))) << 96) | bytes32(uint256(_round));
    }

    function mint(uint256[] calldata tokens, uint256[] calldata amounts, uint16 round, bytes calldata signature)
        public
        payable
    {
        bytes32 packedRecipientAndRound = _packRecipientAndRound(msg.sender, round);
        if (block.timestamp > mintEnd) revert MintClosed();
        if (_hasMinted[packedRecipientAndRound]) revert MintedAlready();
        address recovered =
            ECDSA.tryRecoverCalldata(keccak256(abi.encodePacked(msg.sender, round, tokens, amounts)), signature);
        if (recovered != signer) revert InvalidSignature();
        _hasMinted[packedRecipientAndRound] = true;
        _batchMint(msg.sender, tokens, amounts, "");
    }

    function adminMint(address to, uint256[] calldata tokens, uint256[] calldata amounts) public onlyOwner {
        _batchMint(to, tokens, amounts, "");
    }

    function uri(uint256 id) public view override returns (string memory) {
        return IMetadataRenderer(metadataRenderer).tokenURI(id);
    }

    // Admin functions

    function setMetadataRenderer(address _metadataRenderer) public onlyOwner {
        metadataRenderer = _metadataRenderer;
    }

    function setSigner(address _signer) public onlyOwner {
        signer = _signer;
    }

    function setMintEnd(uint256 _mintEnd) public onlyOwner {
        mintEnd = _mintEnd;
    }

    function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId || interfaceId == type(IERC1155).interfaceId
            || interfaceId == type(IERC4906).interfaceId;
    }
}

File 2 of 8 : ECDSA.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Gas optimized ECDSA wrapper.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ECDSA.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ECDSA.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol)
library ECDSA {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                        CUSTOM ERRORS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The signature is invalid.
    error InvalidSignature();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The number which `s` must not exceed in order for
    /// the signature to be non-malleable.
    bytes32 private constant _MALLEABILITY_THRESHOLD =
        0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                    RECOVERY OPERATIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // Note: as of Solady version 0.0.68, these functions will
    // revert upon recovery failure for more safety by default.

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the `signature`.
    ///
    /// This function does NOT accept EIP-2098 short form signatures.
    /// Use `recover(bytes32 hash, bytes32 r, bytes32 vs)` for EIP-2098
    /// short form signatures instead.
    function recover(bytes32 hash, bytes memory signature) internal view returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            // Copy the free memory pointer so that we can restore it later.
            let m := mload(0x40)
            // Copy `r` and `s`.
            mstore(0x40, mload(add(signature, 0x20))) // `r`.
            let s := mload(add(signature, 0x40))
            mstore(0x60, s)
            // Store the `hash` in the scratch space.
            mstore(0x00, hash)
            // Compute `v` and store it in the scratch space.
            mstore(0x20, byte(0, mload(add(signature, 0x60))))
            pop(
                staticcall(
                    gas(), // Amount of gas left for the transaction.
                    and(
                        // If the signature is exactly 65 bytes in length.
                        eq(mload(signature), 65),
                        // If `s` in lower half order, such that the signature is not malleable.
                        lt(s, add(_MALLEABILITY_THRESHOLD, 1))
                    ), // Address of `ecrecover`.
                    0x00, // Start of input.
                    0x80, // Size of input.
                    0x00, // Start of output.
                    0x20 // Size of output.
                )
            )
            result := mload(0x00)
            // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
            if iszero(returndatasize()) {
                // Store the function selector of `InvalidSignature()`.
                mstore(0x00, 0x8baa579f)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            // Restore the zero slot.
            mstore(0x60, 0)
            // Restore the free memory pointer.
            mstore(0x40, m)
        }
    }

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the `signature`.
    ///
    /// This function does NOT accept EIP-2098 short form signatures.
    /// Use `recover(bytes32 hash, bytes32 r, bytes32 vs)` for EIP-2098
    /// short form signatures instead.
    function recoverCalldata(bytes32 hash, bytes calldata signature)
        internal
        view
        returns (address result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Copy the free memory pointer so that we can restore it later.
            let m := mload(0x40)
            // Directly copy `r` and `s` from the calldata.
            calldatacopy(0x40, signature.offset, 0x40)
            // Store the `hash` in the scratch space.
            mstore(0x00, hash)
            // Compute `v` and store it in the scratch space.
            mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40))))
            pop(
                staticcall(
                    gas(), // Amount of gas left for the transaction.
                    and(
                        // If the signature is exactly 65 bytes in length.
                        eq(signature.length, 65),
                        // If `s` in lower half order, such that the signature is not malleable.
                        lt(mload(0x60), add(_MALLEABILITY_THRESHOLD, 1))
                    ), // Address of `ecrecover`.
                    0x00, // Start of input.
                    0x80, // Size of input.
                    0x00, // Start of output.
                    0x20 // Size of output.
                )
            )
            result := mload(0x00)
            // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
            if iszero(returndatasize()) {
                // Store the function selector of `InvalidSignature()`.
                mstore(0x00, 0x8baa579f)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            // Restore the zero slot.
            mstore(0x60, 0)
            // Restore the free memory pointer.
            mstore(0x40, m)
        }
    }

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the EIP-2098 short form signature defined by `r` and `vs`.
    ///
    /// This function only accepts EIP-2098 short form signatures.
    /// See: https://eips.ethereum.org/EIPS/eip-2098
    ///
    /// To be honest, I do not recommend using EIP-2098 signatures
    /// for simplicity, performance, and security reasons. Most if not
    /// all clients support traditional non EIP-2098 signatures by default.
    /// As such, this method is intentionally not fully inlined.
    /// It is merely included for completeness.
    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal view returns (address result) {
        uint8 v;
        bytes32 s;
        /// @solidity memory-safe-assembly
        assembly {
            s := shr(1, shl(1, vs))
            v := add(shr(255, vs), 27)
        }
        result = recover(hash, v, r, s);
    }

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the signature defined by `v`, `r`, `s`.
    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s)
        internal
        view
        returns (address result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Copy the free memory pointer so that we can restore it later.
            let m := mload(0x40)
            mstore(0x00, hash)
            mstore(0x20, and(v, 0xff))
            mstore(0x40, r)
            mstore(0x60, s)
            pop(
                staticcall(
                    gas(), // Amount of gas left for the transaction.
                    // If `s` in lower half order, such that the signature is not malleable.
                    lt(s, add(_MALLEABILITY_THRESHOLD, 1)), // Address of `ecrecover`.
                    0x00, // Start of input.
                    0x80, // Size of input.
                    0x00, // Start of output.
                    0x20 // Size of output.
                )
            )
            result := mload(0x00)
            // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
            if iszero(returndatasize()) {
                // Store the function selector of `InvalidSignature()`.
                mstore(0x00, 0x8baa579f)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            // Restore the zero slot.
            mstore(0x60, 0)
            // Restore the free memory pointer.
            mstore(0x40, m)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   TRY-RECOVER OPERATIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // WARNING!
    // These functions will NOT revert upon recovery failure.
    // Instead, they will return the zero address upon recovery failure.
    // It is critical that the returned address is NEVER compared against
    // a zero address (e.g. an uninitialized address variable).

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the `signature`.
    ///
    /// This function does NOT accept EIP-2098 short form signatures.
    /// Use `recover(bytes32 hash, bytes32 r, bytes32 vs)` for EIP-2098
    /// short form signatures instead.
    function tryRecover(bytes32 hash, bytes memory signature)
        internal
        view
        returns (address result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(xor(mload(signature), 65)) {
                // Copy the free memory pointer so that we can restore it later.
                let m := mload(0x40)
                // Copy `r` and `s`.
                mstore(0x40, mload(add(signature, 0x20))) // `r`.
                let s := mload(add(signature, 0x40))
                mstore(0x60, s)
                // If `s` in lower half order, such that the signature is not malleable.
                if iszero(gt(s, _MALLEABILITY_THRESHOLD)) {
                    // Store the `hash` in the scratch space.
                    mstore(0x00, hash)
                    // Compute `v` and store it in the scratch space.
                    mstore(0x20, byte(0, mload(add(signature, 0x60))))
                    pop(
                        staticcall(
                            gas(), // Amount of gas left for the transaction.
                            0x01, // Address of `ecrecover`.
                            0x00, // Start of input.
                            0x80, // Size of input.
                            0x40, // Start of output.
                            0x20 // Size of output.
                        )
                    )
                    // Restore the zero slot.
                    mstore(0x60, 0)
                    // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
                    result := mload(xor(0x60, returndatasize()))
                }
                // Restore the free memory pointer.
                mstore(0x40, m)
            }
        }
    }

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the `signature`.
    ///
    /// This function does NOT accept EIP-2098 short form signatures.
    /// Use `recover(bytes32 hash, bytes32 r, bytes32 vs)` for EIP-2098
    /// short form signatures instead.
    function tryRecoverCalldata(bytes32 hash, bytes calldata signature)
        internal
        view
        returns (address result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(xor(signature.length, 65)) {
                // Copy the free memory pointer so that we can restore it later.
                let m := mload(0x40)
                // Directly copy `r` and `s` from the calldata.
                calldatacopy(0x40, signature.offset, 0x40)
                // If `s` in lower half order, such that the signature is not malleable.
                if iszero(gt(mload(0x60), _MALLEABILITY_THRESHOLD)) {
                    // Store the `hash` in the scratch space.
                    mstore(0x00, hash)
                    // Compute `v` and store it in the scratch space.
                    mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40))))
                    pop(
                        staticcall(
                            gas(), // Amount of gas left for the transaction.
                            0x01, // Address of `ecrecover`.
                            0x00, // Start of input.
                            0x80, // Size of input.
                            0x40, // Start of output.
                            0x20 // Size of output.
                        )
                    )
                    // Restore the zero slot.
                    mstore(0x60, 0)
                    // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
                    result := mload(xor(0x60, returndatasize()))
                }
                // Restore the free memory pointer.
                mstore(0x40, m)
            }
        }
    }

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the EIP-2098 short form signature defined by `r` and `vs`.
    ///
    /// This function only accepts EIP-2098 short form signatures.
    /// See: https://eips.ethereum.org/EIPS/eip-2098
    ///
    /// To be honest, I do not recommend using EIP-2098 signatures
    /// for simplicity, performance, and security reasons. Most if not
    /// all clients support traditional non EIP-2098 signatures by default.
    /// As such, this method is intentionally not fully inlined.
    /// It is merely included for completeness.
    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs)
        internal
        view
        returns (address result)
    {
        uint8 v;
        bytes32 s;
        /// @solidity memory-safe-assembly
        assembly {
            s := shr(1, shl(1, vs))
            v := add(shr(255, vs), 27)
        }
        result = tryRecover(hash, v, r, s);
    }

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the signature defined by `v`, `r`, `s`.
    function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s)
        internal
        view
        returns (address result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Copy the free memory pointer so that we can restore it later.
            let m := mload(0x40)
            // If `s` in lower half order, such that the signature is not malleable.
            if iszero(gt(s, _MALLEABILITY_THRESHOLD)) {
                // Store the `hash`, `v`, `r`, `s` in the scratch space.
                mstore(0x00, hash)
                mstore(0x20, and(v, 0xff))
                mstore(0x40, r)
                mstore(0x60, s)
                pop(
                    staticcall(
                        gas(), // Amount of gas left for the transaction.
                        0x01, // Address of `ecrecover`.
                        0x00, // Start of input.
                        0x80, // Size of input.
                        0x40, // Start of output.
                        0x20 // Size of output.
                    )
                )
                // Restore the zero slot.
                mstore(0x60, 0)
                // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
                result := mload(xor(0x60, returndatasize()))
            }
            // Restore the free memory pointer.
            mstore(0x40, m)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     HASHING OPERATIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns an Ethereum Signed Message, created from a `hash`.
    /// This produces a hash corresponding to the one signed with the
    /// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign)
    /// JSON-RPC method as part of EIP-191.
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            // Store into scratch space for keccak256.
            mstore(0x20, hash)
            mstore(0x00, "\x00\x00\x00\x00\x19Ethereum Signed Message:\n32")
            // 0x40 - 0x04 = 0x3c
            result := keccak256(0x04, 0x3c)
        }
    }

    /// @dev Returns an Ethereum Signed Message, created from `s`.
    /// This produces a hash corresponding to the one signed with the
    /// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign)
    /// JSON-RPC method as part of EIP-191.
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32 result) {
        assembly {
            // The length of "\x19Ethereum Signed Message:\n" is 26 bytes (i.e. 0x1a).
            // If we reserve 2 words, we'll have 64 - 26 = 38 bytes to store the
            // ASCII decimal representation of the length of `s` up to about 2 ** 126.

            // Instead of allocating, we temporarily copy the 64 bytes before the
            // start of `s` data to some variables.
            let m := mload(sub(s, 0x20))
            // The length of `s` is in bytes.
            let sLength := mload(s)
            let ptr := add(s, 0x20)
            let w := not(0)
            // `end` marks the end of the memory which we will compute the keccak256 of.
            let end := add(ptr, sLength)
            // Convert the length of the bytes to ASCII decimal representation
            // and store it into the memory.
            for { let temp := sLength } 1 {} {
                ptr := add(ptr, w) // `sub(ptr, 1)`.
                mstore8(ptr, add(48, mod(temp, 10)))
                temp := div(temp, 10)
                if iszero(temp) { break }
            }
            // Copy the header over to the memory.
            mstore(sub(ptr, 0x20), "\x00\x00\x00\x00\x00\x00\x19Ethereum Signed Message:\n")
            // Compute the keccak256 of the memory.
            result := keccak256(sub(ptr, 0x1a), sub(end, sub(ptr, 0x1a)))
            // Restore the previous memory.
            mstore(s, sLength)
            mstore(sub(s, 0x20), m)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   EMPTY CALLDATA HELPERS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns an empty calldata bytes.
    function emptySignature() internal pure returns (bytes calldata signature) {
        /// @solidity memory-safe-assembly
        assembly {
            signature.length := 0
        }
    }
}

File 3 of 8 : Ownable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Simple single owner authorization mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)
/// @dev While the ownable portion follows [EIP-173](https://eips.ethereum.org/EIPS/eip-173)
/// for compatibility, the nomenclature for the 2-step ownership handover
/// may be unique to this codebase.
abstract contract Ownable {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The caller is not authorized to call the function.
    error Unauthorized();

    /// @dev The `newOwner` cannot be the zero address.
    error NewOwnerIsZeroAddress();

    /// @dev The `pendingOwner` does not have a valid handover request.
    error NoHandoverRequest();

    /// @dev `bytes4(keccak256(bytes("Unauthorized()")))`.
    uint256 private constant _UNAUTHORIZED_ERROR_SELECTOR = 0x82b42900;

    /// @dev `bytes4(keccak256(bytes("NewOwnerIsZeroAddress()")))`.
    uint256 private constant _NEW_OWNER_IS_ZERO_ADDRESS_ERROR_SELECTOR = 0x7448fbae;

    /// @dev `bytes4(keccak256(bytes("NoHandoverRequest()")))`.
    uint256 private constant _NO_HANDOVER_REQUEST_ERROR_SELECTOR = 0x6f5e8818;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                           EVENTS                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The ownership is transferred from `oldOwner` to `newOwner`.
    /// This event is intentionally kept the same as OpenZeppelin's Ownable to be
    /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),
    /// despite it not being as lightweight as a single argument event.
    event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);

    /// @dev An ownership handover to `pendingOwner` has been requested.
    event OwnershipHandoverRequested(address indexed pendingOwner);

    /// @dev The ownership handover to `pendingOwner` has been canceled.
    event OwnershipHandoverCanceled(address indexed pendingOwner);

    /// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`.
    uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =
        0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;

    /// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`.
    uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =
        0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;

    /// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`.
    uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =
        0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                          STORAGE                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The owner slot is given by: `not(_OWNER_SLOT_NOT)`.
    /// It is intentionally choosen to be a high value
    /// to avoid collision with lower slots.
    /// The choice of manual storage layout is to enable compatibility
    /// with both regular and upgradeable contracts.
    uint256 private constant _OWNER_SLOT_NOT = 0x8b78c6d8;

    /// The ownership handover slot of `newOwner` is given by:
    /// ```
    ///     mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))
    ///     let handoverSlot := keccak256(0x00, 0x20)
    /// ```
    /// It stores the expiry timestamp of the two-step ownership handover.
    uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     INTERNAL FUNCTIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Initializes the owner directly without authorization guard.
    /// This function must be called upon initialization,
    /// regardless of whether the contract is upgradeable or not.
    /// This is to enable generalization to both regular and upgradeable contracts,
    /// and to save gas in case the initial owner is not the caller.
    /// For performance reasons, this function will not check if there
    /// is an existing owner.
    function _initializeOwner(address newOwner) internal virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // Clean the upper 96 bits.
            newOwner := shr(96, shl(96, newOwner))
            // Store the new value.
            sstore(not(_OWNER_SLOT_NOT), newOwner)
            // Emit the {OwnershipTransferred} event.
            log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
        }
    }

    /// @dev Sets the owner directly without authorization guard.
    function _setOwner(address newOwner) internal virtual {
        /// @solidity memory-safe-assembly
        assembly {
            let ownerSlot := not(_OWNER_SLOT_NOT)
            // Clean the upper 96 bits.
            newOwner := shr(96, shl(96, newOwner))
            // Emit the {OwnershipTransferred} event.
            log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
            // Store the new value.
            sstore(ownerSlot, newOwner)
        }
    }

    /// @dev Throws if the sender is not the owner.
    function _checkOwner() internal view virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // If the caller is not the stored owner, revert.
            if iszero(eq(caller(), sload(not(_OWNER_SLOT_NOT)))) {
                mstore(0x00, _UNAUTHORIZED_ERROR_SELECTOR)
                revert(0x1c, 0x04)
            }
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                  PUBLIC UPDATE FUNCTIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Allows the owner to transfer the ownership to `newOwner`.
    function transferOwnership(address newOwner) public payable virtual onlyOwner {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(shl(96, newOwner)) {
                mstore(0x00, _NEW_OWNER_IS_ZERO_ADDRESS_ERROR_SELECTOR)
                revert(0x1c, 0x04)
            }
        }
        _setOwner(newOwner);
    }

    /// @dev Allows the owner to renounce their ownership.
    function renounceOwnership() public payable virtual onlyOwner {
        _setOwner(address(0));
    }

    /// @dev Request a two-step ownership handover to the caller.
    /// The request will be automatically expire in 48 hours (172800 seconds) by default.
    function requestOwnershipHandover() public payable virtual {
        unchecked {
            uint256 expires = block.timestamp + ownershipHandoverValidFor();
            /// @solidity memory-safe-assembly
            assembly {
                // Compute and set the handover slot to `expires`.
                mstore(0x0c, _HANDOVER_SLOT_SEED)
                mstore(0x00, caller())
                sstore(keccak256(0x0c, 0x20), expires)
                // Emit the {OwnershipHandoverRequested} event.
                log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())
            }
        }
    }

    /// @dev Cancels the two-step ownership handover to the caller, if any.
    function cancelOwnershipHandover() public payable virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and set the handover slot to 0.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, caller())
            sstore(keccak256(0x0c, 0x20), 0)
            // Emit the {OwnershipHandoverCanceled} event.
            log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())
        }
    }

    /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`.
    /// Reverts if there is no existing ownership handover requested by `pendingOwner`.
    function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and set the handover slot to 0.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, pendingOwner)
            let handoverSlot := keccak256(0x0c, 0x20)
            // If the handover does not exist, or has expired.
            if gt(timestamp(), sload(handoverSlot)) {
                mstore(0x00, _NO_HANDOVER_REQUEST_ERROR_SELECTOR)
                revert(0x1c, 0x04)
            }
            // Set the handover slot to 0.
            sstore(handoverSlot, 0)
        }
        _setOwner(pendingOwner);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   PUBLIC READ FUNCTIONS                    */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the owner of the contract.
    function owner() public view virtual returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := sload(not(_OWNER_SLOT_NOT))
        }
    }

    /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.
    function ownershipHandoverExpiresAt(address pendingOwner)
        public
        view
        virtual
        returns (uint256 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the handover slot.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, pendingOwner)
            // Load the handover slot.
            result := sload(keccak256(0x0c, 0x20))
        }
    }

    /// @dev Returns how long a two-step ownership handover is valid for in seconds.
    function ownershipHandoverValidFor() public view virtual returns (uint64) {
        return 48 * 3600;
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         MODIFIERS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Marks a function as only callable by the owner.
    modifier onlyOwner() virtual {
        _checkOwner();
        _;
    }
}

File 4 of 8 : ERC1155.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Minimalist and gas efficient standard ERC1155 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol)
abstract contract ERC1155 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event TransferSingle(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 id,
        uint256 amount
    );

    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] amounts
    );

    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    event URI(string value, uint256 indexed id);

    /*//////////////////////////////////////////////////////////////
                             ERC1155 STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(address => mapping(uint256 => uint256)) public balanceOf;

    mapping(address => mapping(address => bool)) public isApprovedForAll;

    /*//////////////////////////////////////////////////////////////
                             METADATA LOGIC
    //////////////////////////////////////////////////////////////*/

    function uri(uint256 id) public view virtual returns (string memory);

    /*//////////////////////////////////////////////////////////////
                              ERC1155 LOGIC
    //////////////////////////////////////////////////////////////*/

    function setApprovalForAll(address operator, bool approved) public virtual {
        isApprovedForAll[msg.sender][operator] = approved;

        emit ApprovalForAll(msg.sender, operator, approved);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) public virtual {
        require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED");

        balanceOf[from][id] -= amount;
        balanceOf[to][id] += amount;

        emit TransferSingle(msg.sender, from, to, id, amount);

        require(
            to.code.length == 0
                ? to != address(0)
                : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) ==
                    ERC1155TokenReceiver.onERC1155Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) public virtual {
        require(ids.length == amounts.length, "LENGTH_MISMATCH");

        require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED");

        // Storing these outside the loop saves ~15 gas per iteration.
        uint256 id;
        uint256 amount;

        for (uint256 i = 0; i < ids.length; ) {
            id = ids[i];
            amount = amounts[i];

            balanceOf[from][id] -= amount;
            balanceOf[to][id] += amount;

            // An array can't have a total length
            // larger than the max uint256 value.
            unchecked {
                ++i;
            }
        }

        emit TransferBatch(msg.sender, from, to, ids, amounts);

        require(
            to.code.length == 0
                ? to != address(0)
                : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) ==
                    ERC1155TokenReceiver.onERC1155BatchReceived.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function balanceOfBatch(address[] calldata owners, uint256[] calldata ids)
        public
        view
        virtual
        returns (uint256[] memory balances)
    {
        require(owners.length == ids.length, "LENGTH_MISMATCH");

        balances = new uint256[](owners.length);

        // Unchecked because the only math done is incrementing
        // the array index counter which cannot possibly overflow.
        unchecked {
            for (uint256 i = 0; i < owners.length; ++i) {
                balances[i] = balanceOf[owners[i]][ids[i]];
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                              ERC165 LOGIC
    //////////////////////////////////////////////////////////////*/

    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return
            interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
            interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155
            interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        balanceOf[to][id] += amount;

        emit TransferSingle(msg.sender, address(0), to, id, amount);

        require(
            to.code.length == 0
                ? to != address(0)
                : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) ==
                    ERC1155TokenReceiver.onERC1155Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function _batchMint(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        uint256 idsLength = ids.length; // Saves MLOADs.

        require(idsLength == amounts.length, "LENGTH_MISMATCH");

        for (uint256 i = 0; i < idsLength; ) {
            balanceOf[to][ids[i]] += amounts[i];

            // An array can't have a total length
            // larger than the max uint256 value.
            unchecked {
                ++i;
            }
        }

        emit TransferBatch(msg.sender, address(0), to, ids, amounts);

        require(
            to.code.length == 0
                ? to != address(0)
                : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) ==
                    ERC1155TokenReceiver.onERC1155BatchReceived.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function _batchBurn(
        address from,
        uint256[] memory ids,
        uint256[] memory amounts
    ) internal virtual {
        uint256 idsLength = ids.length; // Saves MLOADs.

        require(idsLength == amounts.length, "LENGTH_MISMATCH");

        for (uint256 i = 0; i < idsLength; ) {
            balanceOf[from][ids[i]] -= amounts[i];

            // An array can't have a total length
            // larger than the max uint256 value.
            unchecked {
                ++i;
            }
        }

        emit TransferBatch(msg.sender, from, address(0), ids, amounts);
    }

    function _burn(
        address from,
        uint256 id,
        uint256 amount
    ) internal virtual {
        balanceOf[from][id] -= amount;

        emit TransferSingle(msg.sender, from, address(0), id, amount);
    }
}

/// @notice A generic interface for a contract which properly accepts ERC1155 tokens.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol)
abstract contract ERC1155TokenReceiver {
    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes calldata
    ) external virtual returns (bytes4) {
        return ERC1155TokenReceiver.onERC1155Received.selector;
    }

    function onERC1155BatchReceived(
        address,
        address,
        uint256[] calldata,
        uint256[] calldata,
        bytes calldata
    ) external virtual returns (bytes4) {
        return ERC1155TokenReceiver.onERC1155BatchReceived.selector;
    }
}

File 5 of 8 : IERC165.sol
// SPDX-License-Identifier: MIT
// 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 6 of 8 : IERC1155.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external
        view
        returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

File 7 of 8 : IMetadataRenderer.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;

interface IMetadataRenderer {
    function tokenURI(uint256 id) external view returns (string memory);
}

File 8 of 8 : IERC4906.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

interface IERC4906 {
    /// @dev This event emits when the metadata of a token is changed.
    /// So that the third-party platforms such as NFT market could
    /// timely update the images and related attributes of the NFT.
    event MetadataUpdate(uint256 _tokenId);

    /// @dev This event emits when the metadata of a range of tokens is changed.
    /// So that the third-party platforms such as NFT market could
    /// timely update the images and related attributes of the NFTs.
    event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);
}

Settings
{
  "remappings": [
    "ERC721A/=lib/ERC721A/contracts/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin/=lib/openzeppelin-contracts/contracts/",
    "solmate/=lib/solmate/src/",
    "solady/=lib/solady/src/",
    "fundrop/=src/Fundrop/",
    "operator-filter-registry/=lib/operator-filter-registry/src/",
    "erc4626-tests/=lib/operator-filter-registry/lib/openzeppelin-contracts/lib/erc4626-tests/",
    "openzeppelin-contracts-upgradeable/=lib/operator-filter-registry/lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 250000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"MintClosed","type":"error"},{"inputs":[],"name":"MintedAlready","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"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":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"tokens","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"adminMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"owners","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metadataRenderer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokens","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint16","name":"round","type":"uint16"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintEnd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownershipHandoverValidFor","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_metadataRenderer","type":"address"}],"name":"setMetadataRenderer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintEnd","type":"uint256"}],"name":"setMintEnd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"name":"setSigner","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":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b5061001a3261001f565b61005b565b6001600160a01b0316638b78c6d8198190558060007f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a350565b6121ff8061006a6000396000f3fe6080604052600436106101955760003560e01c8063715018a6116100e1578063ea2b4ab21161008a578063f242432a11610064578063f242432a146104b0578063f2fde38b146104d0578063fd4fe8a8146104e3578063fee81cf41461050357600080fd5b8063ea2b4ab214610467578063eb20614e1461047d578063f04e283e1461049d57600080fd5b8063a22cb465116100bb578063a22cb465146103ee578063d7533f021461040e578063e985e9c51461042c57600080fd5b8063715018a614610392578063812015b91461039a5780638da5cb5b146103ba57600080fd5b80632eb2c2d61161014357806354d1f13d1161011d57806354d1f13d1461033d5780636c19e78314610345578063703199701461036557600080fd5b80632eb2c2d6146102dd5780634e1273f4146102fd578063525b6ba01461032a57600080fd5b80630e89341c116101745780630e89341c14610261578063238ac9331461028157806325692962146102d357600080fd5b8062fdd58e1461019a57806301ffc9a7146101e257806306fdde0314610212575b600080fd5b3480156101a657600080fd5b506101cf6101b5366004611829565b600060208181529281526040808220909352908152205481565b6040519081526020015b60405180910390f35b3480156101ee57600080fd5b506102026101fd366004611881565b610536565b60405190151581526020016101d9565b34801561021e57600080fd5b5060408051808201909152601181527f2166756e64726f7020537469636b65727300000000000000000000000000000060208201525b6040516101d9919061190c565b34801561026d57600080fd5b5061025461027c36600461191f565b6105fa565b34801561028d57600080fd5b506002546102ae9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d9565b6102db6106b0565b005b3480156102e957600080fd5b506102db6102f83660046119c6565b610700565b34801561030957600080fd5b5061031d610318366004611a81565b610af6565b6040516101d99190611b28565b6102db610338366004611b3b565b610c6d565b6102db610e70565b34801561035157600080fd5b506102db610360366004611bf1565b610eac565b34801561037157600080fd5b506003546102ae9073ffffffffffffffffffffffffffffffffffffffff1681565b6102db610efb565b3480156103a657600080fd5b506102db6103b5366004611c0c565b610f0f565b3480156103c657600080fd5b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927546102ae565b3480156103fa57600080fd5b506102db610409366004611c8d565b610f9a565b34801561041a57600080fd5b506040516202a30081526020016101d9565b34801561043857600080fd5b50610202610447366004611cc9565b600160209081526000928352604080842090915290825290205460ff1681565b34801561047357600080fd5b506101cf60045481565b34801561048957600080fd5b506102db61049836600461191f565b611031565b6102db6104ab366004611bf1565b61103e565b3480156104bc57600080fd5b506102db6104cb366004611cfc565b61107e565b6102db6104de366004611bf1565b611384565b3480156104ef57600080fd5b506102db6104fe366004611bf1565b6113ab565b34801561050f57600080fd5b506101cf61051e366004611bf1565b63389a75e1600c908152600091909152602090205490565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806105c957507fffffffff0000000000000000000000000000000000000000000000000000000082167fd9b67a2600000000000000000000000000000000000000000000000000000000145b806105f457507fffffffff000000000000000000000000000000000000000000000000000000008216155b92915050565b6003546040517fc87b56dd0000000000000000000000000000000000000000000000000000000081526004810183905260609173ffffffffffffffffffffffffffffffffffffffff169063c87b56dd90602401600060405180830381865afa15801561066a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f49190810190611da3565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b84831461076e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4c454e4754485f4d49534d41544348000000000000000000000000000000000060448201526064015b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff891614806107c2575073ffffffffffffffffffffffffffffffffffffffff8816600090815260016020908152604080832033845290915290205460ff165b610828576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a45440000000000000000000000000000000000006044820152606401610765565b60008060005b878110156108fd5788888281811061084857610848611e6e565b90506020020135925086868281811061086357610863611e6e565b73ffffffffffffffffffffffffffffffffffffffff8e16600090815260208181526040808320898452825282208054939091029490940135955085939250906108ad908490611ecc565b909155505073ffffffffffffffffffffffffffffffffffffffff8a16600090815260208181526040808320868452909152812080548492906108f0908490611edf565b909155505060010161082e565b508873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8b8b8b8b6040516109789493929190611f3d565b60405180910390a473ffffffffffffffffffffffffffffffffffffffff89163b15610a6a576040517fbc197c81000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff8b169063bc197c81906109ff9033908f908e908e908e908e908e908e90600401611fad565b6020604051808303816000875af1158015610a1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a42919061201e565b7fffffffff000000000000000000000000000000000000000000000000000000001614610a84565b73ffffffffffffffffffffffffffffffffffffffff891615155b610aea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e54000000000000000000000000000000006044820152606401610765565b50505050505050505050565b6060838214610b61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4c454e4754485f4d49534d4154434800000000000000000000000000000000006044820152606401610765565b8367ffffffffffffffff811115610b7a57610b7a611d74565b604051908082528060200260200182016040528015610ba3578160200160208202803683370190505b50905060005b84811015610c6457600080878784818110610bc657610bc6611e6e565b9050602002016020810190610bdb9190611bf1565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858584818110610c2957610c29611e6e565b90506020020135815260200190815260200160002054828281518110610c5157610c51611e6e565b6020908102919091010152600101610ba9565b50949350505050565b60045461ffff84163360601b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000161790421115610cd6576040517f589ed34b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526005602052604090205460ff1615610d1f576040517f96dd8aac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d5c33868b8b8b8b604051602001610d3f9695949392919061207d565b6040516020818303038152906040528051906020012085856113fa565b60025490915073ffffffffffffffffffffffffffffffffffffffff808316911614610db3576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526005602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905581518a820281810183019093528a8152610e659233928d918d9182919085019084908082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c91829185019084908082843760009201829052506040805160208101909152908152925061146a915050565b505050505050505050565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b610eb4611764565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610f03611764565b610f0d600061179a565b565b610f17611764565b610f93858585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080890282810182019093528882529093508892508791829185019084908082843760009201829052506040805160208101909152908152925061146a915050565b5050505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611039611764565b600455565b611046611764565b63389a75e1600c52806000526020600c20805442111561106e57636f5e88186000526004601cfd5b6000905561107b8161179a565b50565b3373ffffffffffffffffffffffffffffffffffffffff871614806110d2575073ffffffffffffffffffffffffffffffffffffffff8616600090815260016020908152604080832033845290915290205460ff165b611138576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a45440000000000000000000000000000000000006044820152606401610765565b73ffffffffffffffffffffffffffffffffffffffff861660009081526020818152604080832087845290915281208054859290611176908490611ecc565b909155505073ffffffffffffffffffffffffffffffffffffffff8516600090815260208181526040808320878452909152812080548592906111b9908490611edf565b9091555050604080518581526020810185905273ffffffffffffffffffffffffffffffffffffffff808816929089169133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a473ffffffffffffffffffffffffffffffffffffffff85163b156112fc576040517ff23a6e61000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff87169063f23a6e61906112919033908b908a908a908a908a906004016120f6565b6020604051808303816000875af11580156112b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d4919061201e565b7fffffffff000000000000000000000000000000000000000000000000000000001614611316565b73ffffffffffffffffffffffffffffffffffffffff851615155b61137c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e54000000000000000000000000000000006044820152606401610765565b505050505050565b61138c611764565b8060601b6113a257637448fbae6000526004601cfd5b61107b8161179a565b6113b3611764565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600060418218611463576040516040846040377f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a06060511161145f5784600052604084013560001a602052602060406080600060015afa5060006060523d6060185191505b6040525b9392505050565b8251825181146114d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4c454e4754485f4d49534d4154434800000000000000000000000000000000006044820152606401610765565b60005b8181101561157f578381815181106114f3576114f3611e6e565b60200260200101516000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600087848151811061154d5761154d611e6e565b6020026020010151815260200190815260200160002060008282546115729190611edf565b90915550506001016114d9565b508473ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516115f792919061213c565b60405180910390a473ffffffffffffffffffffffffffffffffffffffff85163b156116e4576040517fbc197c81000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff87169063bc197c81906116799033906000908a908a908a9060040161216a565b6020604051808303816000875af1158015611698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116bc919061201e565b7fffffffff0000000000000000000000000000000000000000000000000000000016146116fe565b73ffffffffffffffffffffffffffffffffffffffff851615155b610f93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e54000000000000000000000000000000006044820152606401610765565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927543314610f0d576382b429006000526004601cfd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927805473ffffffffffffffffffffffffffffffffffffffff9092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b803573ffffffffffffffffffffffffffffffffffffffff8116811461182457600080fd5b919050565b6000806040838503121561183c57600080fd5b61184583611800565b946020939093013593505050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461107b57600080fd5b60006020828403121561189357600080fd5b813561146381611853565b60005b838110156118b95781810151838201526020016118a1565b50506000910152565b600081518084526118da81602086016020860161189e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061146360208301846118c2565b60006020828403121561193157600080fd5b5035919050565b60008083601f84011261194a57600080fd5b50813567ffffffffffffffff81111561196257600080fd5b6020830191508360208260051b850101111561197d57600080fd5b9250929050565b60008083601f84011261199657600080fd5b50813567ffffffffffffffff8111156119ae57600080fd5b60208301915083602082850101111561197d57600080fd5b60008060008060008060008060a0898b0312156119e257600080fd5b6119eb89611800565b97506119f960208a01611800565b9650604089013567ffffffffffffffff80821115611a1657600080fd5b611a228c838d01611938565b909850965060608b0135915080821115611a3b57600080fd5b611a478c838d01611938565b909650945060808b0135915080821115611a6057600080fd5b50611a6d8b828c01611984565b999c989b5096995094979396929594505050565b60008060008060408587031215611a9757600080fd5b843567ffffffffffffffff80821115611aaf57600080fd5b611abb88838901611938565b90965094506020870135915080821115611ad457600080fd5b50611ae187828801611938565b95989497509550505050565b600081518084526020808501945080840160005b83811015611b1d57815187529582019590820190600101611b01565b509495945050505050565b6020815260006114636020830184611aed565b60008060008060008060006080888a031215611b5657600080fd5b873567ffffffffffffffff80821115611b6e57600080fd5b611b7a8b838c01611938565b909950975060208a0135915080821115611b9357600080fd5b611b9f8b838c01611938565b909750955060408a0135915061ffff82168214611bbb57600080fd5b90935060608901359080821115611bd157600080fd5b50611bde8a828b01611984565b989b979a50959850939692959293505050565b600060208284031215611c0357600080fd5b61146382611800565b600080600080600060608688031215611c2457600080fd5b611c2d86611800565b9450602086013567ffffffffffffffff80821115611c4a57600080fd5b611c5689838a01611938565b90965094506040880135915080821115611c6f57600080fd5b50611c7c88828901611938565b969995985093965092949392505050565b60008060408385031215611ca057600080fd5b611ca983611800565b915060208301358015158114611cbe57600080fd5b809150509250929050565b60008060408385031215611cdc57600080fd5b611ce583611800565b9150611cf360208401611800565b90509250929050565b60008060008060008060a08789031215611d1557600080fd5b611d1e87611800565b9550611d2c60208801611800565b94506040870135935060608701359250608087013567ffffffffffffffff811115611d5657600080fd5b611d6289828a01611984565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215611db557600080fd5b815167ffffffffffffffff80821115611dcd57600080fd5b818401915084601f830112611de157600080fd5b815181811115611df357611df3611d74565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611e3957611e39611d74565b81604052828152876020848701011115611e5257600080fd5b611e6383602083016020880161189e565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f4576105f4611e9d565b808201808211156105f4576105f4611e9d565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115611f2457600080fd5b8260051b80836020870137939093016020019392505050565b604081526000611f51604083018688611ef2565b8281036020840152611e63818587611ef2565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b600073ffffffffffffffffffffffffffffffffffffffff808b168352808a1660208401525060a06040830152611fe760a08301888a611ef2565b8281036060840152611ffa818789611ef2565b9050828103608084015261200f818587611f64565b9b9a5050505050505050505050565b60006020828403121561203057600080fd5b815161146381611853565b60007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561206a57600080fd5b8260051b80838637939093019392505050565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008760601b1681527fffff0000000000000000000000000000000000000000000000000000000000008660f01b16601482015260006120ea6120e360168401878961203b565b848661203b565b98975050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835280881660208401525085604083015284606083015260a060808301526120ea60a083018486611f64565b60408152600061214f6040830185611aed565b82810360208401526121618185611aed565b95945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a060408301526121a360a0830186611aed565b82810360608401526121b58186611aed565b905082810360808401526120ea81856118c256fea26469706673582212204f435c2221be3df7ed00f719688c96d8efeb99481b1d32738bd68358ff82ec9764736f6c63430008140033

Deployed Bytecode

0x6080604052600436106101955760003560e01c8063715018a6116100e1578063ea2b4ab21161008a578063f242432a11610064578063f242432a146104b0578063f2fde38b146104d0578063fd4fe8a8146104e3578063fee81cf41461050357600080fd5b8063ea2b4ab214610467578063eb20614e1461047d578063f04e283e1461049d57600080fd5b8063a22cb465116100bb578063a22cb465146103ee578063d7533f021461040e578063e985e9c51461042c57600080fd5b8063715018a614610392578063812015b91461039a5780638da5cb5b146103ba57600080fd5b80632eb2c2d61161014357806354d1f13d1161011d57806354d1f13d1461033d5780636c19e78314610345578063703199701461036557600080fd5b80632eb2c2d6146102dd5780634e1273f4146102fd578063525b6ba01461032a57600080fd5b80630e89341c116101745780630e89341c14610261578063238ac9331461028157806325692962146102d357600080fd5b8062fdd58e1461019a57806301ffc9a7146101e257806306fdde0314610212575b600080fd5b3480156101a657600080fd5b506101cf6101b5366004611829565b600060208181529281526040808220909352908152205481565b6040519081526020015b60405180910390f35b3480156101ee57600080fd5b506102026101fd366004611881565b610536565b60405190151581526020016101d9565b34801561021e57600080fd5b5060408051808201909152601181527f2166756e64726f7020537469636b65727300000000000000000000000000000060208201525b6040516101d9919061190c565b34801561026d57600080fd5b5061025461027c36600461191f565b6105fa565b34801561028d57600080fd5b506002546102ae9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d9565b6102db6106b0565b005b3480156102e957600080fd5b506102db6102f83660046119c6565b610700565b34801561030957600080fd5b5061031d610318366004611a81565b610af6565b6040516101d99190611b28565b6102db610338366004611b3b565b610c6d565b6102db610e70565b34801561035157600080fd5b506102db610360366004611bf1565b610eac565b34801561037157600080fd5b506003546102ae9073ffffffffffffffffffffffffffffffffffffffff1681565b6102db610efb565b3480156103a657600080fd5b506102db6103b5366004611c0c565b610f0f565b3480156103c657600080fd5b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927546102ae565b3480156103fa57600080fd5b506102db610409366004611c8d565b610f9a565b34801561041a57600080fd5b506040516202a30081526020016101d9565b34801561043857600080fd5b50610202610447366004611cc9565b600160209081526000928352604080842090915290825290205460ff1681565b34801561047357600080fd5b506101cf60045481565b34801561048957600080fd5b506102db61049836600461191f565b611031565b6102db6104ab366004611bf1565b61103e565b3480156104bc57600080fd5b506102db6104cb366004611cfc565b61107e565b6102db6104de366004611bf1565b611384565b3480156104ef57600080fd5b506102db6104fe366004611bf1565b6113ab565b34801561050f57600080fd5b506101cf61051e366004611bf1565b63389a75e1600c908152600091909152602090205490565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806105c957507fffffffff0000000000000000000000000000000000000000000000000000000082167fd9b67a2600000000000000000000000000000000000000000000000000000000145b806105f457507fffffffff000000000000000000000000000000000000000000000000000000008216155b92915050565b6003546040517fc87b56dd0000000000000000000000000000000000000000000000000000000081526004810183905260609173ffffffffffffffffffffffffffffffffffffffff169063c87b56dd90602401600060405180830381865afa15801561066a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105f49190810190611da3565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b84831461076e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4c454e4754485f4d49534d41544348000000000000000000000000000000000060448201526064015b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff891614806107c2575073ffffffffffffffffffffffffffffffffffffffff8816600090815260016020908152604080832033845290915290205460ff165b610828576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a45440000000000000000000000000000000000006044820152606401610765565b60008060005b878110156108fd5788888281811061084857610848611e6e565b90506020020135925086868281811061086357610863611e6e565b73ffffffffffffffffffffffffffffffffffffffff8e16600090815260208181526040808320898452825282208054939091029490940135955085939250906108ad908490611ecc565b909155505073ffffffffffffffffffffffffffffffffffffffff8a16600090815260208181526040808320868452909152812080548492906108f0908490611edf565b909155505060010161082e565b508873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8b8b8b8b6040516109789493929190611f3d565b60405180910390a473ffffffffffffffffffffffffffffffffffffffff89163b15610a6a576040517fbc197c81000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff8b169063bc197c81906109ff9033908f908e908e908e908e908e908e90600401611fad565b6020604051808303816000875af1158015610a1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a42919061201e565b7fffffffff000000000000000000000000000000000000000000000000000000001614610a84565b73ffffffffffffffffffffffffffffffffffffffff891615155b610aea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e54000000000000000000000000000000006044820152606401610765565b50505050505050505050565b6060838214610b61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4c454e4754485f4d49534d4154434800000000000000000000000000000000006044820152606401610765565b8367ffffffffffffffff811115610b7a57610b7a611d74565b604051908082528060200260200182016040528015610ba3578160200160208202803683370190505b50905060005b84811015610c6457600080878784818110610bc657610bc6611e6e565b9050602002016020810190610bdb9190611bf1565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858584818110610c2957610c29611e6e565b90506020020135815260200190815260200160002054828281518110610c5157610c51611e6e565b6020908102919091010152600101610ba9565b50949350505050565b60045461ffff84163360601b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000161790421115610cd6576040517f589ed34b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526005602052604090205460ff1615610d1f576040517f96dd8aac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d5c33868b8b8b8b604051602001610d3f9695949392919061207d565b6040516020818303038152906040528051906020012085856113fa565b60025490915073ffffffffffffffffffffffffffffffffffffffff808316911614610db3576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526005602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905581518a820281810183019093528a8152610e659233928d918d9182919085019084908082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c91829185019084908082843760009201829052506040805160208101909152908152925061146a915050565b505050505050505050565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b610eb4611764565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610f03611764565b610f0d600061179a565b565b610f17611764565b610f93858585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080890282810182019093528882529093508892508791829185019084908082843760009201829052506040805160208101909152908152925061146a915050565b5050505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611039611764565b600455565b611046611764565b63389a75e1600c52806000526020600c20805442111561106e57636f5e88186000526004601cfd5b6000905561107b8161179a565b50565b3373ffffffffffffffffffffffffffffffffffffffff871614806110d2575073ffffffffffffffffffffffffffffffffffffffff8616600090815260016020908152604080832033845290915290205460ff165b611138576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a45440000000000000000000000000000000000006044820152606401610765565b73ffffffffffffffffffffffffffffffffffffffff861660009081526020818152604080832087845290915281208054859290611176908490611ecc565b909155505073ffffffffffffffffffffffffffffffffffffffff8516600090815260208181526040808320878452909152812080548592906111b9908490611edf565b9091555050604080518581526020810185905273ffffffffffffffffffffffffffffffffffffffff808816929089169133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a473ffffffffffffffffffffffffffffffffffffffff85163b156112fc576040517ff23a6e61000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff87169063f23a6e61906112919033908b908a908a908a908a906004016120f6565b6020604051808303816000875af11580156112b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d4919061201e565b7fffffffff000000000000000000000000000000000000000000000000000000001614611316565b73ffffffffffffffffffffffffffffffffffffffff851615155b61137c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e54000000000000000000000000000000006044820152606401610765565b505050505050565b61138c611764565b8060601b6113a257637448fbae6000526004601cfd5b61107b8161179a565b6113b3611764565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600060418218611463576040516040846040377f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a06060511161145f5784600052604084013560001a602052602060406080600060015afa5060006060523d6060185191505b6040525b9392505050565b8251825181146114d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4c454e4754485f4d49534d4154434800000000000000000000000000000000006044820152606401610765565b60005b8181101561157f578381815181106114f3576114f3611e6e565b60200260200101516000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600087848151811061154d5761154d611e6e565b6020026020010151815260200190815260200160002060008282546115729190611edf565b90915550506001016114d9565b508473ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516115f792919061213c565b60405180910390a473ffffffffffffffffffffffffffffffffffffffff85163b156116e4576040517fbc197c81000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff87169063bc197c81906116799033906000908a908a908a9060040161216a565b6020604051808303816000875af1158015611698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116bc919061201e565b7fffffffff0000000000000000000000000000000000000000000000000000000016146116fe565b73ffffffffffffffffffffffffffffffffffffffff851615155b610f93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e54000000000000000000000000000000006044820152606401610765565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927543314610f0d576382b429006000526004601cfd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927805473ffffffffffffffffffffffffffffffffffffffff9092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b803573ffffffffffffffffffffffffffffffffffffffff8116811461182457600080fd5b919050565b6000806040838503121561183c57600080fd5b61184583611800565b946020939093013593505050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461107b57600080fd5b60006020828403121561189357600080fd5b813561146381611853565b60005b838110156118b95781810151838201526020016118a1565b50506000910152565b600081518084526118da81602086016020860161189e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061146360208301846118c2565b60006020828403121561193157600080fd5b5035919050565b60008083601f84011261194a57600080fd5b50813567ffffffffffffffff81111561196257600080fd5b6020830191508360208260051b850101111561197d57600080fd5b9250929050565b60008083601f84011261199657600080fd5b50813567ffffffffffffffff8111156119ae57600080fd5b60208301915083602082850101111561197d57600080fd5b60008060008060008060008060a0898b0312156119e257600080fd5b6119eb89611800565b97506119f960208a01611800565b9650604089013567ffffffffffffffff80821115611a1657600080fd5b611a228c838d01611938565b909850965060608b0135915080821115611a3b57600080fd5b611a478c838d01611938565b909650945060808b0135915080821115611a6057600080fd5b50611a6d8b828c01611984565b999c989b5096995094979396929594505050565b60008060008060408587031215611a9757600080fd5b843567ffffffffffffffff80821115611aaf57600080fd5b611abb88838901611938565b90965094506020870135915080821115611ad457600080fd5b50611ae187828801611938565b95989497509550505050565b600081518084526020808501945080840160005b83811015611b1d57815187529582019590820190600101611b01565b509495945050505050565b6020815260006114636020830184611aed565b60008060008060008060006080888a031215611b5657600080fd5b873567ffffffffffffffff80821115611b6e57600080fd5b611b7a8b838c01611938565b909950975060208a0135915080821115611b9357600080fd5b611b9f8b838c01611938565b909750955060408a0135915061ffff82168214611bbb57600080fd5b90935060608901359080821115611bd157600080fd5b50611bde8a828b01611984565b989b979a50959850939692959293505050565b600060208284031215611c0357600080fd5b61146382611800565b600080600080600060608688031215611c2457600080fd5b611c2d86611800565b9450602086013567ffffffffffffffff80821115611c4a57600080fd5b611c5689838a01611938565b90965094506040880135915080821115611c6f57600080fd5b50611c7c88828901611938565b969995985093965092949392505050565b60008060408385031215611ca057600080fd5b611ca983611800565b915060208301358015158114611cbe57600080fd5b809150509250929050565b60008060408385031215611cdc57600080fd5b611ce583611800565b9150611cf360208401611800565b90509250929050565b60008060008060008060a08789031215611d1557600080fd5b611d1e87611800565b9550611d2c60208801611800565b94506040870135935060608701359250608087013567ffffffffffffffff811115611d5657600080fd5b611d6289828a01611984565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215611db557600080fd5b815167ffffffffffffffff80821115611dcd57600080fd5b818401915084601f830112611de157600080fd5b815181811115611df357611df3611d74565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611e3957611e39611d74565b81604052828152876020848701011115611e5257600080fd5b611e6383602083016020880161189e565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f4576105f4611e9d565b808201808211156105f4576105f4611e9d565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115611f2457600080fd5b8260051b80836020870137939093016020019392505050565b604081526000611f51604083018688611ef2565b8281036020840152611e63818587611ef2565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b600073ffffffffffffffffffffffffffffffffffffffff808b168352808a1660208401525060a06040830152611fe760a08301888a611ef2565b8281036060840152611ffa818789611ef2565b9050828103608084015261200f818587611f64565b9b9a5050505050505050505050565b60006020828403121561203057600080fd5b815161146381611853565b60007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561206a57600080fd5b8260051b80838637939093019392505050565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008760601b1681527fffff0000000000000000000000000000000000000000000000000000000000008660f01b16601482015260006120ea6120e360168401878961203b565b848661203b565b98975050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835280881660208401525085604083015284606083015260a060808301526120ea60a083018486611f64565b60408152600061214f6040830185611aed565b82810360208401526121618185611aed565b95945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a060408301526121a360a0830186611aed565b82810360608401526121b58186611aed565b905082810360808401526120ea81856118c256fea26469706673582212204f435c2221be3df7ed00f719688c96d8efeb99481b1d32738bd68358ff82ec9764736f6c63430008140033

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.