ETH Price: $2,650.61 (+1.74%)

Token

Purplecheck (🟪️✅)
 

Overview

Max Total Supply

27 🟪️✅

Holders

20

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
agrin.eth
Balance
1 🟪️✅
0x3dedb545e9b89f63fa71ab75497735d802c9d26f
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:
Purplecheck

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
Yes with 200000 runs

Other Settings:
default evmVersion
File 1 of 11 : Purplecheck.sol
// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity ^0.8.13;

import {ERC721} from "solmate/tokens/ERC721.sol";
import {Owned} from "solmate/auth/Owned.sol";
import {LinearVRGDA} from "VRGDAs/LinearVRGDA.sol";
import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol";
import {toDaysWadUnsafe} from "solmate/utils/SignedWadMath.sol";

import {Metadata} from "./Metadata.sol";

/// @title Purplecheck - Your JPEGs deserve to feel special.
/// @notice Mint an ERC721 token associated with an IPFS content ID.
/// Mint price is calculated by a linear VRGDA targeting 6.9 purplechecks
/// per day at a price of 0.00420 ETH.
/// @author horsefacts <[email protected]>
contract Purplecheck is ERC721, LinearVRGDA, Owned {
    /// @notice Total number of Purplecheck tokens.
    uint256 public totalSupply;

    /// @notice Mint start time. Used in VRGDA price calculations.
    uint256 public immutable startTime = block.timestamp;

    /// @notice tokenId => IPFS CIDv1
    mapping(uint256 => string) public cid;

    constructor(address owner)
        ERC721("Purplecheck", unicode"🟪️✅")
        // Target rate 6.9 per day @ 0.00420 ETH
        LinearVRGDA(0.0042e18, 0.31e18, 6.9e18)
        Owned(owner)
    {}

    /// @notice Get the contract URI for this contract, encoded as a data URI.
    /// @return Contract metadata URI.
    function contractURI() external pure returns (string memory) {
        return Metadata.contractURI();
    }

    /// @notice Get the metadata URI for the given token ID, encoded as a data URI.
    /// @param tokenId uint256 token ID.
    /// @return Metadata URI.
    function tokenURI(uint256 tokenId) public view override returns (string memory) {
        return Metadata.tokenURI(tokenId, imageURI(tokenId));
    }

    /// @notice Get the IPFS image URI for the given token ID.
    /// @param tokenId uint256 token ID.
    /// @return URI of given token ID.
    function imageURI(uint256 tokenId) public view returns (string memory) {
        return Metadata.toImageURI(cid[tokenId]);
    }

    /// @notice Current mint price of a Purplecheck token, based on block.timestamp.
    /// @return uint256 mint price in wei.
    function price() public view returns (uint256) {
        return getVRGDAPrice(toDaysWadUnsafe(block.timestamp - startTime), totalSupply);
    }

    /// @notice Mint a Purplecheck token.
    /// @param _cid IPFS CIDv1 of the associated image.
    /// @return tokenId uint256 token ID.
    function mint(string calldata _cid) external payable returns (uint256 tokenId) {
        unchecked {
            // Get current VRGDA price
            uint256 _price = price();

            // Revert if caller has underpaid
            require(msg.value >= _price, "UNDERPAID");

            // Increment total supply and store image CID
            cid[tokenId = ++totalSupply] = _cid;

            // Mint token to caller
            _mint(msg.sender, tokenId);

            // Refund excess payment to caller
            if (msg.value != _price) SafeTransferLib.safeTransferETH(msg.sender, msg.value - _price);
        }
    }

    /// @notice Burn a Purplecheck token. Must be owner or approved.
    /// @param tokenId uint256 token ID.
    function burn(uint256 tokenId) external {
        address owner = _ownerOf[tokenId];

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

    /// @notice Revert on attempted transfer.
    function transferFrom(address, address, uint256) public pure override {
        revert("TRANSFERS_DISABLED");
    }

    /// @notice Withdraw full balance to given recipient address.
    function withdrawBalance(address to) external onlyOwner {
        SafeTransferLib.safeTransferETH(to, address(this).balance);
    }
}

File 2 of 11 : LinearVRGDA.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

import {unsafeWadDiv} from "solmate/utils/SignedWadMath.sol";

import {VRGDA} from "./VRGDA.sol";

/// @title Linear Variable Rate Gradual Dutch Auction
/// @author transmissions11 <[email protected]>
/// @author FrankieIsLost <[email protected]>
/// @notice VRGDA with a linear issuance curve.
abstract contract LinearVRGDA is VRGDA {
    /*//////////////////////////////////////////////////////////////
                           PRICING PARAMETERS
    //////////////////////////////////////////////////////////////*/

    /// @dev The total number of tokens to target selling every full unit of time.
    /// @dev Represented as an 18 decimal fixed point number.
    int256 internal immutable perTimeUnit;

    /// @notice Sets pricing parameters for the VRGDA.
    /// @param _targetPrice The target price for a token if sold on pace, scaled by 1e18.
    /// @param _priceDecayPercent The percent price decays per unit of time with no sales, scaled by 1e18.
    /// @param _perTimeUnit The number of tokens to target selling in 1 full unit of time, scaled by 1e18.
    constructor(
        int256 _targetPrice,
        int256 _priceDecayPercent,
        int256 _perTimeUnit
    ) VRGDA(_targetPrice, _priceDecayPercent) {
        perTimeUnit = _perTimeUnit;
    }

    /*//////////////////////////////////////////////////////////////
                              PRICING LOGIC
    //////////////////////////////////////////////////////////////*/

    /// @dev Given a number of tokens sold, return the target time that number of tokens should be sold by.
    /// @param sold A number of tokens sold, scaled by 1e18, to get the corresponding target sale time for.
    /// @return The target time the tokens should be sold by, scaled by 1e18, where the time is
    /// relative, such that 0 means the tokens should be sold immediately when the VRGDA begins.
    function getTargetSaleTime(int256 sold) public view virtual override returns (int256) {
        return unsafeWadDiv(sold, perTimeUnit);
    }
}

File 3 of 11 : VRGDA.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

import {wadExp, wadLn, wadMul, unsafeWadMul, toWadUnsafe} from "solmate/utils/SignedWadMath.sol";

/// @title Variable Rate Gradual Dutch Auction
/// @author transmissions11 <[email protected]>
/// @author FrankieIsLost <[email protected]>
/// @notice Sell tokens roughly according to an issuance schedule.
abstract contract VRGDA {
    /*//////////////////////////////////////////////////////////////
                            VRGDA PARAMETERS
    //////////////////////////////////////////////////////////////*/

    /// @notice Target price for a token, to be scaled according to sales pace.
    /// @dev Represented as an 18 decimal fixed point number.
    int256 public immutable targetPrice;

    /// @dev Precomputed constant that allows us to rewrite a pow() as an exp().
    /// @dev Represented as an 18 decimal fixed point number.
    int256 internal immutable decayConstant;

    /// @notice Sets target price and per time unit price decay for the VRGDA.
    /// @param _targetPrice The target price for a token if sold on pace, scaled by 1e18.
    /// @param _priceDecayPercent The percent price decays per unit of time with no sales, scaled by 1e18.
    constructor(int256 _targetPrice, int256 _priceDecayPercent) {
        targetPrice = _targetPrice;

        decayConstant = wadLn(1e18 - _priceDecayPercent);

        // The decay constant must be negative for VRGDAs to work.
        require(decayConstant < 0, "NON_NEGATIVE_DECAY_CONSTANT");
    }

    /*//////////////////////////////////////////////////////////////
                              PRICING LOGIC
    //////////////////////////////////////////////////////////////*/

    /// @notice Calculate the price of a token according to the VRGDA formula.
    /// @param timeSinceStart Time passed since the VRGDA began, scaled by 1e18.
    /// @param sold The total number of tokens that have been sold so far.
    /// @return The price of a token according to VRGDA, scaled by 1e18.
    function getVRGDAPrice(int256 timeSinceStart, uint256 sold) public view virtual returns (uint256) {
        unchecked {
            // prettier-ignore
            return uint256(wadMul(targetPrice, wadExp(unsafeWadMul(decayConstant,
                // Theoretically calling toWadUnsafe with sold can silently overflow but under
                // any reasonable circumstance it will never be large enough. We use sold + 1 as
                // the VRGDA formula's n param represents the nth token and sold is the n-1th token.
                timeSinceStart - getTargetSaleTime(toWadUnsafe(sold + 1))
            ))));
        }
    }

    /// @dev Given a number of tokens sold, return the target time that number of tokens should be sold by.
    /// @param sold A number of tokens sold, scaled by 1e18, to get the corresponding target sale time for.
    /// @return The target time the tokens should be sold by, scaled by 1e18, where the time is
    /// relative, such that 0 means the tokens should be sold immediately when the VRGDA begins.
    function getTargetSaleTime(int256 sold) public view virtual returns (int256);
}

File 4 of 11 : Base64.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Library to encode strings in Base64.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/Base64.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Base64.sol)
/// @author Modified from (https://github.com/Brechtpd/base64/blob/main/base64.sol) by Brecht Devos - <[email protected]>.
library Base64 {
    /// @dev Encodes `data` using the base64 encoding described in RFC 4648.
    /// See: https://datatracker.ietf.org/doc/html/rfc4648
    /// @param fileSafe  Whether to replace '+' with '-' and '/' with '_'.
    /// @param noPadding Whether to strip away the padding.
    function encode(
        bytes memory data,
        bool fileSafe,
        bool noPadding
    ) internal pure returns (string memory result) {
        assembly {
            let dataLength := mload(data)

            if dataLength {
                // Multiply by 4/3 rounded up.
                // The `shl(2, ...)` is equivalent to multiplying by 4.
                let encodedLength := shl(2, div(add(dataLength, 2), 3))

                // Set `result` to point to the start of the free memory.
                result := mload(0x40)

                // Store the table into the scratch space.
                // Offsetted by -1 byte so that the `mload` will load the character.
                // We will rewrite the free memory pointer at `0x40` later with
                // the allocated size.
                // The magic constant 0x0230 will translate "-_" + "+/".
                mstore(0x1f, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef")
                mstore(0x3f, sub("ghijklmnopqrstuvwxyz0123456789-_", mul(iszero(fileSafe), 0x0230)))

                // Skip the first slot, which stores the length.
                let ptr := add(result, 0x20)
                let end := add(ptr, encodedLength)

                // Run over the input, 3 bytes at a time.
                // prettier-ignore
                for {} 1 {} {
                    data := add(data, 3) // Advance 3 bytes.
                    let input := mload(data)

                    // Write 4 bytes. Optimized for fewer stack operations.
                    mstore8(    ptr    , mload(and(shr(18, input), 0x3F)))
                    mstore8(add(ptr, 1), mload(and(shr(12, input), 0x3F)))
                    mstore8(add(ptr, 2), mload(and(shr( 6, input), 0x3F)))
                    mstore8(add(ptr, 3), mload(and(        input , 0x3F)))
                    
                    ptr := add(ptr, 4) // Advance 4 bytes.
                    // prettier-ignore
                    if iszero(lt(ptr, end)) { break }
                }

                let r := mod(dataLength, 3)

                switch noPadding
                case 0 {
                    // Offset `ptr` and pad with '='. We can simply write over the end.
                    mstore8(sub(ptr, iszero(iszero(r))), 0x3d) // Pad at `ptr - 1` if `r > 0`.
                    mstore8(sub(ptr, shl(1, eq(r, 1))), 0x3d) // Pad at `ptr - 2` if `r == 1`.
                    // Write the length of the string.
                    mstore(result, encodedLength)
                }
                default {
                    // Write the length of the string.
                    mstore(result, sub(encodedLength, add(iszero(iszero(r)), eq(r, 1))))
                }

                // Allocate the memory for the string.
                // Add 31 and mask with `not(31)` to round the
                // free memory pointer up the next multiple of 32.
                mstore(0x40, and(add(end, 31), not(31)))
            }
        }
    }

    /// @dev Encodes `data` using the base64 encoding described in RFC 4648.
    /// Equivalent to `encode(data, false, false)`.
    function encode(bytes memory data) internal pure returns (string memory result) {
        result = encode(data, false, false);
    }

    /// @dev Encodes `data` using the base64 encoding described in RFC 4648.
    /// Equivalent to `encode(data, fileSafe, false)`.
    function encode(bytes memory data, bool fileSafe) internal pure returns (string memory result) {
        result = encode(data, fileSafe, false);
    }

    /// @dev Encodes base64 encoded `data`.
    ///
    /// Supports:
    /// - RFC 4648 (both standard and file-safe mode).
    /// - RFC 3501 (63: ',').
    ///
    /// Does not support:
    /// - Line breaks.
    ///
    /// Note: For performance reasons,
    /// this function will NOT revert on invalid `data` inputs.
    /// Outputs for invalid inputs will simply be undefined behaviour.
    /// It is the user's responsibility to ensure that the `data`
    /// is a valid base64 encoded string.
    function decode(string memory data) internal pure returns (bytes memory result) {
        assembly {
            let dataLength := mload(data)

            if dataLength {
                let end := add(data, dataLength)
                let decodedLength := mul(shr(2, dataLength), 3)

                switch and(dataLength, 3)
                case 0 {
                    // If padded.
                    decodedLength := sub(
                        decodedLength,
                        add(eq(and(mload(end), 0xFF), 0x3d), eq(and(mload(end), 0xFFFF), 0x3d3d))
                    )
                }
                default {
                    // If non-padded.
                    decodedLength := add(decodedLength, sub(and(dataLength, 3), 1))
                }

                result := mload(0x40)

                // Write the length of the string.
                mstore(result, decodedLength)

                // Skip the first slot, which stores the length.
                let ptr := add(result, 0x20)

                // Load the table into the scratch space.
                // Constants are optimized for smaller bytecode with zero gas overhead.
                // `m` also doubles as the mask of the upper 6 bits.
                let m := 0xfc000000fc00686c7074787c8084888c9094989ca0a4a8acb0b4b8bcc0c4c8cc
                mstore(0x5b, m)
                mstore(0x3b, 0x04080c1014181c2024282c3034383c4044484c5054585c6064)
                mstore(0x1a, 0xf8fcf800fcd0d4d8dce0e4e8ecf0f4)

                // prettier-ignore
                for {} 1 {} {
                    // Read 4 bytes.
                    data := add(data, 4)
                    let input := mload(data)

                    // Write 3 bytes.
                    mstore(ptr, or(
                        and(m, mload(byte(28, input))),
                        shr(6, or(
                            and(m, mload(byte(29, input))),
                            shr(6, or(
                                and(m, mload(byte(30, input))),
                                shr(6, mload(byte(31, input)))
                            ))
                        ))
                    ))

                    ptr := add(ptr, 3)
                    
                    // prettier-ignore
                    if iszero(lt(data, end)) { break }
                }

                // Allocate the memory for the string.
                // Add 32 + 31 and mask with `not(31)` to round the
                // free memory pointer up the next multiple of 32.
                mstore(0x40, and(add(add(result, decodedLength), 63), not(31)))

                // Restore the zero slot.
                mstore(0x60, 0)
            }
        }
    }
}

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

/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

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

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public owner;

    modifier onlyOwner() virtual {
        require(msg.sender == owner, "UNAUTHORIZED");

        _;
    }

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

    constructor(address _owner) {
        owner = _owner;

        emit OwnershipTransferred(address(0), _owner);
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    function transferOwnership(address newOwner) public virtual onlyOwner {
        owner = newOwner;

        emit OwnershipTransferred(msg.sender, newOwner);
    }
}

File 6 of 11 : ERC20.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

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

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

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

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*//////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

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

    /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

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

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

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

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

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

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

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }
}

