ETH Price: $3,469.20 (+2.99%)

Token

RKL x Stance Boxes (RKLSB)
 

Overview

Max Total Supply

0 RKLSB

Holders

487

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 RKLSB
0xf616ed8cbc78aab64f24f5fe67b7a8b6cb3aba86
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:
StanceRKLBoxesCollection

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
File 1 of 11 : StanceRKLBoxesCollection.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.20;

import {IStanceRKLCollection} from "./interfaces/IStanceRKLCollection.sol";
import {IMinterController} from "./interfaces/IMinterController.sol";
import {IStanceRKLBoxesCollection} from "./interfaces/IStanceRKLBoxesCollection.sol";
import {ISocksMinter} from "./interfaces/ISocksMinter.sol";
import {IERC721} from "./interfaces/IERC721.sol";

import {BitMaps} from "./lib/Bitmaps.sol";
import {Ownable} from "./common/Ownable.sol";
import {MintGuard} from "./common/MintGuard.sol";
import {Constants} from "./common/Constants.sol";

import {ERC721} from "solady/src/tokens/ERC721.sol";

/// @title Each Stance RKL Box acts as a unique key for RKL <> Stance collaboration
contract StanceRKLBoxesCollection is ERC721, IStanceRKLBoxesCollection, Ownable, MintGuard, Constants {
    using BitMaps for BitMaps.BitMap;

    /// @notice testnet address: 0xC83664c31616dE95345a4Bd0c6dEa9C9350935b4
    ///        ethereum address: 0xEf0182dc0574cd5874494a120750FD222FdB909a
    IERC721 public RKL_KONGS_COLLECTION;
    string private baseUri = "ipfs://QmYjGPXWbnmXpb5gSBM8MDao8Q5jTXJeVTKA9t3i65Ys7S/";
    /// @notice we use this to check if a given kong minted the socks in this contract
    /// this information is used to determine what metadata to show (open box or closed)
    ISocksMinter private socksMinter;
    /// @notice tracks last minted token id
    uint256 private lastTokenId;
    /// @notice tracks which kongs minted boxes
    BitMaps.BitMap kongsThatMinted;

    constructor(address rklKongsCollection) {
        admin = msg.sender;
        RKL_KONGS_COLLECTION = IERC721(rklKongsCollection);
        // UTC: Monday, 4 September 2023 17:00:00, which is 1PM ET
        mintOpenOnTimestamp = 1693846800;
    }

    // =====================================================================//
    //                          Collection Meta                             //
    // =====================================================================//

    function name() public pure override returns (string memory) {
        return "RKL x Stance Boxes";
    }

    function symbol() public pure override returns (string memory) {
        return "RKLSB";
    }

    function tokenURI(uint256 id) public view override returns (string memory) {
        if (socksMinter.getBoxesThatMinted(id) == true) {
            return string(abi.encodePacked(baseUri, "openbox.json"));
        }
        return string(abi.encodePacked(baseUri, "closedbox.json"));
    }

    // =====================================================================//
    //                          Utils & Mint                                //
    // =====================================================================//

    function checkKongCanClaim(uint256[] calldata kongIds) public view returns (bool[] memory) {
        bool[] memory kongCanClaim = new bool[](kongIds.length);
        for (uint256 i = 0; i < kongIds.length;) {
            if (kongsThatMinted.get(kongIds[i]) == true) {
                kongCanClaim[i] = false;
            } else {
                kongCanClaim[i] = true;
            }
            unchecked {
                ++i;
            }
        }
        return kongCanClaim;
    }

    function checkKongCanClaimReverts(uint256[] calldata kongIds) private view {
        for (uint256 i = 0; i < kongIds.length;) {
            if (kongsThatMinted.get(kongIds[i]) == true) {
                revert KongAlreadyClaimed(kongIds[i]);
            }
            unchecked {
                ++i;
            }
        }
    }

    function checkCallerOwnerOfKongs(uint256[] calldata kongIds) private view {
        for (uint256 i = 0; i < kongIds.length;) {
            if (msg.sender != RKL_KONGS_COLLECTION.ownerOf(kongIds[i])) {
                revert CallerNotOwner(kongIds[i]);
            }
            unchecked {
                ++i;
            }
        }
    }

    function getTokensOwnedByAddress(address owner, uint256 offset, uint256 limit)
        external
        view
        returns (uint256[] memory)
    {
        uint256 balance = balanceOf(owner);

        if (balance == 0 || offset >= balance) {
            // return empty array if no tokens owned or offset is out of bounds
            return new uint256[](0);
        }

        // ensure that we don't fetch more than the balance or exceed the limit
        uint256 balanceMinusOffset = balance - offset;
        uint256 resultsCount = (balanceMinusOffset > limit) ? limit : balanceMinusOffset;

        uint256[] memory ownedTokens = new uint256[](resultsCount);
        uint256 counter = 0;
        uint256 tokenId = 0;

        while (counter < resultsCount) {
            try this.ownerOf(tokenId) returns (address tokenOwner) {
                if (tokenOwner == owner) {
                    if (tokenId >= offset) {
                        ownedTokens[counter] = tokenId;
                        counter++;
                    }
                }
                // catch and do nothing if ownerOf reverts
            } catch {}
            tokenId++;
        }

        return ownedTokens;
    }

    function mint(address to, uint256[] calldata kongIds) external {
        checkIfMintOpen();
        checkKongCanClaimReverts(kongIds);
        checkCallerOwnerOfKongs(kongIds);
        kongsThatMinted.batchSet(kongIds);
        for (uint256 i = 0; i < kongIds.length;) {
            super._mint(to, lastTokenId);
            unchecked {
                ++i;
                ++lastTokenId;
            }
        }
    }

    // =====================================================================//
    //                              Admin                                   //
    // =====================================================================//

    function setSocksMinter(address _socksMinter) external onlyOwner {
        socksMinter = ISocksMinter(_socksMinter);
    }

    function setBaseUri(string calldata newBaseUri) external onlyOwner {
        baseUri = newBaseUri;
    }
}

File 2 of 11 : IStanceRKLCollection.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.20;

interface IStanceRKLCollection {
    error NothingToMint();
    error ArgLengthMismatch();
    error MintToZeroAddr();

    function mint(address to, uint256[] memory tokenIds, uint256[] memory amounts) external;
}

File 3 of 11 : IMinterController.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.20;

/// @dev responsible for registering minters with StanceRKLCollection
///      responsible for checking if particular Minter is allowed to mint token ids
///      responsible for managing token ids for StanceRKLCollection
interface IMinterController {
    error MinterZeroAddressNotAllowed();
    error MinterNotRegistered();
    error MinterNotAllowedForTokenId(uint256 requestedTokenId, uint256 allowedLowerBound, uint256 allowedUpperBound);
    error MinterAlreadyRegistered();
    error InvalidBounds(uint128 lowerBound, uint128 upperBound);

    /// @dev if only one token id is allowed, then lowerBound == upperBound
    ///      note that the bounds are inclusive, so lowerBound := 2 and
    ///      upperBound := 4 would mean that minter is allowed to mint token
    ///      ids 2, 3 and 4.
    struct MinterAllowedTokenIds {
        uint128 lowerBound;
        uint128 upperBound;
    }

    /// @dev minter is the address of the contract that implementes IMinter
    ///      throws MinterNotAllowedForTokenId
    function checkMinterAllowedForTokenIds(address minter, uint256[] memory tokenIds) external;

    /// @dev registers a new minter with StanceRKLCollection
    function registerMinter(address minter, MinterAllowedTokenIds calldata) external;
}

File 4 of 11 : IStanceRKLBoxesCollection.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.20;

interface IStanceRKLBoxesCollection {
    error KongAlreadyClaimed(uint256 kongId);
    error CallerNotOwner(uint256 kongId);
    error OnlyRegisteredMintersAllowed();
    error MinterControllerAddressAlreadySet();

    function getTokensOwnedByAddress(address owner, uint256 offset, uint256 limit)
        external
        view
        returns (uint256[] memory);
}

