ETH Price: $3,456.32 (-0.02%)

Contract

0x7Bb1c3a225eBA7981FAc716C14e2D4e9ca068f8D
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Approval For...213378392024-12-05 17:39:1115 days ago1733420351IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.0012017526.14221575
Set Approval For...213120352024-12-02 3:06:3518 days ago1733108795IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.0007783216.9310836
Mint210832462024-10-31 4:31:1150 days ago1730349071IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.00069347.33586348
Transfer From208450052024-09-27 22:39:1183 days ago1727476751IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.000537389.11087984
Mint207486382024-09-14 11:46:2397 days ago1726314383IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.000188771.997141
Mint206793922024-09-04 19:45:23107 days ago1725479123IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.000496923.79440883
Set Approval For...205581202024-08-18 21:12:11124 days ago1724015531IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.000056491.22897816
Transfer From204437272024-08-02 22:06:23140 days ago1722636383IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.000119593.22501924
Transfer From202096862024-07-01 5:49:23172 days ago1719812963IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.000140022.58494863
Mint201613242024-06-24 11:44:47179 days ago1719229487IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.000753393.69596527
Mint201504232024-06-22 23:09:11180 days ago1719097751IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.00028931.7793616
Set Approval For...201477232024-06-22 14:04:35181 days ago1719065075IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.000200964.36492198
Mint198299622024-05-09 3:59:59225 days ago1715227199IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.000610393.64630253
Mint197445342024-04-27 5:17:11237 days ago1714195031IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.000487125.15422933
Set Approval For...197028872024-04-21 9:28:47243 days ago1713691727IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.000339597.38730443
Mint194855692024-03-21 21:00:59274 days ago1711054859IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.0033750835.70689979
Mint193876812024-03-08 3:10:35287 days ago1709867435IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.0149057150.34660137
Mint193241542024-02-28 6:09:59296 days ago1709100599IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.0033180735.10818427
Mint193127662024-02-26 15:55:11298 days ago1708962911IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.0047186349.92099758
Safe Transfer Fr...193005232024-02-24 22:47:47299 days ago1708814867IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.0014903224.18693218
Set Approval For...193004962024-02-24 22:42:23299 days ago1708814543IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.0011897225.88053293
Mint192802732024-02-22 2:45:35302 days ago1708569935IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.0041717931.85500421
Mint192801612024-02-22 2:22:59302 days ago1708568579IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.0034920936.94482146
Mint192538632024-02-18 9:41:11306 days ago1708249271IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.0022286623.57829089
Safe Transfer Fr...192526502024-02-18 5:34:59306 days ago1708234499IN
0x7Bb1c3a2...9ca068f8D
0 ETH0.0010091916.37852414
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

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


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.