File 7 of 11 : 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 8 of 11 : LibString.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

/// @notice Efficient library for creating string representations of integers.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol)
/// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/LibString.sol)
library LibString {
    function toString(uint256 value) internal pure returns (string memory str) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit), but we allocate 160 bytes
            // to keep the free memory pointer word aligned. We'll need 1 word for the length, 1 word for the
            // trailing zeros padding, and 3 other words for a max of 78 digits. In total: 5 * 32 = 160 bytes.
            let newFreeMemoryPointer := add(mload(0x40), 160)

            // Update the free memory pointer to avoid overriding our string.
            mstore(0x40, newFreeMemoryPointer)

            // Assign str to the end of the zone of newly allocated memory.
            str := sub(newFreeMemoryPointer, 32)

            // Clean the last word of memory it may not be overwritten.
            mstore(str, 0)

            // Cache the end of the memory to calculate the length later.
            let end := str

            // We write the string from rightmost digit to leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // prettier-ignore
            for { let temp := value } 1 {} {
                // Move the pointer 1 byte to the left.
                str := sub(str, 1)

                // Write the character to the pointer.
                // The ASCII index of the '0' character is 48.
                mstore8(str, add(48, mod(temp, 10)))

                // Keep dividing temp until zero.
                temp := div(temp, 10)

                 // prettier-ignore
                if iszero(temp) { break }
            }

            // Compute and cache the final total length of the string.
            let length := sub(end, str)

            // Move the pointer 32 bytes leftwards to make room for the length.
            str := sub(str, 32)

            // Store the string's length at the start of memory allocated for our string.
            mstore(str, length)
        }
    }
}