File 5 of 11 : ISocksMinter.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.20;

interface ISocksMinter {
    error BoxAlreadyClaimed(uint256 boxId);
    error CallerNotOwner(uint256 boxId);

    function getBoxesThatMinted(uint256 boxId) external view returns (bool);
}

File 6 of 11 : IERC721.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.20;

interface IERC721 {
    function ownerOf(uint256 _tokenId) external view returns (address);
}

File 7 of 11 : Bitmaps.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.20;

library BitMaps {
    struct BitMap {
        mapping(uint256 bucket => uint256 tokenIdHasMinted) _data;
    }

    function get(BitMap storage bitmap, uint256 tokenId) internal view returns (bool) {
        uint256 bucket = tokenId >> 8;
        uint256 mask = 1 << (tokenId & 0xff);
        return bitmap._data[bucket] & mask != 0;
    }

    function set(BitMap storage bitmap, uint256 tokenId) internal {
        uint256 bucket = tokenId >> 8;
        uint256 mask = 1 << (tokenId & 0xff);
        bitmap._data[bucket] |= mask;
    }

    function batchSet(BitMap storage bitmap, uint256[] memory tokenId) internal {
        uint256 bucket;
        uint256 mask;
        for (uint256 i = 0; i < tokenId.length;) {
            bucket = tokenId[i] >> 8;
            mask = 1 << (tokenId[i] & 0xff);
            bitmap._data[bucket] |= mask;
            unchecked {
                ++i;
            }
        }
    }
}

File 8 of 11 : Ownable.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.20;

abstract contract Ownable {
    error NotAdmin();

    address public admin;

    modifier onlyOwner() {
        if (msg.sender != admin) {
            revert NotAdmin();
        }
        _;
    }

    function changeAdmin(address newAdmin) external onlyOwner {
        admin = newAdmin;
    }
}

File 9 of 11 : MintGuard.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.20;

import "./Ownable.sol";

abstract contract MintGuard is Ownable {
    error MintNotOpen();

    uint256 public mintOpenOnTimestamp;

    function checkIfMintOpen() internal view {
        if (block.timestamp < mintOpenOnTimestamp) {
            revert MintNotOpen();
        }
    }

    function changeMintOpenOnTimestamp(uint256 newMintOpenOnTimestamp) external onlyOwner {
        mintOpenOnTimestamp = newMintOpenOnTimestamp;
    }
}

File 10 of 11 : Constants.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.20;

abstract contract Constants {
    address internal constant ZERO_ADDRESS = address(0);
}

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

