Mock NFT (MOCK)
Overview
TokenID
3
Total Transfers
-
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
MockNFT
Compiler Version
v0.8.28+commit.7893614a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {ERC721} from "solady/tokens/ERC721.sol"; import {IShadowCallbackReceiver} from "../../src/interfaces/IShadowCallbackReceiver.sol"; contract MockNFT is ERC721 { mapping(uint256 => bool) public locked; uint256 private iterator; function name() public pure override returns (string memory) { return "Mock NFT"; } function symbol() public pure override returns (string memory) { return "MOCK"; } function tokenURI(uint256) public pure override returns (string memory) { return ""; } function mint(address to, uint256 tokenId) public returns (uint256) { _mint(to, tokenId); return tokenId; } function setLocked(uint256 tokenId, bool isLocked) public { locked[tokenId] = isLocked; } function readWithCallback(uint256[] calldata tokenIds, uint32[] calldata, uint128) external payable returns (bytes32) { // Simple mock implementation - just return a deterministic guid bytes32 guid = keccak256(abi.encodePacked(block.timestamp, tokenIds, ++iterator)); // Execute callback immediately for testing purposes IShadowCallbackReceiver(msg.sender).executeCallback(guid); return guid; } function tokensOfOwnerIn(address owner, uint256 start, uint256 stop) external view returns (uint256[] memory) { uint256 numberOfTokens = balanceOf(owner); uint256 tokenIdIdx = 0; uint256[] memory tokenIds = new uint256[](numberOfTokens); for (uint256 i = start; i <= stop; i++) { if (_ownerOf(i) == owner) { tokenIds[tokenIdIdx] = i; unchecked { tokenIdIdx++; } if (tokenIdIdx == numberOfTokens) { return tokenIds; } } } // in case we did not find all the tokens within this start/stop, we need to resize the array uint256[] memory result = new uint256[](tokenIdIdx); for (uint256 i = 0; i < tokenIdIdx; i++) { result[i] = tokenIds[i]; } return result; } }
// 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) /// /// @dev 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. /// - For performance, methods are made payable where permitted by the ERC721 standard. /// - The `safeTransfer` functions use the identity precompile (0x4) /// to copy memory internally. /// /// If you are overriding: /// - NEVER violate the ERC721 invariant: /// the balance of an owner MUST always be equal to their number of ownership slots. /// The transfer functions do not have an underflow guard for user token balances. /// - Make sure all variables written to storage are properly cleaned /// (e.g. the bool value for `isApprovedForAll` MUST be either 1 or 0 under the hood). /// - Check that the overridden function is actually used in the function you want to /// change the behavior of. Much of the code has been manually inlined for performance. 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..255] `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..255] `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 manage 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(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 an {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 an {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) // forgefmt: disable-next-item 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 the token does not exist, or if `from` is not the owner. if iszero(mul(owner, eq(owner, from))) { // `TokenDoesNotExist()`, `TransferFromIncorrectOwner()`. mstore(shl(2, iszero(owner)), 0xceea21b6a1148100) 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 p := sload(toBalanceSlot) // `toBalanceSlotPacked`. // Revert if `to` is the zero address, or if the account balance is maxed. if iszero(mul(to, xor(and(p, _MAX_ACCOUNT_BALANCE), _MAX_ACCOUNT_BALANCE))) { // `TransferToZeroAddress()`, `AccountBalanceOverflow()`. mstore(shl(2, iszero(to)), 0xea553b3401336cea) revert(0x1c, 0x04) } sstore(toBalanceSlot, add(1, p)) } // Emit the {Transfer} event. log4(codesize(), 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 := iszero(iszero(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 */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ // For performance, no events are emitted for the hitchhiking setters. // Please emit your own events if required. /// @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)) // 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 p := sload(balanceSlot) // `balanceSlotPacked`. // Revert if `to` is the zero address, or if the account balance is maxed. if iszero(mul(to, xor(and(p, _MAX_ACCOUNT_BALANCE), _MAX_ACCOUNT_BALANCE))) { // `TransferToZeroAddress()`, `AccountBalanceOverflow()`. mstore(shl(2, iszero(to)), 0xea553b3401336cea) revert(0x1c, 0x04) } sstore(balanceSlot, add(1, p)) } // Emit the {Transfer} event. log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, 0, to, id) } _afterTokenTransfer(address(0), to, id); } /// @dev Mints token `id` to `to`, and updates the extra data for token `id` to `value`. /// Does NOT check if token `id` already exists (assumes `id` is auto-incrementing). /// /// Requirements: /// /// - `to` cannot be the zero address. /// /// Emits a {Transfer} event. function _mintAndSetExtraDataUnchecked(address to, uint256 id, uint96 value) internal virtual { _beforeTokenTransfer(address(0), to, id); /// @solidity memory-safe-assembly assembly { // Clear the upper 96 bits. to := shr(96, shl(96, to)) // Update with the owner and extra data. mstore(0x00, id) mstore(0x1c, _ERC721_MASTER_SLOT_SEED) sstore(add(id, add(id, keccak256(0x00, 0x20))), or(shl(160, value), to)) // Increment the balance of the owner. { mstore(0x00, to) let balanceSlot := keccak256(0x0c, 0x1c) let p := sload(balanceSlot) // `balanceSlotPacked`. // Revert if `to` is the zero address, or if the account balance is maxed. if iszero(mul(to, xor(and(p, _MAX_ACCOUNT_BALANCE), _MAX_ACCOUNT_BALANCE))) { // `TransferToZeroAddress()`, `AccountBalanceOverflow()`. mstore(shl(2, iszero(to)), 0xea553b3401336cea) revert(0x1c, 0x04) } sstore(balanceSlot, add(1, p)) } // Emit the {Transfer} event. log4(codesize(), 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(codesize(), 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 manage 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 manage the token. 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 {Approval} 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(codesize(), 0x00, _APPROVAL_EVENT_SIGNATURE, owner, account, id) } } /// @dev Approve or remove the `operator` as an operator for `by`, /// without authorization checks. /// /// Emits an {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 the token does not exist, or if `from` is not the owner. if iszero(mul(owner, eq(owner, from))) { // `TokenDoesNotExist()`, `TransferFromIncorrectOwner()`. mstore(shl(2, iszero(owner)), 0xceea21b6a1148100) 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 p := sload(toBalanceSlot) // `toBalanceSlotPacked`. // Revert if `to` is the zero address, or if the account balance is maxed. if iszero(mul(to, xor(and(p, _MAX_ACCOUNT_BALANCE), _MAX_ACCOUNT_BALANCE))) { // `TransferToZeroAddress()`, `AccountBalanceOverflow()`. mstore(shl(2, iszero(to)), 0xea553b3401336cea) revert(0x1c, 0x04) } sstore(toBalanceSlot, add(1, p)) } // Emit the {Transfer} event. log4(codesize(), 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(m, 0x00, returndatasize()) revert(m, returndatasize()) } } // Load the returndata and compare it. if iszero(eq(mload(m), shl(224, onERC721ReceivedSelector))) { mstore(0x00, 0xd1a57ed6) // `TransferToNonERC721ReceiverImplementer()`. revert(0x1c, 0x04) } } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.28; interface IShadowCallbackReceiver { function executeCallback(bytes32 guid) external; }
{ "remappings": [ "solady/=lib/solady/src/", "forge-std/=lib/forge-std/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "evmVersion": "cancun", "viaIR": true, "libraries": {} }
Contract ABI
API[{"inputs":[],"name":"AccountBalanceOverflow","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"NotOwnerNorApproved","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":[{"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":"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":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"locked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","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":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint32[]","name":"","type":"uint32[]"},{"internalType":"uint128","name":"","type":"uint128"}],"name":"readWithCallback","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"payable","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":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bool","name":"isLocked","type":"bool"}],"name":"setLocked","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":"","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
60808060405234601557610cc0908161001a8239f35b5f80fdfe60806040526004361015610011575f80fd5b5f3560e01c806301ffc9a71461013457806306fdde031461012f578063081812fc1461012a578063095ea7b3146101255780630a3cc9891461012057806323b872dd1461011b57806340c10f191461011657806342842e0e146101115780636352211e1461010c57806370a082311461010757806395d89b411461010257806399a2557a146100fd578063a22cb465146100f8578063b45a3c0e146100f3578063b88d4fde146100ee578063c87b56dd146100e9578063e985e9c5146100e45763f7dec9b4146100df575f80fd5b6107a5565b610730565b6106ff565b610694565b610666565b6105f7565b61058b565b61054d565b610522565b6104cf565b610496565b6103c8565b6103b4565b610340565b610289565b6101ff565b6101b9565b34610181576020366003190112610181576004356001600160e01b0319811681036101815760209060e01c60405190635b5e139f8114906301ffc9a76380ac58cd82149114171715158152f35b5f80fd5b5f91031261018157565b602060409281835280519182918282860152018484015e5f828201840152601f01601f1916010190565b34610181575f366003190112610181576101fb6040516101da6040826108c5565b6008815267135bd8dac813919560c21b60208201526040519182918261018f565b0390f35b34610181576020366003190112610181576004355f818152673ec412a9852d173d60c11b601c5260209020810101805460601b1561025057600101546040516001600160a01b039091168152602090f35b63ceea21b65f526004601cfd5b600435906001600160a01b038216820361018157565b602435906001600160a01b038216820361018157565b60403660031901126101815761029d61025d565b6024355f818152673ec412a9852d173d60c11b3317601c526020902081018101805491926001600160a01b0390811692169081156102505782908233143315171561030d575b600101557f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9255f80a4005b9050815f526030600c2054156103245782906102e3565b634b6e7f185f526004601cfd5b60243590811515820361018157565b346101815760403660031901126101815760043561035c610331565b905f525f60205260405f209060ff8019835416911515161790555f80f35b6060906003190112610181576004356001600160a01b038116810361018157906024356001600160a01b0381168103610181579060443590565b6103c66103c03661037a565b916108ec565b005b34610181576040366003190112610181576103e161025d565b6024355f818152673ec412a9852d173d60c11b601c52602090208101810180546001600160a01b0390931692606081901b6104895783179055815f52601c600c20805463ffffffff808216188402156104745760010190556101fb9181905f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a46040519081529081906020820190565b67ea553b3401336cea841560021b526004601cfd5b63c991cbb15f526004601cfd5b61049f3661037a565b6104ac81838594956108ec565b823b6104b457005b6103c692604051926104c76020856108c5565b5f8452610bf8565b34610181576020366003190112610181576004355f818152673ec412a9852d173d60c11b601c5260209020810101546001600160a01b03168015610250576040516001600160a01b039091168152602090f35b3461018157602036600319011261018157602061054561054061025d565b6109d0565b604051908152f35b34610181575f366003190112610181576101fb60405161056e6040826108c5565b60048152634d4f434b60e01b60208201526040519182918261018f565b34610181576060366003190112610181576105b36105a761025d565b60243560443591610a97565b6040518091602082016020835281518091526020604084019201905f5b8181106105de575050500390f35b82518452859450602093840193909201916001016105d0565b346101815760403660031901126101815761061061025d565b610618610331565b151581601c52670a5a2e7a00000000600852335f52806030600c20555f5260018060a01b0316337f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160205fa3005b34610181576020366003190112610181576004355f525f602052602060ff60405f2054166040519015158152f35b6080366003190112610181576106a861025d565b6106b0610273565b6064359160443567ffffffffffffffff841161018157366023850112156101815783600401359267ffffffffffffffff84116101815736602485870101116101815760246103c6950192610b53565b34610181576020366003190112610181576101fb6040516107216020826108c5565b5f81526040519182918261018f565b346101815760403660031901126101815761074961025d565b610751610273565b601c52670a5a2e7a000000006008525f5260206030600c20546040519015158152f35b9181601f840112156101815782359167ffffffffffffffff8311610181576020808501948460051b01011161018157565b60603660031901126101815760043567ffffffffffffffff8111610181576107d1903690600401610774565b60243567ffffffffffffffff8111610181576107f1903690600401610774565b50506044356fffffffffffffffffffffffffffffffff8116036101815761084961081c600154610a4d565b9161082683600155565b61083b60405193849260208401964288610bc1565b03601f1981018352826108c5565b519020333b156101815760405163163b5cc360e31b815260048101829052905f8260248183335af19182156108ac576101fb92610892575b506040519081529081906020820190565b806108a05f6108a6936108c5565b80610185565b5f610881565b610bed565b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff8211176108e757604052565b6108b1565b5f838152673ec412a9852d173d60c11b3317601c52602090208301830180546001600160a01b03938416939283169281168084148102156109bb5750825f5281600101805480331485331417156109a4575b61099b575b50838318189055601c600c205f198154019055815f52601c600c20805463ffffffff808216188402156104745760010190557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4565b5f90555f610943565b6030600c205461093e57634b6e7f185f526004601cfd5b67ceea21b6a1148100901560021b526004601cfd5b80156109f657673ec412a9852d173d60c11b601c525f5263ffffffff601c600c20541690565b638f4eb6045f526004601cfd5b67ffffffffffffffff81116108e75760051b60200190565b90610a2582610a03565b610a3260405191826108c5565b8281528092610a43601f1991610a03565b0190602036910137565b5f198114610a5b5760010190565b634e487b7160e01b5f52601160045260245ffd5b8051821015610a835760209160051b010190565b634e487b7160e01b5f52603260045260245ffd5b909291610aa3826109d0565b5f92610aae82610a1b565b955b83811115610af55750505050610ac581610a1b565b905f5b818110610ad6575090925050565b80610ae360019287610a6f565b51610aee8286610a6f565b5201610ac8565b5f818152673ec412a9852d173d60c11b601c526020902081018101546001600160a01b03838116911614610b32575b610b2d90610a4d565b610ab0565b938085610b416001938a610a6f565b520193828503610b24575b5050505050565b939293610b618383836108ec565b813b610b6e575050505050565b67ffffffffffffffff84116108e75760405193610b95601f8201601f1916602001866108c5565b8085523681870111610181576020815f92610bb7988389013786010152610bf8565b5f80808080610b4c565b9081529192916001600160fb1b0384116101815760409360051b80926020830137019060208201520190565b6040513d5f823e3d90fd5b9060a46020939460405195869463150b7a028652338787015260018060a01b03166040860152606085015260808085015280518091818060a0880152610c76575b505001905f601c8401915af115610c68575b5163757a42ff60e11b01610c5b57565b63d1a57ed65f526004601cfd5b3d15610c4b573d5f823e3d90fd5b818760c08801920160045afa50805f610c3956fea2646970667358221220476aa2966ab9591ad5d81fdf99f725f1fdf28d0bbb9ae13955bc878b99106fc664736f6c634300081c0033
Deployed Bytecode
0x60806040526004361015610011575f80fd5b5f3560e01c806301ffc9a71461013457806306fdde031461012f578063081812fc1461012a578063095ea7b3146101255780630a3cc9891461012057806323b872dd1461011b57806340c10f191461011657806342842e0e146101115780636352211e1461010c57806370a082311461010757806395d89b411461010257806399a2557a146100fd578063a22cb465146100f8578063b45a3c0e146100f3578063b88d4fde146100ee578063c87b56dd146100e9578063e985e9c5146100e45763f7dec9b4146100df575f80fd5b6107a5565b610730565b6106ff565b610694565b610666565b6105f7565b61058b565b61054d565b610522565b6104cf565b610496565b6103c8565b6103b4565b610340565b610289565b6101ff565b6101b9565b34610181576020366003190112610181576004356001600160e01b0319811681036101815760209060e01c60405190635b5e139f8114906301ffc9a76380ac58cd82149114171715158152f35b5f80fd5b5f91031261018157565b602060409281835280519182918282860152018484015e5f828201840152601f01601f1916010190565b34610181575f366003190112610181576101fb6040516101da6040826108c5565b6008815267135bd8dac813919560c21b60208201526040519182918261018f565b0390f35b34610181576020366003190112610181576004355f818152673ec412a9852d173d60c11b601c5260209020810101805460601b1561025057600101546040516001600160a01b039091168152602090f35b63ceea21b65f526004601cfd5b600435906001600160a01b038216820361018157565b602435906001600160a01b038216820361018157565b60403660031901126101815761029d61025d565b6024355f818152673ec412a9852d173d60c11b3317601c526020902081018101805491926001600160a01b0390811692169081156102505782908233143315171561030d575b600101557f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9255f80a4005b9050815f526030600c2054156103245782906102e3565b634b6e7f185f526004601cfd5b60243590811515820361018157565b346101815760403660031901126101815760043561035c610331565b905f525f60205260405f209060ff8019835416911515161790555f80f35b6060906003190112610181576004356001600160a01b038116810361018157906024356001600160a01b0381168103610181579060443590565b6103c66103c03661037a565b916108ec565b005b34610181576040366003190112610181576103e161025d565b6024355f818152673ec412a9852d173d60c11b601c52602090208101810180546001600160a01b0390931692606081901b6104895783179055815f52601c600c20805463ffffffff808216188402156104745760010190556101fb9181905f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a46040519081529081906020820190565b67ea553b3401336cea841560021b526004601cfd5b63c991cbb15f526004601cfd5b61049f3661037a565b6104ac81838594956108ec565b823b6104b457005b6103c692604051926104c76020856108c5565b5f8452610bf8565b34610181576020366003190112610181576004355f818152673ec412a9852d173d60c11b601c5260209020810101546001600160a01b03168015610250576040516001600160a01b039091168152602090f35b3461018157602036600319011261018157602061054561054061025d565b6109d0565b604051908152f35b34610181575f366003190112610181576101fb60405161056e6040826108c5565b60048152634d4f434b60e01b60208201526040519182918261018f565b34610181576060366003190112610181576105b36105a761025d565b60243560443591610a97565b6040518091602082016020835281518091526020604084019201905f5b8181106105de575050500390f35b82518452859450602093840193909201916001016105d0565b346101815760403660031901126101815761061061025d565b610618610331565b151581601c52670a5a2e7a00000000600852335f52806030600c20555f5260018060a01b0316337f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160205fa3005b34610181576020366003190112610181576004355f525f602052602060ff60405f2054166040519015158152f35b6080366003190112610181576106a861025d565b6106b0610273565b6064359160443567ffffffffffffffff841161018157366023850112156101815783600401359267ffffffffffffffff84116101815736602485870101116101815760246103c6950192610b53565b34610181576020366003190112610181576101fb6040516107216020826108c5565b5f81526040519182918261018f565b346101815760403660031901126101815761074961025d565b610751610273565b601c52670a5a2e7a000000006008525f5260206030600c20546040519015158152f35b9181601f840112156101815782359167ffffffffffffffff8311610181576020808501948460051b01011161018157565b60603660031901126101815760043567ffffffffffffffff8111610181576107d1903690600401610774565b60243567ffffffffffffffff8111610181576107f1903690600401610774565b50506044356fffffffffffffffffffffffffffffffff8116036101815761084961081c600154610a4d565b9161082683600155565b61083b60405193849260208401964288610bc1565b03601f1981018352826108c5565b519020333b156101815760405163163b5cc360e31b815260048101829052905f8260248183335af19182156108ac576101fb92610892575b506040519081529081906020820190565b806108a05f6108a6936108c5565b80610185565b5f610881565b610bed565b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff8211176108e757604052565b6108b1565b5f838152673ec412a9852d173d60c11b3317601c52602090208301830180546001600160a01b03938416939283169281168084148102156109bb5750825f5281600101805480331485331417156109a4575b61099b575b50838318189055601c600c205f198154019055815f52601c600c20805463ffffffff808216188402156104745760010190557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4565b5f90555f610943565b6030600c205461093e57634b6e7f185f526004601cfd5b67ceea21b6a1148100901560021b526004601cfd5b80156109f657673ec412a9852d173d60c11b601c525f5263ffffffff601c600c20541690565b638f4eb6045f526004601cfd5b67ffffffffffffffff81116108e75760051b60200190565b90610a2582610a03565b610a3260405191826108c5565b8281528092610a43601f1991610a03565b0190602036910137565b5f198114610a5b5760010190565b634e487b7160e01b5f52601160045260245ffd5b8051821015610a835760209160051b010190565b634e487b7160e01b5f52603260045260245ffd5b909291610aa3826109d0565b5f92610aae82610a1b565b955b83811115610af55750505050610ac581610a1b565b905f5b818110610ad6575090925050565b80610ae360019287610a6f565b51610aee8286610a6f565b5201610ac8565b5f818152673ec412a9852d173d60c11b601c526020902081018101546001600160a01b03838116911614610b32575b610b2d90610a4d565b610ab0565b938085610b416001938a610a6f565b520193828503610b24575b5050505050565b939293610b618383836108ec565b813b610b6e575050505050565b67ffffffffffffffff84116108e75760405193610b95601f8201601f1916602001866108c5565b8085523681870111610181576020815f92610bb7988389013786010152610bf8565b5f80808080610b4c565b9081529192916001600160fb1b0384116101815760409360051b80926020830137019060208201520190565b6040513d5f823e3d90fd5b9060a46020939460405195869463150b7a028652338787015260018060a01b03166040860152606085015260808085015280518091818060a0880152610c76575b505001905f601c8401915af115610c68575b5163757a42ff60e11b01610c5b57565b63d1a57ed65f526004601cfd5b3d15610c4b573d5f823e3d90fd5b818760c08801920160045afa50805f610c3956fea2646970667358221220476aa2966ab9591ad5d81fdf99f725f1fdf28d0bbb9ae13955bc878b99106fc664736f6c634300081c0033
Deployed Bytecode Sourcemap
198:2043:1:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;;;;;-1:-1:-1;;198:2043:1;;;;;;-1:-1:-1;;;;;;198:2043:1;;;;;;;15004:232:0;;;198:2043:1;;15004:232:0;;;;;;;;;;;;;198:2043:1;;;;;;-1:-1:-1;198:2043:1;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;198:2043:1;;;;:::o;:::-;;;;;;-1:-1:-1;;198:2043:1;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;198:2043:1;;;;;;;;;;;:::i;:::-;;;;;;;;;;-1:-1:-1;;198:2043:1;;;;;;-1:-1:-1;8230:395:0;;;-1:-1:-1;;;8230:395:0;;198:2043:1;8230:395:0;;;;;;;;;;;;;;;198:2043:1;;-1:-1:-1;;;;;198:2043:1;;;;;;;;8230:395:0;;-1:-1:-1;8230:395:0;198:2043:1;8230:395:0;;198:2043:1;;;;-1:-1:-1;;;;;198:2043:1;;;;;;:::o;:::-;;;;-1:-1:-1;;;;;198:2043:1;;;;;;:::o;:::-;;;-1:-1:-1;;198:2043:1;;;;;;:::i;:::-;;;-1:-1:-1;29127:1350:0;;;-1:-1:-1;;;9013:10:0;29127:1350;;;198:2043:1;29127:1350:0;;;;;;;;198:2043:1;;-1:-1:-1;;;;;29127:1350:0;;;;;;;;;;9013:10;;;;29127:1350;9013:10;29127:1350;;;;;198:2043:1;29127:1350:0;;;;-1:-1:-1;29127:1350:0;;198:2043:1;29127:1350:0;;;;-1:-1:-1;29127:1350:0;;;;;;;;;;;;;;-1:-1:-1;29127:1350:0;198:2043:1;29127:1350:0;;198:2043:1;;;;;;;;;;;:::o;:::-;;;;;;-1:-1:-1;;198:2043:1;;;;;;;;:::i;:::-;;-1:-1:-1;198:2043:1;-1:-1:-1;198:2043:1;;;-1:-1:-1;198:2043:1;;;;;;;;;;;;;;;-1:-1:-1;198:2043:1;;;;;;;;;;;;;-1:-1:-1;;;;;198:2043:1;;;;;;;;;-1:-1:-1;;;;;198:2043:1;;;;;;;;;;:::o;:::-;;;;;:::i;:::-;;;:::i;:::-;;;;;;;;-1:-1:-1;;198:2043:1;;;;;;:::i;:::-;;;-1:-1:-1;19766:1441:0;;;-1:-1:-1;;;19766:1441:0;;198:2043:1;19766:1441:0;;;;;;;;-1:-1:-1;;;;;19766:1441:0;;;;;;;;;;;;;;;-1:-1:-1;19766:1441:0;;;;;;;;;;;;;;;;;;;;198:2043:1;;19766:1441:0;;-1:-1:-1;19766:1441:0;-1:-1:-1;;19766:1441:0;198:2043:1;;;;;;;;;;;;;19766:1441:0;;;;;;;198:2043:1;19766:1441:0;;;;-1:-1:-1;19766:1441:0;198:2043:1;19766:1441:0;;198:2043:1;;;;:::i;:::-;13823:2:0;;;;;;;:::i;:::-;38334:89;;13836:58;;198:2043:1;13836:58:0;13854:40;198:2043:1;;;;;;;;:::i;:::-;;;;13854:40:0;:::i;198:2043:1:-;;;;;;-1:-1:-1;;198:2043:1;;;;;;16165:187:0;;;;-1:-1:-1;;;16165:187:0;;;;;;;;;-1:-1:-1;;;;;16165:187:0;7115:168;;;;198:2043:1;;-1:-1:-1;;;;;198:2043:1;;;;;;;;;;;;;;-1:-1:-1;;198:2043:1;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;198:2043:1;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;198:2043:1;;;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;198:2043:1;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;198:2043:1;;;;;;;;;;;;;;;;;;;-1:-1:-1;198:2043:1;;;;;;;;;;;;;;;;;;;-1:-1:-1;;198:2043:1;;;;;;:::i;:::-;;;:::i;:::-;9797:590:0;;;;;;;;;-1:-1:-1;9797:590:0;;;;;;-1:-1:-1;9797:590:0;198:2043:1;;;;;9797:590:0;;;198:2043:1;-1:-1:-1;9797:590:0;198:2043:1;;;;;;;-1:-1:-1;;198:2043:1;;;;;;-1:-1:-1;198:2043:1;-1:-1:-1;198:2043:1;;;;;-1:-1:-1;198:2043:1;;;;;;;;;;;;;;-1:-1:-1;;198:2043:1;;;;;;:::i;:::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;198:2043:1;;;;;;;;;;;:::i;:::-;-1:-1:-1;198:2043:1;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;198:2043:1;;;;;;:::i;:::-;;;:::i;:::-;9325:196:0;;;;;-1:-1:-1;9325:196:0;198:2043:1;9325:196:0;;;;198:2043:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;198:2043:1;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;1104:55;1148:10;;198:2043;1148:10;:::i;:::-;;;;;198:2043;;1148:10;1104:55;198:2043;;1104:55;;;198:2043;1104:55;;1121:15;;1104:55;;:::i;:::-;;198:2043;;1104:55;;;;;;:::i;:::-;198:2043;1094:66;;1264:10;1240:57;;;;198:2043;;-1:-1:-1;;;1240:57:1;;198:2043;1240:57;;198:2043;;;;-1:-1:-1;198:2043:1;;;-1:-1:-1;1264:10:1;1240:57;;;;;;;198:2043;1240:57;;;198:2043;-1:-1:-1;198:2043:1;;;;;;;;;;;;;1240:57;;;-1:-1:-1;1240:57:1;;;:::i;:::-;;;:::i;:::-;;;;;;:::i;198:2043::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;:::i;10748:2884:0:-;10928:2655;;;;-1:-1:-1;;;10928:2655:0;;;;;;;;;;;;;-1:-1:-1;;;;;10928:2655:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10748:2884;10928:2655;;10748:2884;10928:2655;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10748:2884::o;10928:2655::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7433:533;7565:395;;;;8230;;;7565;;;;;;;;;;7433:533;:::o;7565:395::-;;;;;;;198:2043:1;;;;;;;;;;;:::o;:::-;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;:::o;:::-;-1:-1:-1;;198:2043:1;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;1340:899;;;;1485:16;;;:::i;:::-;1532:1;1571:29;;;;:::i;:::-;1616:17;1635:9;;;;;;;2085:25;;;;;;;:::i;:::-;2125:13;1532:1;2140:14;;;;;;-1:-1:-1;2219:13:1;;-1:-1:-1;;1340:899:1:o;2156:3::-;2187:11;;198:2043;2187:11;;;:::i;:::-;198:2043;2175:23;;;;:::i;:::-;198:2043;;2125:13;;1646:3;16165:187:0;;;;-1:-1:-1;;;16165:187:0;;;;;;;;;;-1:-1:-1;;;;;198:2043:1;;;16165:187:0;;1669:20:1;1665:272;;1646:3;;;;:::i;:::-;1616:17;;1665:272;1709:24;;;;198:2043;1709:24;;;:::i;:::-;198:2043;;1837:28;;;;1665:272;1833:90;;1889:15;;;;;:::o;14404:249:0:-;;;;14573:2;;;;;:::i;:::-;38334:89;;14586:60;;14404:249;;;;;:::o;14586:60::-;198:2043:1;;;;;;;;;;;;-1:-1:-1;;198:2043:1;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;198:2043:1;14604:42:0;198:2043:1;;;;;;;;;14604:42:0;:::i;:::-;14586:60;;;;;;;198:2043:1;;;;;;;-1:-1:-1;;;;;198:2043:1;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;38588:1370:0;;38750:1202;;38588:1370;;38750:1202;;;;;;;;;;;;;198:2043:1;;;;;38750:1202:0;;;;;;;;;;;;;;;;;;;;;;;;;;38588:1370;38750:1202;;;;;;;;;;;;;;38588:1370;38750:1202;-1:-1:-1;;;38750:1202:0;;;38588:1370::o;38750:1202::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Swarm Source
ipfs://476aa2966ab9591ad5d81fdf99f725f1fdf28d0bbb9ae13955bc878b99106fc6
[ 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.