File 9 of 11 : SafeTransferLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

import {ERC20} from "../tokens/ERC20.sol";

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
    /*//////////////////////////////////////////////////////////////
                             ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address to, uint256 amount) internal {
        bool success;

        assembly {
            // Transfer the ETH and store if it succeeded or not.
            success := call(gas(), to, amount, 0, 0, 0, 0)
        }

        require(success, "ETH_TRANSFER_FAILED");
    }

    /*//////////////////////////////////////////////////////////////
                            ERC20 OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferFrom(
        ERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), from) // Append the "from" argument.
            mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
            )
        }

        require(success, "TRANSFER_FROM_FAILED");
    }

    function safeTransfer(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "TRANSFER_FAILED");
    }

    function safeApprove(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "APPROVE_FAILED");
    }
}

File 10 of 11 : SignedWadMath.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

/// @notice Signed 18 decimal fixed point (wad) arithmetic library.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SignedWadMath.sol)
/// @author Modified from Remco Bloemen (https://xn--2-umb.com/22/exp-ln/index.html)

/// @dev Will not revert on overflow, only use where overflow is not possible.
function toWadUnsafe(uint256 x) pure returns (int256 r) {
    assembly {
        // Multiply x by 1e18.
        r := mul(x, 1000000000000000000)
    }
}

/// @dev Takes an integer amount of seconds and converts it to a wad amount of days.
/// @dev Will not revert on overflow, only use where overflow is not possible.
/// @dev Not meant for negative second amounts, it assumes x is positive.
function toDaysWadUnsafe(uint256 x) pure returns (int256 r) {
    assembly {
        // Multiply x by 1e18 and then divide it by 86400.
        r := div(mul(x, 1000000000000000000), 86400)
    }
}

/// @dev Takes a wad amount of days and converts it to an integer amount of seconds.
/// @dev Will not revert on overflow, only use where overflow is not possible.
/// @dev Not meant for negative day amounts, it assumes x is positive.
function fromDaysWadUnsafe(int256 x) pure returns (uint256 r) {
    assembly {
        // Multiply x by 86400 and then divide it by 1e18.
        r := div(mul(x, 86400), 1000000000000000000)
    }
}

/// @dev Will not revert on overflow, only use where overflow is not possible.
function unsafeWadMul(int256 x, int256 y) pure returns (int256 r) {
    assembly {
        // Multiply x by y and divide by 1e18.
        r := sdiv(mul(x, y), 1000000000000000000)
    }
}

/// @dev Will return 0 instead of reverting if y is zero and will
/// not revert on overflow, only use where overflow is not possible.
function unsafeWadDiv(int256 x, int256 y) pure returns (int256 r) {
    assembly {
        // Multiply x by 1e18 and divide it by y.
        r := sdiv(mul(x, 1000000000000000000), y)
    }
}