/// @notice Simple ERC721 implementation with storage hitchhiking.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC721.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC721/ERC721.sol)
/// Note:
/// The ERC721 standard allows for self-approvals.
/// For performance, this implementation WILL NOT revert for such actions.
/// Please add any checks with overrides if desired.
abstract contract ERC721 {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev An account can hold up to 4294967295 tokens.
    uint256 internal constant _MAX_ACCOUNT_BALANCE = 0xffffffff;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Only the token owner or an approved account can manage the token.
    error NotOwnerNorApproved();

    /// @dev The token does not exist.
    error TokenDoesNotExist();

    /// @dev The token already exists.
    error TokenAlreadyExists();

    /// @dev Cannot query the balance for the zero address.
    error BalanceQueryForZeroAddress();

    /// @dev Cannot mint or transfer to the zero address.
    error TransferToZeroAddress();

    /// @dev The token must be owned by `from`.
    error TransferFromIncorrectOwner();

    /// @dev The recipient's balance has overflowed.
    error AccountBalanceOverflow();

    /// @dev Cannot safely transfer to a contract that does not implement
    /// the ERC721Receiver interface.
    error TransferToNonERC721ReceiverImplementer();

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

    /// @dev Emitted when token `id` is transferred from `from` to `to`.
    event Transfer(address indexed from, address indexed to, uint256 indexed id);

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

    /// @dev Emitted when `owner` enables or disables `operator` to manage all of their tokens.
    event ApprovalForAll(address indexed owner, address indexed operator, bool isApproved);

    /// @dev `keccak256(bytes("Transfer(address,address,uint256)"))`.
    uint256 private constant _TRANSFER_EVENT_SIGNATURE =
        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;

    /// @dev `keccak256(bytes("Approval(address,address,uint256)"))`.
    uint256 private constant _APPROVAL_EVENT_SIGNATURE =
        0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925;

    /// @dev `keccak256(bytes("ApprovalForAll(address,address,bool)"))`.
    uint256 private constant _APPROVAL_FOR_ALL_EVENT_SIGNATURE =
        0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31;

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

    /// @dev The ownership data slot of `id` is given by:
    /// ```
    ///     mstore(0x00, id)
    ///     mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
    ///     let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
    /// ```
    /// Bits Layout:
    // - [0..159]   `addr`
    // - [160..223] `extraData`
    ///
    /// The approved address slot is given by: `add(1, ownershipSlot)`.
    ///
    /// See: https://notes.ethereum.org/%40vbuterin/verkle_tree_eip
    ///
    /// The balance slot of `owner` is given by:
    /// ```
    ///     mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
    ///     mstore(0x00, owner)
    ///     let balanceSlot := keccak256(0x0c, 0x1c)
    /// ```
    /// Bits Layout:
    /// - [0..31]   `balance`
    /// - [32..225] `aux`
    ///
    /// The `operator` approval slot of `owner` is given by:
    /// ```
    ///     mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator))
    ///     mstore(0x00, owner)
    ///     let operatorApprovalSlot := keccak256(0x0c, 0x30)
    /// ```
    uint256 private constant _ERC721_MASTER_SLOT_SEED = 0x7d8825530a5a2e7a << 192;

    /// @dev Pre-shifted and pre-masked constant.
    uint256 private constant _ERC721_MASTER_SLOT_SEED_MASKED = 0x0a5a2e7a00000000;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      ERC721 METADATA                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the token collection name.
    function name() public view virtual returns (string memory);

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

    /// @dev Returns the Uniform Resource Identifier (URI) for token `id`.
    function tokenURI(uint256 id) public view virtual returns (string memory);

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

    /// @dev Returns the owner of token `id`.
    ///
    /// Requirements:
    /// - Token `id` must exist.
    function ownerOf(uint256 id) public view virtual returns (address result) {
        result = _ownerOf(id);
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(result) {
                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Returns the number of tokens owned by `owner`.
    ///
    /// Requirements:
    /// - `owner` must not be the zero address.
    function balanceOf(address owner) public view virtual returns (uint256 result) {
        /// @solidity memory-safe-assembly
        assembly {
            // Revert if the `owner` is the zero address.
            if iszero(owner) {
                mstore(0x00, 0x8f4eb604) // `BalanceQueryForZeroAddress()`.
                revert(0x1c, 0x04)
            }
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            mstore(0x00, owner)
            result := and(sload(keccak256(0x0c, 0x1c)), _MAX_ACCOUNT_BALANCE)
        }
    }

    /// @dev Returns the account approved to managed token `id`.
    ///
    /// Requirements:
    /// - Token `id` must exist.
    function getApproved(uint256 id) public view virtual returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, id)
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
            if iszero(shr(96, shl(96, sload(ownershipSlot)))) {
                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
                revert(0x1c, 0x04)
            }
            result := sload(add(1, ownershipSlot))
        }
    }

    /// @dev Sets `account` as the approved account to manage token `id`.
    ///
    /// Requirements:
    /// - Token `id` must exist.
    /// - The caller must be the owner of the token,
    ///   or an approved operator for the token owner.
    ///
    /// Emits a {Approval} event.
    function approve(address account, uint256 id) public payable virtual {
        _approve(msg.sender, account, id);
    }

    /// @dev Returns whether `operator` is approved to manage the tokens of `owner`.
    function isApprovedForAll(address owner, address operator)
        public
        view
        virtual
        returns (bool result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x1c, operator)
            mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED)
            mstore(0x00, owner)
            result := sload(keccak256(0x0c, 0x30))
        }
    }

    /// @dev Sets whether `operator` is approved to manage the tokens of the caller.
    ///
    /// Emits a {ApprovalForAll} event.
    function setApprovalForAll(address operator, bool isApproved) public virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // Convert to 0 or 1.
            isApproved := iszero(iszero(isApproved))
            // Update the `isApproved` for (`msg.sender`, `operator`).
            mstore(0x1c, operator)
            mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED)
            mstore(0x00, caller())
            sstore(keccak256(0x0c, 0x30), isApproved)
            // Emit the {ApprovalForAll} event.
            mstore(0x00, isApproved)
            log3(
                0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, caller(), shr(96, shl(96, operator))
            )
        }
    }

    /// @dev Transfers token `id` from `from` to `to`.
    ///
    /// Requirements:
    ///
    /// - Token `id` must exist.
    /// - `from` must be the owner of the token.
    /// - `to` cannot be the zero address.
    /// - The caller must be the owner of the token, or be approved to manage the token.
    ///
    /// Emits a {Transfer} event.
    function transferFrom(address from, address to, uint256 id) public payable virtual {
        _beforeTokenTransfer(from, to, id);
        /// @solidity memory-safe-assembly
        assembly {
            // Clear the upper 96 bits.
            let bitmaskAddress := shr(96, not(0))
            from := and(bitmaskAddress, from)
            to := and(bitmaskAddress, to)
            // Load the ownership data.
            mstore(0x00, id)
            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, caller()))
            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
            let ownershipPacked := sload(ownershipSlot)
            let owner := and(bitmaskAddress, ownershipPacked)
            // Revert if `from` is not the owner, or does not exist.
            if iszero(mul(owner, eq(owner, from))) {
                if iszero(owner) {
                    mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
                    revert(0x1c, 0x04)
                }
                mstore(0x00, 0xa1148100) // `TransferFromIncorrectOwner()`.
                revert(0x1c, 0x04)
            }
            // Revert if `to` is the zero address.
            if iszero(to) {
                mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`.
                revert(0x1c, 0x04)
            }
            // Load, check, and update the token approval.
            {
                mstore(0x00, from)
                let approvedAddress := sload(add(1, ownershipSlot))
                // Revert if the caller is not the owner, nor approved.
                if iszero(or(eq(caller(), from), eq(caller(), approvedAddress))) {
                    if iszero(sload(keccak256(0x0c, 0x30))) {
                        mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.
                        revert(0x1c, 0x04)
                    }
                }
                // Delete the approved address if any.
                if approvedAddress { sstore(add(1, ownershipSlot), 0) }
            }
            // Update with the new owner.
            sstore(ownershipSlot, xor(ownershipPacked, xor(from, to)))
            // Decrement the balance of `from`.
            {
                let fromBalanceSlot := keccak256(0x0c, 0x1c)
                sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1))
            }
            // Increment the balance of `to`.
            {
                mstore(0x00, to)
                let toBalanceSlot := keccak256(0x0c, 0x1c)
                let toBalanceSlotPacked := add(sload(toBalanceSlot), 1)
                if iszero(and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE)) {
                    mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`.
                    revert(0x1c, 0x04)
                }
                sstore(toBalanceSlot, toBalanceSlotPacked)
            }
            // Emit the {Transfer} event.
            log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id)
        }
        _afterTokenTransfer(from, to, id);
    }

    /// @dev Equivalent to `safeTransferFrom(from, to, id, "")`.
    function safeTransferFrom(address from, address to, uint256 id) public payable virtual {
        transferFrom(from, to, id);
        if (_hasCode(to)) _checkOnERC721Received(from, to, id, "");
    }

    /// @dev Transfers token `id` from `from` to `to`.
    ///
    /// Requirements:
    ///
    /// - Token `id` must exist.
    /// - `from` must be the owner of the token.
    /// - `to` cannot be the zero address.
    /// - The caller must be the owner of the token, or be approved to manage the token.
    /// - If `to` refers to a smart contract, it must implement
    ///   {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
    ///
    /// Emits a {Transfer} event.
    function safeTransferFrom(address from, address to, uint256 id, bytes calldata data)
        public
        payable
        virtual
    {
        transferFrom(from, to, id);
        if (_hasCode(to)) _checkOnERC721Received(from, to, id, data);
    }

    /// @dev Returns true if this contract implements the interface defined by `interfaceId`.
    /// See: https://eips.ethereum.org/EIPS/eip-165
    /// This function call must use less than 30000 gas.
    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) {
        /// @solidity memory-safe-assembly
        assembly {
            let s := shr(224, interfaceId)
            // ERC165: 0x01ffc9a7, ERC721: 0x80ac58cd, ERC721Metadata: 0x5b5e139f.
            result := or(or(eq(s, 0x01ffc9a7), eq(s, 0x80ac58cd)), eq(s, 0x5b5e139f))
        }
    }

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

    /// @dev Returns if token `id` exists.
    function _exists(uint256 id) internal view virtual returns (bool result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, id)
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            result := shl(96, sload(add(id, add(id, keccak256(0x00, 0x20)))))
        }
    }

    /// @dev Returns the owner of token `id`.
    /// Returns the zero address instead of reverting if the token does not exist.
    function _ownerOf(uint256 id) internal view virtual returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, id)
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            result := shr(96, shl(96, sload(add(id, add(id, keccak256(0x00, 0x20))))))
        }
    }

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

    /// @dev Returns the auxiliary data for `owner`.
    /// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data.
    /// Auxiliary data can be set for any address, even if it does not have any tokens.
    function _getAux(address owner) internal view virtual returns (uint224 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            mstore(0x00, owner)
            result := shr(32, sload(keccak256(0x0c, 0x1c)))
        }
    }

    /// @dev Set the auxiliary data for `owner` to `value`.
    /// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data.
    /// Auxiliary data can be set for any address, even if it does not have any tokens.
    function _setAux(address owner, uint224 value) internal virtual {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            mstore(0x00, owner)
            let balanceSlot := keccak256(0x0c, 0x1c)
            let packed := sload(balanceSlot)
            sstore(balanceSlot, xor(packed, shl(32, xor(value, shr(32, packed)))))
        }
    }

    /// @dev Returns the extra data for token `id`.
    /// Minting, transferring, burning a token will not change the extra data.
    /// The extra data can be set on a non existent token.
    function _getExtraData(uint256 id) internal view virtual returns (uint96 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, id)
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            result := shr(160, sload(add(id, add(id, keccak256(0x00, 0x20)))))
        }
    }

    /// @dev Sets the extra data for token `id` to `value`.
    /// Minting, transferring, burning a token will not change the extra data.
    /// The extra data can be set on a non existent token.
    function _setExtraData(uint256 id, uint96 value) internal virtual {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, id)
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
            let packed := sload(ownershipSlot)
            sstore(ownershipSlot, xor(packed, shl(160, xor(value, shr(160, packed)))))
        }
    }

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

    /// @dev Mints token `id` to `to`.
    ///
    /// Requirements:
    ///
    /// - Token `id` must not exist.
    /// - `to` cannot be the zero address.
    ///
    /// Emits a {Transfer} event.
    function _mint(address to, uint256 id) internal virtual {
        _beforeTokenTransfer(address(0), to, id);
        /// @solidity memory-safe-assembly
        assembly {
            // Clear the upper 96 bits.
            to := shr(96, shl(96, to))
            // Revert if `to` is the zero address.
            if iszero(to) {
                mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`.
                revert(0x1c, 0x04)
            }
            // Load the ownership data.
            mstore(0x00, id)
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
            let ownershipPacked := sload(ownershipSlot)
            // Revert if the token already exists.
            if shl(96, ownershipPacked) {
                mstore(0x00, 0xc991cbb1) // `TokenAlreadyExists()`.
                revert(0x1c, 0x04)
            }
            // Update with the owner.
            sstore(ownershipSlot, or(ownershipPacked, to))
            // Increment the balance of the owner.
            {
                mstore(0x00, to)
                let balanceSlot := keccak256(0x0c, 0x1c)
                let balanceSlotPacked := add(sload(balanceSlot), 1)
                if iszero(and(balanceSlotPacked, _MAX_ACCOUNT_BALANCE)) {
                    mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`.
                    revert(0x1c, 0x04)
                }
                sstore(balanceSlot, balanceSlotPacked)
            }
            // Emit the {Transfer} event.
            log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, 0, to, id)
        }
        _afterTokenTransfer(address(0), to, id);
    }

    /// @dev Equivalent to `_safeMint(to, id, "")`.
    function _safeMint(address to, uint256 id) internal virtual {
        _safeMint(to, id, "");
    }

    /// @dev Mints token `id` to `to`.
    ///
    /// Requirements:
    ///
    /// - Token `id` must not exist.
    /// - `to` cannot be the zero address.
    /// - If `to` refers to a smart contract, it must implement
    ///   {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
    ///
    /// Emits a {Transfer} event.
    function _safeMint(address to, uint256 id, bytes memory data) internal virtual {
        _mint(to, id);
        if (_hasCode(to)) _checkOnERC721Received(address(0), to, id, data);
    }

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

    /// @dev Equivalent to `_burn(address(0), id)`.
    function _burn(uint256 id) internal virtual {
        _burn(address(0), id);
    }

    /// @dev Destroys token `id`, using `by`.
    ///
    /// Requirements:
    ///
    /// - Token `id` must exist.
    /// - If `by` is not the zero address,
    ///   it must be the owner of the token, or be approved to manage the token.
    ///
    /// Emits a {Transfer} event.
    function _burn(address by, uint256 id) internal virtual {
        address owner = ownerOf(id);
        _beforeTokenTransfer(owner, address(0), id);
        /// @solidity memory-safe-assembly
        assembly {
            // Clear the upper 96 bits.
            by := shr(96, shl(96, by))
            // Load the ownership data.
            mstore(0x00, id)
            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by))
            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
            let ownershipPacked := sload(ownershipSlot)
            // Reload the owner in case it is changed in `_beforeTokenTransfer`.
            owner := shr(96, shl(96, ownershipPacked))
            // Revert if the token does not exist.
            if iszero(owner) {
                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
                revert(0x1c, 0x04)
            }
            // Load and check the token approval.
            {
                mstore(0x00, owner)
                let approvedAddress := sload(add(1, ownershipSlot))
                // If `by` is not the zero address, do the authorization check.
                // Revert if the `by` is not the owner, nor approved.
                if iszero(or(iszero(by), or(eq(by, owner), eq(by, approvedAddress)))) {
                    if iszero(sload(keccak256(0x0c, 0x30))) {
                        mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.
                        revert(0x1c, 0x04)
                    }
                }
                // Delete the approved address if any.
                if approvedAddress { sstore(add(1, ownershipSlot), 0) }
            }
            // Clear the owner.
            sstore(ownershipSlot, xor(ownershipPacked, owner))
            // Decrement the balance of `owner`.
            {
                let balanceSlot := keccak256(0x0c, 0x1c)
                sstore(balanceSlot, sub(sload(balanceSlot), 1))
            }
            // Emit the {Transfer} event.
            log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, owner, 0, id)
        }
        _afterTokenTransfer(owner, address(0), id);
    }

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

    /// @dev Returns whether `account` is the owner of token `id`, or is approved to managed it.
    ///
    /// Requirements:
    /// - Token `id` must exist.
    function _isApprovedOrOwner(address account, uint256 id)
        internal
        view
        virtual
        returns (bool result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            result := 1
            // Clear the upper 96 bits.
            account := shr(96, shl(96, account))
            // Load the ownership data.
            mstore(0x00, id)
            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, account))
            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
            let owner := shr(96, shl(96, sload(ownershipSlot)))
            // Revert if the token does not exist.
            if iszero(owner) {
                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
                revert(0x1c, 0x04)
            }
            // Check if `account` is the `owner`.
            if iszero(eq(account, owner)) {
                mstore(0x00, owner)
                // Check if `account` is approved to
                if iszero(sload(keccak256(0x0c, 0x30))) {
                    result := eq(account, sload(add(1, ownershipSlot)))
                }
            }
        }
    }

    /// @dev Returns the account approved to manage token `id`.
    /// Returns the zero address instead of reverting if the token does not exist.
    function _getApproved(uint256 id) internal view virtual returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, id)
            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
            result := sload(add(1, add(id, add(id, keccak256(0x00, 0x20)))))
        }
    }

    /// @dev Equivalent to `_approve(address(0), account, id)`.
    function _approve(address account, uint256 id) internal virtual {
        _approve(address(0), account, id);
    }

    /// @dev Sets `account` as the approved account to manage token `id`, using `by`.
    ///
    /// Requirements:
    /// - Token `id` must exist.
    /// - If `by` is not the zero address, `by` must be the owner
    ///   or an approved operator for the token owner.
    ///
    /// Emits a {Transfer} event.
    function _approve(address by, address account, uint256 id) internal virtual {
        assembly {
            // Clear the upper 96 bits.
            let bitmaskAddress := shr(96, not(0))
            account := and(bitmaskAddress, account)
            by := and(bitmaskAddress, by)
            // Load the owner of the token.
            mstore(0x00, id)
            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by))
            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
            let owner := and(bitmaskAddress, sload(ownershipSlot))
            // Revert if the token does not exist.
            if iszero(owner) {
                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
                revert(0x1c, 0x04)
            }
            // If `by` is not the zero address, do the authorization check.
            // Revert if `by` is not the owner, nor approved.
            if iszero(or(iszero(by), eq(by, owner))) {
                mstore(0x00, owner)
                if iszero(sload(keccak256(0x0c, 0x30))) {
                    mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.
                    revert(0x1c, 0x04)
                }
            }
            // Sets `account` as the approved account to manage `id`.
            sstore(add(1, ownershipSlot), account)
            // Emit the {Approval} event.
            log4(0x00, 0x00, _APPROVAL_EVENT_SIGNATURE, owner, account, id)
        }
    }

    /// @dev Approve or remove the `operator` as an operator for `by`,
    /// without authorization checks.
    ///
    /// Emits a {ApprovalForAll} event.
    function _setApprovalForAll(address by, address operator, bool isApproved) internal virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // Clear the upper 96 bits.
            by := shr(96, shl(96, by))
            operator := shr(96, shl(96, operator))
            // Convert to 0 or 1.
            isApproved := iszero(iszero(isApproved))
            // Update the `isApproved` for (`by`, `operator`).
            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator))
            mstore(0x00, by)
            sstore(keccak256(0x0c, 0x30), isApproved)
            // Emit the {ApprovalForAll} event.
            mstore(0x00, isApproved)
            log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, by, operator)
        }
    }

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

    /// @dev Equivalent to `_transfer(address(0), from, to, id)`.
    function _transfer(address from, address to, uint256 id) internal virtual {
        _transfer(address(0), from, to, id);
    }

    /// @dev Transfers token `id` from `from` to `to`.
    ///
    /// Requirements:
    ///
    /// - Token `id` must exist.
    /// - `from` must be the owner of the token.
    /// - `to` cannot be the zero address.
    /// - If `by` is not the zero address,
    ///   it must be the owner of the token, or be approved to manage the token.
    ///
    /// Emits a {Transfer} event.
    function _transfer(address by, address from, address to, uint256 id) internal virtual {
        _beforeTokenTransfer(from, to, id);
        /// @solidity memory-safe-assembly
        assembly {
            // Clear the upper 96 bits.
            let bitmaskAddress := shr(96, not(0))
            from := and(bitmaskAddress, from)
            to := and(bitmaskAddress, to)
            by := and(bitmaskAddress, by)
            // Load the ownership data.
            mstore(0x00, id)
            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by))
            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
            let ownershipPacked := sload(ownershipSlot)
            let owner := and(bitmaskAddress, ownershipPacked)
            // Revert if `from` is not the owner, or does not exist.
            if iszero(mul(owner, eq(owner, from))) {
                if iszero(owner) {
                    mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
                    revert(0x1c, 0x04)
                }
                mstore(0x00, 0xa1148100) // `TransferFromIncorrectOwner()`.
                revert(0x1c, 0x04)
            }
            // Revert if `to` is the zero address.
            if iszero(to) {
                mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`.
                revert(0x1c, 0x04)
            }
            // Load, check, and update the token approval.
            {
                mstore(0x00, from)
                let approvedAddress := sload(add(1, ownershipSlot))
                // If `by` is not the zero address, do the authorization check.
                // Revert if the `by` is not the owner, nor approved.
                if iszero(or(iszero(by), or(eq(by, from), eq(by, approvedAddress)))) {
                    if iszero(sload(keccak256(0x0c, 0x30))) {
                        mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.
                        revert(0x1c, 0x04)
                    }
                }
                // Delete the approved address if any.
                if approvedAddress { sstore(add(1, ownershipSlot), 0) }
            }
            // Update with the new owner.
            sstore(ownershipSlot, xor(ownershipPacked, xor(from, to)))
            // Decrement the balance of `from`.
            {
                let fromBalanceSlot := keccak256(0x0c, 0x1c)
                sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1))
            }
            // Increment the balance of `to`.
            {
                mstore(0x00, to)
                let toBalanceSlot := keccak256(0x0c, 0x1c)
                let toBalanceSlotPacked := add(sload(toBalanceSlot), 1)
                if iszero(and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE)) {
                    mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`.
                    revert(0x1c, 0x04)
                }
                sstore(toBalanceSlot, toBalanceSlotPacked)
            }
            // Emit the {Transfer} event.
            log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id)
        }
        _afterTokenTransfer(from, to, id);
    }

    /// @dev Equivalent to `_safeTransfer(from, to, id, "")`.
    function _safeTransfer(address from, address to, uint256 id) internal virtual {
        _safeTransfer(from, to, id, "");
    }

    /// @dev Transfers token `id` from `from` to `to`.
    ///
    /// Requirements:
    ///
    /// - Token `id` must exist.
    /// - `from` must be the owner of the token.
    /// - `to` cannot be the zero address.
    /// - The caller must be the owner of the token, or be approved to manage the token.
    /// - If `to` refers to a smart contract, it must implement
    ///   {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
    ///
    /// Emits a {Transfer} event.
    function _safeTransfer(address from, address to, uint256 id, bytes memory data)
        internal
        virtual
    {
        _transfer(address(0), from, to, id);
        if (_hasCode(to)) _checkOnERC721Received(from, to, id, data);
    }

    /// @dev Equivalent to `_safeTransfer(by, from, to, id, "")`.
    function _safeTransfer(address by, address from, address to, uint256 id) internal virtual {
        _safeTransfer(by, from, to, id, "");
    }

    /// @dev Transfers token `id` from `from` to `to`.
    ///
    /// Requirements:
    ///
    /// - Token `id` must exist.
    /// - `from` must be the owner of the token.
    /// - `to` cannot be the zero address.
    /// - If `by` is not the zero address,
    ///   it must be the owner of the token, or be approved to manage the token.
    /// - If `to` refers to a smart contract, it must implement
    ///   {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
    ///
    /// Emits a {Transfer} event.
    function _safeTransfer(address by, address from, address to, uint256 id, bytes memory data)
        internal
        virtual
    {
        _transfer(by, from, to, id);
        if (_hasCode(to)) _checkOnERC721Received(from, to, id, data);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                    HOOKS FOR OVERRIDING                    */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Hook that is called before any token transfers, including minting and burning.
    function _beforeTokenTransfer(address from, address to, uint256 id) internal virtual {}

    /// @dev Hook that is called after any token transfers, including minting and burning.
    function _afterTokenTransfer(address from, address to, uint256 id) internal virtual {}

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      PRIVATE HELPERS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns if `a` has bytecode of non-zero length.
    function _hasCode(address a) private view returns (bool result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := extcodesize(a) // Can handle dirty upper bits.
        }
    }

    /// @dev Perform a call to invoke {IERC721Receiver-onERC721Received} on `to`.
    /// Reverts if the target does not support the function correctly.
    function _checkOnERC721Received(address from, address to, uint256 id, bytes memory data)
        private
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Prepare the calldata.
            let m := mload(0x40)
            let onERC721ReceivedSelector := 0x150b7a02
            mstore(m, onERC721ReceivedSelector)
            mstore(add(m, 0x20), caller()) // The `operator`, which is always `msg.sender`.
            mstore(add(m, 0x40), shr(96, shl(96, from)))
            mstore(add(m, 0x60), id)
            mstore(add(m, 0x80), 0x80)
            let n := mload(data)
            mstore(add(m, 0xa0), n)
            if n { pop(staticcall(gas(), 4, add(data, 0x20), n, add(m, 0xc0), n)) }
            // Revert if the call reverts.
            if iszero(call(gas(), to, 0, add(m, 0x1c), add(n, 0xa4), m, 0x20)) {
                if returndatasize() {
                    // Bubble up the revert if the call reverts.
                    returndatacopy(0x00, 0x00, returndatasize())
                    revert(0x00, returndatasize())
                }
                mstore(m, 0)
            }
            // Load the returndata and compare it.
            if iszero(eq(mload(m), shl(224, onERC721ReceivedSelector))) {
                mstore(0x00, 0xd1a57ed6) // `TransferToNonERC721ReceiverImplementer()`.
                revert(0x1c, 0x04)
            }
        }
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"rklKongsCollection","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountBalanceOverflow","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"kongId","type":"uint256"}],"name":"CallerNotOwner","type":"error"},{"inputs":[{"internalType":"uint256","name":"kongId","type":"uint256"}],"name":"KongAlreadyClaimed","type":"error"},{"inputs":[],"name":"MintNotOpen","type":"error"},{"inputs":[],"name":"MinterControllerAddressAlreadySet","type":"error"},{"inputs":[],"name":"NotAdmin","type":"error"},{"inputs":[],"name":"NotOwnerNorApproved","type":"error"},{"inputs":[],"name":"OnlyRegisteredMintersAllowed","type":"error"},{"inputs":[],"name":"TokenAlreadyExists","type":"error"},{"inputs":[],"name":"TokenDoesNotExist","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"account","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":"isApproved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"RKL_KONGS_COLLECTION","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"changeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMintOpenOnTimestamp","type":"uint256"}],"name":"changeMintOpenOnTimestamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"kongIds","type":"uint256[]"}],"name":"checkKongCanClaim","outputs":[{"internalType":"bool[]","name":"","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"offset","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"getTokensOwnedByAddress","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"kongIds","type":"uint256[]"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintOpenOnTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","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":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"isApproved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseUri","type":"string"}],"name":"setBaseUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_socksMinter","type":"address"}],"name":"setSocksMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"}]

