ETH Price: $2,405.21 (-1.79%)
 

Overview

Max Total Supply

513,547 FUNPASS

Holders

513,547

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 FUNPASS
0xc11098E261cF77704616a84E7B0D28673639f8e7
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:
FundropPass

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 250000 runs

Other Settings:
default evmVersion
File 1 of 11 : FundropPass.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;

import {IERC165} from "openzeppelin/utils/introspection/IERC165.sol";
import {IERC721} from "openzeppelin/token/ERC721/IERC721.sol";
import {IERC721Metadata} from "openzeppelin/token/ERC721/extensions/IERC721Metadata.sol";
import {ECDSA} from "solady/utils/ECDSA.sol";
import {Ownable} from "openzeppelin/access/Ownable.sol";

import "./NonTransferrableERC721.sol";
import "./IERC4906.sol";
import "./IFundropRewards.sol";
import "./IMetadataRenderer.sol";

contract FundropPass is NonTransferrableERC721, IERC4906, Ownable {
    address public metadataRenderer;
    address public rewardsDistributor;

    address public metadataUpdater;
    address public signer;
    bool public mintOpen;

    error InvalidSignature();
    error MintClosed();
    error OnlyOwnerOrMetadataUpdater();

    event MinterReferred(address referrer);

    constructor() NonTransferrableERC721("mint.fun !fundrop pass", "FUNPASS") {
        if (msg.sender != tx.origin) {
            transferOwnership(tx.origin);
        }
    }

    function mint(address referrer, bytes calldata signature) public {
        if (!mintOpen) revert MintClosed();
        address recovered = ECDSA.tryRecoverCalldata(keccak256(abi.encodePacked(msg.sender, referrer)), signature);
        if (recovered != signer) revert InvalidSignature();
        if (referrer != address(0)) emit MinterReferred(referrer);
        _mint(msg.sender);
    }

    function tokenURI(uint256 id) public view override returns (string memory) {
        if (!_exists(id)) revert InvalidTokenId();
        return IMetadataRenderer(metadataRenderer).tokenURI(id);
    }

    // Admin functions

    function refreshMetadata() public {
        if (msg.sender != metadataUpdater && msg.sender != owner()) {
            revert OnlyOwnerOrMetadataUpdater();
        }
        emit BatchMetadataUpdate(0, type(uint256).max);
    }

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

    function setMetadataUpdater(address _metadataUpdater) public onlyOwner {
        metadataUpdater = _metadataUpdater;
    }

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

    function setRewardsDistributor(address _rewardsDistributor) public onlyOwner {
        rewardsDistributor = _rewardsDistributor;
    }

    function setMintOpen(bool _mintOpen) public onlyOwner {
        mintOpen = _mintOpen;
    }

    function adminBurn(uint256[] calldata ids) public onlyOwner {
        for (uint256 i = 0; i < ids.length; i++) {
            _burn(ids[i]);
        }
    }

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

File 2 of 11 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

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

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

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

File 3 of 11 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

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

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

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

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

File 4 of 11 : IERC721Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC721.sol";

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

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

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

File 5 of 11 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

File 6 of 11 : 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 7 of 11 : 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 8 of 11 : 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);
}

File 9 of 11 : IFundropRewards.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.17;

interface IFundropRewards {
    function getRewardsBalance(address _minter) external view returns (uint256);
    function claimRewards(address _minter, bytes memory _args) external;
}

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

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

File 11 of 11 : NonTransferrableERC721.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;

import {IERC721} from "openzeppelin/token/ERC721/IERC721.sol";
import {IERC721Metadata} from "openzeppelin/token/ERC721/extensions/IERC721Metadata.sol";
import {IERC165} from "openzeppelin/utils/introspection/IERC165.sol";

