ETH Price: $3,476.98 (-0.38%)
Gas: 3.81 Gwei

Token

Guns & Toilet Paper (GXTP)
 

Overview

Max Total Supply

117 GXTP

Holders

117

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 GXTP
0x1fec13dff1deed9e911b819587bb818665b59f5a
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:
GXTP

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 5 : GXTP.sol
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.20;

import {ERC721} from "solmate/tokens/ERC721.sol";
import {ECDSA} from "solady/utils/ECDSA.sol";
import {Strings} from "openzeppelin-contracts/contracts/utils/Strings.sol";

error AlreadyMinted();
error InvalidSignature();
error MintingClosed();
error Unauthorized();

contract GXTP is ERC721 {
    using ECDSA for bytes32;
    using Strings for uint256;

    bool public mintingOpen = true;
    uint256 public totalSupply = 0;
    address internal expectedSigner;
    address internal mintingToggler;
    address internal metadataOwner;
    string internal baseURI;
    mapping(address minter => bool used) public minted;
    mapping(uint256 tokenId => uint256 type_) public types;

    constructor(address _expectedSigner, address _mintingToggler, string memory _name, string memory _symbol) ERC721(_name, _symbol) {
        expectedSigner = _expectedSigner;
        mintingToggler = _mintingToggler;
        metadataOwner = msg.sender;
    }

    function toggleMinting() external {
        if (msg.sender != mintingToggler) revert Unauthorized();
        mintingOpen = !mintingOpen;
    }

    function mint(bytes calldata signature, uint256 type_) external {
        if (!mintingOpen) revert MintingClosed();
        if (minted[msg.sender]) revert AlreadyMinted();
        bytes32 digest = keccak256(
            abi.encodePacked(
                "\x19\x01",
                type_,
                DOMAIN_SEPARATOR(),
                keccak256(abi.encode(msg.sender))
            )
        );

        if (digest.recover(signature) != expectedSigner) revert InvalidSignature();

        types[totalSupply] = type_;
        minted[msg.sender] = true;
        _mint(msg.sender, totalSupply++);
    }

    function DOMAIN_SEPARATOR() public view returns (bytes32 separator) {
        separator = keccak256(
            abi.encode(keccak256("EIP712Domain(uint256 chainId, address collection)"), block.chainid, address(this))
        );
    }

    function setExpectedSigner(address _expectedSigner) external {
        if (msg.sender != expectedSigner) revert Unauthorized();
        expectedSigner = _expectedSigner;
    }

    function setMintingToggler(address _mintingToggler) external {
        if (msg.sender != _mintingToggler) revert Unauthorized();
        mintingToggler = _mintingToggler;
    }

    function setMetadataOwner(address _metadataOwner) external {
        if (msg.sender != metadataOwner) revert Unauthorized();
        metadataOwner = _metadataOwner;
    }

    function setBaseURI(string calldata _baseURI) external {
        if (msg.sender != metadataOwner) revert Unauthorized();
        baseURI = _baseURI;
    }

    function tokenURI(uint256 id) public view override returns (string memory) {
        return string.concat(baseURI, id.toString());
    }
}