60e060405260366080818152906200194960a03960039062000022908262000134565b503480156200003057600080fd5b506040516200197f3803806200197f833981016040819052620000539162000200565b60008054336001600160a01b031991821617909155600280549091166001600160a01b03929092169190911790556364f60d1060015562000232565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620000ba57607f821691505b602082108103620000db57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200012f57600081815260208120601f850160051c810160208610156200010a5750805b601f850160051c820191505b818110156200012b5782815560010162000116565b5050505b505050565b81516001600160401b038111156200015057620001506200008f565b6200016881620001618454620000a5565b84620000e1565b602080601f831160018114620001a05760008415620001875750858301515b600019600386901b1c1916600185901b1785556200012b565b600085815260208120601f198616915b82811015620001d157888601518255948401946001909101908401620001b0565b5085821015620001f05787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602082840312156200021357600080fd5b81516001600160a01b03811681146200022b57600080fd5b9392505050565b61170780620002426000396000f3fe6080604052600436106101405760003560e01c8063750d0c68116100b6578063c87b56dd1161006f578063c87b56dd146103c0578063c964ec24146103e0578063d7d98eed1461040d578063de836ebd1461042d578063e985e9c51461044d578063f851a4401461048357600080fd5b8063750d0c68146103095780638f2839701461031f57806395d89b411461033f578063a0bcfc7f1461036d578063a22cb4651461038d578063b88d4fde146103ad57600080fd5b806342842e0e1161010857806342842e0e1461023b5780634dbab6ff1461024e5780635c3845071461026e5780636352211e1461029b57806368e3bf71146102bb57806370a08231146102db57600080fd5b806301ffc9a71461014557806306fdde0314610197578063081812fc146101db578063095ea7b31461021357806323b872dd14610228575b600080fd5b34801561015157600080fd5b50610182610160366004610ffb565b6301ffc9a760e09190911c9081146380ac58cd821417635b5e139f9091141790565b60405190151581526020015b60405180910390f35b3480156101a357600080fd5b50604080518082019091526012815271524b4c2078205374616e636520426f78657360701b60208201525b60405161018e9190611025565b3480156101e757600080fd5b506101fb6101f6366004611073565b6104a3565b6040516001600160a01b03909116815260200161018e565b6102266102213660046110a4565b6104e6565b005b6102266102363660046110d0565b6104f5565b6102266102493660046110d0565b61060c565b34801561025a57600080fd5b506002546101fb906001600160a01b031681565b34801561027a57600080fd5b5061028e61028936600461115d565b610639565b60405161018e919061119f565b3480156102a757600080fd5b506101fb6102b6366004611073565b610722565b3480156102c757600080fd5b506102266102d6366004611073565b610760565b3480156102e757600080fd5b506102fb6102f63660046111e5565b610790565b60405190815260200161018e565b34801561031557600080fd5b506102fb60015481565b34801561032b57600080fd5b5061022661033a3660046111e5565b6107cb565b34801561034b57600080fd5b506040805180820190915260058152642925a629a160d91b60208201526101ce565b34801561037957600080fd5b50610226610388366004611244565b610818565b34801561039957600080fd5b506102266103a8366004611288565b610850565b6102266103bb3660046112c1565b6108a6565b3480156103cc57600080fd5b506101ce6103db366004611073565b610901565b3480156103ec57600080fd5b506104006103fb366004611334565b6109b4565b60405161018e9190611369565b34801561041957600080fd5b506102266104283660046111e5565b610b2c565b34801561043957600080fd5b506102266104483660046113a1565b610b79565b34801561045957600080fd5b506101826104683660046113f6565b601c52670a5a2e7a000000006008526000526030600c205490565b34801561048f57600080fd5b506000546101fb906001600160a01b031681565b6000818152673ec412a9852d173d60c11b601c52602081208201820180546001600160a01b03166104dc5763ceea21b66000526004601cfd5b6001015492915050565b6104f1338383610c04565b5050565b6000818152673ec412a9852d173d60c11b3317601c52602090208101810180546001600160a01b03948516949384169381169190828614830261055357826105455763ceea21b66000526004601cfd5b63a11481006000526004601cfd5b846105665763ea553b346000526004601cfd5b856000528160010154925082331486331417610594576030600c205461059457634b6e7f186000526004601cfd5b82156105a257600082600101555b85851818905550601c600c8181208054600019019055600084905220805460010163ffffffff81166105dc576301336cea6000526004601cfd5b90558082847fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a45b505050565b6106178383836104f5565b813b156106075761060783838360405180602001604052806000815250610ca5565b606060008267ffffffffffffffff81111561065657610656611424565b60405190808252806020026020018201604052801561067f578160200160208202803683370190505b50905060005b83811015610718576106b98585838181106106a2576106a261143a565b905060200201356006610d3790919063ffffffff16565b15156001036106eb5760008282815181106106d6576106d661143a565b91151560209283029190910190910152610710565b60018282815181106106ff576106ff61143a565b911515602092830291909101909101525b600101610685565b5090505b92915050565b6000818152673ec412a9852d173d60c11b601c526020902081018101546001600160a01b03168061075b5763ceea21b66000526004601cfd5b919050565b6000546001600160a01b0316331461078b57604051637bfa4b9f60e01b815260040160405180910390fd5b600155565b6000816107a557638f4eb6046000526004601cfd5b673ec412a9852d173d60c11b601c528160005263ffffffff601c600c2054169050919050565b6000546001600160a01b031633146107f657604051637bfa4b9f60e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b0316331461084357604051637bfa4b9f60e01b815260040160405180910390fd5b60036106078284836114d0565b801515905081601c52670a5a2e7a0000000060085233600052806030600c2055806000528160601b60601c337f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160206000a35050565b6108b18585856104f5565b833b156108fa576108fa85858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ca592505050565b5050505050565b60048054604051636d32365360e11b81529182018390526060916001600160a01b039091169063da646ca690602401602060405180830381865afa15801561094d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109719190611590565b15156001036109a257600360405160200161098c9190611620565b6040516020818303038152906040529050919050565b600360405160200161098c9190611648565b606060006109c185610790565b90508015806109d05750808410155b156109eb575050604080516000815260208101909152610b25565b60006109f78583611688565b90506000848211610a085781610a0a565b845b905060008167ffffffffffffffff811115610a2757610a27611424565b604051908082528060200260200182016040528015610a50578160200160208202803683370190505b5090506000805b83821015610b1c576040516331a9108f60e11b8152600481018290523090636352211e90602401602060405180830381865afa925050508015610ab7575060408051601f3d908101601f19168201909252610ab49181019061169b565b60015b15610b0a578a6001600160a01b0316816001600160a01b031603610b0857898210610b085781848481518110610aef57610aef61143a565b602090810291909101015282610b04816116b8565b9350505b505b80610b14816116b8565b915050610a57565b50909450505050505b9392505050565b6000546001600160a01b03163314610b5757604051637bfa4b9f60e01b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b610b81610d5b565b610b8b8282610d80565b610b958282610def565b610bd5828280806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250600693925050610ed89050565b60005b81811015610bfe57610bec84600554610f4d565b60058054600190810190915501610bd8565b50505050565b60001960601c828116925083811693508160005283673ec412a9852d173d60c11b17601c5260206000208201820180548216915081610c4b5763ceea21b66000526004601cfd5b818514851517610c7157816000526030600c2054610c7157634b6e7f186000526004601cfd5b6001018390558183827f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600080a450505050565b60405163150b7a028082523360208301528560601b60601c604083015283606083015260808083015282518060a08401528015610cec578060c08401826020870160045afa505b60208360a48301601c860160008a5af1610d15573d15610d10573d6000803e3d6000fd5b600083525b508060e01b825114610d2f5763d1a57ed66000526004601cfd5b505050505050565b600881901c600090815260208390526040902054600160ff83161b16151592915050565b600154421015610d7e5760405163951b974f60e01b815260040160405180910390fd5b565b60005b8181101561060757610da08383838181106106a2576106a261143a565b1515600103610de757828282818110610dbb57610dbb61143a565b90506020020135604051633f67342f60e21b8152600401610dde91815260200190565b60405180910390fd5b600101610d83565b60005b81811015610607576002546001600160a01b0316636352211e848484818110610e1d57610e1d61143a565b905060200201356040518263ffffffff1660e01b8152600401610e4291815260200190565b602060405180830381865afa158015610e5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e83919061169b565b6001600160a01b0316336001600160a01b031614610ed057828282818110610ead57610ead61143a565b9050602002013560405163c9cd77cf60e01b8152600401610dde91815260200190565b600101610df2565b60008060005b83518110156108fa576008848281518110610efb57610efb61143a565b6020026020010151901c9250838181518110610f1957610f1961143a565b60209081029190910181015160008581529187905260409091208054600160ff90931683901b908117909155925001610ede565b6001600160a01b039091169081610f6c5763ea553b346000526004601cfd5b80600052673ec412a9852d173d60c11b601c5260206000208101810180548060601b15610fa15763c991cbb16000526004601cfd5b831790556000829052601c600c20805460010163ffffffff8116610fcd576301336cea6000526004601cfd5b9055808260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a45050565b60006020828403121561100d57600080fd5b81356001600160e01b031981168114610b2557600080fd5b600060208083528351808285015260005b8181101561105257858101830151858201604001528201611036565b506000604082860101526040601f19601f8301168501019250505092915050565b60006020828403121561108557600080fd5b5035919050565b6001600160a01b03811681146110a157600080fd5b50565b600080604083850312156110b757600080fd5b82356110c28161108c565b946020939093013593505050565b6000806000606084860312156110e557600080fd5b83356110f08161108c565b925060208401356111008161108c565b929592945050506040919091013590565b60008083601f84011261112357600080fd5b50813567ffffffffffffffff81111561113b57600080fd5b6020830191508360208260051b850101111561115657600080fd5b9250929050565b6000806020838503121561117057600080fd5b823567ffffffffffffffff81111561118757600080fd5b61119385828601611111565b90969095509350505050565b6020808252825182820181905260009190848201906040850190845b818110156111d95783511515835292840192918401916001016111bb565b50909695505050505050565b6000602082840312156111f757600080fd5b8135610b258161108c565b60008083601f84011261121457600080fd5b50813567ffffffffffffffff81111561122c57600080fd5b60208301915083602082850101111561115657600080fd5b6000806020838503121561125757600080fd5b823567ffffffffffffffff81111561126e57600080fd5b61119385828601611202565b80151581146110a157600080fd5b6000806040838503121561129b57600080fd5b82356112a68161108c565b915060208301356112b68161127a565b809150509250929050565b6000806000806000608086880312156112d957600080fd5b85356112e48161108c565b945060208601356112f48161108c565b935060408601359250606086013567ffffffffffffffff81111561131757600080fd5b61132388828901611202565b969995985093965092949392505050565b60008060006060848603121561134957600080fd5b83356113548161108c565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b818110156111d957835183529284019291840191600101611385565b6000806000604084860312156113b657600080fd5b83356113c18161108c565b9250602084013567ffffffffffffffff8111156113dd57600080fd5b6113e986828701611111565b9497909650939450505050565b6000806040838503121561140957600080fd5b82356114148161108c565b915060208301356112b68161108c565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600181811c9082168061146457607f821691505b60208210810361148457634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561060757600081815260208120601f850160051c810160208610156114b15750805b601f850160051c820191505b81811015610d2f578281556001016114bd565b67ffffffffffffffff8311156114e8576114e8611424565b6114fc836114f68354611450565b8361148a565b6000601f84116001811461153057600085156115185750838201355b600019600387901b1c1916600186901b1783556108fa565b600083815260209020601f19861690835b828110156115615786850135825560209485019460019092019101611541565b508682101561157e5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6000602082840312156115a257600080fd5b8151610b258161127a565b600081546115ba81611450565b600182811680156115d257600181146115e757611616565b60ff1984168752821515830287019450611616565b8560005260208060002060005b8581101561160d5781548a8201529084019082016115f4565b50505082870194505b5050505092915050565b600061162c82846115ad565b6b37b832b73137bc173539b7b760a11b8152600c019392505050565b600061165482846115ad565b6d31b637b9b2b23137bc173539b7b760911b8152600e019392505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561071c5761071c611672565b6000602082840312156116ad57600080fd5b8151610b258161108c565b6000600182016116ca576116ca611672565b506001019056fea2646970667358221220cc76004c48162034f67492815a550d65be8b34c43db2af943e58ea351beeec9764736f6c63430008140033697066733a2f2f516d596a47505857626e6d587062356753424d384d44616f3851356a54584a6556544b41397433693635597337532f000000000000000000000000ef0182dc0574cd5874494a120750fd222fdb909a