function wadMul(int256 x, int256 y) pure returns (int256 r) {
    assembly {
        // Store x * y in r for now.
        r := mul(x, y)

        // Equivalent to require(x == 0 || (x * y) / x == y)
        if iszero(or(iszero(x), eq(sdiv(r, x), y))) {
            revert(0, 0)
        }

        // Scale the result down by 1e18.
        r := sdiv(r, 1000000000000000000)
    }
}

function wadDiv(int256 x, int256 y) pure returns (int256 r) {
    assembly {
        // Store x * 1e18 in r for now.
        r := mul(x, 1000000000000000000)

        // Equivalent to require(y != 0 && ((x * 1e18) / 1e18 == x))
        if iszero(and(iszero(iszero(y)), eq(sdiv(r, 1000000000000000000), x))) {
            revert(0, 0)
        }

        // Divide r by y.
        r := sdiv(r, y)
    }
}

function wadExp(int256 x) pure returns (int256 r) {
    unchecked {
        // When the result is < 0.5 we return zero. This happens when
        // x <= floor(log(0.5e18) * 1e18) ~ -42e18
        if (x <= -42139678854452767551) return 0;

        // When the result is > (2**255 - 1) / 1e18 we can not represent it as an
        // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135.
        if (x >= 135305999368893231589) revert("EXP_OVERFLOW");

        // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96
        // for more intermediate precision and a binary basis. This base conversion
        // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.
        x = (x << 78) / 5**18;

        // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers
        // of two such that exp(x) = exp(x') * 2**k, where k is an integer.
        // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).
        int256 k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96;
        x = x - k * 54916777467707473351141471128;

        // k is in the range [-61, 195].

        // Evaluate using a (6, 7)-term rational approximation.
        // p is made monic, we'll multiply by a scale factor later.
        int256 y = x + 1346386616545796478920950773328;
        y = ((y * x) >> 96) + 57155421227552351082224309758442;
        int256 p = y + x - 94201549194550492254356042504812;
        p = ((p * y) >> 96) + 28719021644029726153956944680412240;
        p = p * x + (4385272521454847904659076985693276 << 96);

        // We leave p in 2**192 basis so we don't need to scale it back up for the division.
        int256 q = x - 2855989394907223263936484059900;
        q = ((q * x) >> 96) + 50020603652535783019961831881945;
        q = ((q * x) >> 96) - 533845033583426703283633433725380;
        q = ((q * x) >> 96) + 3604857256930695427073651918091429;
        q = ((q * x) >> 96) - 14423608567350463180887372962807573;
        q = ((q * x) >> 96) + 26449188498355588339934803723976023;

        assembly {
            // Div in assembly because solidity adds a zero check despite the unchecked.
            // The q polynomial won't have zeros in the domain as all its roots are complex.
            // No scaling is necessary because p is already 2**96 too large.
            r := sdiv(p, q)
        }

        // r should be in the range (0.09, 0.25) * 2**96.

        // We now need to multiply r by:
        // * the scale factor s = ~6.031367120.
        // * the 2**k factor from the range reduction.
        // * the 1e18 / 2**96 factor for base conversion.
        // We do this all at once, with an intermediate result in 2**213
        // basis, so the final right shift is always by a positive amount.
        r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k));
    }
}

function wadLn(int256 x) pure returns (int256 r) {
    unchecked {
        require(x > 0, "UNDEFINED");

        // We want to convert x from 10**18 fixed point to 2**96 fixed point.
        // We do this by multiplying by 2**96 / 10**18. But since
        // ln(x * C) = ln(x) + ln(C), we can simply do nothing here
        // and add ln(2**96 / 10**18) at the end.

        assembly {
            r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
            r := or(r, shl(4, lt(0xffff, shr(r, x))))
            r := or(r, shl(3, lt(0xff, shr(r, x))))
            r := or(r, shl(2, lt(0xf, shr(r, x))))
            r := or(r, shl(1, lt(0x3, shr(r, x))))
            r := or(r, lt(0x1, shr(r, x)))
        }

        // Reduce range of x to (1, 2) * 2**96
        // ln(2^k * x) = k * ln(2) + ln(x)
        int256 k = r - 96;
        x <<= uint256(159 - k);
        x = int256(uint256(x) >> 159);

        // Evaluate using a (8, 8)-term rational approximation.
        // p is made monic, we will multiply by a scale factor later.
        int256 p = x + 3273285459638523848632254066296;
        p = ((p * x) >> 96) + 24828157081833163892658089445524;
        p = ((p * x) >> 96) + 43456485725739037958740375743393;
        p = ((p * x) >> 96) - 11111509109440967052023855526967;
        p = ((p * x) >> 96) - 45023709667254063763336534515857;
        p = ((p * x) >> 96) - 14706773417378608786704636184526;
        p = p * x - (795164235651350426258249787498 << 96);

        // We leave p in 2**192 basis so we don't need to scale it back up for the division.
        // q is monic by convention.
        int256 q = x + 5573035233440673466300451813936;
        q = ((q * x) >> 96) + 71694874799317883764090561454958;
        q = ((q * x) >> 96) + 283447036172924575727196451306956;
        q = ((q * x) >> 96) + 401686690394027663651624208769553;
        q = ((q * x) >> 96) + 204048457590392012362485061816622;
        q = ((q * x) >> 96) + 31853899698501571402653359427138;
        q = ((q * x) >> 96) + 909429971244387300277376558375;
        assembly {
            // Div in assembly because solidity adds a zero check despite the unchecked.
            // The q polynomial is known not to have zeros in the domain.
            // No scaling required because p is already 2**96 too large.
            r := sdiv(p, q)
        }

        // r is in the range (0, 0.125) * 2**96

        // Finalization, we need to:
        // * multiply by the scale factor s = 5.549…
        // * add ln(2**96 / 10**18)
        // * add k * ln(2)
        // * multiply by 10**18 / 2**96 = 5**18 >> 78

        // mul s * 5e18 * 2**96, base is now 5**18 * 2**192
        r *= 1677202110996718588342820967067443963516166;
        // add ln(2) * k * 5e18 * 2**192
        r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k;
        // add ln(2**96 / 10**18) * 5e18 * 2**192
        r += 600920179829731861736702779321621459595472258049074101567377883020018308;
        // base conversion: mul 2**18 / 2**192
        r >>= 174;
    }
}

/// @dev Will return 0 instead of reverting if y is zero.
function unsafeDiv(int256 x, int256 y) pure returns (int256 r) {
    assembly {
        // Divide x by y.
        r := sdiv(x, y)
    }
}

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

import {LibString} from "solmate/utils/LibString.sol";
import {Base64} from "solady/utils/Base64.sol";

