Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 29,063 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Set Approval For... | 36316137 | 13 hrs ago | IN | 0 ETH | 0.00000567 | ||||
| Set Approval For... | 36316115 | 13 hrs ago | IN | 0 ETH | 0.00000665 | ||||
| Set Approval For... | 36297760 | 15 hrs ago | IN | 0 ETH | 0.00000419 | ||||
| Safe Transfer Fr... | 36281935 | 18 hrs ago | IN | 0 ETH | 0.00001613 | ||||
| Safe Transfer Fr... | 36281898 | 18 hrs ago | IN | 0 ETH | 0.00001613 | ||||
| Safe Transfer Fr... | 36281861 | 18 hrs ago | IN | 0 ETH | 0.0000188 | ||||
| Set Approval For... | 36229413 | 26 hrs ago | IN | 0 ETH | 0.00000737 | ||||
| Set Approval For... | 36227991 | 26 hrs ago | IN | 0 ETH | 0.00000421 | ||||
| Set Approval For... | 36210858 | 29 hrs ago | IN | 0 ETH | 0.00000479 | ||||
| Set Approval For... | 36197355 | 31 hrs ago | IN | 0 ETH | 0.00000417 | ||||
| Set Approval For... | 36197331 | 31 hrs ago | IN | 0 ETH | 0.0000043 | ||||
| Set Approval For... | 36159170 | 38 hrs ago | IN | 0 ETH | 0.00000406 | ||||
| Set Approval For... | 36148893 | 40 hrs ago | IN | 0 ETH | 0.00000417 | ||||
| Set Approval For... | 36132563 | 43 hrs ago | IN | 0 ETH | 0.00000419 | ||||
| Set Approval For... | 36124484 | 45 hrs ago | IN | 0 ETH | 0.00000418 | ||||
| Set Approval For... | 36099668 | 2 days ago | IN | 0 ETH | 0.00000418 | ||||
| Set Approval For... | 36056880 | 2 days ago | IN | 0 ETH | 0.00000419 | ||||
| Set Approval For... | 36043078 | 2 days ago | IN | 0 ETH | 0.00000581 | ||||
| Set Approval For... | 36007214 | 2 days ago | IN | 0 ETH | 0.00000644 | ||||
| Set Approval For... | 35996568 | 2 days ago | IN | 0 ETH | 0.00000582 | ||||
| Set Approval For... | 35985549 | 2 days ago | IN | 0 ETH | 0.0000042 | ||||
| Set Approval For... | 35978849 | 2 days ago | IN | 0 ETH | 0.00000419 | ||||
| Set Approval For... | 35962017 | 2 days ago | IN | 0 ETH | 0.00000582 | ||||
| Set Approval For... | 35958539 | 3 days ago | IN | 0 ETH | 0.00000567 | ||||
| Set Approval For... | 35952331 | 3 days ago | IN | 0 ETH | 0.00000411 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 16260500 | 170 days ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Miners
Compiler Version
v0.8.30-1.0.2
ZkSolc Version
v1.5.15
Optimization Enabled:
Yes with Mode 3
Other Settings:
prague EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import {ERC721} from "solady-0.1.23/tokens/ERC721.sol";
import {Ownable} from "solady-0.1.23/auth/Ownable.sol";
import {Errors} from "./libraries/Errors.sol";
import {ERC2981} from "solady-0.1.23/tokens/ERC2981.sol";
import {ICreatorToken} from "./interfaces/ICreatorToken.sol";
import {ITransferValidator} from "./interfaces/ITransferValidator.sol";
import {ITokenRenderer} from "./interfaces/ITokenRenderer.sol";
contract Miners is ERC721, Ownable, ERC2981, ICreatorToken {
address immutable main;
string public contractURI;
ITokenRenderer public renderer;
address private _transferValidator;
uint256 public totalSupply;
constructor(address _owner, address _main, address transferValidator, address _renderer) {
_initializeOwner(_owner);
_setDefaultRoyalty(_owner, 500);
_transferValidator = transferValidator;
renderer = ITokenRenderer(_renderer);
emit TransferValidatorUpdated(address(0), transferValidator);
main = _main;
}
function mint(uint256 minerId) external {
require(msg.sender == main, Errors.NotMain());
totalSupply++;
// miners are always minted to main initially
_mint(msg.sender, minerId);
}
function burn(uint256 minerId) external {
totalSupply--;
_burn(msg.sender, minerId);
}
function setContractURI(string memory uri) external onlyOwner {
contractURI = uri;
}
function setRenderer(address newRenderer) external onlyOwner {
renderer = ITokenRenderer(newRenderer);
}
function setTransferValidator(address newValidator) external onlyOwner {
emit TransferValidatorUpdated(_transferValidator, newValidator);
_transferValidator = newValidator;
}
function setDefaultRoyalty(address receiver, uint96 feeNumerator) external onlyOwner {
_setDefaultRoyalty(receiver, feeNumerator);
}
function name() public pure override returns (string memory) {
return "Bigcoin Miners";
}
function symbol() public pure override returns (string memory) {
return "MINER";
}
function tokenURI(uint256 tokenId) public view override returns (string memory) {
require(_exists(tokenId), TokenDoesNotExist());
return renderer.tokenURI(tokenId);
}
function getTransferValidator() external view returns (address) {
return _transferValidator;
}
function getTransferValidationFunction() external pure returns (bytes4 functionSignature, bool isViewFunction) {
return (0xcaee23ea, true);
}
function exists(uint256 tokenId) external view returns (bool) {
return _exists(tokenId);
}
function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC2981) returns (bool) {
return ERC721.supportsInterface(interfaceId) || ERC2981.supportsInterface(interfaceId)
|| interfaceId == type(ICreatorToken).interfaceId;
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal view override {
if (from != address(0)) {
if (to != address(0)) {
address validator = _transferValidator;
if (validator != address(0)) {
ITransferValidator(validator).validateTransfer(msg.sender, from, to, tokenId);
}
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
/// @notice Simple single owner authorization mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)
///
/// @dev Note:
/// This implementation does NOT auto-initialize the owner to `msg.sender`.
/// You MUST call the `_initializeOwner` in the constructor / initializer.
///
/// While the ownable portion follows
/// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility,
/// the nomenclature for the 2-step ownership handover may be unique to this codebase.
abstract contract Ownable {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The caller is not authorized to call the function.
error Unauthorized();
/// @dev The `newOwner` cannot be the zero address.
error NewOwnerIsZeroAddress();
/// @dev The `pendingOwner` does not have a valid handover request.
error NoHandoverRequest();
/// @dev Cannot double-initialize.
error AlreadyInitialized();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* EVENTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The ownership is transferred from `oldOwner` to `newOwner`.
/// This event is intentionally kept the same as OpenZeppelin's Ownable to be
/// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),
/// despite it not being as lightweight as a single argument event.
event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);
/// @dev An ownership handover to `pendingOwner` has been requested.
event OwnershipHandoverRequested(address indexed pendingOwner);
/// @dev The ownership handover to `pendingOwner` has been canceled.
event OwnershipHandoverCanceled(address indexed pendingOwner);
/// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`.
uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =
0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;
/// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`.
uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =
0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;
/// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`.
uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =
0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* STORAGE */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The owner slot is given by:
/// `bytes32(~uint256(uint32(bytes4(keccak256("_OWNER_SLOT_NOT")))))`.
/// It is intentionally chosen to be a high value
/// to avoid collision with lower slots.
/// The choice of manual storage layout is to enable compatibility
/// with both regular and upgradeable contracts.
bytes32 internal constant _OWNER_SLOT =
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927;
/// The ownership handover slot of `newOwner` is given by:
/// ```
/// mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))
/// let handoverSlot := keccak256(0x00, 0x20)
/// ```
/// It stores the expiry timestamp of the two-step ownership handover.
uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* INTERNAL FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Override to return true to make `_initializeOwner` prevent double-initialization.
function _guardInitializeOwner() internal pure virtual returns (bool guard) {}
/// @dev Initializes the owner directly without authorization guard.
/// This function must be called upon initialization,
/// regardless of whether the contract is upgradeable or not.
/// This is to enable generalization to both regular and upgradeable contracts,
/// and to save gas in case the initial owner is not the caller.
/// For performance reasons, this function will not check if there
/// is an existing owner.
function _initializeOwner(address newOwner) internal virtual {
if (_guardInitializeOwner()) {
/// @solidity memory-safe-assembly
assembly {
let ownerSlot := _OWNER_SLOT
if sload(ownerSlot) {
mstore(0x00, 0x0dc149f0) // `AlreadyInitialized()`.
revert(0x1c, 0x04)
}
// Clean the upper 96 bits.
newOwner := shr(96, shl(96, newOwner))
// Store the new value.
sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
// Emit the {OwnershipTransferred} event.
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
}
} else {
/// @solidity memory-safe-assembly
assembly {
// Clean the upper 96 bits.
newOwner := shr(96, shl(96, newOwner))
// Store the new value.
sstore(_OWNER_SLOT, newOwner)
// Emit the {OwnershipTransferred} event.
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
}
}
}
/// @dev Sets the owner directly without authorization guard.
function _setOwner(address newOwner) internal virtual {
if (_guardInitializeOwner()) {
/// @solidity memory-safe-assembly
assembly {
let ownerSlot := _OWNER_SLOT
// Clean the upper 96 bits.
newOwner := shr(96, shl(96, newOwner))
// Emit the {OwnershipTransferred} event.
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
// Store the new value.
sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
}
} else {
/// @solidity memory-safe-assembly
assembly {
let ownerSlot := _OWNER_SLOT
// Clean the upper 96 bits.
newOwner := shr(96, shl(96, newOwner))
// Emit the {OwnershipTransferred} event.
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
// Store the new value.
sstore(ownerSlot, newOwner)
}
}
}
/// @dev Throws if the sender is not the owner.
function _checkOwner() internal view virtual {
/// @solidity memory-safe-assembly
assembly {
// If the caller is not the stored owner, revert.
if iszero(eq(caller(), sload(_OWNER_SLOT))) {
mstore(0x00, 0x82b42900) // `Unauthorized()`.
revert(0x1c, 0x04)
}
}
}
/// @dev Returns how long a two-step ownership handover is valid for in seconds.
/// Override to return a different value if needed.
/// Made internal to conserve bytecode. Wrap it in a public function if needed.
function _ownershipHandoverValidFor() internal view virtual returns (uint64) {
return 48 * 3600;
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* PUBLIC UPDATE FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Allows the owner to transfer the ownership to `newOwner`.
function transferOwnership(address newOwner) public payable virtual onlyOwner {
/// @solidity memory-safe-assembly
assembly {
if iszero(shl(96, newOwner)) {
mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`.
revert(0x1c, 0x04)
}
}
_setOwner(newOwner);
}
/// @dev Allows the owner to renounce their ownership.
function renounceOwnership() public payable virtual onlyOwner {
_setOwner(address(0));
}
/// @dev Request a two-step ownership handover to the caller.
/// The request will automatically expire in 48 hours (172800 seconds) by default.
function requestOwnershipHandover() public payable virtual {
unchecked {
uint256 expires = block.timestamp + _ownershipHandoverValidFor();
/// @solidity memory-safe-assembly
assembly {
// Compute and set the handover slot to `expires`.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x20), expires)
// Emit the {OwnershipHandoverRequested} event.
log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())
}
}
}
/// @dev Cancels the two-step ownership handover to the caller, if any.
function cancelOwnershipHandover() public payable virtual {
/// @solidity memory-safe-assembly
assembly {
// Compute and set the handover slot to 0.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x20), 0)
// Emit the {OwnershipHandoverCanceled} event.
log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())
}
}
/// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`.
/// Reverts if there is no existing ownership handover requested by `pendingOwner`.
function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {
/// @solidity memory-safe-assembly
assembly {
// Compute and set the handover slot to 0.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, pendingOwner)
let handoverSlot := keccak256(0x0c, 0x20)
// If the handover does not exist, or has expired.
if gt(timestamp(), sload(handoverSlot)) {
mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`.
revert(0x1c, 0x04)
}
// Set the handover slot to 0.
sstore(handoverSlot, 0)
}
_setOwner(pendingOwner);
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* PUBLIC READ FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns the owner of the contract.
function owner() public view virtual returns (address result) {
/// @solidity memory-safe-assembly
assembly {
result := sload(_OWNER_SLOT)
}
}
/// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.
function ownershipHandoverExpiresAt(address pendingOwner)
public
view
virtual
returns (uint256 result)
{
/// @solidity memory-safe-assembly
assembly {
// Compute the handover slot.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, pendingOwner)
// Load the handover slot.
result := sload(keccak256(0x0c, 0x20))
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* MODIFIERS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Marks a function as only callable by the owner.
modifier onlyOwner() virtual {
_checkOwner();
_;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
/// @notice Simple ERC2981 NFT Royalty Standard implementation.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC2981.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/common/ERC2981.sol)
abstract contract ERC2981 {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The royalty fee numerator exceeds the fee denominator.
error RoyaltyOverflow();
/// @dev The royalty receiver cannot be the zero address.
error RoyaltyReceiverIsZeroAddress();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* STORAGE */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The default royalty info is given by:
/// ```
/// let packed := sload(_ERC2981_MASTER_SLOT_SEED)
/// let receiver := shr(96, packed)
/// let royaltyFraction := xor(packed, shl(96, receiver))
/// ```
///
/// The per token royalty info is given by.
/// ```
/// mstore(0x00, tokenId)
/// mstore(0x20, _ERC2981_MASTER_SLOT_SEED)
/// let packed := sload(keccak256(0x00, 0x40))
/// let receiver := shr(96, packed)
/// let royaltyFraction := xor(packed, shl(96, receiver))
/// ```
uint256 private constant _ERC2981_MASTER_SLOT_SEED = 0xaa4ec00224afccfdb7;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* ERC2981 */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Checks that `_feeDenominator` is non-zero.
constructor() {
require(_feeDenominator() != 0, "Fee denominator cannot be zero.");
}
/// @dev Returns the denominator for the royalty amount.
/// Defaults to 10000, which represents fees in basis points.
/// Override this function to return a custom amount if needed.
function _feeDenominator() internal pure virtual returns (uint96) {
return 10000;
}
/// @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, ERC2981: 0x2a55205a.
result := or(eq(s, 0x01ffc9a7), eq(s, 0x2a55205a))
}
}
/// @dev Returns the `receiver` and `royaltyAmount` for `tokenId` sold at `salePrice`.
function royaltyInfo(uint256 tokenId, uint256 salePrice)
public
view
virtual
returns (address receiver, uint256 royaltyAmount)
{
uint256 feeDenominator = _feeDenominator();
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, tokenId)
mstore(0x20, _ERC2981_MASTER_SLOT_SEED)
let packed := sload(keccak256(0x00, 0x40))
receiver := shr(96, packed)
if iszero(receiver) {
packed := sload(mload(0x20))
receiver := shr(96, packed)
}
let x := salePrice
let y := xor(packed, shl(96, receiver)) // `feeNumerator`.
// Overflow check, equivalent to `require(y == 0 || x <= type(uint256).max / y)`.
// Out-of-gas revert. Should not be triggered in practice, but included for safety.
returndatacopy(returndatasize(), returndatasize(), mul(y, gt(x, div(not(0), y))))
royaltyAmount := div(mul(x, y), feeDenominator)
}
}
/// @dev Sets the default royalty `receiver` and `feeNumerator`.
///
/// Requirements:
/// - `receiver` must not be the zero address.
/// - `feeNumerator` must not be greater than the fee denominator.
function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
uint256 feeDenominator = _feeDenominator();
/// @solidity memory-safe-assembly
assembly {
feeNumerator := shr(160, shl(160, feeNumerator))
if gt(feeNumerator, feeDenominator) {
mstore(0x00, 0x350a88b3) // `RoyaltyOverflow()`.
revert(0x1c, 0x04)
}
let packed := shl(96, receiver)
if iszero(packed) {
mstore(0x00, 0xb4457eaa) // `RoyaltyReceiverIsZeroAddress()`.
revert(0x1c, 0x04)
}
sstore(_ERC2981_MASTER_SLOT_SEED, or(packed, feeNumerator))
}
}
/// @dev Sets the default royalty `receiver` and `feeNumerator` to zero.
function _deleteDefaultRoyalty() internal virtual {
/// @solidity memory-safe-assembly
assembly {
sstore(_ERC2981_MASTER_SLOT_SEED, 0)
}
}
/// @dev Sets the royalty `receiver` and `feeNumerator` for `tokenId`.
///
/// Requirements:
/// - `receiver` must not be the zero address.
/// - `feeNumerator` must not be greater than the fee denominator.
function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator)
internal
virtual
{
uint256 feeDenominator = _feeDenominator();
/// @solidity memory-safe-assembly
assembly {
feeNumerator := shr(160, shl(160, feeNumerator))
if gt(feeNumerator, feeDenominator) {
mstore(0x00, 0x350a88b3) // `RoyaltyOverflow()`.
revert(0x1c, 0x04)
}
let packed := shl(96, receiver)
if iszero(packed) {
mstore(0x00, 0xb4457eaa) // `RoyaltyReceiverIsZeroAddress()`.
revert(0x1c, 0x04)
}
mstore(0x00, tokenId)
mstore(0x20, _ERC2981_MASTER_SLOT_SEED)
sstore(keccak256(0x00, 0x40), or(packed, feeNumerator))
}
}
/// @dev Sets the royalty `receiver` and `feeNumerator` for `tokenId` to zero.
function _resetTokenRoyalty(uint256 tokenId) internal virtual {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, tokenId)
mstore(0x20, _ERC2981_MASTER_SLOT_SEED)
sstore(keccak256(0x00, 0x40), 0)
}
}
}// 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 toBalanceSlotPacked := add(sload(toBalanceSlot), 1)
// Revert if `to` is the zero address, or if the account balance overflows.
if iszero(mul(to, and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE))) {
// `TransferToZeroAddress()`, `AccountBalanceOverflow()`.
mstore(shl(2, iszero(to)), 0xea553b3401336cea)
revert(0x1c, 0x04)
}
sstore(toBalanceSlot, toBalanceSlotPacked)
}
// 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 balanceSlotPacked := add(sload(balanceSlot), 1)
// Revert if `to` is the zero address, or if the account balance overflows.
if iszero(mul(to, and(balanceSlotPacked, _MAX_ACCOUNT_BALANCE))) {
// `TransferToZeroAddress()`, `AccountBalanceOverflow()`.
mstore(shl(2, iszero(to)), 0xea553b3401336cea)
revert(0x1c, 0x04)
}
sstore(balanceSlot, balanceSlotPacked)
}
// 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 balanceSlotPacked := add(sload(balanceSlot), 1)
// Revert if `to` is the zero address, or if the account balance overflows.
if iszero(mul(to, and(balanceSlotPacked, _MAX_ACCOUNT_BALANCE))) {
// `TransferToZeroAddress()`, `AccountBalanceOverflow()`.
mstore(shl(2, iszero(to)), 0xea553b3401336cea)
revert(0x1c, 0x04)
}
sstore(balanceSlot, balanceSlotPacked)
}
// 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 {
/// @solidity memory-safe-assembly
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 toBalanceSlotPacked := add(sload(toBalanceSlot), 1)
// Revert if `to` is the zero address, or if the account balance overflows.
if iszero(mul(to, and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE))) {
// `TransferToZeroAddress()`, `AccountBalanceOverflow()`.
mstore(shl(2, iszero(to)), 0xea553b3401336cea)
revert(0x1c, 0x04)
}
sstore(toBalanceSlot, toBalanceSlotPacked)
}
// 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.4;
interface ICreatorToken {
event TransferValidatorUpdated(address oldValidator, address newValidator);
function getTransferValidator() external view returns (address validator);
function setTransferValidator(address validator) external;
function getTransferValidationFunction() external view returns (bytes4 functionSignature, bool isViewFunction);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
interface ITokenRenderer {
function tokenURI(uint256 tokenId) external view returns (string memory);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
interface ITransferValidator {
function applyCollectionTransferPolicy(address caller, address from, address to) external view;
function validateTransfer(address caller, address from, address to) external view;
function validateTransfer(address caller, address from, address to, uint256 tokenId) external view;
function validateTransfer(address caller, address from, address to, uint256 tokenId, uint256 amount) external;
function beforeAuthorizedTransfer(address operator, address token, uint256 tokenId) external;
function afterAuthorizedTransfer(address token, uint256 tokenId) external;
function beforeAuthorizedTransfer(address operator, address token) external;
function afterAuthorizedTransfer(address token) external;
function beforeAuthorizedTransfer(address token, uint256 tokenId) external;
function beforeAuthorizedTransferWithAmount(address token, uint256 tokenId, uint256 amount) external;
function afterAuthorizedTransferWithAmount(address token, uint256 tokenId) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
library Errors {
error IncorrectValue();
error AlreadyPurchasedInitialFactory();
error StarterMinerAlreadyAcquired();
error FacilityAtMaxCapacity();
error FacilityInadequatePowerOutput();
error PlayerDoesNotOwnMiner();
error GreatDepression();
error MinerNotInProduction();
error TooPoor();
error NewFacilityNotInProduction();
error CannotDowngradeAFacility();
error NoRewardsPending();
error CannotDecreaseBelowZero();
error InvalidMinerCoordinates();
error FacilityDimensionsInvalid();
error NeedToInitializeFacility();
error InvalidReferrer();
error NonExistentMiner();
error CantModifyStarterMiner();
error NonExistentFacility();
error CantModifyStarterFacility();
error AlreadyAtMaxFacility();
error CantBuyNewFacilityYet();
error InvalidMinerIndex();
error InvalidFacilityIndex();
error InvalidFee();
error InvalidPowerOutput();
error MiningHasntStarted();
error WithdrawFailed();
error NotMain();
error Done();
error MinersCannotBeTokenized();
error TooSoon();
error MinerSoldOut();
error InvalidSignature();
error MaxPurchaseForFacilityReached();
}{
"codegen": "yul",
"enableEraVMExtensions": false,
"evmVersion": "prague",
"forceEVMLA": false,
"libraries": {},
"metadata": {},
"optimizer": {
"disable_system_request_memoization": true,
"enabled": true,
"mode": "3",
"size_fallback": false
},
"outputSelection": {
"*": {
"*": [
"abi"
]
}
},
"remappings": [
"@openzeppelin-upgradeable/=dependencies/@openzeppelin-contracts-upgradeable-5.3.0/",
"@openzeppelin/contracts/=dependencies/@openzeppelin-contracts-5.3.0/",
"forge-std/=dependencies/forge-std-1.9.7/src/",
"forge-zksync-std/=dependencies/forge-zksync-std-0.0.1/src/",
"solady/=dependencies/solady-0.1.23/src/",
"@openzeppelin-contracts-5.3.0/=dependencies/@openzeppelin-contracts-5.3.0/",
"@openzeppelin-contracts-upgradeable-5.3.0/=dependencies/@openzeppelin-contracts-upgradeable-5.3.0/",
"forge-std-1.9.7/=dependencies/forge-std-1.9.7/src/",
"forge-zksync-std-0.0.1/=dependencies/forge-zksync-std-0.0.1/src/",
"solady-0.1.23/=dependencies/solady-0.1.23/src/"
],
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_main","type":"address"},{"internalType":"address","name":"transferValidator","type":"address"},{"internalType":"address","name":"_renderer","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountBalanceOverflow","type":"error"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"NotMain","type":"error"},{"inputs":[],"name":"NotOwnerNorApproved","type":"error"},{"inputs":[],"name":"RoyaltyOverflow","type":"error"},{"inputs":[],"name":"RoyaltyReceiverIsZeroAddress","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"},{"inputs":[],"name":"Unauthorized","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":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldValidator","type":"address"},{"indexed":false,"internalType":"address","name":"newValidator","type":"address"}],"name":"TransferValidatorUpdated","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":"minerId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","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":[],"name":"getTransferValidationFunction","outputs":[{"internalType":"bytes4","name":"functionSignature","type":"bytes4"},{"internalType":"bool","name":"isViewFunction","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getTransferValidator","outputs":[{"internalType":"address","name":"","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":"minerId","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","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":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renderer","outputs":[{"internalType":"contract ITokenRenderer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"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":"uri","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRenderer","type":"address"}],"name":"setRenderer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newValidator","type":"address"}],"name":"setTransferValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"}]Contract Creation Code
9c4d535b0000000000000000000000000000000000000000000000000000000000000000010002c1ab68b0c94bd8b17e81df2eb31800d45e93f57df86f9707a33f50e4270000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000056c667bd74cc0aab32297754bbf5dfe626d72c4d00000000000000000000000089eb96a0a157f935de38d548b79af511d424e33a000000000000000000000000721c008fdff27bf06e7e123956e2fe03b63342e300000000000000000000000041b64aa2a9f90bf20a48c264226e1651abb74573
Deployed Bytecode
0x000400000000000200060000000000020000006004100270000002390340019700030000003103550002000000010355000002390040019d00000001002001900000002d0000c13d0000008004000039000000400040043f000000040030008c000005f90000413d000000000201043b000000e002200270000002450020009c000000730000a13d000002460020009c000000c50000a13d000002470020009c000000dc0000a13d000002480020009c000001680000a13d000002490020009c000003fe0000613d0000024a0020009c0000025c0000613d0000024b0020009c000005f90000c13d0000000002000416000000000002004b000005f90000c13d000000240030008c000005f90000413d0000000401100370000000000101043b0000023c0010009c000005f90000213d00000275020000410000000c0020043f000000000010043f0000000c01000039000000200200003908df08c00000040f000001e50000013d0000000002000416000000000002004b000005f90000c13d0000001f023000390000023a02200197000000a002200039000000400020043f0000001f0430018f0000023b05300198000000a0025000390000003e0000613d000000a006000039000000000701034f000000007807043c0000000006860436000000000026004b0000003a0000c13d000000000004004b0000004b0000613d000000000151034f0000000304400210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000120435000000800030008c000005f90000413d000000a00600043d0000023c0060009c000005f90000213d000000c00100043d000600000001001d0000023c0010009c000005f90000213d000000e00100043d000500000001001d0000023c0010009c000005f90000213d000001000100043d000300000001001d0000023c0010009c000005f90000213d0000023d01000041000000000061041b0000000001000414000002390010009c0000023901008041000000c0011002100000023e011001c70000800d0200003900000003030000390000023f040000410000000005000019000400000006001d000000040600002908df08d50000040f00000004010000290000000100200190000005f90000613d000000000001004b000004730000c13d000002a901000041000000000010043f0000027801000041000008e1000104300000025e0020009c000000960000213d0000026a0020009c0000010a0000213d000002700020009c000001870000213d000002730020009c0000026d0000613d000002740020009c000005f90000c13d0000000002000416000000000002004b000005f90000c13d000000440030008c000005f90000413d0000000402100370000000000202043b0000023c0020009c000005f90000213d0000002401100370000000000101043b0000029e0010009c000005f90000213d0000023d03000041000000000303041a0000000004000411000000000034004b000005a40000c13d0000029e03100197000027110030008c000006250000413d000002aa01000041000000000010043f0000027801000041000008e1000104300000025f0020009c000001150000213d000002650020009c000001aa0000213d000002680020009c0000028d0000613d000002690020009c000005f90000c13d00000275010000410000000c0010043f0000000001000411000000000010043f0000027a0100004100000000001004430000000001000414000002390010009c0000023901008041000000c0011002100000027b011001c70000800b0200003908df08da0000040f0000000100200190000004720000613d000000000101043b000600000001001d0000000001000414000002390010009c0000023901008041000000c00110021000000279011001c7000080100200003908df08da0000040f0000000100200190000005f90000613d000000000101043b0000000602000029000002a00220009a000000000021041b0000000001000414000002390010009c0000023901008041000000c0011002100000023e011001c70000800d020000390000000203000039000002a104000041000003f80000013d000002530020009c000001240000213d000002590020009c000001ff0000213d0000025c0020009c0000042d0000613d0000025d0020009c000005f90000c13d0000000002000416000000000002004b000005f90000c13d000000240030008c000005f90000413d0000000401100370000000000101043b0000023c0010009c000005f90000213d000000000001004b000004c80000c13d0000029b01000041000000000010043f0000027801000041000008e1000104300000024e0020009c000001450000213d000002510020009c000002920000613d000002520020009c000005f90000c13d0000000002000416000000000002004b000005f90000c13d000000240030008c000005f90000413d0000000401100370000000000101043b000600000001001d0000023c0010009c000005f90000213d0000023d01000041000000000101041a0000000002000411000000000012004b000005a40000c13d0000000201000039000000000101041a000500000001001d0000023c01100197000000800010043f0000000601000029000000a00010043f0000000001000414000002390010009c0000023901008041000000c0011002100000028b011001c70000800d020000390000000103000039000002430400004108df08d50000040f0000000100200190000005f90000613d0000000501000029000002410110019700000006011001af0000000202000039000000000012041b0000000001000019000008e00001042e0000026b0020009c000001dd0000213d0000026e0020009c000002c20000613d0000026f0020009c000005f90000c13d0000000001000416000000000001004b000005f90000c13d0000000201000039000004400000013d000002600020009c000001e90000213d000002630020009c000002fb0000613d000002640020009c000005f90000c13d0000000002000416000000000002004b000005f90000c13d000000240030008c000005f90000413d0000000401100370000000000101043b08df08900000040f000004350000013d000002540020009c000002080000213d000002570020009c0000043c0000613d000002580020009c000005f90000c13d0000000002000416000000000002004b000005f90000c13d000000240030008c000005f90000413d0000000402100370000000000502043b000002830050009c000005f90000213d0000002302500039000000000032004b000005f90000813d0000000404500039000000000241034f000000000202043b000002830020009c0000013f0000213d0000001f062000390000028506600197000002960060009c000005560000a13d0000029a01000041000000000010043f0000004101000039000000040010043f0000028201000041000008e1000104300000024f0020009c0000030c0000613d000002500020009c000005f90000c13d0000000002000416000000000002004b000005f90000c13d000000240030008c000005f90000413d0000000401100370000000000101043b000600000001001d000000000010043f0000027f010000410000001c0010043f0000000001000414000002390010009c0000023901008041000000c00110021000000280011001c7000080100200003908df08da0000040f0000000100200190000005f90000613d00000006030000290000000102300210000000000101043b0000000001210019000000000101041a0000023c00100198000004d30000c13d0000028701000041000000000010043f0000028801000041000008e1000104300000024c0020009c000003710000613d0000024d0020009c000005f90000c13d0000000002000416000000000002004b000005f90000c13d000000440030008c000005f90000413d0000000402100370000000000202043b0000023c0020009c000005f90000213d0000002401100370000000000101043b0000023c0010009c000005f90000213d0000001c0010043f0000027d01000041000000080010043f000000000020043f0000000c01000039000000300200003908df08c00000040f000000000101041a000000000001004b0000000001000039000000010100c039000000800010043f0000027601000041000008e00001042e000002710020009c000003840000613d000002720020009c000005f90000c13d0000000002000416000000000002004b000005f90000c13d000000240030008c000005f90000413d0000000401100370000000000101043b000600000001001d000000000010043f0000027f010000410000001c0010043f0000000001000414000002390010009c0000023901008041000000c00110021000000280011001c7000080100200003908df08da0000040f0000000100200190000005f90000613d00000006020000290000000102200210000000000101043b0000000001210019000000000201041a0000023c00200198000004b40000613d0000000101100039000000000101041a0000023c01100197000004350000013d000002660020009c0000038e0000613d000002670020009c000005f90000c13d000000640030008c000005f90000413d0000000402100370000000000202043b000600000002001d0000023c0020009c000005f90000213d0000002402100370000000000202043b000500000002001d0000023c0020009c000005f90000213d0000004401100370000000000301043b00000006010000290000000502000029000400000003001d08df06df0000040f00000289010000410000000000100443000000050100002900000004001004430000000001000414000002390010009c0000023901008041000000c0011002100000028a011001c7000080020200003908df08da0000040f0000000100200190000004720000613d000000000101043b000000000001004b000003fc0000613d000000400100043d000002980010009c0000013f0000813d0000002002100039000000400020043f0000000004010019000000000001043500000006010000290000000502000029000000040300002908df07f10000040f0000000001000019000008e00001042e0000026c0020009c000003d80000613d0000026d0020009c000005f90000c13d0000000001000416000000000001004b000005f90000c13d0000000301000039000000000101041a000000800010043f0000027601000041000008e00001042e000002610020009c000003e10000613d000002620020009c000005f90000c13d0000000002000416000000000002004b000005f90000c13d000000240030008c000005f90000413d0000000401100370000000000101043b000600000001001d0000023c0010009c000005f90000213d08df07e70000040f0000000101000039000000000201041a000002410220019700000006022001af000000000021041b0000000001000019000008e00001042e0000025a0020009c000004450000613d0000025b0020009c000005f90000c13d0000000001000416000000000001004b000005f90000c13d0000000101000039000004400000013d000002550020009c0000045a0000613d000002560020009c000005f90000c13d0000000002000416000000000002004b000005f90000c13d000000240030008c000005f90000413d0000000401100370000000000101043b000600000001001d0000028e0100004100000000001004430000000001000412000000040010044300000024000004430000000001000414000002390010009c0000023901008041000000c0011002100000028f011001c7000080050200003908df08da0000040f0000000100200190000004720000613d000000000101043b0000023c011001970000000002000411000000000012004b000005490000c13d0000000301000039000000000201041a000000010220003a000003060000613d000000000021041b0000000601000029000000000010043f0000027f010000410000001c0010043f0000000001000414000002390010009c0000023901008041000000c00110021000000280011001c7000080100200003908df08da0000040f0000000100200190000005f90000613d00000006020000290000000102200210000000000101043b0000000001210019000000000201041a0000023c002001980000062d0000c13d0000000003000411000000000232019f000000000021041b000000000030043f0000000001000414000002390010009c0000023901008041000000c00110021000000292011001c7000080100200003908df08da0000040f0000000100200190000005f90000613d000000000101043b000000000201041a00000001022000390000023903200197000000000400041100000000004300aa000006370000c13d0000000001000411000000000001004b00000000010000390000000401006039000002940200004100000000002104350000027801000041000008e100010430000000240030008c000005f90000413d0000000401100370000000000101043b0000023c0010009c000005f90000213d0000023d02000041000000000202041a0000000003000411000000000023004b000005a40000c13d000000000001004b000006340000c13d0000027701000041000000000010043f0000027801000041000008e1000104300000000002000416000000000002004b000005f90000c13d000000240030008c000005f90000413d0000000401100370000000000101043b000002ab00100198000005f90000c13d000002ac0010009c00000000020000390000000102006039000002ad0010009c00000001022061bf000000e003100270000002730030009c000002850000613d000002ae0030009c000002850000613d000002af0030009c000002850000613d000002b00010009c00000000020000390000000102006039000002b10010009c00000001022061bf000002b20010009c00000001022061bf000000010120018f000000800010043f0000027601000041000008e00001042e000000000103001908df06bb0000040f08df06df0000040f0000000001000019000008e00001042e0000000002000416000000000002004b000005f90000c13d000000440030008c000005f90000413d0000000402100370000000000202043b000600000002001d0000023c0020009c000005f90000213d0000002401100370000000000101043b000000000001004b0000000002000039000000010200c039000500000002001d000000010010008c000005f90000213d00000006010000290000001c0010043f0000027d01000041000000080010043f0000000001000411000000000010043f0000000001000414000002390010009c0000023901008041000000c0011002100000028c011001c7000080100200003908df08da0000040f0000000100200190000005f90000613d000000000101043b0000000502000029000000000021041b000000000020043f0000000001000414000002390010009c0000023901008041000000c00110021000000280011001c70000800d0200003900000003030000390000028d0400004100000000050004110000000606000029000003f90000013d000000440030008c000005f90000413d0000000402100370000000000202043b000600000002001d0000023c0020009c000005f90000213d0000002401100370000000000101043b000500000001001d000000000010043f00000000010004110000027f011001c70000001c0010043f0000000001000414000002390010009c0000023901008041000000c00110021000000280011001c7000080100200003908df08da0000040f0000000100200190000005f90000613d00000005020000290000000102200210000000000101043b0000000002210019000000000102041a0000023c05100198000004b40000613d0000000001000411000000000001004b000006180000613d000000000051004b000006180000613d000300000002001d000400000005001d000000000050043f0000000001000414000002390010009c0000023901008041000000c0011002100000028c011001c7000080100200003908df08da0000040f0000000100200190000005f90000613d000000000101043b000000000101041a000000000001004b00000004050000290000000302000029000006180000c13d000002a501000041000000000010043f0000027801000041000008e1000104300000000002000416000000000002004b000005f90000c13d000000240030008c000005f90000413d0000000401100370000000000301043b0000000301000039000000000201041a000000000002004b0000049e0000c13d0000029a01000041000000000010043f0000001101000039000000040010043f0000028201000041000008e100010430000000840030008c000005f90000413d0000000402100370000000000202043b000600000002001d0000023c0020009c000005f90000213d0000002402100370000000000202043b000500000002001d0000023c0020009c000005f90000213d0000004402100370000000000202043b000400000002001d0000006402100370000000000202043b000002830020009c000005f90000213d0000002304200039000000000034004b000005f90000813d000200040020003d0000000201100360000000000101043b000300000001001d000002830010009c000005f90000213d0000000301200029000100240010003d000000010030006b000005f90000213d00000006010000290000000502000029000000040300002908df06df0000040f00000289010000410000000000100443000000050100002900000004001004430000000001000414000002390010009c0000023901008041000000c0011002100000028a011001c7000080020200003908df08da0000040f0000000100200190000004720000613d000000000101043b000000000001004b000003fc0000613d00000003010000290000001f0110003900000285011001970000003f011000390000028601100197000000400400043d0000000001140019000000000041004b00000000020000390000000102004039000002830010009c0000013f0000213d00000001002001900000013f0000c13d000000400010043f000000030100002900000000011404360000000103000029000000000030007c000005f90000213d0000000305000029000002b3035001980000001f0550018f0000000002310019000000020600002900000020066000390000000206600367000003620000613d000000000706034f0000000008010019000000007907043c0000000008980436000000000028004b0000035e0000c13d000000000005004b0000036f0000613d000000000336034f0000000305500210000000000602043300000000065601cf000000000656022f000000000303043b0000010005500089000000000353022f00000000035301cf000000000363019f00000000003204350000000301100029000001d60000013d0000000001000416000000000001004b000005f90000c13d000000000200041a000000010320019000000001012002700000007f0110618f0000001f0010008c00000000050000390000000105002039000000000525013f0000000100500190000004b80000613d0000029a01000041000000000010043f0000002201000039000000040010043f0000028201000041000008e1000104300000000001000416000000000001004b000005f90000c13d0000008001000039000000400200003908df06cd0000040f0000000e01000039000000800010043f000002a701000041000004630000013d0000000002000416000000000002004b000005f90000c13d000000440030008c000005f90000413d0000002402100370000000000202043b000600000002001d0000000401100370000000000101043b000000000010043f0000024001000041000000200010043f0000000001000414000002390010009c0000023901008041000000c00110021000000242011001c7000080100200003908df08da0000040f0000000100200190000005f90000613d000000000101043b000000000201041a0000029e0020009c000003aa0000213d0000024001000041000000000201041a0000029e012001980000000003000019000000010300c08a000000000313c0d9000000060030006b0000000003000019000000000301201900000001040000310000000005430019000000000045004b000005f90000213d000002b3053001980000001f0630018f00000003074003670000000003540019000003bf0000613d000000000807034f000000008908043c0000000004940436000000000034004b000003bb0000c13d0000006002200270000000000006004b000003cd0000613d000000000457034f0000000305600210000000000603043300000000065601cf000000000656022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000464019f000000000043043500000006011000b9000027100110011a000000400300043d000000200430003900000000001404350000000000230435000002390030009c000002390300804100000040013002100000029f011001c7000008e00001042e0000000001000416000000000001004b000005f90000c13d000002a201000041000000800010043f0000000101000039000000a00010043f000002a301000041000008e00001042e00000275010000410000000c0010043f0000000001000411000000000010043f0000000001000414000002390010009c0000023901008041000000c00110021000000279011001c7000080100200003908df08da0000040f0000000100200190000005f90000613d000000000101043b000000000001041b0000000001000414000002390010009c0000023901008041000000c0011002100000023e011001c70000800d0200003900000002030000390000029d04000041000000000500041108df08d50000040f0000000100200190000005f90000613d0000000001000019000008e00001042e000000240030008c000005f90000413d0000000401100370000000000101043b000600000001001d0000023c0010009c000005f90000213d0000023d01000041000000000101041a0000000002000411000000000012004b000005a40000c13d00000275010000410000000c0010043f0000000601000029000000000010043f0000000001000414000002390010009c0000023901008041000000c00110021000000279011001c7000080100200003908df08da0000040f0000000100200190000005f90000613d000000000101043b000400000001001d000000000101041a000500000001001d0000027a0100004100000000001004430000000001000414000002390010009c0000023901008041000000c0011002100000027b011001c70000800b0200003908df08da0000040f0000000100200190000004720000613d000000000101043b000000050010006c000006310000a13d0000027c01000041000000000010043f0000027801000041000008e1000104300000000002000416000000000002004b000005f90000c13d000000240030008c000005f90000413d0000000401100370000000000101043b08df07cb0000040f000000400200043d0000000000120435000002390020009c000002390200804100000040012002100000029c011001c7000008e00001042e0000000001000416000000000001004b000005f90000c13d0000023d01000041000000000101041a0000023c01100197000000800010043f0000027601000041000008e00001042e0000023d01000041000000000501041a0000000001000411000000000051004b000005a40000c13d0000000001000414000002390010009c0000023901008041000000c0011002100000023e011001c70000800d0200003900000003030000390000023f04000041000000000600001908df08d50000040f0000000100200190000005f90000613d0000023d01000041000000000001041b0000000001000019000008e00001042e0000000001000416000000000001004b000005f90000c13d0000008001000039000000400200003908df06cd0000040f0000000501000039000000800010043f0000029501000041000000a00010043f000000400100043d000600000001001d000000800200003908df06860000040f00000006020000290000000001210049000002390010009c00000239010080410000006001100210000002390020009c00000239020080410000004002200210000000000121019f000008e00001042e000000000001042f0000006001100210000001f4011001bf0000024002000041000000000012041b0000000201000039000000000201041a00000241022001970000000504000029000000000242019f000000000021041b0000000103000039000000000103041a000002410110019700000003011001af000000000013041b000000400100043d000000200210003900000000004204350000000000010435000002390010009c000002390100804100000040011002100000000002000414000002390020009c0000023902008041000000c002200210000000000112019f00000242011001c70000800d02000039000002430400004108df08d50000040f0000000100200190000005f90000613d0000000601000029000000800010043f0000014000000443000001600010044300000020010000390000010000100443000000010100003900000120001004430000024401000041000008e00001042e000000010220008a000000000021041b000600000003001d000000000030043f0000027f010000410000001c0010043f0000000001000414000002390010009c0000023901008041000000c00110021000000280011001c7000080100200003908df08da0000040f0000000100200190000005f90000613d00000006020000290000000103200210000000000101043b0000000001310019000000000101041a0000023c00100198000005a80000c13d000002a601000041000000000010043f0000027801000041000008e100010430000000800010043f000000000003004b0000054d0000613d000000000000043f000000000001004b000005520000613d0000027e020000410000000003000019000000000502041a000000a004300039000000000054043500000001022000390000002003300039000000000013004b000004c00000413d000005520000013d0000027f020000410000001c0020043f000000000010043f0000000c010000390000001c0200003908df08c00000040f000000000101041a0000023901100197000000800010043f0000027601000041000008e00001042e0000000101000039000000000201041a000000400400043d0000028101000041000000000014043500000004014000390000000000310435000002390040009c000600000004001d0000023901000041000000000104401900000040011002100000000003000414000002390030009c0000023903008041000000c003300210000000000113019f00000282011001c70000023c0220019708df08da0000040f00000060031002700000001f0430018f0000023b05300197000102390030019d000002390330019700030000000103550000000100200190000005fb0000613d00000006090000290000000002590019000000000005004b000004f90000613d000000000601034f0000000007090019000000006806043c0000000007870436000000000027004b000004f50000c13d000000000004004b000005060000613d000000000151034f0000000304400210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001204350000001f013000390000023a011001970000000002910019000000000012004b00000000010000390000000101004039000002830020009c0000013f0000213d00000001001001900000013f0000c13d000000400020043f000000200030008c000005f90000413d0000000001090433000002830010009c000005f90000213d000000000593001900000000019100190000001f03100039000000000053004b0000000004000019000002840400804100000284033001970000028406500197000000000763013f000000000063004b00000000030000190000028403004041000002840070009c000000000304c019000000000003004b000005f90000c13d0000000031010434000002830010009c0000013f0000213d0000001f0410003900000285044001970000003f0440003900000286044001970000000004240019000002830040009c0000013f0000213d000000400040043f00000000041204360000000006130019000000000056004b000005f90000213d000002b3061001970000001f0510018f000000000043004b0000066b0000813d000000000006004b000005450000613d00000000085300190000000007540019000000200770008a000000200880008a0000000009670019000000000a680019000000000a0a04330000000000a90435000000200660008c0000053f0000c13d000000000005004b000006810000613d0000000007040019000006770000013d0000029001000041000000000010043f0000028801000041000008e100010430000002b402200197000000a00020043f000000000001004b000000a0040000390000008004006039000000600240008a000000800100003908df06cd0000040f000004640000013d00000024055000390000003f0660003900000285066001970000008006600039000000400060043f000000800020043f0000000005520019000000000035004b000005f90000213d0000002003400039000000000331034f000002b3042001980000001f0520018f000000a0014000390000056b0000613d000000a006000039000000000703034f000000007807043c0000000006860436000000000016004b000005670000c13d000000000005004b000005780000613d000000000343034f0000000304500210000000000501043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000310435000000a00120003900000000000104350000023d01000041000000000101041a0000000002000411000000000012004b000005a40000c13d000000800100043d000002830010009c0000013f0000213d000000000200041a000000010420019000000001032002700000007f0330618f0000001f0030008c00000000020000390000000102002039000000000042004b0000037e0000c13d000000200030008c0000059c0000413d0000001f021000390000000502200270000002970220009a000000200010008c0000027e02004041000000000000043f0000001f033000390000000503300270000002970330009a000000000032004b0000059c0000813d000000000002041b0000000102200039000000000032004b000005980000413d0000001f0010008c000006440000a13d000000000000043f00000298031001980000064e0000c13d000000a0040000390000027e020000410000065c0000013d000002a801000041000000000010043f0000027801000041000008e100010430000500000003001d000000000020043f00000000010004110000027f011001c70000001c0010043f0000000001000414000002390010009c0000023901008041000000c00110021000000280011001c7000080100200003908df08da0000040f0000000100200190000005f90000613d000000000101043b0000000502100029000000000302041a0000023c01300198000004b40000613d000400000003001d000000000010043f000500000002001d0000000102200039000200000002001d000000000302041a0000000002000411000000000002004b000300000001001d000005d80000613d000000000012004b000005d80000613d000000000032004b000005d80000613d000100000003001d0000000001000414000002390010009c0000023901008041000000c0011002100000028c011001c7000080100200003908df08da0000040f0000000100200190000005f90000613d000000000101043b000000000101041a000000000001004b0000000103000029000002f70000613d000000000003004b000005dc0000613d0000000201000029000000000001041b000000040100002900000241011001970000000502000029000000000012041b0000000001000414000002390010009c0000023901008041000000c00110021000000292011001c7000080100200003908df08da0000040f0000000100200190000005f90000613d000000000101043b000000000201041a000000010220008a000000000021041b0000000001000414000002390010009c0000023901008041000000c0011002100000023e011001c70000800d0200003900000004030000390000029304000041000000030500002900000000060000190000000607000029000003f90000013d0000000001000019000008e100010430000000400200043d0000000006520019000000000005004b000006050000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000068004b000006010000c13d000000000004004b000006120000613d000000000151034f0000000304400210000000000506043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001604350000006001300210000002390020009c00000239020080410000004002200210000000000112019f000008e10001043000000001012000390000000606000029000000000061041b0000000001000414000002390010009c0000023901008041000000c0011002100000023e011001c70000800d020000390000000403000039000002a4040000410000000507000029000003f90000013d000000000002004b0000006f0000613d0000006002200210000000000121019f0000024002000041000000000012041b0000000001000019000008e00001042e0000029101000041000000000010043f0000027801000041000008e1000104300000000401000029000000000001041b000000060100002908df08a90000040f0000000001000019000008e00001042e000000000021041b0000000001000414000002390010009c0000023901008041000000c0011002100000023e011001c70000800d0200003900000004030000390000029304000041000000000500001900000000060004110000000607000029000003f90000013d000000000001004b0000000002000019000006480000613d000000a00200043d0000000303100210000002b50330027f000002b503300167000000000332016f0000000102100210000006670000013d0000027e020000410000002005000039000000010430008a0000000504400270000002990440009a000000000605001900000080055000390000000005050433000000000052041b00000020056000390000000102200039000000000042004b000006530000c13d000000a004600039000000000013004b000006650000613d0000000303100210000000f80330018f000002b50330027f000002b5033001670000000004040433000000000334016f000000000032041b00000001020000390000000103100210000000000123019f000000000010041b0000000001000019000008e00001042e0000000007640019000000000006004b000006740000613d00000000080300190000000009040019000000008a0804340000000009a90436000000000079004b000006700000c13d000000000005004b000006810000613d00000000036300190000000305500210000000000607043300000000065601cf000000000656022f00000000030304330000010005500089000000000353022f00000000035301cf000000000363019f000000000037043500000000011400190000000000010435000000400100043d000600000001001d000004670000013d0000002003000039000000000331043600000000420204340000000000230435000002b3062001970000001f0520018f0000004001100039000000000014004b0000069f0000813d000000000006004b0000069b0000613d00000000085400190000000007510019000000200770008a000000200880008a0000000009670019000000000a680019000000000a0a04330000000000a90435000000200660008c000006950000c13d000000000005004b000006b50000613d0000000007010019000006ab0000013d0000000007610019000000000006004b000006a80000613d00000000080400190000000009010019000000008a0804340000000009a90436000000000079004b000006a40000c13d000000000005004b000006b50000613d00000000046400190000000305500210000000000607043300000000065601cf000000000656022f00000000040404330000010005500089000000000454022f00000000045401cf000000000464019f0000000000470435000000000421001900000000000404350000001f02200039000002b3022001970000000001210019000000000001042d000002b60010009c000006cb0000213d000000630010008c000006cb0000a13d00000002030003670000000401300370000000000101043b0000023c0010009c000006cb0000213d0000002402300370000000000202043b0000023c0020009c000006cb0000213d0000004403300370000000000303043b000000000001042d0000000001000019000008e1000104300000001f02200039000002b3022001970000000001120019000000000021004b00000000020000390000000102004039000002830010009c000006d90000213d0000000100200190000006d90000c13d000000400010043f000000000001042d0000029a01000041000000000010043f0000004101000039000000040010043f0000028201000041000008e1000104300007000000000002000500000003001d0000023c022001970007023c0010019c0000000003000411000007230000613d000000000002004b000007250000613d0000000201000039000000000101041a0000023c04100198000600000002001d000007260000613d00000289010000410000000000100443000400000004001d00000004004004430000000001000414000002390010009c0000023901008041000000c0011002100000028a011001c7000080020200003908df08da0000040f0000000100200190000007a50000613d000000000101043b000000000001004b0000000603000029000007910000613d000000400400043d00000064014000390000000502000029000000000021043500000044014000390000000000310435000000240140003900000007020000290000000000210435000002a2010000410000000000140435000000040140003900000000020004110000000000210435000002390040009c000300000004001d0000023901000041000000000104401900000040011002100000000002000414000002390020009c0000023902008041000000c002200210000000000112019f000002b7011001c7000000040200002908df08da0000040f0000006003100270000102390030019d00030000000103550000000100200190000007a60000613d0000000301000029000002b80010009c000007c50000813d000000400010043f0000000003000411000007260000013d000600000002001d000007260000013d000600000000001d0000000501000029000000000010043f0000027f013001c70000001c0010043f0000000001000414000002390010009c0000023901008041000000c00110021000000280011001c7000080100200003908df08da0000040f00000001002001900000000603000029000007910000613d00000005020000290000000102200210000000000101043b0000000004210019000000000504041a0000023c01500197000000070010006c000007930000c13d000000000001004b000007930000613d0000000701000029000000000010043f0000000106400039000000000706041a0000000002000411000000000012004b0000075d0000613d000000000072004b0000075d0000613d000100000007001d000200000006001d000300000005001d000400000004001d0000000001000414000002390010009c0000023901008041000000c0011002100000028c011001c7000080100200003908df08da0000040f00000006030000290000000100200190000007910000613d000000000101043b000000000101041a000000000001004b0000000404000029000000030500002900000002060000290000000107000029000007a10000613d000000000007004b000007600000613d000000000006041b000000070130014f000000000151013f000000000014041b0000000001000414000002390010009c0000023901008041000000c00110021000000292011001c7000080100200003908df08da0000040f00000006030000290000000100200190000007910000613d000000000101043b000000000201041a000000010220008a000000000021041b000000000030043f0000000001000414000002390010009c0000023901008041000000c00110021000000292011001c7000080100200003908df08da0000040f00000006060000290000000100200190000007910000613d000000000101043b000000000201041a0000000102200039000002390320019700000000006300aa0000079a0000613d000000000021041b0000000001000414000002390010009c0000023901008041000000c0011002100000023e011001c70000800d02000039000000040300003900000293040000410000000705000029000000050700002908df08d50000040f0000000100200190000007910000613d000000000001042d0000000001000019000008e100010430000000000001004b00000000010000390000000401006039000002b90200004100000000002104350000027801000041000008e100010430000000000006004b00000000010000390000000401006039000002940200004100000000002104350000027801000041000008e100010430000002a501000041000000000010043f0000027801000041000008e100010430000000000001042f00000239033001970000001f0530018f0000023b06300198000000400200043d0000000004620019000007b20000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000007ae0000c13d000000000005004b000007bf0000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f00000000001404350000006001300210000002390020009c00000239020080410000004002200210000000000112019f000008e1000104300000029a01000041000000000010043f0000004101000039000000040010043f0000028201000041000008e1000104300001000000000002000100000001001d000000000010043f0000027f010000410000001c0010043f0000000001000414000002390010009c0000023901008041000000c00110021000000280011001c7000080100200003908df08da0000040f0000000100200190000007e10000613d00000001020000290000000102200210000000000101043b0000000001210019000000000101041a0000023c01100198000007e30000613d000000000001042d0000000001000019000008e100010430000002a601000041000000000010043f0000027801000041000008e1000104300000023d01000041000000000101041a0000000002000411000000000012004b000007ed0000c13d000000000001042d000002a801000041000000000010043f0000027801000041000008e1000104300003000000000002000000400900043d000000800690003900000080050000390000000000560435000000600590003900000000003504350000023c0110019700000040039000390000000000130435000000200190003900000000030004110000000000310435000002ba010000410000000000190435000000001a040434000000a0039000390000000000a3043500000000000a004b000300000009001d000008380000613d000200000002001d0000023900a0009c000002390200004100000000020a40190000006002200210000002390010009c00000239010080410000004001100210000000000112019f0000000002000414000002390020009c0000023902008041000000c002200210000000000112019f000000040200003900010000000a001d08df08da0000040f000000010a0000290000000309000029000000600210027000000239022001970000000000a2004b00000000030a001900000000030240190000001f0430018f000000c0069000390000023b053001980000000003560019000008280000613d000000000701034f000000007807043c0000000006860436000000000036004b000008240000c13d000000000004004b000008350000613d000000000551034f0000000304400210000000000603043300000000064601cf000000000646022f000000000505043b0000010004400089000000000545022f00000000044501cf000000000464019f0000000000430435000100000002001f000300000001035500000002020000290000001c01900039000002390010009c00000239010080410000004001100210000000a403a00039000002390030009c00000239030080410000006003300210000000000113019f0000000003000414000002390030009c0000023903008041000000c003300210000000000113019f08df08d50000040f000000030a00002900000060031002700000023903300197000000200030008c000000200400003900000000040340190000001f0540018f000000200640019000000000046a0019000008570000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000048004b000008530000c13d000000000005004b000008640000613d000000000661034f0000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f00000000005404350003000000010355000100000003001f000000000003004b00000001022061bf00000001002001900000086e0000613d00000000010a0433000002bb0010009c0000088c0000c13d000000000001042d0000001f0430018f0000023b0530019800000000025a0019000008780000613d000000000601034f0000000307000029000000006806043c0000000007870436000000000027004b000008740000c13d000000000004004b000008850000613d000000000151034f0000000304400210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f000000000012043500000060013002100000000302000029000002390020009c00000239020080410000004002200210000000000121019f000008e100010430000002bc01000041000000000010043f0000027801000041000008e1000104300001000000000002000100000001001d000000000010043f0000027f010000410000001c0010043f0000000001000414000002390010009c0000023901008041000000c00110021000000280011001c7000080100200003908df08da0000040f0000000100200190000008a70000613d00000001020000290000000102200210000000000101043b0000000001210019000000000101041a0000023c001001980000000001000039000000010100c039000000000001042d0000000001000019000008e10001043000010000000000020000023d02000041000000000502041a00000000020004140000023c06100197000002390020009c0000023902008041000000c0012002100000023e011001c70000800d0200003900000003030000390000023f04000041000100000006001d08df08d50000040f0000000100200190000008bd0000613d0000023d010000410000000102000029000000000021041b000000000001042d0000000001000019000008e100010430000000000001042f000002390010009c00000239010080410000004001100210000002390020009c00000239020080410000006002200210000000000112019f0000000002000414000002390020009c0000023902008041000000c002200210000000000112019f0000023e011001c7000080100200003908df08da0000040f0000000100200190000008d30000613d000000000101043b000000000001042d0000000001000019000008e100010430000008d8002104210000000102000039000000000001042d0000000002000019000000000001042d000008dd002104230000000102000039000000000001042d0000000002000019000000000001042d000008df00000432000008e00001042e000008e1000104300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000001ffffffe000000000000000000000000000000000000000000000000000000000ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7487392702000000000000000000000000000000000000000000000000000000000000008be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e00000000000000000000000000000000000000000000000aa4ec00224afccfdb7ffffffffffffffffffffffff00000000000000000000000000000000000000000200000000000000000000000000000000000040000000000000000000000000cc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac0000000200000000000000000000000000000080000001000000000000000000000000000000000000000000000000000000000000000000000000006352211d00000000000000000000000000000000000000000000000000000000a22cb46400000000000000000000000000000000000000000000000000000000e8a3d48400000000000000000000000000000000000000000000000000000000f04e283d00000000000000000000000000000000000000000000000000000000f04e283e00000000000000000000000000000000000000000000000000000000f2fde38b00000000000000000000000000000000000000000000000000000000fee81cf400000000000000000000000000000000000000000000000000000000e8a3d48500000000000000000000000000000000000000000000000000000000e985e9c500000000000000000000000000000000000000000000000000000000b88d4fdd00000000000000000000000000000000000000000000000000000000b88d4fde00000000000000000000000000000000000000000000000000000000c87b56dd00000000000000000000000000000000000000000000000000000000a22cb46500000000000000000000000000000000000000000000000000000000a9fc664e000000000000000000000000000000000000000000000000000000008da5cb5a0000000000000000000000000000000000000000000000000000000095d89b400000000000000000000000000000000000000000000000000000000095d89b4100000000000000000000000000000000000000000000000000000000a0712d68000000000000000000000000000000000000000000000000000000008da5cb5b00000000000000000000000000000000000000000000000000000000938e3d7b00000000000000000000000000000000000000000000000000000000715018a500000000000000000000000000000000000000000000000000000000715018a6000000000000000000000000000000000000000000000000000000008ada6b0f000000000000000000000000000000000000000000000000000000006352211e0000000000000000000000000000000000000000000000000000000070a082310000000000000000000000000000000000000000000000000000000023b872dc0000000000000000000000000000000000000000000000000000000042966c670000000000000000000000000000000000000000000000000000000054d1f13c0000000000000000000000000000000000000000000000000000000054d1f13d0000000000000000000000000000000000000000000000000000000056d3163d0000000000000000000000000000000000000000000000000000000042966c68000000000000000000000000000000000000000000000000000000004f558e79000000000000000000000000000000000000000000000000000000002a552059000000000000000000000000000000000000000000000000000000002a55205a0000000000000000000000000000000000000000000000000000000042842e0e0000000000000000000000000000000000000000000000000000000023b872dd000000000000000000000000000000000000000000000000000000002569296200000000000000000000000000000000000000000000000000000000095ea7b2000000000000000000000000000000000000000000000000000000000d705df5000000000000000000000000000000000000000000000000000000000d705df60000000000000000000000000000000000000000000000000000000018160ddd00000000000000000000000000000000000000000000000000000000095ea7b300000000000000000000000000000000000000000000000000000000098144d40000000000000000000000000000000000000000000000000000000006fdde020000000000000000000000000000000000000000000000000000000006fdde0300000000000000000000000000000000000000000000000000000000081812fc0000000000000000000000000000000000000000000000000000000001ffc9a70000000000000000000000000000000000000000000000000000000004634d8d00000000000000000000000000000000000000000000000000000000389a75e10000000000000000000000000000000000000020000000800000000000000000000000000000000000000000000000000000000000000000000000007448fbae00000000000000000000000000000000000000040000001c000000000000000002000000000000000000000000000000000000200000000c0000000000000000796b89b91644bc98cd93958e4c9038275d622183e25ac5af08cc6b5d955391320200000200000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000006f5e88180000000000000000000000000000000000000000000000000a5a2e7a00000000290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5637d8825530a5a2e7a0000000000000000000000000000000000000000000000000200000000000000000000000000000000000020000000000000000000000000c87b56dd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ffffffffffffffe0000000000000000000000000000000000000000000000003ffffffffffffffe0ceea21b60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b830200000200000000000000000000000000000024000000000000000000000000020000000000000000000000000000000000004000000080000000000000000002000000000000000000000000000000000000300000000c000000000000000017307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e02000002000000000000000000000000000000440000000000000000000000006e67310a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c991cbb1020000000000000000000000000000000000001c0000000c0000000000000000ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef000000000000000000000000000000000000000000000000ea553b3401336cea4d494e4552000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff40d6f21326ab749d5729fcba5677c79037b459436ab7bff709c9d06ce9f10c1a9d000000000000000000000000000000000000000000000000ffffffffffffffe0d6f21326ab749d5729fcba5677c79037b459436ab7bff709c9d06ce9f10c1a9c4e487b7100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008f4eb6040000000000000000000000000000000000000020000000000000000000000000fa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c920000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000040000000000000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd5d00dbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1dcaee23ea0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000008000000000000000008c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925000000000000000000000000000000000000000000000000000000004b6e7f1800000000000000000000000000000000000000000000000000000000ceea21b6426967636f696e204d696e6572730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000082b4290000000000000000000000000000000000000000000000000000000000b4457eaa00000000000000000000000000000000000000000000000000000000350a88b300000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b5e139f0000000000000000000000000000000000000000000000000000000080ac58cd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b5e139f0000000000000000000000000000000000000000000000000000000080ac58cd2a55205a0000000000000000000000000000000000000000000000000000000001ffc9a700000000000000000000000000000000000000000000000000000000ad0d7f6c00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000840000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000ceea21b6a114810000000000000000000000000000000000000000000000000000000000150b7a02150b7a020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d1a57ed60000000000000000000000000000000000000000000000000000000000000000000000000000000000a26469706673582212202fc15aa79084333c0e69adb35e17d7033b9d3b97895c79e0c5b78279f7e1c39764736f6c6378247a6b736f6c633a312e352e31353b736f6c633a302e382e33303b6c6c766d3a312e302e320055
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000056c667bd74cc0aab32297754bbf5dfe626d72c4d00000000000000000000000089eb96a0a157f935de38d548b79af511d424e33a000000000000000000000000721c008fdff27bf06e7e123956e2fe03b63342e300000000000000000000000041b64aa2a9f90bf20a48c264226e1651abb74573
-----Decoded View---------------
Arg [0] : _owner (address): 0x56C667bD74cC0aab32297754Bbf5DFe626d72c4d
Arg [1] : _main (address): 0x89eB96a0A157f935dE38d548b79AF511d424E33a
Arg [2] : transferValidator (address): 0x721C008fdff27BF06E7E123956E2Fe03B63342e3
Arg [3] : _renderer (address): 0x41b64aA2A9f90bF20a48c264226e1651abb74573
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000056c667bd74cc0aab32297754bbf5dfe626d72c4d
Arg [1] : 00000000000000000000000089eb96a0a157f935de38d548b79af511d424e33a
Arg [2] : 000000000000000000000000721c008fdff27bf06e7e123956e2fe03b63342e3
Arg [3] : 00000000000000000000000041b64aa2a9f90bf20a48c264226e1651abb74573
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.