File 2 of 5 : ERC721.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)
abstract contract ERC721 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 indexed id);

    event Approval(address indexed owner, address indexed spender, uint256 indexed id);

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

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

    string public name;

    string public symbol;

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

    /*//////////////////////////////////////////////////////////////
                      ERC721 BALANCE/OWNER STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(uint256 => address) internal _ownerOf;

    mapping(address => uint256) internal _balanceOf;

    function ownerOf(uint256 id) public view virtual returns (address owner) {
        require((owner = _ownerOf[id]) != address(0), "NOT_MINTED");
    }

    function balanceOf(address owner) public view virtual returns (uint256) {
        require(owner != address(0), "ZERO_ADDRESS");

        return _balanceOf[owner];
    }

    /*//////////////////////////////////////////////////////////////
                         ERC721 APPROVAL STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(uint256 => address) public getApproved;

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

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(string memory _name, string memory _symbol) {
        name = _name;
        symbol = _symbol;
    }

    /*//////////////////////////////////////////////////////////////
                              ERC721 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 id) public virtual {
        address owner = _ownerOf[id];

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

        getApproved[id] = spender;

        emit Approval(owner, spender, id);
    }

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

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

    function transferFrom(
        address from,
        address to,
        uint256 id
    ) public virtual {
        require(from == _ownerOf[id], "WRONG_FROM");

        require(to != address(0), "INVALID_RECIPIENT");

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

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        unchecked {
            _balanceOf[from]--;

            _balanceOf[to]++;
        }

        _ownerOf[id] = to;

        delete getApproved[id];

        emit Transfer(from, to, id);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id
    ) public virtual {
        transferFrom(from, to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        bytes calldata data
    ) public virtual {
        transferFrom(from, to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

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

    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return
            interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
            interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
            interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata
    }

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

    function _mint(address to, uint256 id) internal virtual {
        require(to != address(0), "INVALID_RECIPIENT");

        require(_ownerOf[id] == address(0), "ALREADY_MINTED");

        // Counter overflow is incredibly unrealistic.
        unchecked {
            _balanceOf[to]++;
        }

        _ownerOf[id] = to;

        emit Transfer(address(0), to, id);
    }

    function _burn(uint256 id) internal virtual {
        address owner = _ownerOf[id];

        require(owner != address(0), "NOT_MINTED");

        // Ownership check above ensures no underflow.
        unchecked {
            _balanceOf[owner]--;
        }

        delete _ownerOf[id];

        delete getApproved[id];

        emit Transfer(owner, address(0), id);
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL SAFE MINT LOGIC
    //////////////////////////////////////////////////////////////*/

    function _safeMint(address to, uint256 id) internal virtual {
        _mint(to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function _safeMint(
        address to,
        uint256 id,
        bytes memory data
    ) internal virtual {
        _mint(to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }
}

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

File 3 of 5 : 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 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 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 4 of 5 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

import "./math/Math.sol";

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

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

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

File 5 of 5 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10**64) {
                value /= 10**64;
                result += 64;
            }
            if (value >= 10**32) {
                value /= 10**32;
                result += 32;
            }
            if (value >= 10**16) {
                value /= 10**16;
                result += 16;
            }
            if (value >= 10**8) {
                value /= 10**8;
                result += 8;
            }
            if (value >= 10**4) {
                value /= 10**4;
                result += 4;
            }
            if (value >= 10**2) {
                value /= 10**2;
                result += 2;
            }
            if (value >= 10**1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
        }
    }
}