library Metadata {
    using LibString for uint256;

    function toImageURI(string memory cid) internal pure returns (string memory) {
        return string.concat("ipfs://", cid);
    }

    function tokenJSON(uint256 tokenId, string memory imageURI) internal pure returns (string memory) {
        return string.concat('{"image":"', imageURI, '","name":"Purplecheck #', tokenId.toString(), '"}');
    }

    function contractJSON() internal pure returns (string memory) {
        return
        '{"name":"Purplecheck","image":"ipfs://bafkreibhw7wybdzmpg5tfjr6pjynalpeb3zs7c3va26prjyc6gl2bvo7y4","description":"Your JPEGs deserve to feel special."}';
    }

    function contractURI() internal pure returns (string memory) {
        return toDataURI(contractJSON());
    }

    function tokenURI(uint256 tokenId, string memory imageURI) internal pure returns (string memory) {
        return toDataURI(tokenJSON(tokenId, imageURI));
    }

    function toDataURI(string memory json) internal pure returns (string memory) {
        return string.concat("data:application/json;base64,", Base64.encode(abi.encodePacked(json)));
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"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":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"cid","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"sold","type":"int256"}],"name":"getTargetSaleTime","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"timeSinceStart","type":"int256"},{"internalType":"uint256","name":"sold","type":"uint256"}],"name":"getVRGDAPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"imageURI","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"string","name":"_cid","type":"string"}],"name":"mint","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"payable","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":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","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":"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":[],"name":"startTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"targetPrice","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"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"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"withdrawBalance","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6101006040524260e0523480156200001657600080fd5b506040516200286d3803806200286d8339810160408190526200003991620003be565b80660eebe0b40e800067044d575b885f0000675fc1b9713632000082826040518060400160405280600b81526020016a507572706c65636865636b60a81b8152506040518060400160405280600a815260200169f09f9faaefb88fe29c8560b01b8152508160009081620000ae919062000495565b506001620000bd828262000495565b5050506080829052620000e3620000dd82670de0b6b3a764000062000561565b62000195565b60a08190526000136200013d5760405162461bcd60e51b815260206004820152601b60248201527f4e4f4e5f4e454741544956455f44454341595f434f4e5354414e54000000000060448201526064015b60405180910390fd5b505060c0525050600680546001600160a01b0319166001600160a01b0383169081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3505062000597565b6000808213620001d45760405162461bcd60e51b815260206004820152600960248201526815539111519253915160ba1b604482015260640162000134565b5060606001600160801b03821160071b82811c6001600160401b031060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110600190811b90911783811c90911017609f81810383019390931b90921c6c465772b2bbbb5f824b15207a3081018102821d6d0388eaa27412d5aca026815d636e018102821d6d0df99ac502031bf953eff472fdcc018102821d6d13cdffb29d51d99322bdff5f2211018102821d6d0a0f742023def783a307a986912e018102821d6d01920d8043ca89b5239253284e42018102821d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7882018202831d6d0139601a2efabe717e604cbb4894018202831d6d02247f7a7b6594320649aa03aba1018202831d6c8c3f38e95a6b1ff2ab1c3b343619018202831d6d02384773bdf1ac5676facced60901901820290921d6cb9a025d814b29c212b8b1a07cd19010260016c0504a838426634cdd8738f543560611b03190105711340daa0d5f769dba1915cef59f0815a550602605f19919091017d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b302017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d90565b600060208284031215620003d157600080fd5b81516001600160a01b0381168114620003e957600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200041b57607f821691505b6020821081036200043c57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200049057600081815260208120601f850160051c810160208610156200046b5750805b601f850160051c820191505b818110156200048c5782815560010162000477565b5050505b505050565b81516001600160401b03811115620004b157620004b1620003f0565b620004c981620004c2845462000406565b8462000442565b602080601f831160018114620005015760008415620004e85750858301515b600019600386901b1c1916600185901b1785556200048c565b600085815260208120601f198616915b82811015620005325788860151825594840194600190910190840162000511565b5085821015620005515787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b81810360008312801583831316838312821617156200059057634e487b7160e01b600052601160045260246000fd5b5092915050565b60805160a05160c05160e05161228e620005df600039600081816103a80152610de201526000610bbf015260006112340152600081816104e6015261120d015261228e6000f3fe6080604052600436106101ac5760003560e01c80638da5cb5b116100ec578063c87b56dd1161008a578063e8a3d48511610064578063e8a3d48514610508578063e985e9c51461051d578063f2fde38b14610558578063f466d4ab1461057857600080fd5b8063c87b56dd146104a1578063d85d3d27146104c1578063dc38679c146104d457600080fd5b8063a035b1fe116100c6578063a035b1fe1461042c578063a22cb46514610441578063b0c479a514610461578063b88d4fde1461048157600080fd5b80638da5cb5b146103ca5780638f742d16146103f757806395d89b411461041757600080fd5b806342842e0e116101595780636d9d33b7116101335780636d9d33b71461033657806370a0823114610356578063756af45f1461037657806378e979251461039657600080fd5b806342842e0e146102d657806342966c68146102f65780636352211e1461031657600080fd5b8063095ea7b31161018a578063095ea7b31461027057806318160ddd1461029257806323b872dd146102b657600080fd5b806301ffc9a7146101b157806306fdde03146101e6578063081812fc14610208575b600080fd5b3480156101bd57600080fd5b506101d16101cc366004611ad5565b610598565b60405190151581526020015b60405180910390f35b3480156101f257600080fd5b506101fb61067d565b6040516101dd9190611b16565b34801561021457600080fd5b5061024b610223366004611b67565b60046020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101dd565b34801561027c57600080fd5b5061029061028b366004611ba4565b61070b565b005b34801561029e57600080fd5b506102a860075481565b6040519081526020016101dd565b3480156102c257600080fd5b506102906102d1366004611bce565b61085a565b3480156102e257600080fd5b506102906102f1366004611bce565b6108bc565b34801561030257600080fd5b50610290610311366004611b67565b610a26565b34801561032257600080fd5b5061024b610331366004611b67565b610b2a565b34801561034257600080fd5b506102a8610351366004611b67565b610bbb565b34801561036257600080fd5b506102a8610371366004611c0a565b610bef565b34801561038257600080fd5b50610290610391366004611c0a565b610c97565b3480156103a257600080fd5b506102a87f000000000000000000000000000000000000000000000000000000000000000081565b3480156103d657600080fd5b5060065461024b9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561040357600080fd5b506101fb610412366004611b67565b610d25565b34801561042357600080fd5b506101fb610dc8565b34801561043857600080fd5b506102a8610dd5565b34801561044d57600080fd5b5061029061045c366004611c25565b610e29565b34801561046d57600080fd5b506101fb61047c366004611b67565b610ec0565b34801561048d57600080fd5b5061029061049c366004611caa565b610ed9565b3480156104ad57600080fd5b506101fb6104bc366004611b67565b611033565b6102a86104cf366004611d19565b611047565b3480156104e057600080fd5b506102a87f000000000000000000000000000000000000000000000000000000000000000081565b34801561051457600080fd5b506101fb61110a565b34801561052957600080fd5b506101d1610538366004611d5b565b600560209081526000928352604080842090915290825290205460ff1681565b34801561056457600080fd5b50610290610573366004611c0a565b611114565b34801561058457600080fd5b506102a8610593366004611d8e565b611206565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061062b57507f80ac58cd000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b8061067757507f5b5e139f000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6000805461068a90611db0565b80601f01602080910402602001604051908101604052809291908181526020018280546106b690611db0565b80156107035780601f106106d857610100808354040283529160200191610703565b820191906000526020600020905b8154815290600101906020018083116106e657829003601f168201915b505050505081565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff163381148061076e575073ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152604080832033845290915290205460ff165b6107d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008281526004602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff87811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f5452414e53464552535f44495341424c4544000000000000000000000000000060448201526064016107d0565b6108c783838361085a565b73ffffffffffffffffffffffffffffffffffffffff82163b15806109bb57506040517f150b7a020000000000000000000000000000000000000000000000000000000080825233600483015273ffffffffffffffffffffffffffffffffffffffff858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af1158015610973573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109979190611e03565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b610a21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e540000000000000000000000000000000060448201526064016107d0565b505050565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1633811480610a89575073ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152604080832033845290915290205460ff165b80610ab7575060008281526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1633145b610b1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016107d0565b610b268261128b565b5050565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610bb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e4f545f4d494e5445440000000000000000000000000000000000000000000060448201526064016107d0565b919050565b60007f0000000000000000000000000000000000000000000000000000000000000000670de0b6b3a7640000830205610677565b600073ffffffffffffffffffffffffffffffffffffffff8216610c6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f5a45524f5f41444452455353000000000000000000000000000000000000000060448201526064016107d0565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b60065473ffffffffffffffffffffffffffffffffffffffff163314610d18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016107d0565b610d2281476113d5565b50565b6000818152600860205260409020805460609161067791610d4590611db0565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7190611db0565b8015610dbe5780601f10610d9357610100808354040283529160200191610dbe565b820191906000526020600020905b815481529060010190602001808311610da157829003601f168201915b505050505061144a565b6001805461068a90611db0565b6000610e24610e1c610e077f000000000000000000000000000000000000000000000000000000000000000042611e20565b62015180670de0b6b3a7640000919091020490565b600754611206565b905090565b33600081815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6008602052600090815260409020805461068a90611db0565b610ee485858561085a565b73ffffffffffffffffffffffffffffffffffffffff84163b1580610fc657506040517f150b7a02000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff86169063150b7a0290610f5f9033908a90899089908990600401611e5a565b6020604051808303816000875af1158015610f7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa29190611e03565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b61102c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e540000000000000000000000000000000060448201526064016107d0565b5050505050565b60606106778261104284610d25565b611473565b600080611052610dd5565b9050803410156110be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e44455250414944000000000000000000000000000000000000000000000060448201526064016107d0565b600780546001019081905560008181526008602052604090209092506110e5848683611f56565b506110f03383611487565b80341461110357611103338234036113d5565b5092915050565b6060610e24611620565b60065473ffffffffffffffffffffffffffffffffffffffff163314611195576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016107d0565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff831690811790915560405133907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b60006112847f000000000000000000000000000000000000000000000000000000000000000061127f61127a7f0000000000000000000000000000000000000000000000000000000000000000611269670de0b6b3a76400006001890102610bbb565b8803670de0b6b3a764000091020590565b61162d565b61186c565b9392505050565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1680611317576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e4f545f4d494e5445440000000000000000000000000000000000000000000060448201526064016107d0565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260036020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190558583526002825280832080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811690915560049092528083208054909216909155518492907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600080600080600085875af1905080610a21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4554485f5452414e534645525f4641494c45440000000000000000000000000060448201526064016107d0565b60608160405160200161145d9190612070565b6040516020818303038152906040529050919050565b60606112846114828484611891565b6118c5565b73ffffffffffffffffffffffffffffffffffffffff8216611504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f494e56414c49445f524543495049454e5400000000000000000000000000000060448201526064016107d0565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f414c52454144595f4d494e54454400000000000000000000000000000000000060448201526064016107d0565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260036020908152604080832080546001019055848352600290915280822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6060610e246114826118ff565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361165e57506000919050565b680755bf798b4a1bf1e582126116d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f57000000000000000000000000000000000000000060448201526064016107d0565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b818102821583820583141761188057600080fd5b670de0b6b3a7640000900592915050565b60608161189d8461191f565b6040516020016118ae9291906120b5565b604051602081830303815290604052905092915050565b60606118ef826040516020016118db9190612160565b604051602081830303815290604052611981565b60405160200161145d919061217c565b60606040518060c00160405280609781526020016121c260979139905090565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a90048061193957508190037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909101908152919050565b606061067782600080606083518015611a9f576003600282010460021b60405192507f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566601f526102308515027f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5f03603f52602083018181015b6003880197508751603f8160121c16518353603f81600c1c16516001840153603f8160061c16516002840153603f8116516003840153506004820191508082106119fa5760038406868015611a5a57600182148215150185038752611a72565b603d821515850353603d6001831460011b8503538487525b5050601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660405250505b509392505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114610d2257600080fd5b600060208284031215611ae757600080fd5b813561128481611aa7565b60005b83811015611b0d578181015183820152602001611af5565b50506000910152565b6020815260008251806020840152611b35816040850160208701611af2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600060208284031215611b7957600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610bb657600080fd5b60008060408385031215611bb757600080fd5b611bc083611b80565b946020939093013593505050565b600080600060608486031215611be357600080fd5b611bec84611b80565b9250611bfa60208501611b80565b9150604084013590509250925092565b600060208284031215611c1c57600080fd5b61128482611b80565b60008060408385031215611c3857600080fd5b611c4183611b80565b915060208301358015158114611c5657600080fd5b809150509250929050565b60008083601f840112611c7357600080fd5b50813567ffffffffffffffff811115611c8b57600080fd5b602083019150836020828501011115611ca357600080fd5b9250929050565b600080600080600060808688031215611cc257600080fd5b611ccb86611b80565b9450611cd960208701611b80565b935060408601359250606086013567ffffffffffffffff811115611cfc57600080fd5b611d0888828901611c61565b969995985093965092949392505050565b60008060208385031215611d2c57600080fd5b823567ffffffffffffffff811115611d4357600080fd5b611d4f85828601611c61565b90969095509350505050565b60008060408385031215611d6e57600080fd5b611d7783611b80565b9150611d8560208401611b80565b90509250929050565b60008060408385031215611da157600080fd5b50508035926020909101359150565b600181811c90821680611dc457607f821691505b602082108103611dfd577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215611e1557600080fd5b815161128481611aa7565b81810381811115610677577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525084604083015260806060830152826080830152828460a0840137600060a0848401015260a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011683010190509695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b601f821115610a2157600081815260208120601f850160051c81016020861015611f2f5750805b601f850160051c820191505b81811015611f4e57828155600101611f3b565b505050505050565b67ffffffffffffffff831115611f6e57611f6e611ed9565b611f8283611f7c8354611db0565b83611f08565b6000601f841160018114611fd45760008515611f9e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561102c565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156120235786850135825560209485019460019092019101612003565b508682101561205e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b7f697066733a2f2f000000000000000000000000000000000000000000000000008152600082516120a8816007850160208701611af2565b9190910160070192915050565b7f7b22696d616765223a22000000000000000000000000000000000000000000008152600083516120ed81600a850160208801611af2565b7f222c226e616d65223a22507572706c65636865636b2023000000000000000000600a91840191820152835161212a816021840160208801611af2565b7f227d00000000000000000000000000000000000000000000000000000000000060219290910191820152602301949350505050565b60008251612172818460208701611af2565b9190910192915050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000008152600082516121b481601d850160208701611af2565b91909101601d019291505056fe7b226e616d65223a22507572706c65636865636b222c22696d616765223a22697066733a2f2f6261666b72656962687737777962647a6d70673574666a7236706a796e616c706562337a733763337661323670726a796336676c3262766f377934222c226465736372697074696f6e223a22596f7572204a50454773206465736572766520746f206665656c207370656369616c2e227da2646970667358221220668d48eb1f816d1ddc35de38ea2b4a14824c6087bb99575fea2489c30fe5a5c264736f6c6343000810003300000000000000000000000079d31bfca5fda7a4f15b36763d2e44c99d811a6c