abstract contract NonTransferrableERC721 is IERC721, IERC721Metadata {
    string public override name;
    string public override symbol;

    mapping(uint256 => address) private _owners;
    mapping(address => uint256) private _tokens;
    uint256 private _nextTokenId = 1;
    uint256 private _burnedTokenCount;

    error AlreadyMinted();
    error InvalidAddress();
    error InvalidTokenId();
    error NonTransferrable();

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

    function _mint(address to) internal {
        if (to == address(0)) revert InvalidAddress();
        if (_tokens[to] != 0) revert AlreadyMinted();

        unchecked {
            uint256 tokenId = _nextTokenId++;
            _owners[tokenId] = to;
            _tokens[to] = tokenId;

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

    function _burn(uint256 tokenId) internal {
        address owner = _owners[tokenId];
        if (owner == address(0)) revert InvalidTokenId();

        _owners[tokenId] = address(0);
        _tokens[owner] = 0;
        unchecked {
            _burnedTokenCount++;
        }

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

    function _burn(address owner) internal {
        uint256 tokenId = _tokens[owner];
        if (tokenId == 0) revert InvalidAddress();

        _owners[tokenId] = address(0);
        _tokens[owner] = 0;
        unchecked {
            _burnedTokenCount++;
        }

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

    function _exists(uint256 tokenId) internal view returns (bool) {
        return _owners[tokenId] != address(0);
    }

    function supportsInterface(bytes4 interfaceID) external pure virtual override returns (bool) {
        return interfaceID == type(IERC165).interfaceId || interfaceID == type(IERC721).interfaceId
            || interfaceID == type(IERC721Metadata).interfaceId;
    }

    function balanceOf(address _owner) external view override returns (uint256) {
        if (_owner == address(0)) revert InvalidAddress();
        return _tokens[_owner] > 0 ? 1 : 0;
    }

    function ownerOf(uint256 _tokenId) external view override returns (address) {
        address owner = _owners[_tokenId];
        if (owner == address(0)) revert InvalidTokenId();
        return owner;
    }

    function safeTransferFrom(address, address, uint256) external pure override {
        revert NonTransferrable();
    }

    function safeTransferFrom(address, address, uint256, bytes calldata) external pure override {
        revert NonTransferrable();
    }

    function transferFrom(address, address, uint256) external pure override {
        revert NonTransferrable();
    }

    function approve(address, uint256) external pure override {
        revert NonTransferrable();
    }

    function setApprovalForAll(address, bool) external pure override {
        revert NonTransferrable();
    }

    function getApproved(uint256) external pure override returns (address) {
        revert NonTransferrable();
    }

    function isApprovedForAll(address, address) external pure override returns (bool) {
        return false;
    }

    function totalSupply() external view returns (uint256) {
        return _nextTokenId - 1 - _burnedTokenCount;
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyMinted","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"InvalidTokenId","type":"error"},{"inputs":[],"name":"MintClosed","type":"error"},{"inputs":[],"name":"NonTransferrable","type":"error"},{"inputs":[],"name":"OnlyOwnerOrMetadataUpdater","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_toTokenId","type":"uint256"}],"name":"BatchMetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"MetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"referrer","type":"address"}],"name":"MinterReferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"adminBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"pure","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":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"metadataRenderer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metadataUpdater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"referrer","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refreshMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardsDistributor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_metadataRenderer","type":"address"}],"name":"setMetadataRenderer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_metadataUpdater","type":"address"}],"name":"setMetadataUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_mintOpen","type":"bool"}],"name":"setMintOpen","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsDistributor","type":"address"}],"name":"setRewardsDistributor","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":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","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":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405260016004553480156200001657600080fd5b506040518060400160405280601681526020017f6d696e742e66756e202166756e64726f702070617373000000000000000000008152506040518060400160405280600781526020016646554e5041535360c81b81525081600090816200007e91906200029f565b5060016200008d82826200029f565b505050620000aa620000a4620000c360201b60201c565b620000c7565b333214620000bd57620000bd3262000119565b6200036b565b3390565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b620001236200019c565b6001600160a01b0381166200018e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b6200019981620000c7565b50565b6006546001600160a01b03163314620001f85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000185565b565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200022557607f821691505b6020821081036200024657634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029a57600081815260208120601f850160051c81016020861015620002755750805b601f850160051c820191505b81811015620002965782815560010162000281565b5050505b505050565b81516001600160401b03811115620002bb57620002bb620001fa565b620002d381620002cc845462000210565b846200024c565b602080601f8311600181146200030b5760008415620002f25750858301515b600019600386901b1c1916600185901b17855562000296565b600085815260208120601f198616915b828110156200033c578886015182559484019460019091019084016200031b565b50858210156200035b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6116de806200037b6000396000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c806370a0823111610104578063b88d4fde116100a2578063e985e9c511610071578063e985e9c51461041c578063f2fde38b14610432578063f8004d3114610445578063fd4fe8a81461045857600080fd5b8063b88d4fde146103d5578063c87b56dd146103e3578063d1f5c33b146103f6578063d66fe70e1461040957600080fd5b80638da5cb5b116100de5780638da5cb5b1461038e57806395d89b41146103ac578063a22cb465146103b4578063b510391f146103c257600080fd5b806370a0823114610353578063715018a6146103665780638325c62f1461036e57600080fd5b806324bbd0491161017c5780636352211e1161014b5780636352211e146102fa5780636ba253fd1461030d5780636c19e78314610320578063703199701461033357600080fd5b806324bbd049146102ad5780633f2a5540146102d257806341006605146102f257806342842e0e1461029f57600080fd5b8063095ea7b3116101b8578063095ea7b31461025457806318160ddd14610269578063238ac9331461027f57806323b872dd1461029f57600080fd5b806301ffc9a7146101df57806306fdde0314610207578063081812fc1461021c575b600080fd5b6101f26101ed366004611130565b61046b565b60405190151581526020015b60405180910390f35b61020f61057b565b6040516101fe9190611196565b61022f61022a3660046111e7565b610609565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101fe565b610267610262366004611229565b61063d565b005b61027161066f565b6040519081526020016101fe565b600a5461022f9073ffffffffffffffffffffffffffffffffffffffff1681565b610267610262366004611253565b600a546101f29074010000000000000000000000000000000000000000900460ff1681565b60085461022f9073ffffffffffffffffffffffffffffffffffffffff1681565b610267610692565b61022f6103083660046111e7565b610764565b61026761031b36600461128f565b6107c0565b61026761032e36600461128f565b61080f565b60075461022f9073ffffffffffffffffffffffffffffffffffffffff1681565b61027161036136600461128f565b61085e565b6102676108ea565b60095461022f9073ffffffffffffffffffffffffffffffffffffffff1681565b60065473ffffffffffffffffffffffffffffffffffffffff1661022f565b61020f6108fe565b6102676102623660046112ba565b6102676103d0366004611336565b61090b565b610267610262366004611389565b61020f6103f13660046111e7565b610a8c565b61026761040436600461128f565b610b9f565b6102676104173660046113f8565b610bee565b6101f261042a36600461146d565b600092915050565b61026761044036600461128f565b610c39565b610267610453366004611497565b610cf5565b61026761046636600461128f565b610d47565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806104fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd00000000000000000000000000000000000000000000000000000000145b8061052957507fffffffff000000000000000000000000000000000000000000000000000000008216155b8061057557507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b92915050565b60008054610588906114b2565b80601f01602080910402602001604051908101604052809291908181526020018280546105b4906114b2565b80156106015780601f106105d657610100808354040283529160200191610601565b820191906000526020600020905b8154815290600101906020018083116105e457829003601f168201915b505050505081565b60006040517fbf9e1a7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fbf9e1a7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060055460016004546106839190611534565b61068d9190611534565b905090565b60095473ffffffffffffffffffffffffffffffffffffffff1633148015906106d2575060065473ffffffffffffffffffffffffffffffffffffffff163314155b15610709576040517f0707164200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051600081527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208201527f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c910160405180910390a1565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff1680610575576040517f3f6cc76800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c8610d97565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610817610d97565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff82166108ad576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260409020546108de5760006108e1565b60015b60ff1692915050565b6108f2610d97565b6108fc6000610e18565b565b60018054610588906114b2565b600a5474010000000000000000000000000000000000000000900460ff1661095f576040517f589ed34b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fffffffffffffffffffffffffffffffffffffffff00000000000000000000000033606090811b8216602084015285901b1660348201526000906109c090604801604051602081830303815290604052805190602001208484610e8f565b600a5490915073ffffffffffffffffffffffffffffffffffffffff808316911614610a17576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff841615610a7d5760405173ffffffffffffffffffffffffffffffffffffffff851681527fcecb5f5b62b88dc819e81f535d3c431ec78987ab181067baac5d532dde7ee38a9060200160405180910390a15b610a8633610eff565b50505050565b60008181526002602052604090205460609073ffffffffffffffffffffffffffffffffffffffff16610aea576040517f3f6cc76800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546040517fc87b56dd0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff9091169063c87b56dd90602401600060405180830381865afa158015610b59573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105759190810190611576565b610ba7610d97565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610bf6610d97565b60005b81811015610c3457610c22838383818110610c1657610c16611641565b90506020020135611041565b80610c2c81611670565b915050610bf9565b505050565b610c41610d97565b73ffffffffffffffffffffffffffffffffffffffff8116610ce9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610cf281610e18565b50565b610cfd610d97565b600a805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b610d4f610d97565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316179055610cf2610692565b60065473ffffffffffffffffffffffffffffffffffffffff1633146108fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610ce0565b6006805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600060418218610ef8576040516040846040377f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a060605111610ef45784600052604084013560001a602052602060406080600060015afa5060006060523d6060185191505b6040525b9392505050565b73ffffffffffffffffffffffffffffffffffffffff8116610f4c576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604090205415610fa9576040517fddefae2800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805460018101909155600081815260026020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff87169081179091558084526003909252808320849055518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff168061109d576040517f3f6cc76800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260026020908152604080832080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905573ffffffffffffffffffffffffffffffffffffffff8416808452600390925280832083905560058054600101905551849291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60006020828403121561114257600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610ef857600080fd5b60005b8381101561118d578181015183820152602001611175565b50506000910152565b60208152600082518060208401526111b5816040850160208701611172565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000602082840312156111f957600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461122457600080fd5b919050565b6000806040838503121561123c57600080fd5b61124583611200565b946020939093013593505050565b60008060006060848603121561126857600080fd5b61127184611200565b925061127f60208501611200565b9150604084013590509250925092565b6000602082840312156112a157600080fd5b610ef882611200565b8035801515811461122457600080fd5b600080604083850312156112cd57600080fd5b6112d683611200565b91506112e4602084016112aa565b90509250929050565b60008083601f8401126112ff57600080fd5b50813567ffffffffffffffff81111561131757600080fd5b60208301915083602082850101111561132f57600080fd5b9250929050565b60008060006040848603121561134b57600080fd5b61135484611200565b9250602084013567ffffffffffffffff81111561137057600080fd5b61137c868287016112ed565b9497909650939450505050565b6000806000806000608086880312156113a157600080fd5b6113aa86611200565b94506113b860208701611200565b935060408601359250606086013567ffffffffffffffff8111156113db57600080fd5b6113e7888289016112ed565b969995985093965092949392505050565b6000806020838503121561140b57600080fd5b823567ffffffffffffffff8082111561142357600080fd5b818501915085601f83011261143757600080fd5b81358181111561144657600080fd5b8660208260051b850101111561145b57600080fd5b60209290920196919550909350505050565b6000806040838503121561148057600080fd5b61148983611200565b91506112e460208401611200565b6000602082840312156114a957600080fd5b610ef8826112aa565b600181811c908216806114c657607f821691505b6020821081036114ff577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561057557610575611505565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561158857600080fd5b815167ffffffffffffffff808211156115a057600080fd5b818401915084601f8301126115b457600080fd5b8151818111156115c6576115c6611547565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561160c5761160c611547565b8160405282815287602084870101111561162557600080fd5b611636836020830160208801611172565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036116a1576116a1611505565b506001019056fea2646970667358221220df1432e10b439c47c2222cb54563bde482d7a3e8ac331e8e9d23e76a42d80ed664736f6c63430008130033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101da5760003560e01c806370a0823111610104578063b88d4fde116100a2578063e985e9c511610071578063e985e9c51461041c578063f2fde38b14610432578063f8004d3114610445578063fd4fe8a81461045857600080fd5b8063b88d4fde146103d5578063c87b56dd146103e3578063d1f5c33b146103f6578063d66fe70e1461040957600080fd5b80638da5cb5b116100de5780638da5cb5b1461038e57806395d89b41146103ac578063a22cb465146103b4578063b510391f146103c257600080fd5b806370a0823114610353578063715018a6146103665780638325c62f1461036e57600080fd5b806324bbd0491161017c5780636352211e1161014b5780636352211e146102fa5780636ba253fd1461030d5780636c19e78314610320578063703199701461033357600080fd5b806324bbd049146102ad5780633f2a5540146102d257806341006605146102f257806342842e0e1461029f57600080fd5b8063095ea7b3116101b8578063095ea7b31461025457806318160ddd14610269578063238ac9331461027f57806323b872dd1461029f57600080fd5b806301ffc9a7146101df57806306fdde0314610207578063081812fc1461021c575b600080fd5b6101f26101ed366004611130565b61046b565b60405190151581526020015b60405180910390f35b61020f61057b565b6040516101fe9190611196565b61022f61022a3660046111e7565b610609565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101fe565b610267610262366004611229565b61063d565b005b61027161066f565b6040519081526020016101fe565b600a5461022f9073ffffffffffffffffffffffffffffffffffffffff1681565b610267610262366004611253565b600a546101f29074010000000000000000000000000000000000000000900460ff1681565b60085461022f9073ffffffffffffffffffffffffffffffffffffffff1681565b610267610692565b61022f6103083660046111e7565b610764565b61026761031b36600461128f565b6107c0565b61026761032e36600461128f565b61080f565b60075461022f9073ffffffffffffffffffffffffffffffffffffffff1681565b61027161036136600461128f565b61085e565b6102676108ea565b60095461022f9073ffffffffffffffffffffffffffffffffffffffff1681565b60065473ffffffffffffffffffffffffffffffffffffffff1661022f565b61020f6108fe565b6102676102623660046112ba565b6102676103d0366004611336565b61090b565b610267610262366004611389565b61020f6103f13660046111e7565b610a8c565b61026761040436600461128f565b610b9f565b6102676104173660046113f8565b610bee565b6101f261042a36600461146d565b600092915050565b61026761044036600461128f565b610c39565b610267610453366004611497565b610cf5565b61026761046636600461128f565b610d47565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806104fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd00000000000000000000000000000000000000000000000000000000145b8061052957507fffffffff000000000000000000000000000000000000000000000000000000008216155b8061057557507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b92915050565b60008054610588906114b2565b80601f01602080910402602001604051908101604052809291908181526020018280546105b4906114b2565b80156106015780601f106105d657610100808354040283529160200191610601565b820191906000526020600020905b8154815290600101906020018083116105e457829003601f168201915b505050505081565b60006040517fbf9e1a7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fbf9e1a7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060055460016004546106839190611534565b61068d9190611534565b905090565b60095473ffffffffffffffffffffffffffffffffffffffff1633148015906106d2575060065473ffffffffffffffffffffffffffffffffffffffff163314155b15610709576040517f0707164200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051600081527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208201527f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c910160405180910390a1565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff1680610575576040517f3f6cc76800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c8610d97565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610817610d97565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600073ffffffffffffffffffffffffffffffffffffffff82166108ad576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260409020546108de5760006108e1565b60015b60ff1692915050565b6108f2610d97565b6108fc6000610e18565b565b60018054610588906114b2565b600a5474010000000000000000000000000000000000000000900460ff1661095f576040517f589ed34b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fffffffffffffffffffffffffffffffffffffffff00000000000000000000000033606090811b8216602084015285901b1660348201526000906109c090604801604051602081830303815290604052805190602001208484610e8f565b600a5490915073ffffffffffffffffffffffffffffffffffffffff808316911614610a17576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff841615610a7d5760405173ffffffffffffffffffffffffffffffffffffffff851681527fcecb5f5b62b88dc819e81f535d3c431ec78987ab181067baac5d532dde7ee38a9060200160405180910390a15b610a8633610eff565b50505050565b60008181526002602052604090205460609073ffffffffffffffffffffffffffffffffffffffff16610aea576040517f3f6cc76800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546040517fc87b56dd0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff9091169063c87b56dd90602401600060405180830381865afa158015610b59573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105759190810190611576565b610ba7610d97565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610bf6610d97565b60005b81811015610c3457610c22838383818110610c1657610c16611641565b90506020020135611041565b80610c2c81611670565b915050610bf9565b505050565b610c41610d97565b73ffffffffffffffffffffffffffffffffffffffff8116610ce9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610cf281610e18565b50565b610cfd610d97565b600a805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b610d4f610d97565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316179055610cf2610692565b60065473ffffffffffffffffffffffffffffffffffffffff1633146108fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610ce0565b6006805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600060418218610ef8576040516040846040377f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a060605111610ef45784600052604084013560001a602052602060406080600060015afa5060006060523d6060185191505b6040525b9392505050565b73ffffffffffffffffffffffffffffffffffffffff8116610f4c576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604090205415610fa9576040517fddefae2800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805460018101909155600081815260026020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff87169081179091558084526003909252808320849055518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff168061109d576040517f3f6cc76800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260026020908152604080832080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905573ffffffffffffffffffffffffffffffffffffffff8416808452600390925280832083905560058054600101905551849291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60006020828403121561114257600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610ef857600080fd5b60005b8381101561118d578181015183820152602001611175565b50506000910152565b60208152600082518060208401526111b5816040850160208701611172565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000602082840312156111f957600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461122457600080fd5b919050565b6000806040838503121561123c57600080fd5b61124583611200565b946020939093013593505050565b60008060006060848603121561126857600080fd5b61127184611200565b925061127f60208501611200565b9150604084013590509250925092565b6000602082840312156112a157600080fd5b610ef882611200565b8035801515811461122457600080fd5b600080604083850312156112cd57600080fd5b6112d683611200565b91506112e4602084016112aa565b90509250929050565b60008083601f8401126112ff57600080fd5b50813567ffffffffffffffff81111561131757600080fd5b60208301915083602082850101111561132f57600080fd5b9250929050565b60008060006040848603121561134b57600080fd5b61135484611200565b9250602084013567ffffffffffffffff81111561137057600080fd5b61137c868287016112ed565b9497909650939450505050565b6000806000806000608086880312156113a157600080fd5b6113aa86611200565b94506113b860208701611200565b935060408601359250606086013567ffffffffffffffff8111156113db57600080fd5b6113e7888289016112ed565b969995985093965092949392505050565b6000806020838503121561140b57600080fd5b823567ffffffffffffffff8082111561142357600080fd5b818501915085601f83011261143757600080fd5b81358181111561144657600080fd5b8660208260051b850101111561145b57600080fd5b60209290920196919550909350505050565b6000806040838503121561148057600080fd5b61148983611200565b91506112e460208401611200565b6000602082840312156114a957600080fd5b610ef8826112aa565b600181811c908216806114c657607f821691505b6020821081036114ff577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561057557610575611505565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561158857600080fd5b815167ffffffffffffffff808211156115a057600080fd5b818401915084601f8301126115b457600080fd5b8151818111156115c6576115c6611547565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561160c5761160c611547565b8160405282815287602084870101111561162557600080fd5b611636836020830160208801611172565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036116a1576116a1611505565b506001019056fea2646970667358221220df1432e10b439c47c2222cb54563bde482d7a3e8ac331e8e9d23e76a42d80ed664736f6c63430008130033

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.