Settings
{
  "remappings": [
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "solady/=lib/solady/src/",
    "solmate/=lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "none",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "shanghai",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_expectedSigner","type":"address"},{"internalType":"address","name":"_mintingToggler","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyMinted","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"MintingClosed","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"separator","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"id","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":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":[{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256","name":"type_","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"minted","outputs":[{"internalType":"bool","name":"used","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintingOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"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":"string","name":"_baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_expectedSigner","type":"address"}],"name":"setExpectedSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_metadataOwner","type":"address"}],"name":"setMetadataOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mintingToggler","type":"address"}],"name":"setMintingToggler","outputs":[],"stateMutability":"nonpayable","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":"toggleMinting","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":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"types","outputs":[{"internalType":"uint256","name":"type_","type":"uint256"}],"stateMutability":"view","type":"function"}]

60806040526006805460ff191660011790555f60075534801562000021575f80fd5b50604051620018d5380380620018d5833981016040819052620000449162000183565b81815f6200005383826200029a565b5060016200006282826200029a565b5050600880546001600160a01b039687166001600160a01b0319918216179091556009805495909616948116949094179094555050600a8054909116331790555062000362565b80516001600160a01b0381168114620000c0575f80fd5b919050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f830112620000e9575f80fd5b81516001600160401b0380821115620001065762000106620000c5565b604051601f8301601f19908116603f01168101908282118183101715620001315762000131620000c5565b816040528381526020925086838588010111156200014d575f80fd5b5f91505b8382101562000170578582018301518183018401529082019062000151565b5f93810190920192909252949350505050565b5f805f806080858703121562000197575f80fd5b620001a285620000a9565b9350620001b260208601620000a9565b60408601519093506001600160401b0380821115620001cf575f80fd5b620001dd88838901620000d9565b93506060870151915080821115620001f3575f80fd5b506200020287828801620000d9565b91505092959194509250565b600181811c908216806200022357607f821691505b6020821081036200024257634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562000295575f81815260208120601f850160051c81016020861015620002705750805b601f850160051c820191505b8181101562000291578281556001016200027c565b5050505b505050565b81516001600160401b03811115620002b657620002b6620000c5565b620002ce81620002c784546200020e565b8462000248565b602080601f83116001811462000304575f8415620002ec5750858301515b5f19600386901b1c1916600185901b17855562000291565b5f85815260208120601f198616915b82811015620003345788860151825594840194600190910190840162000313565b50858210156200035257878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b61156580620003705f395ff3fe608060405234801561000f575f80fd5b5060043610610152575f3560e01c80636352211e116100bf578063a22cb46511610079578063a22cb465146102de578063b88d4fde146102f1578063c87b56dd14610304578063cefbfa3614610317578063e985e9c514610336578063ecde3c8914610363575f80fd5b80636352211e1461028857806370a082311461029b5780637d55094d146102ae5780638f4bb497146102b657806395d89b41146102c35780639b7995e8146102cb575f80fd5b80631e7269c5116101105780631e7269c51461021257806323b872dd146102345780632a954e5a146102475780633644e5151461025a57806342842e0e1461026257806355f804b314610275575f80fd5b80622576121461015657806301ffc9a71461016b57806306fdde0314610193578063081812fc146101a8578063095ea7b3146101e857806318160ddd146101fb575b5f80fd5b610169610164366004611060565b610376565b005b61017e6101793660046110c0565b6104cd565b60405190151581526020015b60405180910390f35b61019b61051e565b60405161018a9190611104565b6101d06101b6366004611136565b60046020525f90815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161018a565b6101696101f6366004611163565b6105a9565b61020460075481565b60405190815260200161018a565b61017e61022036600461118b565b600c6020525f908152604090205460ff1681565b6101696102423660046111a4565b61068d565b61016961025536600461118b565b61084f565b610204610899565b6101696102703660046111a4565b6108f1565b6101696102833660046111dd565b6109e5565b6101d0610296366004611136565b610a1c565b6102046102a936600461118b565b610a72565b610169610ad3565b60065461017e9060ff1681565b61019b610b11565b6101696102d936600461118b565b610b1e565b6101696102ec36600461121c565b610b6a565b6101696102ff366004611255565b610bd5565b61019b610312366004611136565b610cba565b610204610325366004611136565b600d6020525f908152604090205481565b61017e6103443660046112bf565b600560209081525f928352604080842090915290825290205460ff1681565b61016961037136600461118b565b610cee565b60065460ff166103995760405163a7e4d9bd60e01b815260040160405180910390fd5b335f908152600c602052604090205460ff16156103c957604051631bbdf5c560e31b815260040160405180910390fd5b5f816103d3610899565b6040805133602082015201604051602081830303815290604052805190602001206040516020016104249392919061190160f01b815260028101939093526022830191909152604282015260620190565b60408051601f1981840301815291905280516020909101206008549091506001600160a01b0316610456828686610d3a565b6001600160a01b03161461047d57604051638baa579f60e01b815260040160405180910390fd5b600780545f908152600d6020908152604080832086905533808452600c9092528220805460ff1916600117905582546104c79391929091906104be836112f0565b91905055610dab565b50505050565b5f6301ffc9a760e01b6001600160e01b0319831614806104fd57506380ac58cd60e01b6001600160e01b03198316145b806105185750635b5e139f60e01b6001600160e01b03198316145b92915050565b5f805461052a90611314565b80601f016020809104026020016040519081016040528092919081815260200182805461055690611314565b80156105a15780601f10610578576101008083540402835291602001916105a1565b820191905f5260205f20905b81548152906001019060200180831161058457829003601f168201915b505050505081565b5f818152600260205260409020546001600160a01b0316338114806105f057506001600160a01b0381165f90815260056020908152604080832033845290915290205460ff165b6106325760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b5f8281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b5f818152600260205260409020546001600160a01b038481169116146106e25760405162461bcd60e51b815260206004820152600a60248201526957524f4e475f46524f4d60b01b6044820152606401610629565b6001600160a01b03821661072c5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610629565b336001600160a01b038416148061076557506001600160a01b0383165f90815260056020908152604080832033845290915290205460ff165b8061078557505f818152600460205260409020546001600160a01b031633145b6107c25760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610629565b6001600160a01b038084165f81815260036020908152604080832080545f19019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b336001600160a01b03821614610877576040516282b42960e81b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0392909216919091179055565b604080517febb1b0cbfdbdf1d7214f4fd43d47fa3efa230b09e7a6f4b87e6317df6db31408602082015246918101919091523060608201525f9060800160405160208183030381529060405280519060200120905090565b6108fc83838361068d565b6001600160a01b0382163b15806109a15750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401525f608484015290919084169063150b7a029060a4016020604051808303815f875af1158015610971573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610995919061134c565b6001600160e01b031916145b6109e05760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610629565b505050565b600a546001600160a01b03163314610a0f576040516282b42960e81b815260040160405180910390fd5b600b6109e08284836113c8565b5f818152600260205260409020546001600160a01b031680610a6d5760405162461bcd60e51b815260206004820152600a6024820152691393d517d3525395115160b21b6044820152606401610629565b919050565b5f6001600160a01b038216610ab85760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b6044820152606401610629565b506001600160a01b03165f9081526003602052604090205490565b6009546001600160a01b03163314610afd576040516282b42960e81b815260040160405180910390fd5b6006805460ff19811660ff90911615179055565b6001805461052a90611314565b6008546001600160a01b03163314610b48576040516282b42960e81b815260040160405180910390fd5b600880546001600160a01b0319166001600160a01b0392909216919091179055565b335f8181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b610be085858561068d565b6001600160a01b0384163b1580610c745750604051630a85bd0160e11b808252906001600160a01b0386169063150b7a0290610c289033908a90899089908990600401611483565b6020604051808303815f875af1158015610c44573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c68919061134c565b6001600160e01b031916145b610cb35760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610629565b5050505050565b6060600b610cc783610eb4565b604051602001610cd89291906114d5565b6040516020818303038152906040529050919050565b600a546001600160a01b03163314610d18576040516282b42960e81b815260040160405180910390fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b5f604051604084604037845f5260408401355f1a60205260205f60805f60017f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0016060511060418814165afa505f5191503d610d9d57638baa579f5f526004601cfd5b5f6060526040529392505050565b6001600160a01b038216610df55760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610629565b5f818152600260205260409020546001600160a01b031615610e4a5760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b6044820152606401610629565b6001600160a01b0382165f81815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60605f610ec083610f44565b60010190505f8167ffffffffffffffff811115610edf57610edf611367565b6040519080825280601f01601f191660200182016040528015610f09576020820181803683370190505b5090508181016020015b5f19016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610f1357509392505050565b5f8072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310610f825772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310610fae576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310610fcc57662386f26fc10000830492506010015b6305f5e1008310610fe4576305f5e100830492506008015b6127108310610ff857612710830492506004015b6064831061100a576064830492506002015b600a83106105185760010192915050565b5f8083601f84011261102b575f80fd5b50813567ffffffffffffffff811115611042575f80fd5b602083019150836020828501011115611059575f80fd5b9250929050565b5f805f60408486031215611072575f80fd5b833567ffffffffffffffff811115611088575f80fd5b6110948682870161101b565b909790965060209590950135949350505050565b6001600160e01b0319811681146110bd575f80fd5b50565b5f602082840312156110d0575f80fd5b81356110db816110a8565b9392505050565b5f5b838110156110fc5781810151838201526020016110e4565b50505f910152565b602081525f82518060208401526111228160408501602087016110e2565b601f01601f19169190910160400192915050565b5f60208284031215611146575f80fd5b5035919050565b80356001600160a01b0381168114610a6d575f80fd5b5f8060408385031215611174575f80fd5b61117d8361114d565b946020939093013593505050565b5f6020828403121561119b575f80fd5b6110db8261114d565b5f805f606084860312156111b6575f80fd5b6111bf8461114d565b92506111cd6020850161114d565b9150604084013590509250925092565b5f80602083850312156111ee575f80fd5b823567ffffffffffffffff811115611204575f80fd5b6112108582860161101b565b90969095509350505050565b5f806040838503121561122d575f80fd5b6112368361114d565b91506020830135801515811461124a575f80fd5b809150509250929050565b5f805f805f60808688031215611269575f80fd5b6112728661114d565b94506112806020870161114d565b935060408601359250606086013567ffffffffffffffff8111156112a2575f80fd5b6112ae8882890161101b565b969995985093965092949392505050565b5f80604083850312156112d0575f80fd5b6112d98361114d565b91506112e76020840161114d565b90509250929050565b5f6001820161130d57634e487b7160e01b5f52601160045260245ffd5b5060010190565b600181811c9082168061132857607f821691505b60208210810361134657634e487b7160e01b5f52602260045260245ffd5b50919050565b5f6020828403121561135c575f80fd5b81516110db816110a8565b634e487b7160e01b5f52604160045260245ffd5b601f8211156109e0575f81815260208120601f850160051c810160208610156113a15750805b601f850160051c820191505b818110156113c0578281556001016113ad565b505050505050565b67ffffffffffffffff8311156113e0576113e0611367565b6113f4836113ee8354611314565b8361137b565b5f601f841160018114611425575f851561140e5750838201355b5f19600387901b1c1916600186901b178355610cb3565b5f83815260209020601f19861690835b828110156114555786850135825560209485019460019092019101611435565b5086821015611471575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6001600160a01b038681168252851660208201526040810184905260806060820181905281018290525f828460a08401375f60a0848401015260a0601f19601f85011683010190509695505050505050565b5f8084546114e281611314565b600182811680156114fa576001811461150f5761153b565b60ff198416875282151583028701945061153b565b885f526020805f205f5b858110156115325781548a820152908401908201611519565b50505082870194505b50505050835161154f8183602088016110e2565b0194935050505056fea164736f6c6343000814000a0000000000000000000000008c25823639aad5f4395d777eac847aaec509b027000000000000000000000000822db0604a210bc50ea8550c7495b8fddea98ecc000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000001347756e73202620546f696c65742050617065720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044758545000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561000f575f80fd5b5060043610610152575f3560e01c80636352211e116100bf578063a22cb46511610079578063a22cb465146102de578063b88d4fde146102f1578063c87b56dd14610304578063cefbfa3614610317578063e985e9c514610336578063ecde3c8914610363575f80fd5b80636352211e1461028857806370a082311461029b5780637d55094d146102ae5780638f4bb497146102b657806395d89b41146102c35780639b7995e8146102cb575f80fd5b80631e7269c5116101105780631e7269c51461021257806323b872dd146102345780632a954e5a146102475780633644e5151461025a57806342842e0e1461026257806355f804b314610275575f80fd5b80622576121461015657806301ffc9a71461016b57806306fdde0314610193578063081812fc146101a8578063095ea7b3146101e857806318160ddd146101fb575b5f80fd5b610169610164366004611060565b610376565b005b61017e6101793660046110c0565b6104cd565b60405190151581526020015b60405180910390f35b61019b61051e565b60405161018a9190611104565b6101d06101b6366004611136565b60046020525f90815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161018a565b6101696101f6366004611163565b6105a9565b61020460075481565b60405190815260200161018a565b61017e61022036600461118b565b600c6020525f908152604090205460ff1681565b6101696102423660046111a4565b61068d565b61016961025536600461118b565b61084f565b610204610899565b6101696102703660046111a4565b6108f1565b6101696102833660046111dd565b6109e5565b6101d0610296366004611136565b610a1c565b6102046102a936600461118b565b610a72565b610169610ad3565b60065461017e9060ff1681565b61019b610b11565b6101696102d936600461118b565b610b1e565b6101696102ec36600461121c565b610b6a565b6101696102ff366004611255565b610bd5565b61019b610312366004611136565b610cba565b610204610325366004611136565b600d6020525f908152604090205481565b61017e6103443660046112bf565b600560209081525f928352604080842090915290825290205460ff1681565b61016961037136600461118b565b610cee565b60065460ff166103995760405163a7e4d9bd60e01b815260040160405180910390fd5b335f908152600c602052604090205460ff16156103c957604051631bbdf5c560e31b815260040160405180910390fd5b5f816103d3610899565b6040805133602082015201604051602081830303815290604052805190602001206040516020016104249392919061190160f01b815260028101939093526022830191909152604282015260620190565b60408051601f1981840301815291905280516020909101206008549091506001600160a01b0316610456828686610d3a565b6001600160a01b03161461047d57604051638baa579f60e01b815260040160405180910390fd5b600780545f908152600d6020908152604080832086905533808452600c9092528220805460ff1916600117905582546104c79391929091906104be836112f0565b91905055610dab565b50505050565b5f6301ffc9a760e01b6001600160e01b0319831614806104fd57506380ac58cd60e01b6001600160e01b03198316145b806105185750635b5e139f60e01b6001600160e01b03198316145b92915050565b5f805461052a90611314565b80601f016020809104026020016040519081016040528092919081815260200182805461055690611314565b80156105a15780601f10610578576101008083540402835291602001916105a1565b820191905f5260205f20905b81548152906001019060200180831161058457829003601f168201915b505050505081565b5f818152600260205260409020546001600160a01b0316338114806105f057506001600160a01b0381165f90815260056020908152604080832033845290915290205460ff165b6106325760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b5f8281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b5f818152600260205260409020546001600160a01b038481169116146106e25760405162461bcd60e51b815260206004820152600a60248201526957524f4e475f46524f4d60b01b6044820152606401610629565b6001600160a01b03821661072c5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610629565b336001600160a01b038416148061076557506001600160a01b0383165f90815260056020908152604080832033845290915290205460ff165b8061078557505f818152600460205260409020546001600160a01b031633145b6107c25760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610629565b6001600160a01b038084165f81815260036020908152604080832080545f19019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b336001600160a01b03821614610877576040516282b42960e81b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0392909216919091179055565b604080517febb1b0cbfdbdf1d7214f4fd43d47fa3efa230b09e7a6f4b87e6317df6db31408602082015246918101919091523060608201525f9060800160405160208183030381529060405280519060200120905090565b6108fc83838361068d565b6001600160a01b0382163b15806109a15750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401525f608484015290919084169063150b7a029060a4016020604051808303815f875af1158015610971573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610995919061134c565b6001600160e01b031916145b6109e05760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610629565b505050565b600a546001600160a01b03163314610a0f576040516282b42960e81b815260040160405180910390fd5b600b6109e08284836113c8565b5f818152600260205260409020546001600160a01b031680610a6d5760405162461bcd60e51b815260206004820152600a6024820152691393d517d3525395115160b21b6044820152606401610629565b919050565b5f6001600160a01b038216610ab85760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b6044820152606401610629565b506001600160a01b03165f9081526003602052604090205490565b6009546001600160a01b03163314610afd576040516282b42960e81b815260040160405180910390fd5b6006805460ff19811660ff90911615179055565b6001805461052a90611314565b6008546001600160a01b03163314610b48576040516282b42960e81b815260040160405180910390fd5b600880546001600160a01b0319166001600160a01b0392909216919091179055565b335f8181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b610be085858561068d565b6001600160a01b0384163b1580610c745750604051630a85bd0160e11b808252906001600160a01b0386169063150b7a0290610c289033908a90899089908990600401611483565b6020604051808303815f875af1158015610c44573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c68919061134c565b6001600160e01b031916145b610cb35760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610629565b5050505050565b6060600b610cc783610eb4565b604051602001610cd89291906114d5565b6040516020818303038152906040529050919050565b600a546001600160a01b03163314610d18576040516282b42960e81b815260040160405180910390fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b5f604051604084604037845f5260408401355f1a60205260205f60805f60017f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0016060511060418814165afa505f5191503d610d9d57638baa579f5f526004601cfd5b5f6060526040529392505050565b6001600160a01b038216610df55760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610629565b5f818152600260205260409020546001600160a01b031615610e4a5760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b6044820152606401610629565b6001600160a01b0382165f81815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60605f610ec083610f44565b60010190505f8167ffffffffffffffff811115610edf57610edf611367565b6040519080825280601f01601f191660200182016040528015610f09576020820181803683370190505b5090508181016020015b5f19016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610f1357509392505050565b5f8072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310610f825772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310610fae576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310610fcc57662386f26fc10000830492506010015b6305f5e1008310610fe4576305f5e100830492506008015b6127108310610ff857612710830492506004015b6064831061100a576064830492506002015b600a83106105185760010192915050565b5f8083601f84011261102b575f80fd5b50813567ffffffffffffffff811115611042575f80fd5b602083019150836020828501011115611059575f80fd5b9250929050565b5f805f60408486031215611072575f80fd5b833567ffffffffffffffff811115611088575f80fd5b6110948682870161101b565b909790965060209590950135949350505050565b6001600160e01b0319811681146110bd575f80fd5b50565b5f602082840312156110d0575f80fd5b81356110db816110a8565b9392505050565b5f5b838110156110fc5781810151838201526020016110e4565b50505f910152565b602081525f82518060208401526111228160408501602087016110e2565b601f01601f19169190910160400192915050565b5f60208284031215611146575f80fd5b5035919050565b80356001600160a01b0381168114610a6d575f80fd5b5f8060408385031215611174575f80fd5b61117d8361114d565b946020939093013593505050565b5f6020828403121561119b575f80fd5b6110db8261114d565b5f805f606084860312156111b6575f80fd5b6111bf8461114d565b92506111cd6020850161114d565b9150604084013590509250925092565b5f80602083850312156111ee575f80fd5b823567ffffffffffffffff811115611204575f80fd5b6112108582860161101b565b90969095509350505050565b5f806040838503121561122d575f80fd5b6112368361114d565b91506020830135801515811461124a575f80fd5b809150509250929050565b5f805f805f60808688031215611269575f80fd5b6112728661114d565b94506112806020870161114d565b935060408601359250606086013567ffffffffffffffff8111156112a2575f80fd5b6112ae8882890161101b565b969995985093965092949392505050565b5f80604083850312156112d0575f80fd5b6112d98361114d565b91506112e76020840161114d565b90509250929050565b5f6001820161130d57634e487b7160e01b5f52601160045260245ffd5b5060010190565b600181811c9082168061132857607f821691505b60208210810361134657634e487b7160e01b5f52602260045260245ffd5b50919050565b5f6020828403121561135c575f80fd5b81516110db816110a8565b634e487b7160e01b5f52604160045260245ffd5b601f8211156109e0575f81815260208120601f850160051c810160208610156113a15750805b601f850160051c820191505b818110156113c0578281556001016113ad565b505050505050565b67ffffffffffffffff8311156113e0576113e0611367565b6113f4836113ee8354611314565b8361137b565b5f601f841160018114611425575f851561140e5750838201355b5f19600387901b1c1916600186901b178355610cb3565b5f83815260209020601f19861690835b828110156114555786850135825560209485019460019092019101611435565b5086821015611471575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6001600160a01b038681168252851660208201526040810184905260806060820181905281018290525f828460a08401375f60a0848401015260a0601f19601f85011683010190509695505050505050565b5f8084546114e281611314565b600182811680156114fa576001811461150f5761153b565b60ff198416875282151583028701945061153b565b885f526020805f205f5b858110156115325781548a820152908401908201611519565b50505082870194505b50505050835161154f8183602088016110e2565b0194935050505056fea164736f6c6343000814000a

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

0000000000000000000000008c25823639aad5f4395d777eac847aaec509b027000000000000000000000000822db0604a210bc50ea8550c7495b8fddea98ecc000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000001347756e73202620546f696c65742050617065720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044758545000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _expectedSigner (address): 0x8C25823639AAD5f4395D777eaC847aaEC509b027
Arg [1] : _mintingToggler (address): 0x822DB0604a210BC50Ea8550c7495b8fddeA98ecc
Arg [2] : _name (string): Guns & Toilet Paper
Arg [3] : _symbol (string): GXTP

-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000008c25823639aad5f4395d777eac847aaec509b027
Arg [1] : 000000000000000000000000822db0604a210bc50ea8550c7495b8fddea98ecc
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000013
Arg [5] : 47756e73202620546f696c657420506170657200000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [7] : 4758545000000000000000000000000000000000000000000000000000000000


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.