Deployed Bytecode

0x6080604052600436106101ac5760003560e01c80638da5cb5b116100ec578063c87b56dd1161008a578063e8a3d48511610064578063e8a3d48514610508578063e985e9c51461051d578063f2fde38b14610558578063f466d4ab1461057857600080fd5b8063c87b56dd146104a1578063d85d3d27146104c1578063dc38679c146104d457600080fd5b8063a035b1fe116100c6578063a035b1fe1461042c578063a22cb46514610441578063b0c479a514610461578063b88d4fde1461048157600080fd5b80638da5cb5b146103ca5780638f742d16146103f757806395d89b411461041757600080fd5b806342842e0e116101595780636d9d33b7116101335780636d9d33b71461033657806370a0823114610356578063756af45f1461037657806378e979251461039657600080fd5b806342842e0e146102d657806342966c68146102f65780636352211e1461031657600080fd5b8063095ea7b31161018a578063095ea7b31461027057806318160ddd1461029257806323b872dd146102b657600080fd5b806301ffc9a7146101b157806306fdde03146101e6578063081812fc14610208575b600080fd5b3480156101bd57600080fd5b506101d16101cc366004611ad5565b610598565b60405190151581526020015b60405180910390f35b3480156101f257600080fd5b506101fb61067d565b6040516101dd9190611b16565b34801561021457600080fd5b5061024b610223366004611b67565b60046020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101dd565b34801561027c57600080fd5b5061029061028b366004611ba4565b61070b565b005b34801561029e57600080fd5b506102a860075481565b6040519081526020016101dd565b3480156102c257600080fd5b506102906102d1366004611bce565b61085a565b3480156102e257600080fd5b506102906102f1366004611bce565b6108bc565b34801561030257600080fd5b50610290610311366004611b67565b610a26565b34801561032257600080fd5b5061024b610331366004611b67565b610b2a565b34801561034257600080fd5b506102a8610351366004611b67565b610bbb565b34801561036257600080fd5b506102a8610371366004611c0a565b610bef565b34801561038257600080fd5b50610290610391366004611c0a565b610c97565b3480156103a257600080fd5b506102a87f00000000000000000000000000000000000000000000000000000000634f87f781565b3480156103d657600080fd5b5060065461024b9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561040357600080fd5b506101fb610412366004611b67565b610d25565b34801561042357600080fd5b506101fb610dc8565b34801561043857600080fd5b506102a8610dd5565b34801561044d57600080fd5b5061029061045c366004611c25565b610e29565b34801561046d57600080fd5b506101fb61047c366004611b67565b610ec0565b34801561048d57600080fd5b5061029061049c366004611caa565b610ed9565b3480156104ad57600080fd5b506101fb6104bc366004611b67565b611033565b6102a86104cf366004611d19565b611047565b3480156104e057600080fd5b506102a87f000000000000000000000000000000000000000000000000000eebe0b40e800081565b34801561051457600080fd5b506101fb61110a565b34801561052957600080fd5b506101d1610538366004611d5b565b600560209081526000928352604080842090915290825290205460ff1681565b34801561056457600080fd5b50610290610573366004611c0a565b611114565b34801561058457600080fd5b506102a8610593366004611d8e565b611206565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061062b57507f80ac58cd000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b8061067757507f5b5e139f000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6000805461068a90611db0565b80601f01602080910402602001604051908101604052809291908181526020018280546106b690611db0565b80156107035780601f106106d857610100808354040283529160200191610703565b820191906000526020600020905b8154815290600101906020018083116106e657829003601f168201915b505050505081565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff163381148061076e575073ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152604080832033845290915290205460ff165b6107d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008281526004602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff87811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f5452414e53464552535f44495341424c4544000000000000000000000000000060448201526064016107d0565b6108c783838361085a565b73ffffffffffffffffffffffffffffffffffffffff82163b15806109bb57506040517f150b7a020000000000000000000000000000000000000000000000000000000080825233600483015273ffffffffffffffffffffffffffffffffffffffff858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af1158015610973573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109979190611e03565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b610a21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e540000000000000000000000000000000060448201526064016107d0565b505050565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1633811480610a89575073ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152604080832033845290915290205460ff165b80610ab7575060008281526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1633145b610b1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016107d0565b610b268261128b565b5050565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610bb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e4f545f4d494e5445440000000000000000000000000000000000000000000060448201526064016107d0565b919050565b60007f0000000000000000000000000000000000000000000000005fc1b97136320000670de0b6b3a7640000830205610677565b600073ffffffffffffffffffffffffffffffffffffffff8216610c6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f5a45524f5f41444452455353000000000000000000000000000000000000000060448201526064016107d0565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b60065473ffffffffffffffffffffffffffffffffffffffff163314610d18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016107d0565b610d2281476113d5565b50565b6000818152600860205260409020805460609161067791610d4590611db0565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7190611db0565b8015610dbe5780601f10610d9357610100808354040283529160200191610dbe565b820191906000526020600020905b815481529060010190602001808311610da157829003601f168201915b505050505061144a565b6001805461068a90611db0565b6000610e24610e1c610e077f00000000000000000000000000000000000000000000000000000000634f87f742611e20565b62015180670de0b6b3a7640000919091020490565b600754611206565b905090565b33600081815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6008602052600090815260409020805461068a90611db0565b610ee485858561085a565b73ffffffffffffffffffffffffffffffffffffffff84163b1580610fc657506040517f150b7a02000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff86169063150b7a0290610f5f9033908a90899089908990600401611e5a565b6020604051808303816000875af1158015610f7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa29190611e03565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b61102c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e540000000000000000000000000000000060448201526064016107d0565b5050505050565b60606106778261104284610d25565b611473565b600080611052610dd5565b9050803410156110be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e44455250414944000000000000000000000000000000000000000000000060448201526064016107d0565b600780546001019081905560008181526008602052604090209092506110e5848683611f56565b506110f03383611487565b80341461110357611103338234036113d5565b5092915050565b6060610e24611620565b60065473ffffffffffffffffffffffffffffffffffffffff163314611195576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016107d0565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff831690811790915560405133907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b60006112847f000000000000000000000000000000000000000000000000000eebe0b40e800061127f61127a7ffffffffffffffffffffffffffffffffffffffffffffffffffad9b78c39a6968e611269670de0b6b3a76400006001890102610bbb565b8803670de0b6b3a764000091020590565b61162d565b61186c565b9392505050565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1680611317576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e4f545f4d494e5445440000000000000000000000000000000000000000000060448201526064016107d0565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260036020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190558583526002825280832080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811690915560049092528083208054909216909155518492907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600080600080600085875af1905080610a21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4554485f5452414e534645525f4641494c45440000000000000000000000000060448201526064016107d0565b60608160405160200161145d9190612070565b6040516020818303038152906040529050919050565b60606112846114828484611891565b6118c5565b73ffffffffffffffffffffffffffffffffffffffff8216611504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f494e56414c49445f524543495049454e5400000000000000000000000000000060448201526064016107d0565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f414c52454144595f4d494e54454400000000000000000000000000000000000060448201526064016107d0565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260036020908152604080832080546001019055848352600290915280822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6060610e246114826118ff565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361165e57506000919050565b680755bf798b4a1bf1e582126116d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f57000000000000000000000000000000000000000060448201526064016107d0565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b818102821583820583141761188057600080fd5b670de0b6b3a7640000900592915050565b60608161189d8461191f565b6040516020016118ae9291906120b5565b604051602081830303815290604052905092915050565b60606118ef826040516020016118db9190612160565b604051602081830303815290604052611981565b60405160200161145d919061217c565b60606040518060c00160405280609781526020016121c260979139905090565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a90048061193957508190037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909101908152919050565b606061067782600080606083518015611a9f576003600282010460021b60405192507f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566601f526102308515027f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5f03603f52602083018181015b6003880197508751603f8160121c16518353603f81600c1c16516001840153603f8160061c16516002840153603f8116516003840153506004820191508082106119fa5760038406868015611a5a57600182148215150185038752611a72565b603d821515850353603d6001831460011b8503538487525b5050601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660405250505b509392505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114610d2257600080fd5b600060208284031215611ae757600080fd5b813561128481611aa7565b60005b83811015611b0d578181015183820152602001611af5565b50506000910152565b6020815260008251806020840152611b35816040850160208701611af2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600060208284031215611b7957600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610bb657600080fd5b60008060408385031215611bb757600080fd5b611bc083611b80565b946020939093013593505050565b600080600060608486031215611be357600080fd5b611bec84611b80565b9250611bfa60208501611b80565b9150604084013590509250925092565b600060208284031215611c1c57600080fd5b61128482611b80565b60008060408385031215611c3857600080fd5b611c4183611b80565b915060208301358015158114611c5657600080fd5b809150509250929050565b60008083601f840112611c7357600080fd5b50813567ffffffffffffffff811115611c8b57600080fd5b602083019150836020828501011115611ca357600080fd5b9250929050565b600080600080600060808688031215611cc257600080fd5b611ccb86611b80565b9450611cd960208701611b80565b935060408601359250606086013567ffffffffffffffff811115611cfc57600080fd5b611d0888828901611c61565b969995985093965092949392505050565b60008060208385031215611d2c57600080fd5b823567ffffffffffffffff811115611d4357600080fd5b611d4f85828601611c61565b90969095509350505050565b60008060408385031215611d6e57600080fd5b611d7783611b80565b9150611d8560208401611b80565b90509250929050565b60008060408385031215611da157600080fd5b50508035926020909101359150565b600181811c90821680611dc457607f821691505b602082108103611dfd577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215611e1557600080fd5b815161128481611aa7565b81810381811115610677577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525084604083015260806060830152826080830152828460a0840137600060a0848401015260a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011683010190509695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b601f821115610a2157600081815260208120601f850160051c81016020861015611f2f5750805b601f850160051c820191505b81811015611f4e57828155600101611f3b565b505050505050565b67ffffffffffffffff831115611f6e57611f6e611ed9565b611f8283611f7c8354611db0565b83611f08565b6000601f841160018114611fd45760008515611f9e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561102c565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156120235786850135825560209485019460019092019101612003565b508682101561205e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b7f697066733a2f2f000000000000000000000000000000000000000000000000008152600082516120a8816007850160208701611af2565b9190910160070192915050565b7f7b22696d616765223a22000000000000000000000000000000000000000000008152600083516120ed81600a850160208801611af2565b7f222c226e616d65223a22507572706c65636865636b2023000000000000000000600a91840191820152835161212a816021840160208801611af2565b7f227d00000000000000000000000000000000000000000000000000000000000060219290910191820152602301949350505050565b60008251612172818460208701611af2565b9190910192915050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000008152600082516121b481601d850160208701611af2565b91909101601d019291505056fe7b226e616d65223a22507572706c65636865636b222c22696d616765223a22697066733a2f2f6261666b72656962687737777962647a6d70673574666a7236706a796e616c706562337a733763337661323670726a796336676c3262766f377934222c226465736372697074696f6e223a22596f7572204a50454773206465736572766520746f206665656c207370656369616c2e227da2646970667358221220668d48eb1f816d1ddc35de38ea2b4a14824c6087bb99575fea2489c30fe5a5c264736f6c63430008100033

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

00000000000000000000000079d31bfca5fda7a4f15b36763d2e44c99d811a6c

-----Decoded View---------------
Arg [0] : owner (address): 0x79d31bFcA5Fda7A4F15b36763d2e44C99D811a6C

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000079d31bfca5fda7a4f15b36763d2e44c99d811a6c


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.