Deployed Bytecode

0x6080604052600436106101405760003560e01c8063750d0c68116100b6578063c87b56dd1161006f578063c87b56dd146103c0578063c964ec24146103e0578063d7d98eed1461040d578063de836ebd1461042d578063e985e9c51461044d578063f851a4401461048357600080fd5b8063750d0c68146103095780638f2839701461031f57806395d89b411461033f578063a0bcfc7f1461036d578063a22cb4651461038d578063b88d4fde146103ad57600080fd5b806342842e0e1161010857806342842e0e1461023b5780634dbab6ff1461024e5780635c3845071461026e5780636352211e1461029b57806368e3bf71146102bb57806370a08231146102db57600080fd5b806301ffc9a71461014557806306fdde0314610197578063081812fc146101db578063095ea7b31461021357806323b872dd14610228575b600080fd5b34801561015157600080fd5b50610182610160366004610ffb565b6301ffc9a760e09190911c9081146380ac58cd821417635b5e139f9091141790565b60405190151581526020015b60405180910390f35b3480156101a357600080fd5b50604080518082019091526012815271524b4c2078205374616e636520426f78657360701b60208201525b60405161018e9190611025565b3480156101e757600080fd5b506101fb6101f6366004611073565b6104a3565b6040516001600160a01b03909116815260200161018e565b6102266102213660046110a4565b6104e6565b005b6102266102363660046110d0565b6104f5565b6102266102493660046110d0565b61060c565b34801561025a57600080fd5b506002546101fb906001600160a01b031681565b34801561027a57600080fd5b5061028e61028936600461115d565b610639565b60405161018e919061119f565b3480156102a757600080fd5b506101fb6102b6366004611073565b610722565b3480156102c757600080fd5b506102266102d6366004611073565b610760565b3480156102e757600080fd5b506102fb6102f63660046111e5565b610790565b60405190815260200161018e565b34801561031557600080fd5b506102fb60015481565b34801561032b57600080fd5b5061022661033a3660046111e5565b6107cb565b34801561034b57600080fd5b506040805180820190915260058152642925a629a160d91b60208201526101ce565b34801561037957600080fd5b50610226610388366004611244565b610818565b34801561039957600080fd5b506102266103a8366004611288565b610850565b6102266103bb3660046112c1565b6108a6565b3480156103cc57600080fd5b506101ce6103db366004611073565b610901565b3480156103ec57600080fd5b506104006103fb366004611334565b6109b4565b60405161018e9190611369565b34801561041957600080fd5b506102266104283660046111e5565b610b2c565b34801561043957600080fd5b506102266104483660046113a1565b610b79565b34801561045957600080fd5b506101826104683660046113f6565b601c52670a5a2e7a000000006008526000526030600c205490565b34801561048f57600080fd5b506000546101fb906001600160a01b031681565b6000818152673ec412a9852d173d60c11b601c52602081208201820180546001600160a01b03166104dc5763ceea21b66000526004601cfd5b6001015492915050565b6104f1338383610c04565b5050565b6000818152673ec412a9852d173d60c11b3317601c52602090208101810180546001600160a01b03948516949384169381169190828614830261055357826105455763ceea21b66000526004601cfd5b63a11481006000526004601cfd5b846105665763ea553b346000526004601cfd5b856000528160010154925082331486331417610594576030600c205461059457634b6e7f186000526004601cfd5b82156105a257600082600101555b85851818905550601c600c8181208054600019019055600084905220805460010163ffffffff81166105dc576301336cea6000526004601cfd5b90558082847fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a45b505050565b6106178383836104f5565b813b156106075761060783838360405180602001604052806000815250610ca5565b606060008267ffffffffffffffff81111561065657610656611424565b60405190808252806020026020018201604052801561067f578160200160208202803683370190505b50905060005b83811015610718576106b98585838181106106a2576106a261143a565b905060200201356006610d3790919063ffffffff16565b15156001036106eb5760008282815181106106d6576106d661143a565b91151560209283029190910190910152610710565b60018282815181106106ff576106ff61143a565b911515602092830291909101909101525b600101610685565b5090505b92915050565b6000818152673ec412a9852d173d60c11b601c526020902081018101546001600160a01b03168061075b5763ceea21b66000526004601cfd5b919050565b6000546001600160a01b0316331461078b57604051637bfa4b9f60e01b815260040160405180910390fd5b600155565b6000816107a557638f4eb6046000526004601cfd5b673ec412a9852d173d60c11b601c528160005263ffffffff601c600c2054169050919050565b6000546001600160a01b031633146107f657604051637bfa4b9f60e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b0316331461084357604051637bfa4b9f60e01b815260040160405180910390fd5b60036106078284836114d0565b801515905081601c52670a5a2e7a0000000060085233600052806030600c2055806000528160601b60601c337f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160206000a35050565b6108b18585856104f5565b833b156108fa576108fa85858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ca592505050565b5050505050565b60048054604051636d32365360e11b81529182018390526060916001600160a01b039091169063da646ca690602401602060405180830381865afa15801561094d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109719190611590565b15156001036109a257600360405160200161098c9190611620565b6040516020818303038152906040529050919050565b600360405160200161098c9190611648565b606060006109c185610790565b90508015806109d05750808410155b156109eb575050604080516000815260208101909152610b25565b60006109f78583611688565b90506000848211610a085781610a0a565b845b905060008167ffffffffffffffff811115610a2757610a27611424565b604051908082528060200260200182016040528015610a50578160200160208202803683370190505b5090506000805b83821015610b1c576040516331a9108f60e11b8152600481018290523090636352211e90602401602060405180830381865afa925050508015610ab7575060408051601f3d908101601f19168201909252610ab49181019061169b565b60015b15610b0a578a6001600160a01b0316816001600160a01b031603610b0857898210610b085781848481518110610aef57610aef61143a565b602090810291909101015282610b04816116b8565b9350505b505b80610b14816116b8565b915050610a57565b50909450505050505b9392505050565b6000546001600160a01b03163314610b5757604051637bfa4b9f60e01b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b610b81610d5b565b610b8b8282610d80565b610b958282610def565b610bd5828280806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250600693925050610ed89050565b60005b81811015610bfe57610bec84600554610f4d565b60058054600190810190915501610bd8565b50505050565b60001960601c828116925083811693508160005283673ec412a9852d173d60c11b17601c5260206000208201820180548216915081610c4b5763ceea21b66000526004601cfd5b818514851517610c7157816000526030600c2054610c7157634b6e7f186000526004601cfd5b6001018390558183827f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600080a450505050565b60405163150b7a028082523360208301528560601b60601c604083015283606083015260808083015282518060a08401528015610cec578060c08401826020870160045afa505b60208360a48301601c860160008a5af1610d15573d15610d10573d6000803e3d6000fd5b600083525b508060e01b825114610d2f5763d1a57ed66000526004601cfd5b505050505050565b600881901c600090815260208390526040902054600160ff83161b16151592915050565b600154421015610d7e5760405163951b974f60e01b815260040160405180910390fd5b565b60005b8181101561060757610da08383838181106106a2576106a261143a565b1515600103610de757828282818110610dbb57610dbb61143a565b90506020020135604051633f67342f60e21b8152600401610dde91815260200190565b60405180910390fd5b600101610d83565b60005b81811015610607576002546001600160a01b0316636352211e848484818110610e1d57610e1d61143a565b905060200201356040518263ffffffff1660e01b8152600401610e4291815260200190565b602060405180830381865afa158015610e5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e83919061169b565b6001600160a01b0316336001600160a01b031614610ed057828282818110610ead57610ead61143a565b9050602002013560405163c9cd77cf60e01b8152600401610dde91815260200190565b600101610df2565b60008060005b83518110156108fa576008848281518110610efb57610efb61143a565b6020026020010151901c9250838181518110610f1957610f1961143a565b60209081029190910181015160008581529187905260409091208054600160ff90931683901b908117909155925001610ede565b6001600160a01b039091169081610f6c5763ea553b346000526004601cfd5b80600052673ec412a9852d173d60c11b601c5260206000208101810180548060601b15610fa15763c991cbb16000526004601cfd5b831790556000829052601c600c20805460010163ffffffff8116610fcd576301336cea6000526004601cfd5b9055808260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a45050565b60006020828403121561100d57600080fd5b81356001600160e01b031981168114610b2557600080fd5b600060208083528351808285015260005b8181101561105257858101830151858201604001528201611036565b506000604082860101526040601f19601f8301168501019250505092915050565b60006020828403121561108557600080fd5b5035919050565b6001600160a01b03811681146110a157600080fd5b50565b600080604083850312156110b757600080fd5b82356110c28161108c565b946020939093013593505050565b6000806000606084860312156110e557600080fd5b83356110f08161108c565b925060208401356111008161108c565b929592945050506040919091013590565b60008083601f84011261112357600080fd5b50813567ffffffffffffffff81111561113b57600080fd5b6020830191508360208260051b850101111561115657600080fd5b9250929050565b6000806020838503121561117057600080fd5b823567ffffffffffffffff81111561118757600080fd5b61119385828601611111565b90969095509350505050565b6020808252825182820181905260009190848201906040850190845b818110156111d95783511515835292840192918401916001016111bb565b50909695505050505050565b6000602082840312156111f757600080fd5b8135610b258161108c565b60008083601f84011261121457600080fd5b50813567ffffffffffffffff81111561122c57600080fd5b60208301915083602082850101111561115657600080fd5b6000806020838503121561125757600080fd5b823567ffffffffffffffff81111561126e57600080fd5b61119385828601611202565b80151581146110a157600080fd5b6000806040838503121561129b57600080fd5b82356112a68161108c565b915060208301356112b68161127a565b809150509250929050565b6000806000806000608086880312156112d957600080fd5b85356112e48161108c565b945060208601356112f48161108c565b935060408601359250606086013567ffffffffffffffff81111561131757600080fd5b61132388828901611202565b969995985093965092949392505050565b60008060006060848603121561134957600080fd5b83356113548161108c565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b818110156111d957835183529284019291840191600101611385565b6000806000604084860312156113b657600080fd5b83356113c18161108c565b9250602084013567ffffffffffffffff8111156113dd57600080fd5b6113e986828701611111565b9497909650939450505050565b6000806040838503121561140957600080fd5b82356114148161108c565b915060208301356112b68161108c565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600181811c9082168061146457607f821691505b60208210810361148457634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561060757600081815260208120601f850160051c810160208610156114b15750805b601f850160051c820191505b81811015610d2f578281556001016114bd565b67ffffffffffffffff8311156114e8576114e8611424565b6114fc836114f68354611450565b8361148a565b6000601f84116001811461153057600085156115185750838201355b600019600387901b1c1916600186901b1783556108fa565b600083815260209020601f19861690835b828110156115615786850135825560209485019460019092019101611541565b508682101561157e5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6000602082840312156115a257600080fd5b8151610b258161127a565b600081546115ba81611450565b600182811680156115d257600181146115e757611616565b60ff1984168752821515830287019450611616565b8560005260208060002060005b8581101561160d5781548a8201529084019082016115f4565b50505082870194505b5050505092915050565b600061162c82846115ad565b6b37b832b73137bc173539b7b760a11b8152600c019392505050565b600061165482846115ad565b6d31b637b9b2b23137bc173539b7b760911b8152600e019392505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561071c5761071c611672565b6000602082840312156116ad57600080fd5b8151610b258161108c565b6000600182016116ca576116ca611672565b506001019056fea2646970667358221220cc76004c48162034f67492815a550d65be8b34c43db2af943e58ea351beeec9764736f6c63430008140033

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

000000000000000000000000ef0182dc0574cd5874494a120750fd222fdb909a

-----Decoded View---------------
Arg [0] : rklKongsCollection (address): 0xEf0182dc0574cd5874494a120750FD222FdB909a

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000ef0182dc0574cd5874494a120750fd222fdb909a


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.