Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 18904890 | 239 days ago | IN | 0 ETH | 0.04391152 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
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:
ERC721BaselineImplementation
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 20000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.21; import {ERC721Upgradeable} from "./ERC721Upgradeable.sol"; import {IERC165} from "@openzeppelin/contracts/interfaces/IERC165.sol"; import {IERC721Baseline} from "./IERC721Baseline.sol"; import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import {Utils} from "./Utils.sol"; /** * @title ERC721BaselineImplementation * @custom:version v0.1.0 * @notice A baseline ERC721 contract implementation that exposes internal methods to a proxy instance. */ contract ERC721BaselineImplementation is ERC721Upgradeable, IERC721Baseline { /** * @dev ERC721Baseline uses ERC-7201 (Namespaced Storage Layout) * to prevent collisions with the proxies storage. * See https://eips.ethereum.org/EIPS/eip-7201. * * Proxies are encouraged, but not required, to use a similar pattern for storage. * * @custom:storage-location erc7201:erc721baseline.implementation.storage */ struct ERC721BaselineStorage { string VERSION; /** * Metadata */ uint256 totalSupply; mapping(uint256 => string) __tokenURI; string __sharedURI; string __baseURI; /** * Royalties */ address payable _royaltiesReceiver; uint16 _royaltiesBps; /** * @dev Tracks whether the proxy's `_beforeTokenTransfer` hook is enabled or not. * When enabled, this contract will call the hook when ERC721 calls `_update`. */ bool _beforeTokenTransferHookEnabled; /** * Access Control */ /** * @dev Tracks the contract admins. */ mapping(address => bool) _admins; /** * @dev Tracks the contract owner. */ address _owner; } /** * @dev The ERC7-201 storage slot. See https://eips.ethereum.org/EIPS/eip-7201. * The namespace is: * erc721baseline.implementation.storage * keccak256(abi.encode(uint256(keccak256("erc721baseline.implementation.storage")) - 1)) & ~bytes32(uint256(0xff)) */ bytes32 private constant ERC721BaselineStorageLocation = 0xd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b00; /** * @dev Convenience method to access the storage at ERC721BaselineStorageLocation location. * * Usage: * * ERC721BaselineStorage storage $ = _getStorage(); * * if ($._royaltiesReceiver != address(0)) { * $._royaltiesReceiver = address(0); * } * * @return $ a reference to the storage at ERC721BaselineStorageLocation location for reading and writing */ function _getStorage() private pure returns (ERC721BaselineStorage storage $) { assembly { $.slot := ERC721BaselineStorageLocation } } constructor() { _getStorage().VERSION = "0.1.0"; _disableInitializers(); } /** * @inheritdoc IERC721Baseline */ function VERSION() external view returns (string memory) { return _getStorage().VERSION; } /** * @notice Enables a proxy to call selected methods that are implemented in this contract. * @dev Throws if called by any account other than the proxy contract itself. */ modifier onlyProxy { if (_msgSender() != address(this)) { revert NotProxy(); } _; } /************************************************ * Supported Interfaces ************************************************/ /** * @inheritdoc IERC165 */ function supportsInterface(bytes4 interfaceId) public view override(IERC165, ERC721Upgradeable) returns (bool) { return ( interfaceId == /* NFT Royalty Standard */ bytes4(0x2a55205a) || interfaceId == /* Metadata Update Extension */ bytes4(0x49064906) || interfaceId == type(IERC721Baseline).interfaceId || super.supportsInterface(interfaceId) ); } /************************************************ * Initializer ************************************************/ /** * @inheritdoc IERC721Baseline */ function initialize(string memory name, string memory symbol) external initializer { __ERC721_init(name, symbol); _setAdmin(_msgSender(), true); _transferOwnership(_msgSender()); } /************************************************ * Metadata ************************************************/ /** * @inheritdoc IERC721Baseline */ function totalSupply() external view returns (uint256) { return _getStorage().totalSupply; } /** * Metadata > Token URI */ /** * @inheritdoc IERC721Baseline */ function __tokenURI(uint256 tokenId) external view returns (string memory) { return _getStorage().__tokenURI[tokenId]; } /** * @inheritdoc IERC721Baseline */ function __setTokenURI(uint256 tokenId, string calldata tokenURI) external onlyProxy { _getStorage().__tokenURI[tokenId] = tokenURI; emit MetadataUpdate(tokenId); } /** * @inheritdoc IERC721Baseline */ function __sharedURI() external view returns (string memory) { return _getStorage().__sharedURI; } /** * @inheritdoc IERC721Baseline */ function __setSharedURI(string calldata sharedURI) external onlyProxy { _getStorage().__sharedURI = sharedURI; } /** * @inheritdoc IERC721Baseline */ function __baseURI() external view returns (string memory) { return _getStorage().__baseURI; } /** * @inheritdoc IERC721Baseline */ function __setBaseURI(string calldata baseURI) external onlyProxy { _getStorage().__baseURI = baseURI; } /** * @notice Returns the URI associated with a token ID. * * @dev The tokenURI implementation allows to define uris in the following order: * * 1. Token-specific URI by ID. * 2. Shared URI. * 3. Shared base URI + token ID. * 4. Empty string if none of the above was found. * * @param tokenId token ID * @return string the token URI */ function tokenURI(uint256 tokenId) public view override returns (string memory) { _requireOwned(tokenId); ERC721BaselineStorage storage $ = _getStorage(); string memory uri = $.__tokenURI[tokenId]; if (bytes(uri).length > 0) { return uri; } if (bytes($.__sharedURI).length > 0) { return $.__sharedURI; } if (bytes($.__baseURI).length > 0) { return string.concat($.__baseURI, Utils.toString(tokenId)); } return ""; } /************************************************ * Royalties ************************************************/ /** * @inheritdoc IERC721Baseline */ function royaltiesReceiver() external view returns (address) { return _getStorage()._royaltiesReceiver; } /** * @inheritdoc IERC721Baseline */ function royaltiesBps() external view returns (uint256) { return _getStorage()._royaltiesBps; } /** * @dev See {IERC2981-royaltyInfo}. */ function royaltyInfo( uint256, uint256 salePrice ) external view returns (address, uint256) { ERC721BaselineStorage storage $ = _getStorage(); if ($._royaltiesBps > 0 && $._royaltiesReceiver != address(0)) { return ($._royaltiesReceiver, salePrice * $._royaltiesBps / 10000); } return (address(0), 0); } function _configureRoyalties(address payable receiver, uint16 bps) internal { ERC721BaselineStorage storage $ = _getStorage(); if (receiver != $._royaltiesReceiver) { $._royaltiesReceiver = receiver; } if (bps != $._royaltiesBps) { $._royaltiesBps = bps; } } /** * @inheritdoc IERC721Baseline */ function configureRoyalties(address payable receiver, uint16 bps) external { this.requireAdmin(_msgSender()); _configureRoyalties(receiver, bps); } /** * @inheritdoc IERC721Baseline */ function __configureRoyalties(address payable receiver, uint16 bps) external onlyProxy { _configureRoyalties(receiver, bps); } /************************************************ * Internal ERC721 methods exposed to the proxy ************************************************/ /** * @inheritdoc IERC721Baseline */ function __ownerOf(uint256 tokenId) external view returns (address) { return _ownerOf(tokenId); } /** * @inheritdoc IERC721Baseline */ function __update(address to, uint256 tokenId, address auth) external onlyProxy returns (address) { return super._update(to, tokenId, auth); } /** * @inheritdoc IERC721Baseline */ function __mint(address to, uint256 tokenId) external onlyProxy { _getStorage().totalSupply += 1; _mint(to, tokenId); } /** * @inheritdoc IERC721Baseline */ function __mint(address to, uint256 tokenId, string calldata tokenURI) external onlyProxy { ERC721BaselineStorage storage $ = _getStorage(); $.totalSupply += 1; $.__tokenURI[tokenId] = tokenURI; _mint(to, tokenId); } /** * @inheritdoc IERC721Baseline */ function __burn(uint256 tokenId) external onlyProxy { ERC721BaselineStorage storage $ = _getStorage(); $.totalSupply -= 1; if (bytes($.__tokenURI[tokenId]).length > 0) { delete $.__tokenURI[tokenId]; } _burn(tokenId); } /** * @inheritdoc IERC721Baseline */ function __transfer(address from, address to, uint256 tokenId) external onlyProxy { _transfer(from, to, tokenId); } /** * @inheritdoc IERC721Baseline */ function __setBeforeTokenTransferHookEnabled(bool enabled) external onlyProxy { _getStorage()._beforeTokenTransferHookEnabled = enabled; } /** * @dev See {ERC721-_update}. * @dev Allows to define a `_beforeTokenTransfer` hook method in the proxy contract that is called when `_beforeTokenTransferHookEnabled` is `true`. * * The proxy's `_beforeTokenTransfer` method is called with the following params: * * - address the transaction's _msgSender() * - address from * - address to * - uint256 tokenId */ function _update( address to, uint256 tokenId, address auth ) internal override returns (address) { if (_getStorage()._beforeTokenTransferHookEnabled == true) { (bool success, bytes memory reason) = address(this).delegatecall( abi.encodeWithSignature( "_beforeTokenTransfer(address,address,address,uint256)", _msgSender(), _ownerOf(tokenId), to, tokenId ) ); if (success == false) { if (reason.length == 0) revert("_beforeTokenTransfer"); assembly { revert(add(32, reason), mload(reason)) } } } return super._update(to, tokenId, auth); } /** * @inheritdoc IERC721Baseline */ function __checkOnERC721Received( address sender, address from, address to, uint256 tokenId, bytes memory data ) external { _checkOnERC721Received(sender, from, to, tokenId, data); } /** * @inheritdoc IERC721Baseline */ function __isAuthorized(address owner, address spender, uint256 tokenId) external view returns (bool) { return _isAuthorized(owner, spender, tokenId); } /** * @inheritdoc IERC721Baseline */ function __approve(address to, uint256 tokenId, address auth, bool emitEvent) external onlyProxy { _approve(to, tokenId, auth, emitEvent); } /** * @inheritdoc IERC721Baseline */ function __setApprovalForAll(address owner, address operator, bool approved) external onlyProxy { _setApprovalForAll(owner, operator, approved); } /************************************************ * Access control ************************************************/ /** * Implements a multi-admin system and a minimal Ownable-compatible API. */ /** * Access control > multi-admin system */ /** * @dev Internal method: checks if an address is the contract owner or an admin. * * @param addr address to check * @return bool whether the address is an admin or not */ function _isAdmin(address addr) internal view returns (bool) { ERC721BaselineStorage storage $ = _getStorage(); return $._owner == addr || $._admins[addr] == true; } /** * @inheritdoc IERC721Baseline */ function isAdmin(address addr) external view returns (bool) { return _isAdmin(addr); } /** * @dev Internal method: allows to add or remove an admin. * * @param addr address to add or remove * @param add boolean indicating whether the address should be granted or revoked rights */ function _setAdmin(address addr, bool add) internal { if (add) { _getStorage()._admins[addr] = true; } else { delete _getStorage()._admins[addr]; } emit AdminSet(addr, add); } /** * @inheritdoc IERC721Baseline */ function setAdmin(address addr, bool add) external { this.requireAdmin(_msgSender()); _setAdmin(addr, add); } /** * @inheritdoc IERC721Baseline */ function __setAdmin(address addr, bool add) external onlyProxy { _setAdmin(addr, add); } /** * @inheritdoc IERC721Baseline */ function requireAdmin(address addr) external view { if (_isAdmin(addr) == false) { revert Unauthorized(); } } /** * Access control > Ownable-compatible API. */ /** * @inheritdoc IERC721Baseline */ function owner() external view returns (address) { return _getStorage()._owner; } /** * @dev Internal method: transfers ownership of the contract to a new account. * * @param newOwner new owner address */ function _transferOwnership(address newOwner) internal { ERC721BaselineStorage storage $ = _getStorage(); address oldOwner = $._owner; $._owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @inheritdoc IERC721Baseline */ function transferOwnership(address newOwner) external { this.requireAdmin(_msgSender()); _transferOwnership(newOwner); } /** * @inheritdoc IERC721Baseline */ function __transferOwnership(address newOwner) external onlyProxy { _transferOwnership(newOwner); } /************************************************ * Utils ************************************************/ /** * @inheritdoc IERC721Baseline */ function recover(bytes32 hash, bytes memory signature) external view returns (address) { return Utils.recover(Utils.toEthSignedMessageHash(hash), signature); } /** * @inheritdoc IERC721Baseline */ function recoverCalldata(bytes32 hash, bytes calldata signature) external view returns (address) { return Utils.recoverCalldata(Utils.toEthSignedMessageHash(hash), signature); } /** * @inheritdoc IERC721Baseline */ function toString(uint256 value) external pure returns (string memory) { return Utils.toString(value); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.21; /** * @title Utils * @custom:version v0.1.0 * @notice Utilities used in ERC721Baseline. */ library Utils { /************************************************ * ECDSA Utils ************************************************/ /** * recover * * @notice Recovers the signer's address from a message digest `hash`, and the `signature`. * MIT Licensed, (c) 2022-present Solady. */ function recover(bytes32 hash, bytes memory signature) internal view returns (address result) { /// @solidity memory-safe-assembly assembly { result := 1 let m := mload(0x40) // Cache the free memory pointer. // prettier-ignore for {} 1 {} { mstore(0x00, hash) mstore(0x40, mload(add(signature, 0x20))) // `r`. if eq(mload(signature), 64) { let vs := mload(add(signature, 0x40)) mstore(0x20, add(shr(255, vs), 27)) // `v`. mstore(0x60, shr(1, shl(1, vs))) // `s`. break } if eq(mload(signature), 65) { mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`. mstore(0x60, mload(add(signature, 0x40))) // `s`. break } result := 0 break } result := mload( staticcall( gas(), // Amount of gas left for the transaction. result, // Address of `ecrecover`. 0x00, // Start of input. 0x80, // Size of input. 0x01, // Start of output. 0x20 // Size of output. ) ) // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. if iszero(returndatasize()) { mstore(0x00, 0x8baa579f) // `InvalidSignature()`. revert(0x1c, 0x04) } mstore(0x60, 0) // Restore the zero slot. mstore(0x40, m) // Restore the free memory pointer. } } /** * recoverCalldata * * @notice Recovers the signer's address from a message digest `hash`, and the `signature`. * MIT Licensed, (c) 2022-present Solady. */ function recoverCalldata( bytes32 hash, bytes calldata signature ) internal view returns (address result) { /// @solidity memory-safe-assembly assembly { result := 1 let m := mload(0x40) // Cache the free memory pointer. mstore(0x00, hash) // prettier-ignore for {} 1 {} { if eq(signature.length, 64) { let vs := calldataload(add(signature.offset, 0x20)) mstore(0x20, add(shr(255, vs), 27)) // `v`. mstore(0x40, calldataload(signature.offset)) // `r`. mstore(0x60, shr(1, shl(1, vs))) // `s`. break } if eq(signature.length, 65) { mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`. calldatacopy(0x40, signature.offset, 0x40) // Copy `r` and `s`. break } result := 0 break } result := mload( staticcall( gas(), // Amount of gas left for the transaction. result, // Address of `ecrecover`. 0x00, // Start of input. 0x80, // Size of input. 0x01, // Start of output. 0x20 // Size of output. ) ) // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. if iszero(returndatasize()) { mstore(0x00, 0x8baa579f) // `InvalidSignature()`. revert(0x1c, 0x04) } mstore(0x60, 0) // Restore the zero slot. mstore(0x40, m) // Restore the free memory pointer. } } /** * toEthSignedMessageHash * * @dev Returns an Ethereum Signed Message, created from a `hash`. * This produces a hash corresponding to the one signed with the * [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign) * JSON-RPC method as part of EIP-191. * MIT Licensed, (c) 2022-present Solady. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 result) { /// @solidity memory-safe-assembly assembly { mstore(0x20, hash) // Store into scratch space for keccak256. mstore(0x00, "\x00\x00\x00\x00\x19Ethereum Signed Message:\n32") // 28 bytes. result := keccak256(0x04, 0x3c) // `32 * 2 - (32 - 28) = 60 = 0x3c`. } } /************************************************ * String Utils ************************************************/ /** * @notice toString. * MIT Licensed, (c) 2022-present OpenZeppelin. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), "0123456789abcdef")) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.20; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be * reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.21; import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import {IERC2981} from "@openzeppelin/contracts/interfaces/IERC2981.sol"; /** * @title IERC721Baseline * @custom:version v0.1.0 * @notice A baseline ERC721 contract implementation that exposes internal methods to a proxy instance. */ interface IERC721Baseline is IERC721, IERC2981 { /** * @notice The version of the implementation contract. * @return string the implementation version */ function VERSION() external view returns (string memory); /** * @dev Indicates an unauthorized operation or unauthorized access attempt. */ error Unauthorized(); /************************************************ * Initializer ************************************************/ /** * @notice Initializes a proxy contract. * @dev This method MUST be called in the proxy constructor via delegatecall * to initialize the proxy with a name and symbol for the underlying ERC721. * * Additionally this method sets the deployer as owner and admin of the proxy. * * @param name contract name * @param symbol contract symbol */ function initialize(string memory name, string memory symbol) external; /************************************************ * Metadata ************************************************/ /** * Metadata > ERC-4906 events */ /** * @dev This event emits when the metadata of a token is changed. * So that the third-party platforms such as NFT market could * timely update the images and related attributes of the NFT. * * @param _tokenId the token ID being updated */ event MetadataUpdate(uint256 _tokenId); /** * @dev This event emits when the metadata of a range of tokens is changed. * So that the third-party platforms such as NFT market could * timely update the images and related attributes of the NFTs. * * @param _fromTokenId the starting token ID * @param _toTokenId the ending token ID */ event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId); /** * @notice The total minted supply. * @dev The supply is decreased when a token is burned. * Generally it is recommended to use a separate counter variable to track the supply available for minting. * * @return uint256 the existing tokens' supply */ function totalSupply() external view returns (uint256); /** * Token URI methods. * * The ERC721Baseline tokenURI implementation allows to define uris in the following order: * * 1. Token-specific URI by ID. * 2. Shared URI. * 3. Shared base URI + token ID. * 4. Empty string if none of the above was found. */ /** * @notice Returns the token URI for a token ID. * * @param tokenId token ID * @return string the token URI for the token ID */ function __tokenURI(uint256 tokenId) external view returns (string memory); /** * @notice Sets the token URI for a token ID. * @dev Emits EIP-4906's `MetadataUpdate` event with the `tokenId`. * This method is internal and only the proxy contract can call it. * * @param tokenId token ID * @param tokenURI URI pointing to the metadata */ function __setTokenURI(uint256 tokenId, string calldata tokenURI) external; /** * @notice Returns the shared URI for the tokens. * @dev This method is internal and only the proxy contract can call it. * * @return string the shared URI */ function __sharedURI() external view returns (string memory); /** * @notice Sets a shared URI for the tokens. * @dev This method doesn't emit the EIP-4906's `BatchMetadataUpdate` event * because ERC721Baseline allows to mint any token ID, starting at any index. * The proxy should emit `BatchMetadataUpdate`. * * This method is internal and only the proxy contract can call it. * * @param sharedURI shared URI for the tokens */ function __setSharedURI(string calldata sharedURI) external; /** * @notice Returns the base URI for the tokens. * @dev When set this URI is prepended to the token ID. * * @return string the base URI */ function __baseURI() external view returns (string memory); /** * @notice Sets a contract-wide base URI. * @dev This method doesn't emit the EIP-4906 `BatchMetadataUpdate` event * because ERC721Baseline allows to mint any token ID, starting at any index. * The proxy should emit `BatchMetadataUpdate`. * * This method is internal and only the proxy contract can call it. * * @param baseURI shared base URI for the tokens */ function __setBaseURI(string calldata baseURI) external; /************************************************ * Royalties ************************************************/ /** * @notice The address of the royalties receiver. * * @return address the address of the royalties receiver */ function royaltiesReceiver() external view returns (address); /** * @notice The royalties rate in basis points (100 bps = 1%). * * @return uint256 the royalties rate */ function royaltiesBps() external view returns (uint256); /** * @notice Configures royalties receiver and bps for all the tokens. * @dev Bps stants for basis points where 100 bps = 1%. * The sender must be an admin. * * @param receiver address for the royalties receiver * @param bps (basis points) royalties rate */ function configureRoyalties(address payable receiver, uint16 bps) external; /** * @notice Configures royalties receiver and bps for all the tokens. * @dev Bps stants for basis points where 100 bps = 1%. * This method is internal and only the proxy contract can call it. * * @param receiver address for the royalties receiver * @param bps (basis points) royalties rate */ function __configureRoyalties(address payable receiver, uint16 bps) external; /************************************************ * Internal ERC721 methods exposed to the proxy ************************************************/ /** * @dev Indicates an invalid attempt to call a method from outside of the proxy. */ error NotProxy(); /** * @dev See {ERC721-_ownerOf}. */ function __ownerOf(uint256 tokenId) external returns (address); /** * @dev See {ERC721-_update}. * This method is internal and only the proxy contract can call it. */ function __update(address to, uint256 tokenId, address auth) external returns (address); /** * @dev See {ERC721-_mint}. * This method is internal and only the proxy contract can call it. */ function __mint(address to, uint256 tokenId) external; /** * @dev Similar to {ERC721-_mint} but allows to set a dedicated tokenURI for the token. * This method is internal and only the proxy contract can call it. */ function __mint(address to, uint256 tokenId, string calldata tokenURI) external; /** * @dev See {ERC721-_burn}. * This method is internal and only the proxy contract can call it. */ function __burn(uint256 tokenId) external; /** * @dev See {ERC721-_transfer}. * This method is internal and only the proxy contract can call it. */ function __transfer(address from, address to, uint256 tokenId) external; /** * @notice Allows to enable or disable a `_beforeTokenTransfer` hook method defined in the proxy contract. * @dev This method is internal and only the proxy contract can call it. * * When enabled, the proxy's `_beforeTokenTransfer` hook method is invoked prior to a transfer. * * The proxy's `_beforeTokenTransfer` method is called with the following params: * * - address the transaction's _msgSender() * - address from * - address to * - uint256 tokenId * * This method is internal and only the proxy contract can call it. */ function __setBeforeTokenTransferHookEnabled(bool enabled) external; /** * @dev See {ERC721-_checkOnERC721Received}. * * NOTE: this method accepts an additional first parameter that is the original transaction's `msg.sender`. */ function __checkOnERC721Received(address sender, address from, address to, uint256 tokenId, bytes memory data) external; /** * @dev See {ERC721-_isAuthorized}. */ function __isAuthorized(address owner, address spender, uint256 tokenId) external view returns (bool); /** * @dev See {ERC721-_approve}. * This method is internal and only the proxy contract can call it. */ function __approve(address to, uint256 tokenId, address auth, bool emitEvent) external; /** * @dev See {ERC721-_setApprovalForAll}. * This method is internal and only the proxy contract can call it. */ function __setApprovalForAll(address owner, address operator, bool approved) external; /************************************************ * Access control ************************************************/ /** * Implements a multi-admin system and a minimal Ownable-compatible API. */ /** * Access control > multi-admin system */ /** * @notice Checks if an address is the contract owner or an admin. * * @param addr address to check * @return bool whether the address is an admin or not */ function isAdmin(address addr) external view returns (bool); /** * @dev Emits when an admin is added or removed. * * @param addr address that is being added or removed as an admin * @param add boolean indicating whether the address was grented or revoked admin rights */ event AdminSet(address indexed addr, bool indexed add); /** * @notice Allows to add or remove an admin. * Can only be called by an admin. * * @param addr address to add or remove * @param add boolean indicating whether the address should be granted or revoked rights */ function setAdmin(address addr, bool add) external; /** * @notice Checks whether an address is an admin and reverts with an `Unauthorized` error if not. * @dev Call `requireAdmin` in proxies to implement admin-only public methods. * * @param addr the address to check */ function requireAdmin(address addr) external view; /** * @notice Allows to add or remove an admin. * @dev This method is internal and only the proxy contract can call it. * * @param addr address to add or remove * @param add boolean indicating whether the address should be granted or revoked rights */ function __setAdmin(address addr, bool add) external; /** * Access control > Ownable-compatible API. */ /** * @notice Returns the address of the contract owner. * * @return address of the contract owner */ function owner() external view returns (address); /** * @dev Emits when the contract ownership is transferred. * * @param previousOwner old owner address * @param newOwner new owner address */ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @notice Transfers ownership of the contract to a new account. * Can only be called by an admin. * * @param newOwner new owner address */ function transferOwnership(address newOwner) external; /** * @notice Transfers ownership of the contract to a new account. * @dev This method is internal and only the proxy contract can call it. * * @param newOwner new owner address */ function __transferOwnership(address newOwner) external; /************************************************ * Utils ************************************************/ /** * @dev Indicates an invalid signature. */ error InvalidSignature(); /** * @notice Recovers the signer's address from a message digest `hash`, and the `signature`. * * @param hash the message digest that was signed * @param signature the signature for hash * @return result address the recovered address */ function recover(bytes32 hash, bytes memory signature) external view returns (address result); /** * @notice Recovers the signer's address from a message digest `hash`, and the `signature`. * @dev In this method the signature comes from calldata. * * @param hash the message digest that was signed * @param signature the signature for hash * @return result address the recovered address */ function recoverCalldata(bytes32 hash, bytes calldata signature) external view returns (address result); /** * @notice Converts a uint256 to string * * @param value the uint256 to convert * @return string ASCII string decimal representation of `value` */ function toString(uint256 value) external pure returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "../utils/introspection/IERC165.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/ERC721.sol) pragma solidity 0.8.21; import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import {IERC721Metadata} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol"; import {IERC721Errors} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC-721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ abstract contract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721, IERC721Metadata, IERC721Errors { /// @custom:storage-location erc7201:openzeppelin.storage.ERC721 struct ERC721Storage { // Token name string _name; // Token symbol string _symbol; mapping(uint256 tokenId => address) _owners; mapping(address owner => uint256) _balances; mapping(uint256 tokenId => address) _tokenApprovals; mapping(address owner => mapping(address operator => bool)) _operatorApprovals; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ERC721")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant ERC721StorageLocation = 0x80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079300; function _getERC721Storage() private pure returns (ERC721Storage storage $) { assembly { $.slot := ERC721StorageLocation } } /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC721_init_unchained(name_, symbol_); } function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { ERC721Storage storage $ = _getERC721Storage(); $._name = name_; $._symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual returns (uint256) { ERC721Storage storage $ = _getERC721Storage(); if (owner == address(0)) { revert ERC721InvalidOwner(address(0)); } return $._balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual returns (address) { return _requireOwned(tokenId); } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual returns (string memory) { ERC721Storage storage $ = _getERC721Storage(); return $._name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual returns (string memory) { ERC721Storage storage $ = _getERC721Storage(); return $._symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256) public view virtual returns (string memory) { revert("Not Implemented"); } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual { _approve(to, tokenId, _msgSender()); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual returns (address) { _requireOwned(tokenId); return _getApproved(tokenId); } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual returns (bool) { ERC721Storage storage $ = _getERC721Storage(); return $._operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } // Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here. address previousOwner = _update(to, tokenId, _msgSender()); if (previousOwner != from) { revert ERC721IncorrectOwner(from, tokenId, previousOwner); } } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual { transferFrom(from, to, tokenId); _checkOnERC721Received(_msgSender(), from, to, tokenId, data); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist * * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the * core ERC-721 logic MUST be matched with the use of {_increaseBalance} to keep balances * consistent with ownership. The invariant to preserve is that for any address `a` the value returned by * `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`. */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { ERC721Storage storage $ = _getERC721Storage(); return $._owners[tokenId]; } /** * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted. */ function _getApproved(uint256 tokenId) internal view virtual returns (address) { ERC721Storage storage $ = _getERC721Storage(); return $._tokenApprovals[tokenId]; } /** * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in * particular (ignoring whether it is owned by `owner`). * * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this * assumption. */ function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) { return spender != address(0) && (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender); } /** * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner. * Reverts if `spender` does not have approval from the provided `owner` for the given token or for all its assets * the `spender` for the specific `tokenId`. * * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this * assumption. */ function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual { if (!_isAuthorized(owner, spender, tokenId)) { if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } else { revert ERC721InsufficientApproval(spender, tokenId); } } } /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that * a uint256 would ever overflow from increments when these increments are bounded to uint128 values. * * WARNING: Increasing an account's balance using this function tends to be paired with an override of the * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership * remain consistent with one another. */ function _increaseBalance(address account, uint128 value) internal virtual { ERC721Storage storage $ = _getERC721Storage(); unchecked { $._balances[account] += value; } } /** * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update. * * The `auth` argument is optional. If the value passed is non 0, then this function will check that * `auth` is either the owner of the token, or approved to operate on the token (by the owner). * * Emits a {Transfer} event. * * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}. */ function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) { ERC721Storage storage $ = _getERC721Storage(); address from = _ownerOf(tokenId); // Perform (optional) operator check if (auth != address(0)) { _checkAuthorized(from, auth, tokenId); } // Execute the update if (from != address(0)) { // Clear approval. No need to re-authorize or emit the Approval event _approve(address(0), tokenId, address(0), false); unchecked { $._balances[from] -= 1; } } if (to != address(0)) { unchecked { $._balances[to] += 1; } } $._owners[tokenId] = to; emit Transfer(from, to, tokenId); return from; } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } address previousOwner = _update(to, tokenId, address(0)); if (previousOwner != address(0)) { revert ERC721InvalidSender(address(0)); } } /** * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance. * * Requirements: * * - `tokenId` must not exist. * - 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 tokenId) internal { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { _mint(to, tokenId); _checkOnERC721Received(_msgSender(), address(0), to, tokenId, data); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal { address previousOwner = _update(address(0), tokenId, address(0)); if (previousOwner == address(0)) { revert ERC721NonexistentToken(tokenId); } } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } address previousOwner = _update(to, tokenId, address(0)); if (previousOwner == address(0)) { revert ERC721NonexistentToken(tokenId); } else if (previousOwner != from) { revert ERC721IncorrectOwner(from, tokenId, previousOwner); } } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients * are aware of the ERC-721 standard to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is like {safeTransferFrom} in the sense that it invokes * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `tokenId` token must exist and be owned by `from`. * - `to` cannot be the zero address. * - `from` 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 _safeTransfer(address from, address to, uint256 tokenId) internal { _safeTransfer(from, to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { _transfer(from, to, tokenId); _checkOnERC721Received(_msgSender(), from, to, tokenId, data); } /** * @dev Approve `to` to operate on `tokenId` * * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is * either the owner of the token, or approved to operate on all tokens held by this owner. * * Emits an {Approval} event. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address to, uint256 tokenId, address auth) internal { _approve(to, tokenId, auth, true); } /** * @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not * emitted in the context of transfers. */ function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual { ERC721Storage storage $ = _getERC721Storage(); // Avoid reading the owner unless necessary if (emitEvent || auth != address(0)) { address owner = _requireOwned(tokenId); // We do not use _isAuthorized because single-token approvals should not be able to call approve if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) { revert ERC721InvalidApprover(auth); } if (emitEvent) { emit Approval(owner, to, tokenId); } } $._tokenApprovals[tokenId] = to; } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Requirements: * - operator can't be the address zero. * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { ERC721Storage storage $ = _getERC721Storage(); if (operator == address(0)) { revert ERC721InvalidOperator(operator); } $._operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned). * Returns the owner. * * Overrides to ownership logic should be done to {_ownerOf}. */ function _requireOwned(uint256 tokenId) internal view returns (address) { address owner = _ownerOf(tokenId); if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } return owner; } /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target address. This will revert if the * recipient doesn't accept the token transfer. The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call */ function _checkOnERC721Received(address sender, address from, address to, uint256 tokenId, bytes memory data) internal { if (to.code.length > 0) { try IERC721Receiver(to).onERC721Received(sender, from, tokenId, data) returns (bytes4 retval) { if (retval != IERC721Receiver.onERC721Received.selector) { revert ERC721InvalidReceiver(to); } } catch (bytes memory reason) { if (reason.length == 0) { revert ERC721InvalidReceiver(to); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.20; import {IERC165} from "../utils/introspection/IERC165.sol"; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo( uint256 tokenId, uint256 salePrice ) external view returns (address receiver, uint256 royaltyAmount); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.20; import {IERC165} from "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - 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 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or * {setApprovalForAll}. * - 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 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the address zero. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.20; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Storage of the initializable contract. * * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions * when using with upgradeable contracts. * * @custom:storage-location erc7201:openzeppelin.storage.Initializable */ struct InitializableStorage { /** * @dev Indicates that the contract has been initialized. */ uint64 _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool _initializing; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00; /** * @dev The contract is already initialized. */ error InvalidInitialization(); /** * @dev The contract is not initializing. */ error NotInitializing(); /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint64 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in * production. * * Emits an {Initialized} event. */ modifier initializer() { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); // Cache values to avoid duplicated sloads bool isTopLevelCall = !$._initializing; uint64 initialized = $._initialized; // Allowed calls: // - initialSetup: the contract is not in the initializing state and no previous version was // initialized // - construction: the contract is initialized at version 1 (no reininitialization) and the // current contract is just being deployed bool initialSetup = initialized == 0 && isTopLevelCall; bool construction = initialized == 1 && address(this).code.length == 0; if (!initialSetup && !construction) { revert InvalidInitialization(); } $._initialized = 1; if (isTopLevelCall) { $._initializing = true; } _; if (isTopLevelCall) { $._initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint64 version) { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing || $._initialized >= version) { revert InvalidInitialization(); } $._initialized = version; $._initializing = true; _; $._initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { _checkInitializing(); _; } /** * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}. */ function _checkInitializing() internal view virtual { if (!_isInitializing()) { revert NotInitializing(); } } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing) { revert InvalidInitialization(); } if ($._initialized != type(uint64).max) { $._initialized = type(uint64).max; emit Initialized(type(uint64).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint64) { return _getInitializableStorage()._initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _getInitializableStorage()._initializing; } /** * @dev Returns a pointer to the storage namespace. */ // solhint-disable-next-line var-name-mixedcase function _getInitializableStorage() private pure returns (InitializableStorage storage $) { assembly { $.slot := INITIALIZABLE_STORAGE } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import {Initializable} from "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165Upgradeable is Initializable, IERC165 { function __ERC165_init() internal onlyInitializing { } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.20; import {IERC721} from "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
{ "optimizer": { "enabled": true, "runs": 20000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721IncorrectOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721InsufficientApproval","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC721InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC721InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC721InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC721InvalidSender","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721NonexistentToken","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"NotProxy","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":true,"internalType":"bool","name":"add","type":"bool"}],"name":"AdminSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_toTokenId","type":"uint256"}],"name":"BatchMetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"MetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","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":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"auth","type":"address"},{"internalType":"bool","name":"emitEvent","type":"bool"}],"name":"__approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"__baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"__burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"__checkOnERC721Received","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"uint16","name":"bps","type":"uint16"}],"name":"__configureRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"__isAuthorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"__mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"tokenURI","type":"string"}],"name":"__mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"__ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"add","type":"bool"}],"name":"__setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"__setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"__setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"__setBeforeTokenTransferHookEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"sharedURI","type":"string"}],"name":"__setSharedURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"tokenURI","type":"string"}],"name":"__setTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"__sharedURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"__tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"__transfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"__transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"auth","type":"address"}],"name":"__update","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"uint16","name":"bps","type":"uint16"}],"name":"configureRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"recover","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"recoverCalldata","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"requireAdmin","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltiesBps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltiesReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"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":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"add","type":"bool"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"toString","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":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801562000010575f80fd5b506040805180820190915260058152640302e312e360dc1b60208201527fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b00906200005b9082620001c0565b50620000666200006c565b62000288565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff1615620000bd5760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146200011d5780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806200014957607f821691505b6020821081036200016857634e487b7160e01b5f52602260045260245ffd5b50919050565b601f821115620001bb575f81815260208120601f850160051c81016020861015620001965750805b601f850160051c820191505b81811015620001b757828155600101620001a2565b5050505b505050565b81516001600160401b03811115620001dc57620001dc62000120565b620001f481620001ed845462000134565b846200016e565b602080601f8311600181146200022a575f8415620002125750858301515b5f19600386901b1c1916600185901b178555620001b7565b5f85815260208120601f198616915b828110156200025a5788860151825594840194600190910190840162000239565b50858210156200027857878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b613c8680620002965f395ff3fe608060405234801561000f575f80fd5b506004361061030e575f3560e01c80636900a3ae1161019d578063b88d4fde116100e8578063e985e9c511610093578063f2fde38b1161006e578063f2fde38b146107a8578063f5dbba9d146107bb578063ffa1ad74146107ce575f80fd5b8063e985e9c51461071b578063eb3c1a6e14610782578063ee63074414610795575f80fd5b8063d1a01520116100c3578063d1a01520146106e2578063d1e31346146106f5578063e362286914610708575f80fd5b8063b88d4fde146106a9578063bfa59ea9146106bc578063c87b56dd146106cf575f80fd5b80638fbb64b611610148578063a22cb46511610123578063a22cb46514610646578063a3a51bd514610659578063b0690bf114610696575f80fd5b80638fbb64b6146105e857806395d89b41146105fb57806399d89f9d14610603575f80fd5b8063750354301161017857806375035430146105855780637a66e596146105985780638da5cb5b146105ab575f80fd5b80636900a3ae146105575780636e34a4821461056a57806370a0823114610572575f80fd5b8063314b51701161025d5780634cd88b761161020857806358ee7173116101e357806358ee71731461051e578063615d27a9146105315780636352211e14610544575f80fd5b80634cd88b76146104e55780635577210a146104f857806356d5f24b1461050b575f80fd5b806342842e0e1161023857806342842e0e146104ac5780634a3b889a146104bf5780634b0bddd2146104d2575f80fd5b8063314b5170146104735780633421ce9c146104865780633dc8ded714610499575f80fd5b806318160ddd116102bd57806323b872dd1161029857806323b872dd1461040e57806324d7806c146104215780632a55205a14610434575f80fd5b806318160ddd146103b757806319045a25146103e85780631f44bb25146103fb575f80fd5b8063081812fc116102ed578063081812fc14610364578063095ea7b31461039c57806309fc0f3c146103af575f80fd5b8062e5a2861461031257806301ffc9a71461032757806306fdde031461034f575b5f80fd5b610325610320366004613144565b6107d6565b005b61033a6103353660046131ae565b610863565b60405190151581526020015b60405180910390f35b610357610956565b6040516103469190613234565b610377610372366004613246565b610a0a565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610346565b6103256103aa36600461325d565b610a5d565b610357610a68565b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b01545b604051908152602001610346565b6103776103f636600461335b565b610b1a565b610377610409366004613246565b610b59565b61032561041c36600461339f565b610ba1565b61033a61042f3660046133dd565b610c95565b6104476104423660046133f8565b610c9f565b6040805173ffffffffffffffffffffffffffffffffffffffff9093168352602083019190915201610346565b61032561048136600461342c565b610d99565b61037761049436600461347a565b610dde565b6103256104a736600461325d565b610e2b565b6103256104ba36600461339f565b610ea8565b6103256104cd3660046134f7565b610ec7565b6103256104e0366004613536565b610f2c565b6103256104f3366004613569565b610fb5565b6103256105063660046133dd565b611149565b6103256105193660046135bf565b61118f565b61032561052c366004613603565b6111d3565b61032561053f3660046133dd565b61127c565b610377610552366004613246565b6112be565b610357610565366004613246565b6112c8565b6103576112d3565b6103da6105803660046133dd565b611304565b610325610593366004613144565b6113a2565b6103256105a636600461364b565b6113e5565b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b075473ffffffffffffffffffffffffffffffffffffffff16610377565b6103256105f63660046136a3565b6114a4565b6103576114b1565b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b055474010000000000000000000000000000000000000000900461ffff166103da565b610325610654366004613536565b611502565b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b055473ffffffffffffffffffffffffffffffffffffffff16610377565b61033a6106a436600461339f565b61150d565b6103256106b736600461371d565b611519565b6103256106ca366004613785565b611531565b6103576106dd366004613246565b6115d5565b6103256106f0366004613246565b6117da565b61032561070336600461339f565b6118b0565b6103256107163660046134f7565b6118f4565b61033a61072936600461379e565b73ffffffffffffffffffffffffffffffffffffffff9182165f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab00793056020908152604080832093909416825291909152205460ff1690565b610325610790366004613536565b611959565b6103776107a3366004613603565b61199c565b6103256107b63660046133dd565b6119d5565b6103576107c9366004613246565b611a5d565b610357611b1b565b30635577210a336040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024015f6040518083038186803b15801561083f575f80fd5b505afa158015610851573d5f803e3d5ffd5b5050505061085f8282611b49565b5050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f2a55205a0000000000000000000000000000000000000000000000000000000014806108f557507fffffffff0000000000000000000000000000000000000000000000000000000082167f4906490600000000000000000000000000000000000000000000000000000000145b8061094157507fffffffff0000000000000000000000000000000000000000000000000000000082167f5dc414a500000000000000000000000000000000000000000000000000000000145b80610950575061095082611c67565b92915050565b7f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab00793008054606091908190610988906137ca565b80601f01602080910402602001604051908101604052809291908181526020018280546109b4906137ca565b80156109ff5780601f106109d6576101008083540402835291602001916109ff565b820191905f5260205f20905b8154815290600101906020018083116109e257829003601f168201915b505050505091505090565b5f610a1482611d49565b505f8281527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079304602052604090205473ffffffffffffffffffffffffffffffffffffffff16610950565b61085f828233611dc6565b60607fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b006003018054610a99906137ca565b80601f0160208091040260200160405190810160405280929190818152602001828054610ac5906137ca565b8015610b105780601f10610ae757610100808354040283529160200191610b10565b820191905f5260205f20905b815481529060010190602001808311610af357829003601f168201915b5050505050905090565b5f610b52610b4c846020527b19457468657265756d205369676e6564204d6573736167653a0a33325f52603c60042090565b83611dd3565b9392505050565b5f8181527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079302602052604081205473ffffffffffffffffffffffffffffffffffffffff16610950565b73ffffffffffffffffffffffffffffffffffffffff8216610bf5576040517f64a0ae920000000000000000000000000000000000000000000000000000000081525f60048201526024015b60405180910390fd5b5f610c01838333611e77565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c8f576040517f64283d7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80861660048301526024820184905282166044820152606401610bec565b50505050565b5f61095082612097565b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b05545f9081907fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b009074010000000000000000000000000000000000000000900461ffff1615801590610d2a5750600581015473ffffffffffffffffffffffffffffffffffffffff1615155b15610d8a57600581015473ffffffffffffffffffffffffffffffffffffffff81169061271090610d769074010000000000000000000000000000000000000000900461ffff1687613848565b610d80919061385f565b9250925050610d92565b5f8092509250505b9250929050565b333014610dd2576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8f84848484612134565b5f333014610e18576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e2384848461233d565b949350505050565b333014610e64576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60017fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b006001015f828254610e989190613897565b9091555061085f905082826124fc565b610ec283838360405180602001604052805f815250611519565b505050565b333014610f00576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b04610ec28284836138ef565b30635577210a336040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024015f6040518083038186803b158015610f95575f80fd5b505afa158015610fa7573d5f803e3d5ffd5b5050505061085f82826125a9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f81158015610fff5750825b90505f8267ffffffffffffffff16600114801561101b5750303b155b905081158015611029575080155b15611060576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016600117855583156110c15784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6110cb87876126d2565b6110d63360016125a9565b6110df336126e4565b83156111405784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b61115281612097565b15155f0361118c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b3330146111c8576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ec283838361279d565b33301461120c576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8381527fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b02602052604090206112438284836138ef565b506040518381527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a1505050565b3330146112b5576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61118c816126e4565b5f61095082611d49565b6060610950826128bd565b60607fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b006004018054610a99906137ca565b5f7f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930073ffffffffffffffffffffffffffffffffffffffff8316611375576040517f89c62b640000000000000000000000000000000000000000000000000000000081525f6004820152602401610bec565b73ffffffffffffffffffffffffffffffffffffffff9092165f908152600390920160205250604090205490565b3330146113db576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61085f8282611b49565b33301461141e576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b0180547fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b00916001915f90611473908490613897565b90915550505f84815260028201602052604090206114928385836138ef565b5061149d85856124fc565b5050505050565b61149d8585858585612979565b7f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930180546060917f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930091610988906137ca565b61085f33838361279d565b5f610e23848484612b66565b611524848484610ba1565b610c8f3385858585612979565b33301461156a576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b058054911515760100000000000000000000000000000000000000000000027fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff909216919091179055565b60606115e082611d49565b505f8281527fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b026020526040812080547fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b0092919061163c906137ca565b80601f0160208091040260200160405190810160405280929190818152602001828054611668906137ca565b80156116b35780601f1061168a576101008083540402835291602001916116b3565b820191905f5260205f20905b81548152906001019060200180831161169657829003601f168201915b505050505090505f815111156116ca579392505050565b5f8260030180546116da906137ca565b90501115611776578160030180546116f1906137ca565b80601f016020809104026020016040519081016040528092919081815260200182805461171d906137ca565b80156117685780601f1061173f57610100808354040283529160200191611768565b820191905f5260205f20905b81548152906001019060200180831161174b57829003601f168201915b505050505092505050919050565b5f826004018054611786906137ca565b905011156117c4578160040161179b856128bd565b6040516020016117ac929190613a06565b60405160208183030381529060405292505050919050565b505060408051602081019091525f815292915050565b333014611813576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b0180547fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b00916001915f90611868908490613aa7565b90915550505f82815260028201602052604081208054611887906137ca565b905011156118a7575f82815260028201602052604081206118a7916130d9565b61085f82612c65565b3330146118e9576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ec2838383612cc3565b33301461192d576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b03610ec28284836138ef565b333014611992576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61085f82826125a9565b5f610e236119ce856020527b19457468657265756d205369676e6564204d6573736167653a0a33325f52603c60042090565b8484612dfc565b30635577210a336040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024015f6040518083038186803b158015611a3e575f80fd5b505afa158015611a50573d5f803e3d5ffd5b5050505061118c816126e4565b5f8181527fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b0260205260409020805460609190611a98906137ca565b80601f0160208091040260200160405190810160405280929190818152602001828054611ac4906137ca565b8015611b0f5780601f10611ae657610100808354040283529160200191611b0f565b820191905f5260205f20905b815481529060010190602001808311611af257829003601f168201915b50505050509050919050565b60607fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b008054610a99906137ca565b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b05547fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b009073ffffffffffffffffffffffffffffffffffffffff848116911614611bef576005810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff85161790555b600581015461ffff838116740100000000000000000000000000000000000000009092041614610ec25760058101805461ffff841674010000000000000000000000000000000000000000027fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff909116179055505050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd000000000000000000000000000000000000000000000000000000001480611cf957507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061095057507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610950565b5f8181527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079302602052604081205473ffffffffffffffffffffffffffffffffffffffff1680610950576040517f7e27328900000000000000000000000000000000000000000000000000000000815260048101849052602401610bec565b610ec28383836001612134565b604051600190835f5260208301516040526040835103611e2757604083015160ff81901c601b016020527f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16606052611e4b565b6041835103611e475760608301515f1a6020526040830151606052611e4b565b5f91505b6020600160805f855afa5191503d611e6a57638baa579f5f526004601cfd5b5f60605260405292915050565b5f7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b0060050154760100000000000000000000000000000000000000000000900460ff161515600103610e18575f803033611f11875f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079302602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9283166024820152908216604482015290881660648201526084810187905260a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f68f7dad20000000000000000000000000000000000000000000000000000000017905251611fcc9190613aba565b5f60405180830381855af49150503d805f8114612004576040519150601f19603f3d011682016040523d82523d5f602084013e612009565b606091505b5090925090508115155f0361208a5780515f03612082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5f6265666f7265546f6b656e5472616e736665720000000000000000000000006044820152606401610bec565b805181602001fd5b5050610e2384848461233d565b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b07545f907fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b009073ffffffffffffffffffffffffffffffffffffffff84811691161480610b52575073ffffffffffffffffffffffffffffffffffffffff83165f90815260068201602052604090205460ff1615156001149392505050565b7f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab00793008180612176575073ffffffffffffffffffffffffffffffffffffffff831615155b156122e8575f61218585611d49565b905073ffffffffffffffffffffffffffffffffffffffff8416158015906121d857508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015612235575073ffffffffffffffffffffffffffffffffffffffff8082165f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079305602090815260408083209388168352929052205460ff16155b15612284576040517fa9fbf51f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85166004820152602401610bec565b82156122e657848673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5f93845260040160205250506040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b5f8281527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930260205260408120547f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab00793009073ffffffffffffffffffffffffffffffffffffffff908116908416156123b7576123b7818587612e9c565b73ffffffffffffffffffffffffffffffffffffffff81161561242c576123df5f865f80612134565b73ffffffffffffffffffffffffffffffffffffffff81165f908152600383016020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b73ffffffffffffffffffffffffffffffffffffffff8616156124765773ffffffffffffffffffffffffffffffffffffffff86165f9081526003830160205260409020805460010190555b5f85815260028301602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a811691821790925591518893918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a495945050505050565b73ffffffffffffffffffffffffffffffffffffffff821661254b576040517f64a0ae920000000000000000000000000000000000000000000000000000000081525f6004820152602401610bec565b5f61255783835f611e77565b905073ffffffffffffffffffffffffffffffffffffffff811615610ec2576040517f73c6ac6e0000000000000000000000000000000000000000000000000000000081525f6004820152602401610bec565b80156126205773ffffffffffffffffffffffffffffffffffffffff82165f9081527fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561268a565b73ffffffffffffffffffffffffffffffffffffffff82165f9081527fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b6040518115159073ffffffffffffffffffffffffffffffffffffffff8416907fe68d2c359a771606c400cf8b87000cf5864010363d6a736e98f5047b7bbe18e9905f90a35050565b6126da612f4c565b61085f8282612fb5565b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b0780547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff8481169182179093556040517fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b00939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b7f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930073ffffffffffffffffffffffffffffffffffffffff8316612823576040517f5b08ba1800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610bec565b73ffffffffffffffffffffffffffffffffffffffff8481165f81815260058401602090815260408083209488168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001687151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a350505050565b60605f6128c983612ff8565b60010190505f8167ffffffffffffffff8111156128e8576128e8613287565b6040519080825280601f01601f191660200182016040528015612912576020820181803683370190505b5090508181016020015b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a850494508461291c57509392505050565b73ffffffffffffffffffffffffffffffffffffffff83163b1561149d576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84169063150b7a02906129ee908890889087908790600401613ad5565b6020604051808303815f875af1925050508015612a46575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252612a4391810190613b1d565b60015b612acb573d808015612a73576040519150601f19603f3d011682016040523d82523d5f602084013e612a78565b606091505b5080515f03612082576040517f64a0ae9200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85166004820152602401610bec565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f150b7a020000000000000000000000000000000000000000000000000000000014612b5e576040517f64a0ae9200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85166004820152602401610bec565b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff831615801590610e2357508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612c11575073ffffffffffffffffffffffffffffffffffffffff8085165f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079305602090815260408083209387168352929052205460ff165b80610e235750505f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079304602052604090205473ffffffffffffffffffffffffffffffffffffffff908116911614919050565b5f612c715f835f611e77565b905073ffffffffffffffffffffffffffffffffffffffff811661085f576040517f7e27328900000000000000000000000000000000000000000000000000000000815260048101839052602401610bec565b73ffffffffffffffffffffffffffffffffffffffff8216612d12576040517f64a0ae920000000000000000000000000000000000000000000000000000000081525f6004820152602401610bec565b5f612d1e83835f611e77565b905073ffffffffffffffffffffffffffffffffffffffff8116612d70576040517f7e27328900000000000000000000000000000000000000000000000000000000815260048101839052602401610bec565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c8f576040517f64283d7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80861660048301526024820184905282166044820152606401610bec565b6040515f84905260019060408303612e4e5760208481013560ff81901c601b0190915284356040527f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16606052612e6f565b60418303612e6b5760408401355f1a602052604084604037612e6f565b5f91505b6020600160805f855afa5191503d612e8e57638baa579f5f526004601cfd5b5f6060526040529392505050565b612ea7838383612b66565b610ec25773ffffffffffffffffffffffffffffffffffffffff8316612efb576040517f7e27328900000000000000000000000000000000000000000000000000000000815260048101829052602401610bec565b6040517f177e802f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015260248101829052604401610bec565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff16612fb3576040517fd7e6bcf800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b612fbd612f4c565b7f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930080612fe98482613b38565b5060018101610c8f8382613b38565b5f807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613040577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef8100000000831061306c576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061308a57662386f26fc10000830492506010015b6305f5e10083106130a2576305f5e100830492506008015b61271083106130b657612710830492506004015b606483106130c8576064830492506002015b600a83106109505760010192915050565b5080546130e5906137ca565b5f825580601f106130f4575050565b601f0160209004905f5260205f209081019061118c91905b8082111561311f575f815560010161310c565b5090565b73ffffffffffffffffffffffffffffffffffffffff8116811461118c575f80fd5b5f8060408385031215613155575f80fd5b823561316081613123565b9150602083013561ffff81168114613176575f80fd5b809150509250929050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461118c575f80fd5b5f602082840312156131be575f80fd5b8135610b5281613181565b5f5b838110156131e35781810151838201526020016131cb565b50505f910152565b5f81518084526132028160208601602086016131c9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081525f610b5260208301846131eb565b5f60208284031215613256575f80fd5b5035919050565b5f806040838503121561326e575f80fd5b823561327981613123565b946020939093013593505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f8301126132c3575f80fd5b813567ffffffffffffffff808211156132de576132de613287565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561332457613324613287565b8160405283815286602085880101111561333c575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f806040838503121561336c575f80fd5b82359150602083013567ffffffffffffffff811115613389575f80fd5b613395858286016132b4565b9150509250929050565b5f805f606084860312156133b1575f80fd5b83356133bc81613123565b925060208401356133cc81613123565b929592945050506040919091013590565b5f602082840312156133ed575f80fd5b8135610b5281613123565b5f8060408385031215613409575f80fd5b50508035926020909101359150565b80358015158114613427575f80fd5b919050565b5f805f806080858703121561343f575f80fd5b843561344a81613123565b935060208501359250604085013561346181613123565b915061346f60608601613418565b905092959194509250565b5f805f6060848603121561348c575f80fd5b833561349781613123565b92506020840135915060408401356134ae81613123565b809150509250925092565b5f8083601f8401126134c9575f80fd5b50813567ffffffffffffffff8111156134e0575f80fd5b602083019150836020828501011115610d92575f80fd5b5f8060208385031215613508575f80fd5b823567ffffffffffffffff81111561351e575f80fd5b61352a858286016134b9565b90969095509350505050565b5f8060408385031215613547575f80fd5b823561355281613123565b915061356060208401613418565b90509250929050565b5f806040838503121561357a575f80fd5b823567ffffffffffffffff80821115613591575f80fd5b61359d868387016132b4565b935060208501359150808211156135b2575f80fd5b50613395858286016132b4565b5f805f606084860312156135d1575f80fd5b83356135dc81613123565b925060208401356135ec81613123565b91506135fa60408501613418565b90509250925092565b5f805f60408486031215613615575f80fd5b83359250602084013567ffffffffffffffff811115613632575f80fd5b61363e868287016134b9565b9497909650939450505050565b5f805f806060858703121561365e575f80fd5b843561366981613123565b935060208501359250604085013567ffffffffffffffff81111561368b575f80fd5b613697878288016134b9565b95989497509550505050565b5f805f805f60a086880312156136b7575f80fd5b85356136c281613123565b945060208601356136d281613123565b935060408601356136e281613123565b925060608601359150608086013567ffffffffffffffff811115613704575f80fd5b613710888289016132b4565b9150509295509295909350565b5f805f8060808587031215613730575f80fd5b843561373b81613123565b9350602085013561374b81613123565b925060408501359150606085013567ffffffffffffffff81111561376d575f80fd5b613779878288016132b4565b91505092959194509250565b5f60208284031215613795575f80fd5b610b5282613418565b5f80604083850312156137af575f80fd5b82356137ba81613123565b9150602083013561317681613123565b600181811c908216806137de57607f821691505b602082108103613815577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b80820281158282048414176109505761095061381b565b5f82613892577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b808201808211156109505761095061381b565b601f821115610ec2575f81815260208120601f850160051c810160208610156138d05750805b601f850160051c820191505b81811015612b5e578281556001016138dc565b67ffffffffffffffff83111561390757613907613287565b61391b8361391583546137ca565b836138aa565b5f601f84116001811461396b575f85156139355750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561149d565b5f838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156139b95786850135825560209485019460019092019101613999565b50868210156139f4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f808454613a13816137ca565b60018281168015613a2b5760018114613a5e57613a8a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0084168752821515830287019450613a8a565b885f526020805f205f5b85811015613a815781548a820152908401908201613a68565b50505082870194505b505050508351613a9e8183602088016131c9565b01949350505050565b818103818111156109505761095061381b565b5f8251613acb8184602087016131c9565b9190910192915050565b5f73ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152613b1360808301846131eb565b9695505050505050565b5f60208284031215613b2d575f80fd5b8151610b5281613181565b815167ffffffffffffffff811115613b5257613b52613287565b613b6681613b6084546137ca565b846138aa565b602080601f831160018114613bb8575f8415613b825750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612b5e565b5f858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613c0457888601518255948401946001909101908401613be5565b5085821015613c4057878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220acf6ec4afa46ab03023d3ee855651e75353d6cbc05b0ac25cee3df32fe5e8c4364736f6c63430008150033
Deployed Bytecode
0x608060405234801561000f575f80fd5b506004361061030e575f3560e01c80636900a3ae1161019d578063b88d4fde116100e8578063e985e9c511610093578063f2fde38b1161006e578063f2fde38b146107a8578063f5dbba9d146107bb578063ffa1ad74146107ce575f80fd5b8063e985e9c51461071b578063eb3c1a6e14610782578063ee63074414610795575f80fd5b8063d1a01520116100c3578063d1a01520146106e2578063d1e31346146106f5578063e362286914610708575f80fd5b8063b88d4fde146106a9578063bfa59ea9146106bc578063c87b56dd146106cf575f80fd5b80638fbb64b611610148578063a22cb46511610123578063a22cb46514610646578063a3a51bd514610659578063b0690bf114610696575f80fd5b80638fbb64b6146105e857806395d89b41146105fb57806399d89f9d14610603575f80fd5b8063750354301161017857806375035430146105855780637a66e596146105985780638da5cb5b146105ab575f80fd5b80636900a3ae146105575780636e34a4821461056a57806370a0823114610572575f80fd5b8063314b51701161025d5780634cd88b761161020857806358ee7173116101e357806358ee71731461051e578063615d27a9146105315780636352211e14610544575f80fd5b80634cd88b76146104e55780635577210a146104f857806356d5f24b1461050b575f80fd5b806342842e0e1161023857806342842e0e146104ac5780634a3b889a146104bf5780634b0bddd2146104d2575f80fd5b8063314b5170146104735780633421ce9c146104865780633dc8ded714610499575f80fd5b806318160ddd116102bd57806323b872dd1161029857806323b872dd1461040e57806324d7806c146104215780632a55205a14610434575f80fd5b806318160ddd146103b757806319045a25146103e85780631f44bb25146103fb575f80fd5b8063081812fc116102ed578063081812fc14610364578063095ea7b31461039c57806309fc0f3c146103af575f80fd5b8062e5a2861461031257806301ffc9a71461032757806306fdde031461034f575b5f80fd5b610325610320366004613144565b6107d6565b005b61033a6103353660046131ae565b610863565b60405190151581526020015b60405180910390f35b610357610956565b6040516103469190613234565b610377610372366004613246565b610a0a565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610346565b6103256103aa36600461325d565b610a5d565b610357610a68565b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b01545b604051908152602001610346565b6103776103f636600461335b565b610b1a565b610377610409366004613246565b610b59565b61032561041c36600461339f565b610ba1565b61033a61042f3660046133dd565b610c95565b6104476104423660046133f8565b610c9f565b6040805173ffffffffffffffffffffffffffffffffffffffff9093168352602083019190915201610346565b61032561048136600461342c565b610d99565b61037761049436600461347a565b610dde565b6103256104a736600461325d565b610e2b565b6103256104ba36600461339f565b610ea8565b6103256104cd3660046134f7565b610ec7565b6103256104e0366004613536565b610f2c565b6103256104f3366004613569565b610fb5565b6103256105063660046133dd565b611149565b6103256105193660046135bf565b61118f565b61032561052c366004613603565b6111d3565b61032561053f3660046133dd565b61127c565b610377610552366004613246565b6112be565b610357610565366004613246565b6112c8565b6103576112d3565b6103da6105803660046133dd565b611304565b610325610593366004613144565b6113a2565b6103256105a636600461364b565b6113e5565b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b075473ffffffffffffffffffffffffffffffffffffffff16610377565b6103256105f63660046136a3565b6114a4565b6103576114b1565b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b055474010000000000000000000000000000000000000000900461ffff166103da565b610325610654366004613536565b611502565b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b055473ffffffffffffffffffffffffffffffffffffffff16610377565b61033a6106a436600461339f565b61150d565b6103256106b736600461371d565b611519565b6103256106ca366004613785565b611531565b6103576106dd366004613246565b6115d5565b6103256106f0366004613246565b6117da565b61032561070336600461339f565b6118b0565b6103256107163660046134f7565b6118f4565b61033a61072936600461379e565b73ffffffffffffffffffffffffffffffffffffffff9182165f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab00793056020908152604080832093909416825291909152205460ff1690565b610325610790366004613536565b611959565b6103776107a3366004613603565b61199c565b6103256107b63660046133dd565b6119d5565b6103576107c9366004613246565b611a5d565b610357611b1b565b30635577210a336040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024015f6040518083038186803b15801561083f575f80fd5b505afa158015610851573d5f803e3d5ffd5b5050505061085f8282611b49565b5050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f2a55205a0000000000000000000000000000000000000000000000000000000014806108f557507fffffffff0000000000000000000000000000000000000000000000000000000082167f4906490600000000000000000000000000000000000000000000000000000000145b8061094157507fffffffff0000000000000000000000000000000000000000000000000000000082167f5dc414a500000000000000000000000000000000000000000000000000000000145b80610950575061095082611c67565b92915050565b7f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab00793008054606091908190610988906137ca565b80601f01602080910402602001604051908101604052809291908181526020018280546109b4906137ca565b80156109ff5780601f106109d6576101008083540402835291602001916109ff565b820191905f5260205f20905b8154815290600101906020018083116109e257829003601f168201915b505050505091505090565b5f610a1482611d49565b505f8281527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079304602052604090205473ffffffffffffffffffffffffffffffffffffffff16610950565b61085f828233611dc6565b60607fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b006003018054610a99906137ca565b80601f0160208091040260200160405190810160405280929190818152602001828054610ac5906137ca565b8015610b105780601f10610ae757610100808354040283529160200191610b10565b820191905f5260205f20905b815481529060010190602001808311610af357829003601f168201915b5050505050905090565b5f610b52610b4c846020527b19457468657265756d205369676e6564204d6573736167653a0a33325f52603c60042090565b83611dd3565b9392505050565b5f8181527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079302602052604081205473ffffffffffffffffffffffffffffffffffffffff16610950565b73ffffffffffffffffffffffffffffffffffffffff8216610bf5576040517f64a0ae920000000000000000000000000000000000000000000000000000000081525f60048201526024015b60405180910390fd5b5f610c01838333611e77565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c8f576040517f64283d7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80861660048301526024820184905282166044820152606401610bec565b50505050565b5f61095082612097565b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b05545f9081907fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b009074010000000000000000000000000000000000000000900461ffff1615801590610d2a5750600581015473ffffffffffffffffffffffffffffffffffffffff1615155b15610d8a57600581015473ffffffffffffffffffffffffffffffffffffffff81169061271090610d769074010000000000000000000000000000000000000000900461ffff1687613848565b610d80919061385f565b9250925050610d92565b5f8092509250505b9250929050565b333014610dd2576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8f84848484612134565b5f333014610e18576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e2384848461233d565b949350505050565b333014610e64576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60017fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b006001015f828254610e989190613897565b9091555061085f905082826124fc565b610ec283838360405180602001604052805f815250611519565b505050565b333014610f00576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b04610ec28284836138ef565b30635577210a336040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024015f6040518083038186803b158015610f95575f80fd5b505afa158015610fa7573d5f803e3d5ffd5b5050505061085f82826125a9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f81158015610fff5750825b90505f8267ffffffffffffffff16600114801561101b5750303b155b905081158015611029575080155b15611060576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016600117855583156110c15784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6110cb87876126d2565b6110d63360016125a9565b6110df336126e4565b83156111405784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b61115281612097565b15155f0361118c576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b3330146111c8576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ec283838361279d565b33301461120c576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8381527fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b02602052604090206112438284836138ef565b506040518381527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a1505050565b3330146112b5576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61118c816126e4565b5f61095082611d49565b6060610950826128bd565b60607fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b006004018054610a99906137ca565b5f7f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930073ffffffffffffffffffffffffffffffffffffffff8316611375576040517f89c62b640000000000000000000000000000000000000000000000000000000081525f6004820152602401610bec565b73ffffffffffffffffffffffffffffffffffffffff9092165f908152600390920160205250604090205490565b3330146113db576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61085f8282611b49565b33301461141e576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b0180547fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b00916001915f90611473908490613897565b90915550505f84815260028201602052604090206114928385836138ef565b5061149d85856124fc565b5050505050565b61149d8585858585612979565b7f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930180546060917f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930091610988906137ca565b61085f33838361279d565b5f610e23848484612b66565b611524848484610ba1565b610c8f3385858585612979565b33301461156a576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b058054911515760100000000000000000000000000000000000000000000027fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff909216919091179055565b60606115e082611d49565b505f8281527fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b026020526040812080547fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b0092919061163c906137ca565b80601f0160208091040260200160405190810160405280929190818152602001828054611668906137ca565b80156116b35780601f1061168a576101008083540402835291602001916116b3565b820191905f5260205f20905b81548152906001019060200180831161169657829003601f168201915b505050505090505f815111156116ca579392505050565b5f8260030180546116da906137ca565b90501115611776578160030180546116f1906137ca565b80601f016020809104026020016040519081016040528092919081815260200182805461171d906137ca565b80156117685780601f1061173f57610100808354040283529160200191611768565b820191905f5260205f20905b81548152906001019060200180831161174b57829003601f168201915b505050505092505050919050565b5f826004018054611786906137ca565b905011156117c4578160040161179b856128bd565b6040516020016117ac929190613a06565b60405160208183030381529060405292505050919050565b505060408051602081019091525f815292915050565b333014611813576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b0180547fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b00916001915f90611868908490613aa7565b90915550505f82815260028201602052604081208054611887906137ca565b905011156118a7575f82815260028201602052604081206118a7916130d9565b61085f82612c65565b3330146118e9576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ec2838383612cc3565b33301461192d576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b03610ec28284836138ef565b333014611992576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61085f82826125a9565b5f610e236119ce856020527b19457468657265756d205369676e6564204d6573736167653a0a33325f52603c60042090565b8484612dfc565b30635577210a336040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024015f6040518083038186803b158015611a3e575f80fd5b505afa158015611a50573d5f803e3d5ffd5b5050505061118c816126e4565b5f8181527fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b0260205260409020805460609190611a98906137ca565b80601f0160208091040260200160405190810160405280929190818152602001828054611ac4906137ca565b8015611b0f5780601f10611ae657610100808354040283529160200191611b0f565b820191905f5260205f20905b815481529060010190602001808311611af257829003601f168201915b50505050509050919050565b60607fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b008054610a99906137ca565b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b05547fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b009073ffffffffffffffffffffffffffffffffffffffff848116911614611bef576005810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff85161790555b600581015461ffff838116740100000000000000000000000000000000000000009092041614610ec25760058101805461ffff841674010000000000000000000000000000000000000000027fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff909116179055505050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd000000000000000000000000000000000000000000000000000000001480611cf957507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061095057507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610950565b5f8181527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079302602052604081205473ffffffffffffffffffffffffffffffffffffffff1680610950576040517f7e27328900000000000000000000000000000000000000000000000000000000815260048101849052602401610bec565b610ec28383836001612134565b604051600190835f5260208301516040526040835103611e2757604083015160ff81901c601b016020527f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16606052611e4b565b6041835103611e475760608301515f1a6020526040830151606052611e4b565b5f91505b6020600160805f855afa5191503d611e6a57638baa579f5f526004601cfd5b5f60605260405292915050565b5f7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b0060050154760100000000000000000000000000000000000000000000900460ff161515600103610e18575f803033611f11875f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079302602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9283166024820152908216604482015290881660648201526084810187905260a401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f68f7dad20000000000000000000000000000000000000000000000000000000017905251611fcc9190613aba565b5f60405180830381855af49150503d805f8114612004576040519150601f19603f3d011682016040523d82523d5f602084013e612009565b606091505b5090925090508115155f0361208a5780515f03612082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5f6265666f7265546f6b656e5472616e736665720000000000000000000000006044820152606401610bec565b805181602001fd5b5050610e2384848461233d565b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b07545f907fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b009073ffffffffffffffffffffffffffffffffffffffff84811691161480610b52575073ffffffffffffffffffffffffffffffffffffffff83165f90815260068201602052604090205460ff1615156001149392505050565b7f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab00793008180612176575073ffffffffffffffffffffffffffffffffffffffff831615155b156122e8575f61218585611d49565b905073ffffffffffffffffffffffffffffffffffffffff8416158015906121d857508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015612235575073ffffffffffffffffffffffffffffffffffffffff8082165f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079305602090815260408083209388168352929052205460ff16155b15612284576040517fa9fbf51f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85166004820152602401610bec565b82156122e657848673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5f93845260040160205250506040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b5f8281527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930260205260408120547f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab00793009073ffffffffffffffffffffffffffffffffffffffff908116908416156123b7576123b7818587612e9c565b73ffffffffffffffffffffffffffffffffffffffff81161561242c576123df5f865f80612134565b73ffffffffffffffffffffffffffffffffffffffff81165f908152600383016020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b73ffffffffffffffffffffffffffffffffffffffff8616156124765773ffffffffffffffffffffffffffffffffffffffff86165f9081526003830160205260409020805460010190555b5f85815260028301602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a811691821790925591518893918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a495945050505050565b73ffffffffffffffffffffffffffffffffffffffff821661254b576040517f64a0ae920000000000000000000000000000000000000000000000000000000081525f6004820152602401610bec565b5f61255783835f611e77565b905073ffffffffffffffffffffffffffffffffffffffff811615610ec2576040517f73c6ac6e0000000000000000000000000000000000000000000000000000000081525f6004820152602401610bec565b80156126205773ffffffffffffffffffffffffffffffffffffffff82165f9081527fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561268a565b73ffffffffffffffffffffffffffffffffffffffff82165f9081527fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b6040518115159073ffffffffffffffffffffffffffffffffffffffff8416907fe68d2c359a771606c400cf8b87000cf5864010363d6a736e98f5047b7bbe18e9905f90a35050565b6126da612f4c565b61085f8282612fb5565b7fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b0780547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff8481169182179093556040517fd70e9a647412bf72add39fd1ab5a6a89bfb0d778061be5e3d13cfa60d9d90b00939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b7f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930073ffffffffffffffffffffffffffffffffffffffff8316612823576040517f5b08ba1800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610bec565b73ffffffffffffffffffffffffffffffffffffffff8481165f81815260058401602090815260408083209488168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001687151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a350505050565b60605f6128c983612ff8565b60010190505f8167ffffffffffffffff8111156128e8576128e8613287565b6040519080825280601f01601f191660200182016040528015612912576020820181803683370190505b5090508181016020015b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a850494508461291c57509392505050565b73ffffffffffffffffffffffffffffffffffffffff83163b1561149d576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84169063150b7a02906129ee908890889087908790600401613ad5565b6020604051808303815f875af1925050508015612a46575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252612a4391810190613b1d565b60015b612acb573d808015612a73576040519150601f19603f3d011682016040523d82523d5f602084013e612a78565b606091505b5080515f03612082576040517f64a0ae9200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85166004820152602401610bec565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f150b7a020000000000000000000000000000000000000000000000000000000014612b5e576040517f64a0ae9200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85166004820152602401610bec565b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff831615801590610e2357508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612c11575073ffffffffffffffffffffffffffffffffffffffff8085165f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079305602090815260408083209387168352929052205460ff165b80610e235750505f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079304602052604090205473ffffffffffffffffffffffffffffffffffffffff908116911614919050565b5f612c715f835f611e77565b905073ffffffffffffffffffffffffffffffffffffffff811661085f576040517f7e27328900000000000000000000000000000000000000000000000000000000815260048101839052602401610bec565b73ffffffffffffffffffffffffffffffffffffffff8216612d12576040517f64a0ae920000000000000000000000000000000000000000000000000000000081525f6004820152602401610bec565b5f612d1e83835f611e77565b905073ffffffffffffffffffffffffffffffffffffffff8116612d70576040517f7e27328900000000000000000000000000000000000000000000000000000000815260048101839052602401610bec565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c8f576040517f64283d7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80861660048301526024820184905282166044820152606401610bec565b6040515f84905260019060408303612e4e5760208481013560ff81901c601b0190915284356040527f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16606052612e6f565b60418303612e6b5760408401355f1a602052604084604037612e6f565b5f91505b6020600160805f855afa5191503d612e8e57638baa579f5f526004601cfd5b5f6060526040529392505050565b612ea7838383612b66565b610ec25773ffffffffffffffffffffffffffffffffffffffff8316612efb576040517f7e27328900000000000000000000000000000000000000000000000000000000815260048101829052602401610bec565b6040517f177e802f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015260248101829052604401610bec565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff16612fb3576040517fd7e6bcf800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b612fbd612f4c565b7f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930080612fe98482613b38565b5060018101610c8f8382613b38565b5f807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613040577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef8100000000831061306c576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061308a57662386f26fc10000830492506010015b6305f5e10083106130a2576305f5e100830492506008015b61271083106130b657612710830492506004015b606483106130c8576064830492506002015b600a83106109505760010192915050565b5080546130e5906137ca565b5f825580601f106130f4575050565b601f0160209004905f5260205f209081019061118c91905b8082111561311f575f815560010161310c565b5090565b73ffffffffffffffffffffffffffffffffffffffff8116811461118c575f80fd5b5f8060408385031215613155575f80fd5b823561316081613123565b9150602083013561ffff81168114613176575f80fd5b809150509250929050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461118c575f80fd5b5f602082840312156131be575f80fd5b8135610b5281613181565b5f5b838110156131e35781810151838201526020016131cb565b50505f910152565b5f81518084526132028160208601602086016131c9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081525f610b5260208301846131eb565b5f60208284031215613256575f80fd5b5035919050565b5f806040838503121561326e575f80fd5b823561327981613123565b946020939093013593505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f8301126132c3575f80fd5b813567ffffffffffffffff808211156132de576132de613287565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561332457613324613287565b8160405283815286602085880101111561333c575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f806040838503121561336c575f80fd5b82359150602083013567ffffffffffffffff811115613389575f80fd5b613395858286016132b4565b9150509250929050565b5f805f606084860312156133b1575f80fd5b83356133bc81613123565b925060208401356133cc81613123565b929592945050506040919091013590565b5f602082840312156133ed575f80fd5b8135610b5281613123565b5f8060408385031215613409575f80fd5b50508035926020909101359150565b80358015158114613427575f80fd5b919050565b5f805f806080858703121561343f575f80fd5b843561344a81613123565b935060208501359250604085013561346181613123565b915061346f60608601613418565b905092959194509250565b5f805f6060848603121561348c575f80fd5b833561349781613123565b92506020840135915060408401356134ae81613123565b809150509250925092565b5f8083601f8401126134c9575f80fd5b50813567ffffffffffffffff8111156134e0575f80fd5b602083019150836020828501011115610d92575f80fd5b5f8060208385031215613508575f80fd5b823567ffffffffffffffff81111561351e575f80fd5b61352a858286016134b9565b90969095509350505050565b5f8060408385031215613547575f80fd5b823561355281613123565b915061356060208401613418565b90509250929050565b5f806040838503121561357a575f80fd5b823567ffffffffffffffff80821115613591575f80fd5b61359d868387016132b4565b935060208501359150808211156135b2575f80fd5b50613395858286016132b4565b5f805f606084860312156135d1575f80fd5b83356135dc81613123565b925060208401356135ec81613123565b91506135fa60408501613418565b90509250925092565b5f805f60408486031215613615575f80fd5b83359250602084013567ffffffffffffffff811115613632575f80fd5b61363e868287016134b9565b9497909650939450505050565b5f805f806060858703121561365e575f80fd5b843561366981613123565b935060208501359250604085013567ffffffffffffffff81111561368b575f80fd5b613697878288016134b9565b95989497509550505050565b5f805f805f60a086880312156136b7575f80fd5b85356136c281613123565b945060208601356136d281613123565b935060408601356136e281613123565b925060608601359150608086013567ffffffffffffffff811115613704575f80fd5b613710888289016132b4565b9150509295509295909350565b5f805f8060808587031215613730575f80fd5b843561373b81613123565b9350602085013561374b81613123565b925060408501359150606085013567ffffffffffffffff81111561376d575f80fd5b613779878288016132b4565b91505092959194509250565b5f60208284031215613795575f80fd5b610b5282613418565b5f80604083850312156137af575f80fd5b82356137ba81613123565b9150602083013561317681613123565b600181811c908216806137de57607f821691505b602082108103613815577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b80820281158282048414176109505761095061381b565b5f82613892577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b808201808211156109505761095061381b565b601f821115610ec2575f81815260208120601f850160051c810160208610156138d05750805b601f850160051c820191505b81811015612b5e578281556001016138dc565b67ffffffffffffffff83111561390757613907613287565b61391b8361391583546137ca565b836138aa565b5f601f84116001811461396b575f85156139355750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561149d565b5f838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156139b95786850135825560209485019460019092019101613999565b50868210156139f4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f808454613a13816137ca565b60018281168015613a2b5760018114613a5e57613a8a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0084168752821515830287019450613a8a565b885f526020805f205f5b85811015613a815781548a820152908401908201613a68565b50505082870194505b505050508351613a9e8183602088016131c9565b01949350505050565b818103818111156109505761095061381b565b5f8251613acb8184602087016131c9565b9190910192915050565b5f73ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152613b1360808301846131eb565b9695505050505050565b5f60208284031215613b2d575f80fd5b8151610b5281613181565b815167ffffffffffffffff811115613b5257613b52613287565b613b6681613b6084546137ca565b846138aa565b602080601f831160018114613bb8575f8415613b825750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612b5e565b5f858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613c0457888601518255948401946001909101908401613be5565b5085821015613c4057878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220acf6ec4afa46ab03023d3ee855651e75353d6cbc05b0ac25cee3df32fe5e8c4364736f6c63430008150033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.