Overview
POL Balance
0 POL
POL Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
44824228 | 564 days ago | Contract Creation | 0 POL |
Loading...
Loading
Contract Name:
Layerr721
Compiler Version
v0.8.20+commit.a1b79de6
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.8.0 <0.9.0; import "./ERC721.sol"; import {IERC4906} from "../../interfaces/IERC4906.sol"; import {ILayerr721} from "../../interfaces/ILayerr721.sol"; import {ILayerrRenderer} from "../../interfaces/ILayerrRenderer.sol"; import {LayerrToken} from "../LayerrToken.sol"; import "operator-filter-registry/src/DefaultOperatorFilterer.sol"; /** * @title Layerr721A * @author 0xth0mas (Layerr) * @notice Layerr721A is an ERC721 contract built for the Layerr platform using * a modified Chiru Labs ERC721A implementation for non-sequential * minting. */ contract Layerr721 is DefaultOperatorFilterer, ERC721, ILayerr721, LayerrToken, IERC4906 { /** METADATA FUNCTIONS */ /** * @notice Returns the URI for a given `tokenId` * @param tokenId id of token to return URI of * @return tokenURI location of the token metadata */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { return ILayerrRenderer(_getRenderer()).tokenURI(address(this), tokenId); } /** * @notice Returns the URI for the contract metadata * @return contractURI location of the contract metadata */ function contractURI() public view returns (string memory) { return ILayerrRenderer(_getRenderer()).contractURI(address(this)); } /** * @inheritdoc LayerrToken */ function name() public view virtual override(LayerrToken, ERC721) returns (string memory) { return LayerrToken.name(); } /** * @inheritdoc LayerrToken */ function symbol() public view virtual override(LayerrToken, ERC721) returns (string memory) { return LayerrToken.symbol(); } /** MINT FUNCTIONS */ /** * @inheritdoc ILayerr721 */ function mintTokenId(address minter, address to, uint256 tokenId) external onlyMinter { _mint(minter, to, tokenId); } /** * @inheritdoc ILayerr721 */ function mintBatchTokenIds( address minter, address to, uint256[] calldata tokenIds ) external onlyMinter { for(uint256 i = 0;i < tokenIds.length;) { uint256 tokenId = tokenIds[i]; _mint(minter, to, tokenId); unchecked { ++i; } } } /** * @inheritdoc ILayerr721 */ function burnTokenId(address from, uint256 tokenId) external { if (!isApprovedForAll(from, msg.sender)) { revert NotAuthorized(); } if(ownerOf(tokenId) != from) { revert NotAuthorized(); } _burn(tokenId); } /** * @inheritdoc ILayerr721 */ function burnBatchTokenIds( address from, uint256[] calldata tokenIds ) external { if (!isApprovedForAll(from, msg.sender)) { revert NotAuthorized(); } for(uint256 i = 0;i < tokenIds.length;) { uint256 tokenId = tokenIds[i]; if(ownerOf(tokenId) != from) { revert NotAuthorized(); } _burn(tokenId); unchecked { ++i; } } } /** * @inheritdoc ILayerr721 */ function totalSupply() public view override(ERC721, ILayerr721) returns (uint256) { return ERC721.totalSupply(); } /** * @inheritdoc ILayerr721 */ function totalMintedCollectionAndMinter(address minter) external view returns(uint256 totalMinted, uint256 minterMinted) { totalMinted = _totalMinted(); minterMinted = _numberMinted(minter); } /** OWNER FUNCTIONS */ /** * @inheritdoc ILayerr721 */ function airdrop(address[] calldata recipients, uint256[] calldata tokenIds) external onlyOwner { if(recipients.length != tokenIds.length) { revert ArrayLengthMismatch(); } for(uint256 index = 0;index < recipients.length;) { _mint(msg.sender, recipients[index], tokenIds[index]); unchecked { ++index; } } } /** * @notice Subscribes to an operator filter registry * @param operatorFilterRegistry operator filter address to subscribe to */ function setOperatorFilter(address operatorFilterRegistry) external onlyOwner { if (operatorFilterRegistry != address(0)) { OPERATOR_FILTER_REGISTRY.registerAndSubscribe( address(this), operatorFilterRegistry ); } } /** * @notice Unsubscribes from the operator filter registry */ function removeOperatorFilter() external onlyOwner { OPERATOR_FILTER_REGISTRY.unregister( address(this) ); } /** * @inheritdoc ILayerr721 */ function updateMetadataAllTokens() external onlyOwner { emit BatchMetadataUpdate(0, type(uint256).max); } /** * @inheritdoc ILayerr721 */ function updateMetadataSpecificTokens(uint256[] calldata tokenIds) external onlyOwner { for(uint256 i; i < tokenIds.length; ) { emit MetadataUpdate(tokenIds[i]); unchecked { ++i; } } } /** OPERATOR FILTER OVERRIDES */ function setApprovalForAll( address operator, bool approved ) public override onlyAllowedOperatorApproval(operator) { super.setApprovalForAll(operator, approved); } function approve( address operator, uint256 tokenId ) public payable override onlyAllowedOperatorApproval(operator) { super.approve(operator, tokenId); } function transferFrom( address from, address to, uint256 tokenId ) public payable override onlyAllowedOperator(from) { super.transferFrom(from, to, tokenId); } function safeTransferFrom( address from, address to, uint256 tokenId ) public payable override onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId); } function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public payable override onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId, data); } /** ERC165 */ function supportsInterface( bytes4 interfaceId ) public view virtual override(LayerrToken, ERC721) returns (bool) { return interfaceId == type(ILayerr721).interfaceId || LayerrToken.supportsInterface(interfaceId) || ERC721.supportsInterface(interfaceId); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.20; import {AddressValue} from "../lib/StorageTypes.sol"; import {IOwnable} from "../interfaces/IOwnable.sol"; import {LAYERROWNABLE_OWNER_SLOT, LAYERROWNABLE_NEW_OWNER_SLOT} from "./LayerrStorage.sol"; /** * @title LayerrOwnable * @author 0xth0mas (Layerr) * @notice ERC173 compliant ownership interface with two-step transfer/acceptance. * @dev LayerrOwnable uses two custom storage slots for current contract owner and new owner as defined in LayerrStorage. */ contract LayerrOwnable is IOwnable { modifier onlyOwner() { if (msg.sender != _getOwner()) { revert NotContractOwner(); } _; } modifier onlyNewOwner() { if (msg.sender != _getNewOwner()) { revert NotContractOwner(); } _; } /** * @notice Returns the current contract owner */ function owner() external view returns(address _owner) { _owner = _getOwner(); } /** * @notice Begins first step of ownership transfer. _newOwner will need to call acceptTransfer() to complete. * @param _newOwner address to transfer ownership of contract to */ function transferOwnership(address _newOwner) external onlyOwner { _setNewOwner(_newOwner); } /** * @notice Second step of ownership transfer called by the new contract owner. */ function acceptTransfer() external onlyNewOwner { address _previousOwner = _getOwner(); //set contract owner to new owner, clear out the newOwner value _setOwner(_getNewOwner()); _setNewOwner(address(0)); emit OwnershipTransferred(_previousOwner, _getOwner()); } /** * @notice Cancels ownership transfer to newOwner before the transfer is accepted. */ function cancelTransfer() external onlyOwner { _setNewOwner(address(0)); } /** * @notice EIP165 supportsInterface for introspection */ function supportsInterface(bytes4 interfaceID) public view virtual returns (bool) { return interfaceID == 0x7f5828d0; } /** INTERNAL FUNCTIONS */ /** * @dev Internal helper function to load custom storage slot address value */ function _getOwner() internal view returns(address _owner) { AddressValue storage ownerValue; /// @solidity memory-safe-assembly assembly { ownerValue.slot := LAYERROWNABLE_OWNER_SLOT } _owner = ownerValue.value; } /** * @dev Internal helper function to set owner address in custom storage slot */ function _setOwner(address _owner) internal { AddressValue storage ownerValue; /// @solidity memory-safe-assembly assembly { ownerValue.slot := LAYERROWNABLE_OWNER_SLOT } ownerValue.value = _owner; } /** * @dev Internal helper function to load custom storage slot address value */ function _getNewOwner() internal view returns(address _newOwner) { AddressValue storage newOwnerValue; /// @solidity memory-safe-assembly assembly { newOwnerValue.slot := LAYERROWNABLE_NEW_OWNER_SLOT } _newOwner = newOwnerValue.value; } /** * @dev Internal helper function to set new owner address in custom storage slot */ function _setNewOwner(address _newOwner) internal { AddressValue storage newOwnerValue; /// @solidity memory-safe-assembly assembly { newOwnerValue.slot := LAYERROWNABLE_NEW_OWNER_SLOT } newOwnerValue.value = _newOwner; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.20; /// @dev Storage slot for current owner calculated from keccak256('Layerr.LayerrOwnable.owner') bytes32 constant LAYERROWNABLE_OWNER_SLOT = 0xedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b66; /// @dev Storage slot for pending ownership transfer calculated from keccak256('Layerr.LayerrOwnable.newOwner') bytes32 constant LAYERROWNABLE_NEW_OWNER_SLOT = 0x15c115ab76de082272ae65126522082d4aad634b6478097549f84086af3b84bc; /// @dev Storage slot for token name calculated from keccak256('Layerr.LayerrToken.name') bytes32 constant LAYERRTOKEN_NAME_SLOT = 0x7f84c61ed30727f282b62cab23f49ac7f4d263f04a4948416b7b9ba7f34a20dc; /// @dev Storage slot for token symbol calculated from keccak256('Layerr.LayerrToken.symbol') bytes32 constant LAYERRTOKEN_SYMBOL_SLOT = 0xdc0f2363b26c589c72caecd2357dae5fee235863060295a057e8d69d61a96d8a; /// @dev Storage slot for URI renderer calculated from keccak256('Layerr.LayerrToken.renderer') bytes32 constant LAYERRTOKEN_RENDERER_SLOT = 0x395b7021d979c3dbed0f5d530785632316942232113ba3dbe325dc167550e320;
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @dev Interface identification is specified in ERC-165. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface(bytes4 interfaceID) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; interface IERC4906 { /// @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. 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. event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @title ILayerr721 * @author 0xth0mas (Layerr) * @notice ILayerr721 interface defines functions required in an ERC721 token contract to callable by the LayerrMinter contract. * @dev ILayerr721 should be used for non-sequential token minting. */ interface ILayerr721 { /// @dev Thrown when two or more sets of arrays are supplied that require equal lengths but differ in length. error ArrayLengthMismatch(); /** * @notice Mints tokens to the recipients, each recipient gets the corresponding tokenId in the `tokenIds` array * @dev This function should be protected by a role so that it is not callable by any address * @param recipients addresses to airdrop tokens to * @param tokenIds ids of tokens to be airdropped to recipients */ function airdrop(address[] calldata recipients, uint256[] calldata tokenIds) external; /** * @notice Mints `tokenId` to `to`. * @dev `minter` and `to` may be the same address but are passed as two separate parameters to properly account for * allowlist mints where a minter is using a delegated wallet to mint * @param minter address that the mint count will be credited to * @param to address that will receive the token * @param tokenId the id of the token to mint */ function mintTokenId(address minter, address to, uint256 tokenId) external; /** * @notice Mints `tokenIds` to `to`. * @dev `minter` and `to` may be the same address but are passed as two separate parameters to properly account for * allowlist mints where a minter is using a delegated wallet to mint * @param minter address that the mint count will be credited to * @param to address that will receive the tokens * @param tokenIds the ids of tokens to mint */ function mintBatchTokenIds( address minter, address to, uint256[] calldata tokenIds ) external; /** * @notice Burns `tokenId` from `from` address * @dev This function should check that the caller has permission to burn tokens on behalf of `from` * @param from address to burn the tokenId from * @param tokenId id of token to be burned */ function burnTokenId(address from, uint256 tokenId) external; /** * @notice Burns `tokenIds` from `from` address * @dev This function should check that the caller has permission to burn tokens on behalf of `from` * @param from address to burn the tokenIds from * @param tokenIds ids of tokens to be burned */ function burnBatchTokenIds( address from, uint256[] calldata tokenIds ) external; /** * @notice Emits ERC-4906 BatchMetadataUpdate event for all tokens */ function updateMetadataAllTokens() external; /** * @notice Emits ERC-4906 MetadataUpdate event for tokens provided * @param tokenIds array of token ids to emit MetadataUpdate event for */ function updateMetadataSpecificTokens(uint256[] calldata tokenIds) external; /** * @notice Returns the total supply of ERC721 tokens in circulation. */ function totalSupply() external view returns (uint256); /** * @notice Returns the total number of tokens minted for the contract and the number of tokens minted by the `minter` * @param minter address to check for number of tokens minted * @return totalMinted total number of ERC721 tokens minted since token launch * @return minterMinted total number of ERC721 tokens minted by the `minter` */ function totalMintedCollectionAndMinter(address minter) external view returns(uint256 totalMinted, uint256 minterMinted); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {MintOrder, MintParameters, MintToken, BurnToken, PaymentToken} from "../lib/MinterStructs.sol"; /** * @title ILayerrMinter * @author 0xth0mas (Layerr) * @notice ILayerrMinter interface defines functions required in the LayerrMinter to be callable by token contracts */ interface ILayerrMinter { /// @dev Event emitted when a mint order is fulfilled event MintOrderFulfilled( bytes32 indexed mintParametersDigest, address indexed minter, uint256 indexed quantity ); /// @dev Event emitted when a token contract updates an allowed signer for EIP712 signatures event ContractAllowedSignerUpdate( address indexed _contract, address indexed _signer, bool indexed _allowed ); /// @dev Event emitted when a token contract updates an allowed oracle signer for offchain authorization of a wallet to use a signature event ContractOracleUpdated( address indexed _contract, address indexed _oracle, bool indexed _allowed ); /// @dev Event emitted when a signer updates their nonce with LayerrMinter. Updating a nonce invalidates all previously signed EIP712 signatures. event SignerNonceIncremented( address indexed _signer, uint256 indexed _nonce ); /// @dev Event emitted when a specific signature's validity is updated with the LayerrMinter contract. event SignatureValidityUpdated( address indexed _contract, bool indexed invalid, bytes32 mintParametersDigests ); /// @dev Thrown when the amount of native tokens supplied in msg.value is insufficient for the mint order error InsufficientPayment(); /// @dev Thrown when a payment fails to be forwarded to the intended recipient error PaymentFailed(); /// @dev Thrown when a MintParameters payment token uses a token type value other than native or ERC20 error InvalidPaymentTokenType(); /// @dev Thrown when a MintParameters burn token uses a token type value other than ERC20, ERC721 or ERC1155 error InvalidBurnTokenType(); /// @dev Thrown when a MintParameters mint token uses a token type value other than ERC20, ERC721 or ERC1155 error InvalidMintTokenType(); /// @dev Thrown when a MintParameters burn token uses a burn type value other than contract burn or send to dead error InvalidBurnType(); /// @dev Thrown when a MintParameters burn token requires a specific burn token id and the tokenId supplied does not match error InvalidBurnTokenId(); /// @dev Thrown when a MintParameters burn token requires a specific ERC721 token and the burn amount is greater than 1 error CannotBurnMultipleERC721WithSameId(); /// @dev Thrown when attempting to mint with MintParameters that have a start time greater than the current block time error MintHasNotStarted(); /// @dev Thrown when attempting to mint with MintParameters that have an end time less than the current block time error MintHasEnded(); /// @dev Thrown when a MintParameters has a merkleroot set but the supplied merkle proof is invalid error InvalidMerkleProof(); /// @dev Thrown when a MintOrder will cause a token's minted supply to exceed the defined maximum supply in MintParameters error MintExceedsMaxSupply(); /// @dev Thrown when a MintOrder will cause a minter's minted amount to exceed the defined max per wallet in MintParameters error MintExceedsMaxPerWallet(); /// @dev Thrown when a MintParameters mint token has a specific ERC721 token and the mint amount is greater than 1 error CannotMintMultipleERC721WithSameId(); /// @dev Thrown when the recovered signer for the MintParameters is not an allowed signer for the mint token error NotAllowedSigner(); /// @dev Thrown when the recovered signer's nonce does not match the current nonce in LayerrMinter error SignerNonceInvalid(); /// @dev Thrown when a signature has been marked as invalid for a mint token contract error SignatureInvalid(); /// @dev Thrown when MintParameters requires an oracle signature and the recovered signer is not an allowed oracle for the contract error InvalidOracleSignature(); /// @dev Thrown when MintParameters has a max signature use set and the MintOrder will exceed the maximum uses error ExceedsMaxSignatureUsage(); /// @dev Thrown when attempting to increment nonce on behalf of another account and the signature is invalid error InvalidSignatureToIncrementNonce(); /** * @notice This function is called by token contracts to update allowed signers for minting * @param _signer address of the EIP712 signer * @param _allowed if the `_signer` is allowed to sign for minting */ function setContractAllowedSigner(address _signer, bool _allowed) external; /** * @notice This function is called by token contracts to update allowed oracles for offchain authorizations * @param _oracle address of the oracle * @param _allowed if the `_oracle` is allowed to sign offchain authorizations */ function setContractAllowedOracle(address _oracle, bool _allowed) external; /** * @notice This function is called by token contracts to update validity of signatures for the LayerrMinter contract * @dev `invalid` should be true to invalidate signatures, the default state of `invalid` being false means * a signature is valid for a contract assuming all other conditions are met * @param mintParametersDigests an array of message digests for MintParameters to update validity of * @param invalid if the supplied digests will be marked as valid or invalid */ function setSignatureValidity( bytes32[] calldata mintParametersDigests, bool invalid ) external; /** * @notice Increments the nonce for a signer to invalidate all previous signed MintParameters */ function incrementSignerNonce() external; /** * @notice Increments the nonce on behalf of another account by validating a signature from that account * @dev The signature is an eth personal sign message of the current signer nonce plus the chain id * ex. current nonce 0 on chain 5 would be a signature of \x19Ethereum Signed Message:\n15 * current nonce 50 on chain 1 would be a signature of \x19Ethereum Signed Message:\n251 * @param signer account to increment nonce for * @param signature signature proof that the request is coming from the account */ function incrementNonceFor(address signer, bytes calldata signature) external; /** * @notice Validates and processes a single MintOrder, tokens are minted to msg.sender * @param mintOrder struct containing the details of the mint order */ function mint( MintOrder calldata mintOrder ) external payable; /** * @notice Validates and processes an array of MintOrders, tokens are minted to msg.sender * @param mintOrders array of structs containing the details of the mint orders */ function mintBatch( MintOrder[] calldata mintOrders ) external payable; /** * @notice Validates and processes a single MintOrder, tokens are minted to `mintToWallet` * @param mintToWallet the address tokens will be minted to * @param mintOrder struct containing the details of the mint order * @param paymentContext Contextual information related to the payment process * (Note: This parameter is required for integration with * the payment processor and does not impact the behavior * of the function) */ function mintTo( address mintToWallet, MintOrder calldata mintOrder, uint256 paymentContext ) external payable; /** * @notice Validates and processes an array of MintOrders, tokens are minted to `mintToWallet` * @param mintToWallet the address tokens will be minted to * @param mintOrders array of structs containing the details of the mint orders * @param paymentContext Contextual information related to the payment process * (Note: This parameter is required for integration with * the payment processor and does not impact the behavior * of the function) */ function mintBatchTo( address mintToWallet, MintOrder[] calldata mintOrders, uint256 paymentContext ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {ERC165} from "./IERC165.sol"; /** * @title ILayerrRenderer * @author 0xth0mas (Layerr) * @notice ILayerrRenderer interface defines functions required in LayerrRenderer to be callable by token contracts */ interface ILayerrRenderer is ERC165 { enum RenderType { LAYERR_HOSTED, PREREVEAL, BASE_PLUS_TOKEN } /// @dev Thrown when a payment fails for Layerr-hosted IPFS error PaymentFailed(); /// @dev Thrown when a call is made for an owner-function by a non-contract owner error NotContractOwner(); /// @dev Thrown when a signature is not made by the authorized account error InvalidSignature(); /** * @notice Generates a tokenURI for the `contractAddress` and `tokenId` * @param contractAddress token contract address to render a token URI for * @param tokenId token id to render * @return uri for the token metadata */ function tokenURI( address contractAddress, uint256 tokenId ) external view returns (string memory); /** * @notice Generates a contractURI for the `contractAddress` * @param contractAddress contract address to render a contract URI for * @return uri for the contract metadata */ function contractURI( address contractAddress ) external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @title ILayerrToken * @author 0xth0mas (Layerr) * @notice ILayerrToken interface defines functions required to be supported by the Layerr platform */ interface ILayerrToken { /// @dev Emitted when the contract is deployed so that it can be indexed and assigned to its owner event LayerrContractDeployed(); /// @dev Emitted when a mint extension is updated to allowed or disallowed event MintExtensionUpdated(address mintExtension, bool allowed); /// @dev Emitted when the contract's renderer is updated event RendererUpdated(address renderer); /// @dev Thrown when a caller that is not a mint extension attempts to execute a mint function error NotValidMintingExtension(); /// @dev Thrown when a non-owner attempts to execute an only owner function error NotAuthorized(); /// @dev Thrown when attempting to withdraw funds from the contract and the call fails error WithdrawFailed(); /** * @return name the name of the token */ function name() external view returns(string memory); /** * @return symbol the token symbol */ function symbol() external view returns(string memory); /** * @return renderer the address that will render token/contract URIs */ function renderer() external view returns(address); /** * @notice Sets the renderer for token/contract URIs * @dev This function should be restricted to contract owners * @param _renderer address to set as the token/contract URI renderer */ function setRenderer(address _renderer) external; /** * @notice Sets whether or not an address is allowed to call minting functions * @dev This function should be restricted to contract owners * @param _extension address of the mint extension to update * @param _allowed if the mint extension is allowed to mint tokens */ function setMintExtension( address _extension, bool _allowed ) external; /** * @notice This function calls the mint extension to update `_signer`'s allowance * @dev This function should be restricted to contract owners * @param _extension address of the mint extension to update * @param _signer address of the signer to update * @param _allowed if `_signer` is allowed to sign for `_extension` */ function setContractAllowedSigner( address _extension, address _signer, bool _allowed ) external; /** * @notice This function calls the mint extension to update `_oracle`'s allowance * @dev This function should be restricted to contract owners * @param _extension address of the mint extension to update * @param _oracle address of the oracle to update * @param _allowed if `_oracle` is allowed to sign for `_extension` */ function setContractAllowedOracle( address _extension, address _oracle, bool _allowed ) external; /** * @notice This function calls the mint extension to update signature validity * @dev This function should be restricted to contract owners * @param _extension address of the mint extension to update * @param signatureDigests hash digests of signatures parameters to update * @param invalid true if the signature digests should be marked as invalid */ function setSignatureValidity( address _extension, bytes32[] calldata signatureDigests, bool invalid ) external; /** * @notice This function updates the ERC2981 royalty percentages * @dev This function should be restricted to contract owners * @param pct royalty percentage in BPS * @param royaltyReciever address to receive royalties */ function setRoyalty( uint96 pct, address royaltyReciever ) external; /** * @notice This function updates the token contract's name and symbol * @dev This function should be restricted to contract owners * @param _name new name for the token contract * @param _symbol new symbol for the token contract */ function editContract( string calldata _name, string calldata _symbol ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {ERC165} from './IERC165.sol'; interface IOwnable is ERC165 { /// @dev Thrown when a non-owner is attempting to perform an owner function error NotContractOwner(); /// @dev Emitted when contract ownership is transferred to a new owner event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address); /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership(address _newOwner) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Simple ERC2981 NFT Royalty Standard implementation. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC2981.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/common/ERC2981.sol) abstract contract ERC2981 { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The royalty fee numerator exceeds the fee denominator. error RoyaltyOverflow(); /// @dev The royalty receiver cannot be the zero address. error RoyaltyReceiverIsZeroAddress(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* STORAGE */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The default royalty info is given by: /// ``` /// let packed := sload(_ERC2981_MASTER_SLOT_SEED) /// let receiver := shr(96, packed) /// let royaltyFraction := xor(packed, shl(96, receiver)) /// ``` /// /// The per token royalty info is given by. /// ``` /// mstore(0x00, tokenId) /// mstore(0x20, _ERC2981_MASTER_SLOT_SEED) /// let packed := sload(keccak256(0x00, 0x40)) /// let receiver := shr(96, packed) /// let royaltyFraction := xor(packed, shl(96, receiver)) /// ``` uint256 private constant _ERC2981_MASTER_SLOT_SEED = 0xaa4ec00224afccfdb7; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ERC2981 */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Checks that `_feeDenominator` is non-zero. constructor() { require(_feeDenominator() != 0, "Fee denominator cannot be zero."); } /// @dev Returns the denominator for the royalty amount. /// Defaults to 10000, which represents fees in basis points. /// Override this function to return a custom amount if needed. function _feeDenominator() internal pure virtual returns (uint96) { return 10000; } /// @dev Returns true if this contract implements the interface defined by `interfaceId`. /// See: https://eips.ethereum.org/EIPS/eip-165 /// This function call must use less than 30000 gas. function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) { /// @solidity memory-safe-assembly assembly { let s := shr(224, interfaceId) // ERC165: 0x01ffc9a7, ERC2981: 0x2a55205a. result := or(eq(s, 0x01ffc9a7), eq(s, 0x2a55205a)) } } /// @dev Returns the `receiver` and `royaltyAmount` for `tokenId` sold at `salePrice`. function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual returns (address receiver, uint256 royaltyAmount) { uint256 feeDenominator = _feeDenominator(); /// @solidity memory-safe-assembly assembly { mstore(0x00, tokenId) mstore(0x20, _ERC2981_MASTER_SLOT_SEED) let packed := sload(keccak256(0x00, 0x40)) receiver := shr(96, packed) if iszero(receiver) { packed := sload(mload(0x20)) receiver := shr(96, packed) } let x := salePrice let y := xor(packed, shl(96, receiver)) // `feeNumerator`. // Overflow check, equivalent to `require(y == 0 || x <= type(uint256).max / y)`. // Out-of-gas revert. Should not be triggered in practice, but included for safety. returndatacopy(returndatasize(), returndatasize(), mul(y, gt(x, div(not(0), y)))) royaltyAmount := div(mul(x, y), feeDenominator) } } /// @dev Sets the default royalty `receiver` and `feeNumerator`. /// /// Requirements: /// - `receiver` must not be the zero address. /// - `feeNumerator` must not be greater than the fee denominator. function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { uint256 feeDenominator = _feeDenominator(); /// @solidity memory-safe-assembly assembly { feeNumerator := shr(160, shl(160, feeNumerator)) if gt(feeNumerator, feeDenominator) { mstore(0x00, 0x350a88b3) // `RoyaltyOverflow()`. revert(0x1c, 0x04) } let packed := shl(96, receiver) if iszero(packed) { mstore(0x00, 0xb4457eaa) // `RoyaltyReceiverIsZeroAddress()`. revert(0x1c, 0x04) } sstore(_ERC2981_MASTER_SLOT_SEED, or(packed, feeNumerator)) } } /// @dev Sets the default royalty `receiver` and `feeNumerator` to zero. function _deleteDefaultRoyalty() internal virtual { /// @solidity memory-safe-assembly assembly { sstore(_ERC2981_MASTER_SLOT_SEED, 0) } } /// @dev Sets the royalty `receiver` and `feeNumerator` for `tokenId`. /// /// Requirements: /// - `receiver` must not be the zero address. /// - `feeNumerator` must not be greater than the fee denominator. function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual { uint256 feeDenominator = _feeDenominator(); /// @solidity memory-safe-assembly assembly { feeNumerator := shr(160, shl(160, feeNumerator)) if gt(feeNumerator, feeDenominator) { mstore(0x00, 0x350a88b3) // `RoyaltyOverflow()`. revert(0x1c, 0x04) } let packed := shl(96, receiver) if iszero(packed) { mstore(0x00, 0xb4457eaa) // `RoyaltyReceiverIsZeroAddress()`. revert(0x1c, 0x04) } mstore(0x00, tokenId) mstore(0x20, _ERC2981_MASTER_SLOT_SEED) sstore(keccak256(0x00, 0x40), or(packed, feeNumerator)) } } /// @dev Sets the royalty `receiver` and `feeNumerator` for `tokenId` to zero. function _resetTokenRoyalty(uint256 tokenId) internal virtual { /// @solidity memory-safe-assembly assembly { mstore(0x00, tokenId) mstore(0x20, _ERC2981_MASTER_SLOT_SEED) sstore(keccak256(0x00, 0x40), 0) } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.20; /** * @dev EIP712 Domain for signature verification */ struct EIP712Domain { string name; string version; uint256 chainId; address verifyingContract; } /** * @dev MintOrders contain MintParameters as defined by a token creator * along with proofs required to validate the MintParameters and * parameters specific to the mint being performed. * * `mintParameters` are the parameters signed by the token creator * `quantity` is a multiplier for mintTokens, burnTokens and paymentTokens * defined in mintParameters * `mintParametersSignature` is the signature from the token creator * `oracleSignature` is a signature of the hash of the mintParameters digest * and msg.sender. The recovered signer must be an allowed oracle for * the token contract if oracleSignatureRequired is true for mintParameters. * `merkleProof` is the proof that is checked if merkleRoot is not bytes(0) in * mintParameters * `suppliedBurnTokenIds` is an array of tokenIds to be used when processing * burnTokens. There must be one item in the array for each ERC1155 burnToken * regardless of `quantity` and `quantity` items in the array for each ERC721 * burnToken. * `referrer` is the address that will receive a portion of a paymentToken if * not address(0) and paymentToken's referralBPS is greater than 0 * `vaultWallet` is used for allowlist mints if the msg.sender address it not on * the allowlist but their delegate.cash vault wallet is. * */ struct MintOrder { MintParameters mintParameters; uint256 quantity; bytes mintParametersSignature; bytes oracleSignature; bytes32[] merkleProof; uint256[] suppliedBurnTokenIds; address referrer; address vaultWallet; } /** * @dev MintParameters define the tokens to be minted and conditions that must be met * for the mint to be successfully processed. * * `mintTokens` is an array of tokens that will be minted * `burnTokens` is an array of tokens required to be burned * `paymentTokens` is an array of tokens required as payment * `startTime` is the UTC timestamp of when the mint will start * `endTime` is the UTC timestamp of when the mint will end * `signatureMaxUses` limits the number of mints that can be performed with the * specific mintParameters/signature * `merkleRoot` is the root of the merkletree for allowlist minting * `nonce` is the signer nonce that can be incremented on the LayerrMinter * contract to invalidate all previous signatures * `oracleSignatureRequired` if true requires a secondary signature to process the mint */ struct MintParameters { MintToken[] mintTokens; BurnToken[] burnTokens; PaymentToken[] paymentTokens; uint256 startTime; uint256 endTime; uint256 signatureMaxUses; bytes32 merkleRoot; uint256 nonce; bool oracleSignatureRequired; } /** * @dev Defines the token that will be minted * * `contractAddress` address of contract to mint tokens from * `specificTokenId` used for ERC721 - * if true, mint is non-sequential ERC721 * if false, mint is sequential ERC721A * `tokenType` is the type of token being minted defined in TokenTypes.sol * `tokenId` the tokenId to mint if specificTokenId is true * `mintAmount` is the quantity to be minted * `maxSupply` is checked against the total minted amount at time of mint * minting reverts if `mintAmount` * `quantity` will cause total minted to * exceed `maxSupply` * `maxMintPerWallet` is checked against the number minted for the wallet * minting reverts if `mintAmount` * `quantity` will cause wallet minted to * exceed `maxMintPerWallet` */ struct MintToken { address contractAddress; bool specificTokenId; uint256 tokenType; uint256 tokenId; uint256 mintAmount; uint256 maxSupply; uint256 maxMintPerWallet; } /** * @dev Defines the token that will be burned * * `contractAddress` address of contract to burn tokens from * `specificTokenId` specifies if the user has the option of choosing any token * from the contract or if they must burn a specific token * `tokenType` is the type of token being burned, defined in TokenTypes.sol * `burnType` is the type of burn to perform, burn function call or transfer to * dead address, defined in BurnType.sol * `tokenId` the tokenId to burn if specificTokenId is true * `burnAmount` is the quantity to be burned */ struct BurnToken { address contractAddress; bool specificTokenId; uint256 tokenType; uint256 burnType; uint256 tokenId; uint256 burnAmount; } /** * @dev Defines the token that will be used for payment * * `contractAddress` address of contract to for payment if ERC20 * if tokenType is native token then this should be set to 0x000...000 * to save calldata gas units * `tokenType` is the type of token being used for payment, defined in TokenTypes.sol * `payTo` the address that will receive the payment * `paymentAmount` the amount for the payment in base units for the token * ex. a native payment on Ethereum for 1 ETH would be specified in wei * which would be 1**18 wei * `referralBPS` is the percentage of the payment in BPS that will be sent to the * `referrer` on the MintOrder if `referralBPS` is greater than 0 and `referrer` * is not address(0) */ struct PaymentToken { address contractAddress; uint256 tokenType; address payTo; uint256 paymentAmount; uint256 referralBPS; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.20; /// @dev Simple struct to store a string value in a custom storage slot struct StringValue { string value; } /// @dev Simple struct to store an address value in a custom storage slot struct AddressValue { address value; }
// SPDX-License-Identifier: MIT // Modified from ERC721A Contracts v4.2.3 by Chiru Labs pragma solidity ^0.8.4; import '../ERC721A/IERC721A.sol'; /** * @dev Interface of ERC721 token receiver. */ interface ERC721__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721 * @author 0xth0mas (Layerr) - Modifications to ERC721A for non-sequential minting * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721 is IERC721A { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The number of tokens that have been minted. uint256 private _mintCounter; // The number of tokens that have been burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_mintCounter` times. unchecked { return _mintCounter - _burnCounter; } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256) { return _mintCounter; } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) _revert(BalanceQueryForZeroAddress.selector); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. /// @solidity memory-safe-assembly assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) _revert(URIQueryForNonexistentToken.selector); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Returns whether the ownership slot at `index` is initialized. * An uninitialized slot does not necessarily mean that the slot has no owner. */ function _ownershipIsInitialized(uint256 index) internal view virtual returns (bool) { return _packedOwnerships[index] != 0; } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256 packed) { packed = _packedOwnerships[tokenId]; // If the data at the starting slot does not exist, start the scan. if (packed > 0 && packed & _BITMASK_BURNED == 0) { return packed; } _revert(OwnerQueryForNonexistentToken.selector); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { /// @solidity memory-safe-assembly assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. /// @solidity memory-safe-assembly assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. See {ERC721A-_approve}. * * Requirements: * * - The caller must own the token or be an approved operator. */ function approve(address to, uint256 tokenId) public payable virtual override { _approve(to, tokenId, true); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) _revert(ApprovalQueryForNonexistentToken.selector); return _tokenApprovals[tokenId].value; } /** * @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 caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool result) { uint256 packed = _packedOwnerships[tokenId]; result = (packed > 0 && packed & _BITMASK_BURNED == 0); } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { /// @solidity memory-safe-assembly assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. /// @solidity memory-safe-assembly assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * 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 ) public payable virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); // Mask `from` to the lower 160 bits, in case the upper bits somehow aren't clean. from = address(uint160(uint256(uint160(from)) & _BITMASK_ADDRESS)); if (address(uint160(prevOwnershipPacked)) != from) _revert(TransferFromIncorrectOwner.selector); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) _revert(TransferCallerNotOwnerNorApproved.selector); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. /// @solidity memory-safe-assembly assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); } // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS; /// @solidity memory-safe-assembly assembly { // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. from, // `from`. toMasked, // `to`. tokenId // `tokenId`. ) } if (toMasked == 0) _revert(TransferToZeroAddress.selector); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @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 memory _data ) public payable virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { _revert(TransferToNonERC721ReceiverImplementer.selector); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { _revert(TransferToNonERC721ReceiverImplementer.selector); } /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address minter, address to, uint256 tokenId) internal virtual { if(_packedOwnerships[tokenId] > 0) _revert(TokenAlreadyExists.selector); _beforeTokenTransfers(address(0), to, tokenId, 1); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[tokenId] = _packOwnershipData( to, _nextInitializedFlag(1) | _nextExtraData(address(0), to, 0) ); // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. if(minter == to) { _packedAddressData[to] += ((1 << _BITPOS_NUMBER_MINTED) | 1); } else { _packedAddressData[to] += 1; _packedAddressData[minter] += (1 << _BITPOS_NUMBER_MINTED); } ++_mintCounter; // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS; if (toMasked == 0) _revert(MintToZeroAddress.selector); /// @solidity memory-safe-assembly assembly { // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. tokenId // `tokenId`. ) } } _afterTokenTransfers(address(0), to, tokenId, 1); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address minter, address to, uint256 tokenId, bytes memory _data ) internal virtual { _mint(minter, to, tokenId); unchecked { if (to.code.length != 0) { if (!_checkContractOnERC721Received(address(0), to, tokenId, _data)) { _revert(TransferToNonERC721ReceiverImplementer.selector); } } } } /** * @dev Equivalent to `_safeMint(minter, to, quantity, '')`. */ function _safeMint(address minter, address to, uint256 quantity) internal virtual { _safeMint(minter, to, quantity, ''); } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Equivalent to `_approve(to, tokenId, false)`. */ function _approve(address to, uint256 tokenId) internal virtual { _approve(to, tokenId, false); } /** * @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: * * - `tokenId` must exist. * * Emits an {Approval} event. */ function _approve( address to, uint256 tokenId, bool approvalCheck ) internal virtual { address owner = ownerOf(tokenId); if (approvalCheck && _msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { _revert(ApprovalCallerNotOwnerNorApproved.selector); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) _revert(TransferCallerNotOwnerNorApproved.selector); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. /// @solidity memory-safe-assembly assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; ++_burnCounter; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) _revert(OwnershipNotInitializedForExtraData.selector); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. /// @solidity memory-safe-assembly assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { /// @solidity memory-safe-assembly assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } /** * @dev For more efficient reverts. */ function _revert(bytes4 errorSelector) internal pure { /// @solidity memory-safe-assembly assembly { mstore(0x00, errorSelector) revert(0x00, 0x04) } } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); /** * Cannot mint a token that already exists. */ error TokenAlreadyExists(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @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`, * 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 be 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, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * 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 payable; /** * @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 payable; /** * @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 caller. * * 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); // ============================================================= // IERC721Metadata // ============================================================= /** * @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); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.20; import {AddressValue, StringValue} from "../lib/StorageTypes.sol"; import {LAYERRTOKEN_NAME_SLOT, LAYERRTOKEN_SYMBOL_SLOT, LAYERRTOKEN_RENDERER_SLOT} from "../common/LayerrStorage.sol"; import {LayerrOwnable} from "../common/LayerrOwnable.sol"; import {ILayerrToken} from "../interfaces/ILayerrToken.sol"; import {ILayerrMinter} from "../interfaces/ILayerrMinter.sol"; import {ERC2981} from "../lib/ERC2981.sol"; /** * @title LayerrToken * @author 0xth0mas (Layerr) * @notice LayerrToken contains the general purpose token contract functions for interacting * with the Layerr platform. */ contract LayerrToken is ILayerrToken, LayerrOwnable, ERC2981 { /// @dev mapping of allowed mint extensions mapping(address => bool) public mintingExtensions; modifier onlyMinter() { if (!mintingExtensions[msg.sender]) { revert NotValidMintingExtension(); } _; } /** * @inheritdoc ILayerrToken */ function name() public virtual view returns(string memory _name) { StringValue storage nameValue; /// @solidity memory-safe-assembly assembly { nameValue.slot := LAYERRTOKEN_NAME_SLOT } _name = nameValue.value; } /** * @inheritdoc ILayerrToken */ function symbol() public virtual view returns(string memory _symbol) { StringValue storage symbolValue; /// @solidity memory-safe-assembly assembly { symbolValue.slot := LAYERRTOKEN_SYMBOL_SLOT } _symbol = symbolValue.value; } /** * @inheritdoc ILayerrToken */ function renderer() external view returns(address _renderer) { _renderer = _getRenderer(); } function supportsInterface(bytes4 interfaceId) public view virtual override(LayerrOwnable, ERC2981) returns (bool) { return interfaceId == type(ILayerrToken).interfaceId || ERC2981.supportsInterface(interfaceId) || LayerrOwnable.supportsInterface(interfaceId); } /* OWNER FUNCTIONS */ /** * @inheritdoc ILayerrToken */ function setRenderer(address _renderer) external onlyOwner { _setRenderer(_renderer); emit RendererUpdated(_renderer); } /** * @inheritdoc ILayerrToken */ function setMintExtension( address _extension, bool _allowed ) external onlyOwner { mintingExtensions[_extension] = _allowed; emit MintExtensionUpdated(_extension, _allowed); } /** * @inheritdoc ILayerrToken */ function setContractAllowedSigner( address _extension, address _signer, bool _allowed ) external onlyOwner { ILayerrMinter(_extension).setContractAllowedSigner(_signer, _allowed); } /** * @inheritdoc ILayerrToken */ function setContractAllowedOracle( address _extension, address _oracle, bool _allowed ) external onlyOwner { ILayerrMinter(_extension).setContractAllowedOracle(_oracle, _allowed); } /** * @inheritdoc ILayerrToken */ function setSignatureValidity( address _extension, bytes32[] calldata signatureDigests, bool invalid ) external onlyOwner { ILayerrMinter(_extension).setSignatureValidity(signatureDigests, invalid); } /** * @inheritdoc ILayerrToken */ function setRoyalty( uint96 pct, address royaltyReciever ) external onlyOwner { _setDefaultRoyalty(royaltyReciever, pct); } /** * @inheritdoc ILayerrToken */ function editContract( string calldata _name, string calldata _symbol ) external onlyOwner { _setName(_name); _setSymbol(_symbol); } /** * @notice Called during a proxy deployment to emit the LayerrContractDeployed event */ function initialize() external onlyOwner { emit LayerrContractDeployed(); } /** * @notice Called to withdraw any funds that may be sent to the contract */ function withdraw() external onlyOwner { (bool sent, ) = payable(_getOwner()).call{value: address(this).balance}(""); if (!sent) { revert WithdrawFailed(); } } /** * INTERNAL FUNCTIONS */ /** * @notice Internal function to set the renderer address in a custom storage slot location * @param _renderer address of the renderer to set */ function _setRenderer(address _renderer) internal { AddressValue storage rendererValue; /// @solidity memory-safe-assembly assembly { rendererValue.slot := LAYERRTOKEN_RENDERER_SLOT } rendererValue.value = _renderer; } /** * @notice Internal function to get the renderer address from a custom storage slot location * @return _renderer address of the renderer */ function _getRenderer() internal view returns(address _renderer) { AddressValue storage rendererValue; /// @solidity memory-safe-assembly assembly { rendererValue.slot := LAYERRTOKEN_RENDERER_SLOT } _renderer = rendererValue.value; } /** * @notice Internal function to set the token contract name in a custom storage slot location * @param _name name for the token contract */ function _setName(string calldata _name) internal { StringValue storage nameValue; /// @solidity memory-safe-assembly assembly { nameValue.slot := LAYERRTOKEN_NAME_SLOT } nameValue.value = _name; } /** * @notice Internal function to set the token contract symbol in a custom storage slot location * @param _symbol symbol for the token contract */ function _setSymbol(string calldata _symbol) internal { StringValue storage symbolValue; /// @solidity memory-safe-assembly assembly { symbolValue.slot := LAYERRTOKEN_SYMBOL_SLOT } symbolValue.value = _symbol; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {OperatorFilterer} from "./OperatorFilterer.sol"; import {CANONICAL_CORI_SUBSCRIPTION} from "./lib/Constants.sol"; /** * @title DefaultOperatorFilterer * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription. * @dev Please note that if your token contract does not provide an owner with EIP-173, it must provide * administration methods on the contract itself to interact with the registry otherwise the subscription * will be locked to the options set during construction. */ abstract contract DefaultOperatorFilterer is OperatorFilterer { /// @dev The constructor that is called when the contract is being deployed. constructor() OperatorFilterer(CANONICAL_CORI_SUBSCRIPTION, true) {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IOperatorFilterRegistry { /** * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns * true if supplied registrant address is not registered. */ function isOperatorAllowed(address registrant, address operator) external view returns (bool); /** * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner. */ function register(address registrant) external; /** * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes. */ function registerAndSubscribe(address registrant, address subscription) external; /** * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another * address without subscribing. */ function registerAndCopyEntries(address registrant, address registrantToCopy) external; /** * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner. * Note that this does not remove any filtered addresses or codeHashes. * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes. */ function unregister(address addr) external; /** * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered. */ function updateOperator(address registrant, address operator, bool filtered) external; /** * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates. */ function updateOperators(address registrant, address[] calldata operators, bool filtered) external; /** * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered. */ function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external; /** * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates. */ function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external; /** * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous * subscription if present. * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case, * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be * used. */ function subscribe(address registrant, address registrantToSubscribe) external; /** * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes. */ function unsubscribe(address registrant, bool copyExistingEntries) external; /** * @notice Get the subscription address of a given registrant, if any. */ function subscriptionOf(address addr) external returns (address registrant); /** * @notice Get the set of addresses subscribed to a given registrant. * Note that order is not guaranteed as updates are made. */ function subscribers(address registrant) external returns (address[] memory); /** * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant. * Note that order is not guaranteed as updates are made. */ function subscriberAt(address registrant, uint256 index) external returns (address); /** * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr. */ function copyEntriesOf(address registrant, address registrantToCopy) external; /** * @notice Returns true if operator is filtered by a given address or its subscription. */ function isOperatorFiltered(address registrant, address operator) external returns (bool); /** * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription. */ function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool); /** * @notice Returns true if a codeHash is filtered by a given address or its subscription. */ function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool); /** * @notice Returns a list of filtered operators for a given address or its subscription. */ function filteredOperators(address addr) external returns (address[] memory); /** * @notice Returns the set of filtered codeHashes for a given address or its subscription. * Note that order is not guaranteed as updates are made. */ function filteredCodeHashes(address addr) external returns (bytes32[] memory); /** * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or * its subscription. * Note that order is not guaranteed as updates are made. */ function filteredOperatorAt(address registrant, uint256 index) external returns (address); /** * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or * its subscription. * Note that order is not guaranteed as updates are made. */ function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32); /** * @notice Returns true if an address has registered */ function isRegistered(address addr) external returns (bool); /** * @dev Convenience method to compute the code hash of an arbitrary contract */ function codeHashOf(address addr) external returns (bytes32); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; address constant CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E; address constant CANONICAL_CORI_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol"; import {CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS} from "./lib/Constants.sol"; /** * @title OperatorFilterer * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another * registrant's entries in the OperatorFilterRegistry. * @dev This smart contract is meant to be inherited by token contracts so they can use the following: * - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods. * - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods. * Please note that if your token contract does not provide an owner with EIP-173, it must provide * administration methods on the contract itself to interact with the registry otherwise the subscription * will be locked to the options set during construction. */ abstract contract OperatorFilterer { /// @dev Emitted when an operator is not allowed. error OperatorNotAllowed(address operator); IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY = IOperatorFilterRegistry(CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS); /// @dev The constructor that is called when the contract is being deployed. constructor(address subscriptionOrRegistrantToCopy, bool subscribe) { // If an inheriting token contract is deployed to a network without the registry deployed, the modifier // will not revert, but the contract will need to be registered with the registry once it is deployed in // order for the modifier to filter addresses. if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { if (subscribe) { OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy); } else { if (subscriptionOrRegistrantToCopy != address(0)) { OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy); } else { OPERATOR_FILTER_REGISTRY.register(address(this)); } } } } /** * @dev A helper function to check if an operator is allowed. */ modifier onlyAllowedOperator(address from) virtual { // Allow spending tokens from addresses with balance // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred // from an EOA. if (from != msg.sender) { _checkFilterOperator(msg.sender); } _; } /** * @dev A helper function to check if an operator approval is allowed. */ modifier onlyAllowedOperatorApproval(address operator) virtual { _checkFilterOperator(operator); _; } /** * @dev A helper function to check if an operator is allowed. */ function _checkFilterOperator(address operator) internal view virtual { // Check registry code length to facilitate testing in environments without a deployed registry. if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { // under normal circumstances, this function will revert rather than return false, but inheriting contracts // may specify their own OperatorFilterRegistry implementations, which may behave differently if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) { revert OperatorNotAllowed(operator); } } } }
{ "optimizer": { "enabled": true, "runs": 33333 }, "evmVersion": "paris", "viaIR": true, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ArrayLengthMismatch","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"NotAuthorized","type":"error"},{"inputs":[],"name":"NotContractOwner","type":"error"},{"inputs":[],"name":"NotValidMintingExtension","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"RoyaltyOverflow","type":"error"},{"inputs":[],"name":"RoyaltyReceiverIsZeroAddress","type":"error"},{"inputs":[],"name":"TokenAlreadyExists","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"WithdrawFailed","type":"error"},{"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":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[],"name":"LayerrContractDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"MetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"mintExtension","type":"address"},{"indexed":false,"internalType":"bool","name":"allowed","type":"bool"}],"name":"MintExtensionUpdated","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":false,"internalType":"address","name":"renderer","type":"address"}],"name":"RendererUpdated","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":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"burnBatchTokenIds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burnTokenId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cancelTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"editContract","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":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","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":[{"internalType":"address","name":"minter","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"mintBatchTokenIds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"mintTokenId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mintingExtensions","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":"_owner","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":[],"name":"removeOperatorFilter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renderer","outputs":[{"internalType":"address","name":"_renderer","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_extension","type":"address"},{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"bool","name":"_allowed","type":"bool"}],"name":"setContractAllowedOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_extension","type":"address"},{"internalType":"address","name":"_signer","type":"address"},{"internalType":"bool","name":"_allowed","type":"bool"}],"name":"setContractAllowedSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_extension","type":"address"},{"internalType":"bool","name":"_allowed","type":"bool"}],"name":"setMintExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operatorFilterRegistry","type":"address"}],"name":"setOperatorFilter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_renderer","type":"address"}],"name":"setRenderer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"pct","type":"uint96"},{"internalType":"address","name":"royaltyReciever","type":"address"}],"name":"setRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_extension","type":"address"},{"internalType":"bytes32[]","name":"signatureDigests","type":"bytes32[]"},{"internalType":"bool","name":"invalid","type":"bool"}],"name":"setSignatureValidity","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":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"totalMintedCollectionAndMinter","outputs":[{"internalType":"uint256","name":"totalMinted","type":"uint256"},{"internalType":"uint256","name":"minterMinted","type":"uint256"}],"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":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateMetadataAllTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"updateMetadataSpecificTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60808060405234620000bd576daaeb6d7670e522a718067333cd4e803b62000032575b604051612ff29081620000c38239f35b803b15620000bd578160448160008094633e9f1edf60e11b8352306004840152733cc6cdda760b79bafa08df41ecfa224f810dceb660248401525af18015620000b15762000082575b8062000022565b6001600160401b0381116200009b57604052386200007b565b634e487b7160e01b600052604160045260246000fd5b6040513d6000823e3d90fd5b600080fdfe608060408181526004908136101561001657600080fd5b600092833560e01c90816301bd0cb6146128265750806301ffc9a71461269657806306fdde0314612582578063081812fc146124d7578063095ea7b3146123eb57806318160ddd146123c957806323b872dd146122185780632a55205a146121665780632c6f1bf8146120745780633ccfd60b14611fbc5780633e876afc14611f0f57806341f4343414611ee657806342842e0e14611e435780634c4f2e9c14611d65578063547eeac114611c945780635598d96714611c3457806356d3163d14611b38578063620debc8146119fa5780636352211e146119bd5780636621a0251461188657806367243482146117825780637043358d1461167757806370a08231146115f95780637c8add4b146115305780637d3c5ebe146113905780638129fc1c146113195780638ada6b0f146112c55780638b5298541461122b5780638da5cb5b146111d757806395d89b41146110b1578063a22cb46514610ff3578063b0968a6914610f44578063b88d4fde14610cb9578063c035f9b514610c62578063c87b56dd14610bb0578063c8c9ce6d14610acc578063d783925b14610998578063e8a3d485146108c3578063e946ada81461079d578063e985e9c51461073f578063e9be0def146102c55763f2fde38b146101f257600080fd5b346102c15760206003193601126102c15761020b61286d565b9173ffffffffffffffffffffffffffffffffffffffff91827fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b665416330361029b5750507f15c115ab76de082272ae65126522082d4aad634b6478097549f84086af3b84bc91167fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905580f35b517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b8280fd5b5091903461073b578260031936011261073b5767ffffffffffffffff908035828111610737576102f89036908301612a6d565b919092602435818111610733576103129036908401612a6d565b93909673ffffffffffffffffffffffffffffffffffffffff7fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b665416330361070b57508181116106df577f7f84c61ed30727f282b62cab23f49ac7f4d263f04a4948416b7b9ba7f34a20dc90806103888354612e56565b96601f97888111610674575b5088908883116001146105b55789926105aa575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790555b821161057e57507fdc0f2363b26c589c72caecd2357dae5fee235863060295a057e8d69d61a96d8a9161040d8354612e56565b818111610522575b508390821160011461046b57839482939492610460575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c191617905580f35b01359050388061042c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08216947ffcb398858cad14da6fd248e3b5474dd2c1265e65dde27a57afb895075d9f9c4091855b87811061050a5750836001959697106104d2575b505050811b01905580f35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88560031b161c199101351690553880806104c7565b909260206001819286860135815501940191016104b3565b7ffcb398858cad14da6fd248e3b5474dd2c1265e65dde27a57afb895075d9f9c408280850160051c82019260208610610575575b0160051c01905b81811061056a5750610415565b85815560010161055d565b92508192610556565b8360416024927f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b0135905038806103a8565b90917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01691848a527f5d53f3c05085bb2b2e416f306ba24d6e1c4febd3312b96a42cede1cfc89af829928a5b81811061065c5750908460019594939210610624575b505050811b0190556103da565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88560031b161c19910135169055388080610617565b91936020600181928787013581550195019201610601565b9091508389527f5d53f3c05085bb2b2e416f306ba24d6e1c4febd3312b96a42cede1cfc89af8298880850160051c820192602086106106d6575b9085949392910160051c01905b8181106106c85750610394565b8a81558493506001016106bb565b925081926106ae565b6024866041857f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b8390517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b8580fd5b8380fd5b5080fd5b83823461073b578060031936011261073b5760209161075c61286d565b82610765612895565b9273ffffffffffffffffffffffffffffffffffffffff809316815260078652209116600052825260ff81600020541690519015158152f35b5091903461073b578260031936011261073b576107b861286d565b6107c061296f565b9173ffffffffffffffffffffffffffffffffffffffff90817fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b665416330361089c57507f9ce00016bbc388f307621c5fc9526caf02c4dbf0bc4f778120d1935f86cbbd37939461089691831686526008602052610869848288209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b5173ffffffffffffffffffffffffffffffffffffffff909216825291151560208201529081906040820190565b0390a180f35b85517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b50346102c157826003193601126102c1578273ffffffffffffffffffffffffffffffffffffffff7f395b7021d979c3dbed0f5d530785632316942232113ba3dbe325dc167550e32054169260248351809581937e844d1300000000000000000000000000000000000000000000000000000000835230908301525afa91821561098e57836109659493610969575b5050519182916020835260208301906128db565b0390f35b6109869293503d8091833e61097e81836129f2565b810190612b0a565b903880610951565b81513d85823e3d90fd5b5082903461073b57602060031936011261073b576109b461286d565b9073ffffffffffffffffffffffffffffffffffffffff807fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b6654163303610aa4579383948316610a0257505050f35b6daaeb6d7670e522a718067333cd4e92833b15610aa05782517f7d3e3dbe0000000000000000000000000000000000000000000000000000000081523092810192835273ffffffffffffffffffffffffffffffffffffffff909116602083015292849184919082908490829060400103925af1908115610a975750610a845750f35b610a8d906129af565b610a945780f35b80fd5b513d84823e3d90fd5b8480fd5b8482517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b50346102c1576020908160031936011261073757823567ffffffffffffffff8111610aa057610afe903690850161297e565b909373ffffffffffffffffffffffffffffffffffffffff7fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b6654163303610b895750845b818110610b4c578580f35b807ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce785610b7c600194868a612c9c565b358651908152a101610b41565b82517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b50346102c157826020600319360112610a94577f395b7021d979c3dbed0f5d530785632316942232113ba3dbe325dc167550e3205482517fe9dc6375000000000000000000000000000000000000000000000000000000008152308186019081529435602086015293849173ffffffffffffffffffffffffffffffffffffffff16908290819060400103915afa91821561098e57836109659493610969575050519182916020835260208301906128db565b508234610a94576020600319360112610a945767ffffffffffffffff82610c8761286d565b9273ffffffffffffffffffffffffffffffffffffffff81549416815260056020522054831c1682519182526020820152f35b5060806003193601126102c157610cce61286d565b90610cd7612895565b604435906064359267ffffffffffffffff8411610f405736602385011215610f4057838601359087610d0883612a33565b95610d15835197886129f2565b838752366024858301011161073b5783602494602095869301838a01378701015273ffffffffffffffffffffffffffffffffffffffff90818716913383141580610f32575b610f24575b8281610d6a88612a9b565b1603610efd57918893918693848c52600684528b82812080548033148633141715610ea3575b610e9b575b5083905260058452818c207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81540190558616948593848d52828d2060018154019055858d52527c02000000000000000000000000000000000000000000000000000000004260a01b841717908b20557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8a80a415610e7457803b610e38578580f35b610e4193612d0b565b15610e4e57808080808580f35b907fd1a57ed6000000000000000000000000000000000000000000000000000000008152fd5b84867fea553b34000000000000000000000000000000000000000000000000000000008152fd5b558b38610d95565b929496509294965085905260078652838c2033600052865260ff84600020541615610ed657918b8b969492899694610d90565b8a8c7f59c896be000000000000000000000000000000000000000000000000000000008152fd5b888a7fa1148100000000000000000000000000000000000000000000000000000000008152fd5b610f2d33612ea9565b610d5f565b610f3b33612ea9565b610d5a565b8680fd5b5090346102c15760606003193601126102c157610f5f61286d565b90610f68612895565b9060443567ffffffffffffffff811161073357610f88903690830161297e565b919094338752600860205260ff818820541615610fcd575050845b818110610fae578580f35b80610fc7610fbf6001938589612c9c565b358587612b69565b01610fa3565b517f591b83ac000000000000000000000000000000000000000000000000000000008152fd5b83823461073b578060031936011261073b5761100d61286d565b9061101661296f565b9061102083612ea9565b338452600760205273ffffffffffffffffffffffffffffffffffffffff8185209316928360005260205261108282826000209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b5190151581527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a380f35b508234610a945780600319360112610a94575080516000917fdc0f2363b26c589c72caecd2357dae5fee235863060295a057e8d69d61a96d8a80546110f581612e56565b808552916001918083169081156111915750600114611133575b505050611121826109659403836129f2565b519182916020835260208301906128db565b600090815294507ffcb398858cad14da6fd248e3b5474dd2c1265e65dde27a57afb895075d9f9c405b82861061117957505050611121826020610965958201019461110f565b8054602087870181019190915290950194810161115c565b6109659750869350602092506111219491507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001682840152151560051b8201019461110f565b83823461073b578160031936011261073b5760209073ffffffffffffffffffffffffffffffffffffffff7fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b6654169051908152f35b50346102c157826003193601126102c15773ffffffffffffffffffffffffffffffffffffffff7fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b665416330361029b57827f15c115ab76de082272ae65126522082d4aad634b6478097549f84086af3b84bc7fffffffffffffffffffffffff0000000000000000000000000000000000000000815416905580f35b83823461073b578160031936011261073b5760209073ffffffffffffffffffffffffffffffffffffffff7f395b7021d979c3dbed0f5d530785632316942232113ba3dbe325dc167550e32054169051908152f35b50346102c157826003193601126102c15773ffffffffffffffffffffffffffffffffffffffff7fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b665416330361029b57827f2fb015439d881ee0b6e12ab346f207971a1d0a9afc9868490840b9327716cba38180a180f35b5090346102c157816003193601126102c1576113aa61286d565b9160243567ffffffffffffffff8111610aa0576113ca903690840161297e565b92909173ffffffffffffffffffffffffffffffffffffffff809516928387526020956007875282882033600052875260ff836000205416156115085790944260a01b9190885b81811061141b578980f35b61142681838a612c9c565b3590878461143384612a9b565b16036114e0578361144383612a9b565b1691808c5260068b528b87812080546114d8575b5083905260058b52868c206fffffffffffffffffffffffffffffffff81540190558b600193848054018555828252898d527c030000000000000000000000000000000000000000000000000000000088821717898320557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8280a401611410565b558b38611457565b8686517fea8e4eb5000000000000000000000000000000000000000000000000000000008152fd5b5050517fea8e4eb5000000000000000000000000000000000000000000000000000000008152fd5b5090346102c157826003193601126102c15773ffffffffffffffffffffffffffffffffffffffff7fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b66541633036115d25750807f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c91518381527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6020820152a180f35b90517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b5091903461073b57602060031936011261073b5773ffffffffffffffffffffffffffffffffffffffff61162a61286d565b169081156116515760208467ffffffffffffffff8186868152600585522054169051908152f35b827f8f4eb604000000000000000000000000000000000000000000000000000000008152fd5b5091903461073b57606060031936011261073b5761169361286d565b9261169c612895565b916116a5612960565b73ffffffffffffffffffffffffffffffffffffffff807fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b665416330361175a57859616803b156107335783517f93b670ea00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9095169285019283529015156020830152849184919082908490829060400103925af1908115610a975750610a845750f35b8284517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b5090346102c157816003193601126102c15767ffffffffffffffff908035828111610aa0576117b4903690830161297e565b919092602435908111610733576117ce903690830161297e565b92909173ffffffffffffffffffffffffffffffffffffffff95867fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b665416330361029b57848303611860575050855b818110611827578680f35b611832818387612c9c565b3590868216820361185c5761185660019261184e838888612c9c565b359033612b69565b0161181c565b8780fd5b517fa24a13a6000000000000000000000000000000000000000000000000000000008152fd5b5090346102c157816003193601126102c1576118a061286d565b916024359273ffffffffffffffffffffffffffffffffffffffff80911680865260076020528286203360005260205260ff8360002054161561150857816118e686612a9b565b160361199657908492916118f985612a9b565b1691848452600660205283828120805461198e575b5083905260056020528184206fffffffffffffffffffffffffffffffff815401905560018054016001558484526020527c03000000000000000000000000000000000000000000000000000000004260a01b831717908320557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8280a480f35b55833861190e565b50517fea8e4eb5000000000000000000000000000000000000000000000000000000008152fd5b508234610a94576020600319360112610a94575073ffffffffffffffffffffffffffffffffffffffff6119f260209335612a9b565b169051908152f35b5091903461073b57606060031936011261073b57611a1661286d565b9260243567ffffffffffffffff811161073757611a36903690840161297e565b611a3e612960565b9073ffffffffffffffffffffffffffffffffffffffff807fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b6654163303611b105786971690813b15610f4057848051967f942943f90000000000000000000000000000000000000000000000000000000088528701528060448701527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8111610f40578660648782968196829560051b8092858501371515602483015281010301925af1908115610a975750610a845750f35b8585517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b5090346102c15760206003193601126102c157611b5361286d565b73ffffffffffffffffffffffffffffffffffffffff91827fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b6654163303611c0d5750916020917f482cbbbcf912da3be80deb8503ae1e94c0b7d5d1d0ec0af3d9d6403e06e609ee9316907f395b7021d979c3dbed0f5d530785632316942232113ba3dbe325dc167550e320827fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905551908152a180f35b83517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b5082903461073b57611c453661291e565b92919091338552600860205260ff818620541615611c6c5750611c69939450612b69565b80f35b8590517f591b83ac000000000000000000000000000000000000000000000000000000008152fd5b5090346102c157826003193601126102c1577f15c115ab76de082272ae65126522082d4aad634b6478097549f84086af3b84bc80549073ffffffffffffffffffffffffffffffffffffffff928383169485330361029b5750507fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b668054927fffffffffffffffffffffffff00000000000000000000000000000000000000009186838616179055169055167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5082903461073b578160031936011261073b5773ffffffffffffffffffffffffffffffffffffffff7fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b6654163303611e1b579181926daaeb6d7670e522a718067333cd4e91823b15611e1657839260248492845195869384927f2ec2c24600000000000000000000000000000000000000000000000000000000845230908401525af1908115610a975750610a845750f35b505050fd5b9050517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b50611e4d3661291e565b9073ffffffffffffffffffffffffffffffffffffffff93929392838516338114159182611ed8575b80519560209384880188811067ffffffffffffffff821117611eaa578352808b8952610f3257610f24578281610d6a88612a9b565b60418b7f4e487b71000000000000000000000000000000000000000000000000000000006000525260246000fd5b611ee133612ea9565b611e75565b83823461073b578160031936011261073b57602090516daaeb6d7670e522a718067333cd4e8152f35b5090346102c157816003193601126102c1578035916bffffffffffffffffffffffff831680930361073757611f42612895565b9073ffffffffffffffffffffffffffffffffffffffff7fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b6654163303611e1b57506127108311611fb05760601b908115611fa557501768aa4ec00224afccfdb75580f35b63b4457eaa8452601cfd5b5063350a88b38352601cfd5b50346102c157826003193601126102c15773ffffffffffffffffffffffffffffffffffffffff7fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b66541680330361204d57838080809347905af161201d612cdb565b5015612027578280f35b517f750b219c000000000000000000000000000000000000000000000000000000008152fd5b50517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b50346102c15760606003193601126102c15761208e61286d565b612096612895565b61209e612960565b9173ffffffffffffffffffffffffffffffffffffffff90817fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b6654163303611b1057869392911690813b156107375783612149968651978895869485937ffd0f4a4a000000000000000000000000000000000000000000000000000000008552840190929160209073ffffffffffffffffffffffffffffffffffffffff60408401951683521515910152565b03925af1908115610a97575061215d575080f35b611c69906129af565b509134610a945782600319360112610a945761096590602435923581528368aa4ec00224afccfdb7918260205220548060601c918215612206575b50612710908260601b1894857fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04851186023d3d3e51948594020490836020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b915050546127108160601c91906121a1565b506122223661291e565b9173ffffffffffffffffffffffffffffffffffffffff939193809116933385036123bb575b848261225286612a9b565b16036123945783875260066020528683812080548033148833141715612346575b61233e575b5085905260056020528287207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81540190551692839182875280872060018154019055838752856020527c02000000000000000000000000000000000000000000000000000000004260a01b841717908720557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8680a415612318575080f35b907fea553b34000000000000000000000000000000000000000000000000000000008152fd5b558638612278565b90918790526007602052848920338a5260205260ff858a2054161561236d57908891612273565b87897f59c896be000000000000000000000000000000000000000000000000000000008152fd5b85877fa1148100000000000000000000000000000000000000000000000000000000008152fd5b6123c433612ea9565b612247565b83823461073b578160031936011261073b576020915460015490039051908152f35b5090816003193601126102c15761240061286d565b906024359261240e83612ea9565b73ffffffffffffffffffffffffffffffffffffffff908161242e86612a9b565b1692833303612495575b5084865260066020528520921691827fffffffffffffffffffffffff00000000000000000000000000000000000000008254161790557f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258480a480f35b838752600760205281872033885260205260ff828820541661243857867fcfb3b942000000000000000000000000000000000000000000000000000000008152fd5b5091903461073b57602060031936011261073b578035908183528060205283832054801515908161255a575b50156125345760208473ffffffffffffffffffffffffffffffffffffffff8186868152600685522054169051908152f35b827fcf4700e4000000000000000000000000000000000000000000000000000000008152fd5b7c01000000000000000000000000000000000000000000000000000000009150161538612503565b83823461073b578160031936011261073b57805190827f7f84c61ed30727f282b62cab23f49ac7f4d263f04a4948416b7b9ba7f34a20dc908154906125c682612e56565b8086529260019280841690811561264d57506001146125f1575b6109658686611121828b03836129f2565b815294507f5d53f3c05085bb2b2e416f306ba24d6e1c4febd3312b96a42cede1cfc89af8295b828610612635575050506111218260206109659582010194866125e0565b80546020878701810191909152909501948101612617565b6109659850879450602093506111219592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0091501682840152151560051b82010194866125e0565b5090346102c15760206003193601126102c15735907fffffffff00000000000000000000000000000000000000000000000000000000821680830361073757602093507ff5577e590000000000000000000000000000000000000000000000000000000081149283156127a6575b508215612715575b50519015158152f35b9091507f01ffc9a700000000000000000000000000000000000000000000000000000000811490811561277c575b8115612752575b50903861270c565b7f5b5e139f000000000000000000000000000000000000000000000000000000009150143861274a565b7f80ac58cd0000000000000000000000000000000000000000000000000000000081149150612743565b9092507f4f72377600000000000000000000000000000000000000000000000000000000831490811561280c575b5080156127e3575b9138612704565b507f7f5828d00000000000000000000000000000000000000000000000000000000082146127dc565b905060e01c6301ffc9a7632a55205a8214911417386127d4565b925050346102c15760206003193601126102c15760ff9060209373ffffffffffffffffffffffffffffffffffffffff61285d61286d565b1681526008855220541615158152f35b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361289057565b600080fd5b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361289057565b60005b8381106128cb5750506000910152565b81810151838201526020016128bb565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602093612917815180928187528780880191016128b8565b0116010190565b60031960609101126128905773ffffffffffffffffffffffffffffffffffffffff90600435828116810361289057916024359081168103612890579060443590565b60443590811515820361289057565b60243590811515820361289057565b9181601f840112156128905782359167ffffffffffffffff8311612890576020808501948460051b01011161289057565b67ffffffffffffffff81116129c357604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176129c357604052565b67ffffffffffffffff81116129c357601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b9181601f840112156128905782359167ffffffffffffffff8311612890576020838186019501011161289057565b600052600460205260406000205480151580612ae3575b612ae0577fdf2d9b420000000000000000000000000000000000000000000000000000000060005260046000fd5b90565b507c0100000000000000000000000000000000000000000000000000000000811615612ab2565b6020818303126128905780519067ffffffffffffffff8211612890570181601f82011215612890578051612b3d81612a33565b92612b4b60405194856129f2565b8184526020828401011161289057612ae091602080850191016128b8565b9060009083825260046020526040822054612c745773ffffffffffffffffffffffffffffffffffffffff809116928483527c02000000000000000000000000000000000000000000000000000000004260a01b851717604084205516828114600014612c4757508181526005602052604081206801000000000000000181540190555b600181540181558115612c1f577fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4565b807f2e0763000000000000000000000000000000000000000000000000000000000060049252fd5b82825260056020526040822060018154019055815260408120680100000000000000008154019055612bec565b6004827fc991cbb1000000000000000000000000000000000000000000000000000000008152fd5b9190811015612cac5760051b0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b3d15612d06573d90612cec82612a33565b91612cfa60405193846129f2565b82523d6000602084013e565b606090565b9392602090612d7a9260405180809581947f150b7a02000000000000000000000000000000000000000000000000000000009889845233600485015273ffffffffffffffffffffffffffffffffffffffff809c16602485015260448401526080606484015260848301906128db565b03916000988991165af1849181612dfa575b50612dd35783612d9a612cdb565b90815115612dab5750805190602001fd5b807fd1a57ed60000000000000000000000000000000000000000000000000000000060049252fd5b7fffffffff0000000000000000000000000000000000000000000000000000000016149150565b9091506020813d8211612e4e575b81612e15602093836129f2565b81010312610aa057517fffffffff0000000000000000000000000000000000000000000000000000000081168103610aa0579038612d8c565b3d9150612e08565b90600182811c92168015612e9f575b6020831014612e7057565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b91607f1691612e65565b6daaeb6d7670e522a718067333cd4e803b612ec2575050565b6040517fc617113400000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8316602482015290602090829060449082905afa908115612fb057600091612f76575b5015612f2f5750565b60249073ffffffffffffffffffffffffffffffffffffffff604051917fede71dcc000000000000000000000000000000000000000000000000000000008352166004820152fd5b6020813d8211612fa8575b81612f8e602093836129f2565b8101031261073b5751908115158203610a94575038612f26565b3d9150612f81565b6040513d6000823e3d90fdfea26469706673582212200fc0f51e10d57820e8bba2fd82a70d77a994c34804a2fe0e1f26200c17d84e3364736f6c63430008140033
Deployed Bytecode
0x608060408181526004908136101561001657600080fd5b600092833560e01c90816301bd0cb6146128265750806301ffc9a71461269657806306fdde0314612582578063081812fc146124d7578063095ea7b3146123eb57806318160ddd146123c957806323b872dd146122185780632a55205a146121665780632c6f1bf8146120745780633ccfd60b14611fbc5780633e876afc14611f0f57806341f4343414611ee657806342842e0e14611e435780634c4f2e9c14611d65578063547eeac114611c945780635598d96714611c3457806356d3163d14611b38578063620debc8146119fa5780636352211e146119bd5780636621a0251461188657806367243482146117825780637043358d1461167757806370a08231146115f95780637c8add4b146115305780637d3c5ebe146113905780638129fc1c146113195780638ada6b0f146112c55780638b5298541461122b5780638da5cb5b146111d757806395d89b41146110b1578063a22cb46514610ff3578063b0968a6914610f44578063b88d4fde14610cb9578063c035f9b514610c62578063c87b56dd14610bb0578063c8c9ce6d14610acc578063d783925b14610998578063e8a3d485146108c3578063e946ada81461079d578063e985e9c51461073f578063e9be0def146102c55763f2fde38b146101f257600080fd5b346102c15760206003193601126102c15761020b61286d565b9173ffffffffffffffffffffffffffffffffffffffff91827fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b665416330361029b5750507f15c115ab76de082272ae65126522082d4aad634b6478097549f84086af3b84bc91167fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905580f35b517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b8280fd5b5091903461073b578260031936011261073b5767ffffffffffffffff908035828111610737576102f89036908301612a6d565b919092602435818111610733576103129036908401612a6d565b93909673ffffffffffffffffffffffffffffffffffffffff7fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b665416330361070b57508181116106df577f7f84c61ed30727f282b62cab23f49ac7f4d263f04a4948416b7b9ba7f34a20dc90806103888354612e56565b96601f97888111610674575b5088908883116001146105b55789926105aa575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790555b821161057e57507fdc0f2363b26c589c72caecd2357dae5fee235863060295a057e8d69d61a96d8a9161040d8354612e56565b818111610522575b508390821160011461046b57839482939492610460575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c191617905580f35b01359050388061042c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08216947ffcb398858cad14da6fd248e3b5474dd2c1265e65dde27a57afb895075d9f9c4091855b87811061050a5750836001959697106104d2575b505050811b01905580f35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88560031b161c199101351690553880806104c7565b909260206001819286860135815501940191016104b3565b7ffcb398858cad14da6fd248e3b5474dd2c1265e65dde27a57afb895075d9f9c408280850160051c82019260208610610575575b0160051c01905b81811061056a5750610415565b85815560010161055d565b92508192610556565b8360416024927f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b0135905038806103a8565b90917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01691848a527f5d53f3c05085bb2b2e416f306ba24d6e1c4febd3312b96a42cede1cfc89af829928a5b81811061065c5750908460019594939210610624575b505050811b0190556103da565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88560031b161c19910135169055388080610617565b91936020600181928787013581550195019201610601565b9091508389527f5d53f3c05085bb2b2e416f306ba24d6e1c4febd3312b96a42cede1cfc89af8298880850160051c820192602086106106d6575b9085949392910160051c01905b8181106106c85750610394565b8a81558493506001016106bb565b925081926106ae565b6024866041857f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b8390517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b8580fd5b8380fd5b5080fd5b83823461073b578060031936011261073b5760209161075c61286d565b82610765612895565b9273ffffffffffffffffffffffffffffffffffffffff809316815260078652209116600052825260ff81600020541690519015158152f35b5091903461073b578260031936011261073b576107b861286d565b6107c061296f565b9173ffffffffffffffffffffffffffffffffffffffff90817fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b665416330361089c57507f9ce00016bbc388f307621c5fc9526caf02c4dbf0bc4f778120d1935f86cbbd37939461089691831686526008602052610869848288209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b5173ffffffffffffffffffffffffffffffffffffffff909216825291151560208201529081906040820190565b0390a180f35b85517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b50346102c157826003193601126102c1578273ffffffffffffffffffffffffffffffffffffffff7f395b7021d979c3dbed0f5d530785632316942232113ba3dbe325dc167550e32054169260248351809581937e844d1300000000000000000000000000000000000000000000000000000000835230908301525afa91821561098e57836109659493610969575b5050519182916020835260208301906128db565b0390f35b6109869293503d8091833e61097e81836129f2565b810190612b0a565b903880610951565b81513d85823e3d90fd5b5082903461073b57602060031936011261073b576109b461286d565b9073ffffffffffffffffffffffffffffffffffffffff807fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b6654163303610aa4579383948316610a0257505050f35b6daaeb6d7670e522a718067333cd4e92833b15610aa05782517f7d3e3dbe0000000000000000000000000000000000000000000000000000000081523092810192835273ffffffffffffffffffffffffffffffffffffffff909116602083015292849184919082908490829060400103925af1908115610a975750610a845750f35b610a8d906129af565b610a945780f35b80fd5b513d84823e3d90fd5b8480fd5b8482517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b50346102c1576020908160031936011261073757823567ffffffffffffffff8111610aa057610afe903690850161297e565b909373ffffffffffffffffffffffffffffffffffffffff7fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b6654163303610b895750845b818110610b4c578580f35b807ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce785610b7c600194868a612c9c565b358651908152a101610b41565b82517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b50346102c157826020600319360112610a94577f395b7021d979c3dbed0f5d530785632316942232113ba3dbe325dc167550e3205482517fe9dc6375000000000000000000000000000000000000000000000000000000008152308186019081529435602086015293849173ffffffffffffffffffffffffffffffffffffffff16908290819060400103915afa91821561098e57836109659493610969575050519182916020835260208301906128db565b508234610a94576020600319360112610a945767ffffffffffffffff82610c8761286d565b9273ffffffffffffffffffffffffffffffffffffffff81549416815260056020522054831c1682519182526020820152f35b5060806003193601126102c157610cce61286d565b90610cd7612895565b604435906064359267ffffffffffffffff8411610f405736602385011215610f4057838601359087610d0883612a33565b95610d15835197886129f2565b838752366024858301011161073b5783602494602095869301838a01378701015273ffffffffffffffffffffffffffffffffffffffff90818716913383141580610f32575b610f24575b8281610d6a88612a9b565b1603610efd57918893918693848c52600684528b82812080548033148633141715610ea3575b610e9b575b5083905260058452818c207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81540190558616948593848d52828d2060018154019055858d52527c02000000000000000000000000000000000000000000000000000000004260a01b841717908b20557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8a80a415610e7457803b610e38578580f35b610e4193612d0b565b15610e4e57808080808580f35b907fd1a57ed6000000000000000000000000000000000000000000000000000000008152fd5b84867fea553b34000000000000000000000000000000000000000000000000000000008152fd5b558b38610d95565b929496509294965085905260078652838c2033600052865260ff84600020541615610ed657918b8b969492899694610d90565b8a8c7f59c896be000000000000000000000000000000000000000000000000000000008152fd5b888a7fa1148100000000000000000000000000000000000000000000000000000000008152fd5b610f2d33612ea9565b610d5f565b610f3b33612ea9565b610d5a565b8680fd5b5090346102c15760606003193601126102c157610f5f61286d565b90610f68612895565b9060443567ffffffffffffffff811161073357610f88903690830161297e565b919094338752600860205260ff818820541615610fcd575050845b818110610fae578580f35b80610fc7610fbf6001938589612c9c565b358587612b69565b01610fa3565b517f591b83ac000000000000000000000000000000000000000000000000000000008152fd5b83823461073b578060031936011261073b5761100d61286d565b9061101661296f565b9061102083612ea9565b338452600760205273ffffffffffffffffffffffffffffffffffffffff8185209316928360005260205261108282826000209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b5190151581527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a380f35b508234610a945780600319360112610a94575080516000917fdc0f2363b26c589c72caecd2357dae5fee235863060295a057e8d69d61a96d8a80546110f581612e56565b808552916001918083169081156111915750600114611133575b505050611121826109659403836129f2565b519182916020835260208301906128db565b600090815294507ffcb398858cad14da6fd248e3b5474dd2c1265e65dde27a57afb895075d9f9c405b82861061117957505050611121826020610965958201019461110f565b8054602087870181019190915290950194810161115c565b6109659750869350602092506111219491507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001682840152151560051b8201019461110f565b83823461073b578160031936011261073b5760209073ffffffffffffffffffffffffffffffffffffffff7fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b6654169051908152f35b50346102c157826003193601126102c15773ffffffffffffffffffffffffffffffffffffffff7fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b665416330361029b57827f15c115ab76de082272ae65126522082d4aad634b6478097549f84086af3b84bc7fffffffffffffffffffffffff0000000000000000000000000000000000000000815416905580f35b83823461073b578160031936011261073b5760209073ffffffffffffffffffffffffffffffffffffffff7f395b7021d979c3dbed0f5d530785632316942232113ba3dbe325dc167550e32054169051908152f35b50346102c157826003193601126102c15773ffffffffffffffffffffffffffffffffffffffff7fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b665416330361029b57827f2fb015439d881ee0b6e12ab346f207971a1d0a9afc9868490840b9327716cba38180a180f35b5090346102c157816003193601126102c1576113aa61286d565b9160243567ffffffffffffffff8111610aa0576113ca903690840161297e565b92909173ffffffffffffffffffffffffffffffffffffffff809516928387526020956007875282882033600052875260ff836000205416156115085790944260a01b9190885b81811061141b578980f35b61142681838a612c9c565b3590878461143384612a9b565b16036114e0578361144383612a9b565b1691808c5260068b528b87812080546114d8575b5083905260058b52868c206fffffffffffffffffffffffffffffffff81540190558b600193848054018555828252898d527c030000000000000000000000000000000000000000000000000000000088821717898320557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8280a401611410565b558b38611457565b8686517fea8e4eb5000000000000000000000000000000000000000000000000000000008152fd5b5050517fea8e4eb5000000000000000000000000000000000000000000000000000000008152fd5b5090346102c157826003193601126102c15773ffffffffffffffffffffffffffffffffffffffff7fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b66541633036115d25750807f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c91518381527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6020820152a180f35b90517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b5091903461073b57602060031936011261073b5773ffffffffffffffffffffffffffffffffffffffff61162a61286d565b169081156116515760208467ffffffffffffffff8186868152600585522054169051908152f35b827f8f4eb604000000000000000000000000000000000000000000000000000000008152fd5b5091903461073b57606060031936011261073b5761169361286d565b9261169c612895565b916116a5612960565b73ffffffffffffffffffffffffffffffffffffffff807fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b665416330361175a57859616803b156107335783517f93b670ea00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9095169285019283529015156020830152849184919082908490829060400103925af1908115610a975750610a845750f35b8284517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b5090346102c157816003193601126102c15767ffffffffffffffff908035828111610aa0576117b4903690830161297e565b919092602435908111610733576117ce903690830161297e565b92909173ffffffffffffffffffffffffffffffffffffffff95867fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b665416330361029b57848303611860575050855b818110611827578680f35b611832818387612c9c565b3590868216820361185c5761185660019261184e838888612c9c565b359033612b69565b0161181c565b8780fd5b517fa24a13a6000000000000000000000000000000000000000000000000000000008152fd5b5090346102c157816003193601126102c1576118a061286d565b916024359273ffffffffffffffffffffffffffffffffffffffff80911680865260076020528286203360005260205260ff8360002054161561150857816118e686612a9b565b160361199657908492916118f985612a9b565b1691848452600660205283828120805461198e575b5083905260056020528184206fffffffffffffffffffffffffffffffff815401905560018054016001558484526020527c03000000000000000000000000000000000000000000000000000000004260a01b831717908320557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8280a480f35b55833861190e565b50517fea8e4eb5000000000000000000000000000000000000000000000000000000008152fd5b508234610a94576020600319360112610a94575073ffffffffffffffffffffffffffffffffffffffff6119f260209335612a9b565b169051908152f35b5091903461073b57606060031936011261073b57611a1661286d565b9260243567ffffffffffffffff811161073757611a36903690840161297e565b611a3e612960565b9073ffffffffffffffffffffffffffffffffffffffff807fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b6654163303611b105786971690813b15610f4057848051967f942943f90000000000000000000000000000000000000000000000000000000088528701528060448701527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8111610f40578660648782968196829560051b8092858501371515602483015281010301925af1908115610a975750610a845750f35b8585517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b5090346102c15760206003193601126102c157611b5361286d565b73ffffffffffffffffffffffffffffffffffffffff91827fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b6654163303611c0d5750916020917f482cbbbcf912da3be80deb8503ae1e94c0b7d5d1d0ec0af3d9d6403e06e609ee9316907f395b7021d979c3dbed0f5d530785632316942232113ba3dbe325dc167550e320827fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905551908152a180f35b83517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b5082903461073b57611c453661291e565b92919091338552600860205260ff818620541615611c6c5750611c69939450612b69565b80f35b8590517f591b83ac000000000000000000000000000000000000000000000000000000008152fd5b5090346102c157826003193601126102c1577f15c115ab76de082272ae65126522082d4aad634b6478097549f84086af3b84bc80549073ffffffffffffffffffffffffffffffffffffffff928383169485330361029b5750507fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b668054927fffffffffffffffffffffffff00000000000000000000000000000000000000009186838616179055169055167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5082903461073b578160031936011261073b5773ffffffffffffffffffffffffffffffffffffffff7fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b6654163303611e1b579181926daaeb6d7670e522a718067333cd4e91823b15611e1657839260248492845195869384927f2ec2c24600000000000000000000000000000000000000000000000000000000845230908401525af1908115610a975750610a845750f35b505050fd5b9050517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b50611e4d3661291e565b9073ffffffffffffffffffffffffffffffffffffffff93929392838516338114159182611ed8575b80519560209384880188811067ffffffffffffffff821117611eaa578352808b8952610f3257610f24578281610d6a88612a9b565b60418b7f4e487b71000000000000000000000000000000000000000000000000000000006000525260246000fd5b611ee133612ea9565b611e75565b83823461073b578160031936011261073b57602090516daaeb6d7670e522a718067333cd4e8152f35b5090346102c157816003193601126102c1578035916bffffffffffffffffffffffff831680930361073757611f42612895565b9073ffffffffffffffffffffffffffffffffffffffff7fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b6654163303611e1b57506127108311611fb05760601b908115611fa557501768aa4ec00224afccfdb75580f35b63b4457eaa8452601cfd5b5063350a88b38352601cfd5b50346102c157826003193601126102c15773ffffffffffffffffffffffffffffffffffffffff7fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b66541680330361204d57838080809347905af161201d612cdb565b5015612027578280f35b517f750b219c000000000000000000000000000000000000000000000000000000008152fd5b50517fbfcafd37000000000000000000000000000000000000000000000000000000008152fd5b50346102c15760606003193601126102c15761208e61286d565b612096612895565b61209e612960565b9173ffffffffffffffffffffffffffffffffffffffff90817fedc628ad38a73ae7d50600532f1bf21da1bfb1390b4f8174f361aca54d4c6b6654163303611b1057869392911690813b156107375783612149968651978895869485937ffd0f4a4a000000000000000000000000000000000000000000000000000000008552840190929160209073ffffffffffffffffffffffffffffffffffffffff60408401951683521515910152565b03925af1908115610a97575061215d575080f35b611c69906129af565b509134610a945782600319360112610a945761096590602435923581528368aa4ec00224afccfdb7918260205220548060601c918215612206575b50612710908260601b1894857fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04851186023d3d3e51948594020490836020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b915050546127108160601c91906121a1565b506122223661291e565b9173ffffffffffffffffffffffffffffffffffffffff939193809116933385036123bb575b848261225286612a9b565b16036123945783875260066020528683812080548033148833141715612346575b61233e575b5085905260056020528287207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81540190551692839182875280872060018154019055838752856020527c02000000000000000000000000000000000000000000000000000000004260a01b841717908720557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8680a415612318575080f35b907fea553b34000000000000000000000000000000000000000000000000000000008152fd5b558638612278565b90918790526007602052848920338a5260205260ff858a2054161561236d57908891612273565b87897f59c896be000000000000000000000000000000000000000000000000000000008152fd5b85877fa1148100000000000000000000000000000000000000000000000000000000008152fd5b6123c433612ea9565b612247565b83823461073b578160031936011261073b576020915460015490039051908152f35b5090816003193601126102c15761240061286d565b906024359261240e83612ea9565b73ffffffffffffffffffffffffffffffffffffffff908161242e86612a9b565b1692833303612495575b5084865260066020528520921691827fffffffffffffffffffffffff00000000000000000000000000000000000000008254161790557f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258480a480f35b838752600760205281872033885260205260ff828820541661243857867fcfb3b942000000000000000000000000000000000000000000000000000000008152fd5b5091903461073b57602060031936011261073b578035908183528060205283832054801515908161255a575b50156125345760208473ffffffffffffffffffffffffffffffffffffffff8186868152600685522054169051908152f35b827fcf4700e4000000000000000000000000000000000000000000000000000000008152fd5b7c01000000000000000000000000000000000000000000000000000000009150161538612503565b83823461073b578160031936011261073b57805190827f7f84c61ed30727f282b62cab23f49ac7f4d263f04a4948416b7b9ba7f34a20dc908154906125c682612e56565b8086529260019280841690811561264d57506001146125f1575b6109658686611121828b03836129f2565b815294507f5d53f3c05085bb2b2e416f306ba24d6e1c4febd3312b96a42cede1cfc89af8295b828610612635575050506111218260206109659582010194866125e0565b80546020878701810191909152909501948101612617565b6109659850879450602093506111219592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0091501682840152151560051b82010194866125e0565b5090346102c15760206003193601126102c15735907fffffffff00000000000000000000000000000000000000000000000000000000821680830361073757602093507ff5577e590000000000000000000000000000000000000000000000000000000081149283156127a6575b508215612715575b50519015158152f35b9091507f01ffc9a700000000000000000000000000000000000000000000000000000000811490811561277c575b8115612752575b50903861270c565b7f5b5e139f000000000000000000000000000000000000000000000000000000009150143861274a565b7f80ac58cd0000000000000000000000000000000000000000000000000000000081149150612743565b9092507f4f72377600000000000000000000000000000000000000000000000000000000831490811561280c575b5080156127e3575b9138612704565b507f7f5828d00000000000000000000000000000000000000000000000000000000082146127dc565b905060e01c6301ffc9a7632a55205a8214911417386127d4565b925050346102c15760206003193601126102c15760ff9060209373ffffffffffffffffffffffffffffffffffffffff61285d61286d565b1681526008855220541615158152f35b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361289057565b600080fd5b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361289057565b60005b8381106128cb5750506000910152565b81810151838201526020016128bb565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602093612917815180928187528780880191016128b8565b0116010190565b60031960609101126128905773ffffffffffffffffffffffffffffffffffffffff90600435828116810361289057916024359081168103612890579060443590565b60443590811515820361289057565b60243590811515820361289057565b9181601f840112156128905782359167ffffffffffffffff8311612890576020808501948460051b01011161289057565b67ffffffffffffffff81116129c357604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176129c357604052565b67ffffffffffffffff81116129c357601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b9181601f840112156128905782359167ffffffffffffffff8311612890576020838186019501011161289057565b600052600460205260406000205480151580612ae3575b612ae0577fdf2d9b420000000000000000000000000000000000000000000000000000000060005260046000fd5b90565b507c0100000000000000000000000000000000000000000000000000000000811615612ab2565b6020818303126128905780519067ffffffffffffffff8211612890570181601f82011215612890578051612b3d81612a33565b92612b4b60405194856129f2565b8184526020828401011161289057612ae091602080850191016128b8565b9060009083825260046020526040822054612c745773ffffffffffffffffffffffffffffffffffffffff809116928483527c02000000000000000000000000000000000000000000000000000000004260a01b851717604084205516828114600014612c4757508181526005602052604081206801000000000000000181540190555b600181540181558115612c1f577fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4565b807f2e0763000000000000000000000000000000000000000000000000000000000060049252fd5b82825260056020526040822060018154019055815260408120680100000000000000008154019055612bec565b6004827fc991cbb1000000000000000000000000000000000000000000000000000000008152fd5b9190811015612cac5760051b0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b3d15612d06573d90612cec82612a33565b91612cfa60405193846129f2565b82523d6000602084013e565b606090565b9392602090612d7a9260405180809581947f150b7a02000000000000000000000000000000000000000000000000000000009889845233600485015273ffffffffffffffffffffffffffffffffffffffff809c16602485015260448401526080606484015260848301906128db565b03916000988991165af1849181612dfa575b50612dd35783612d9a612cdb565b90815115612dab5750805190602001fd5b807fd1a57ed60000000000000000000000000000000000000000000000000000000060049252fd5b7fffffffff0000000000000000000000000000000000000000000000000000000016149150565b9091506020813d8211612e4e575b81612e15602093836129f2565b81010312610aa057517fffffffff0000000000000000000000000000000000000000000000000000000081168103610aa0579038612d8c565b3d9150612e08565b90600182811c92168015612e9f575b6020831014612e7057565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b91607f1691612e65565b6daaeb6d7670e522a718067333cd4e803b612ec2575050565b6040517fc617113400000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8316602482015290602090829060449082905afa908115612fb057600091612f76575b5015612f2f5750565b60249073ffffffffffffffffffffffffffffffffffffffff604051917fede71dcc000000000000000000000000000000000000000000000000000000008352166004820152fd5b6020813d8211612fa8575b81612f8e602093836129f2565b8101031261073b5751908115158203610a94575038612f26565b3d9150612f81565b6040513d6000823e3d90fdfea26469706673582212200fc0f51e10d57820e8bba2fd82a70d77a994c34804a2fe0e1f26200c17d84e3364736f6c63430008140033
Deployed Bytecode Sourcemap
646:6186:13:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;:::i;:::-;;;;;2496:78:0;646:6186:13;;620:10:0;:25;616:83;;3654:85;;;646:6186:13;;;;;;;;;;;616:83:0;646:6186:13;669:18:0;;;;646:6186:13;;;;;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;2496:78:0;646:6186:13;;620:10:0;:25;616:83;;646:6186:13;;;;;;5822:74:15;646:6186:13;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6268:78:15;;646:6186:13;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;646:6186:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;646:6186:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;646:6186:13;;;;;;;;;;;;;;;;;;;;;616:83:0;646:6186:13;;;669:18:0;;;;646:6186:13;;;;;;;;;;;;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;;;:::i;:::-;;;;:::i;:::-;;;;;;;;15931:18:12;646:6186:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;:::i;:::-;;;:::i;:::-;;;;;2496:78:0;646:6186:13;;620:10:0;:25;616:83;;646:6186:13;2630:42:15;646:6186:13;;2630:42:15;646:6186:13;;;;;2572:17:15;646:6186:13;;2572:40:15;646:6186:13;;;;;;;;;;;;;;;;;;2572:40:15;646:6186:13;;;;;;;;;;;;;;;;;;;;;;2630:42:15;;;;646:6186:13;;616:83:0;646:6186:13;;669:18:0;;;;646:6186:13;;;;;;-1:-1:-1;;646:6186:13;;;;;;;5372:82:15;646:6186:13;;;;;;1362:58;;;;646:6186;1362:58;;1414:4;1362:58;;;646:6186;1362:58;;;;;;;;646:6186;1362:58;;;;646:6186;;;;;;;;;;;;;;;:::i;:::-;;;;1362:58;;;;;;;;;;;;;;:::i;:::-;;;;;:::i;:::-;;;;;;;646:6186;;;;;;;;;;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;:::i;:::-;;;;2496:78:0;646:6186:13;;620:10:0;:25;616:83;;646:6186:13;;;;;4419:202;;646:6186;;;;4419:202;120:42:19;4476:133:13;;;;;;646:6186;;;4476:133;;4548:4;4476:133;;;646:6186;;;;;;;;;;;;;;;;;;;;;;;;;4476:133;;;;;;;;;;;;646:6186;;4476:133;;;;:::i;:::-;646:6186;;4476:133;646:6186;;;;4476:133;646:6186;;;;;;;;4476:133;646:6186;;;616:83:0;646:6186:13;;;669:18:0;;;;646:6186:13;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;2496:78:0;646:6186:13;;620:10:0;:25;616:83;;5195:9:13;;5206:19;;;;;;646:6186;;;5195:9;5264:11;5249:27;5264:11;;646:6186;5264:11;;;;:::i;:::-;646:6186;;;;;;5249:27;1525:2:12;5195:9:13;;616:83:0;646:6186:13;;669:18:0;;;;646:6186:13;;;;;;;-1:-1:-1;;646:6186:13;;;;;5372:82:15;646:6186:13;;;;1067:64;;1116:4;1067:64;;;646:6186;;;;;;;;;;;;;;;;;;;;;1067:64;;;;;;;;;;646:6186;1067:64;;;;646:6186;;;;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;646:6186:13;;;;;1387:13:12;646:6186:13;;;:::i;:::-;;;;;;;;;6666:18:12;646:6186:13;;;;;;6665:82:12;646:6186:13;;;;;;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;:::i;:::-;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2646:10:18;;2638:18;;;2634:81;;;646:6186:13;2634:81:18;;646:6186:13;18683:27:12;;;;;:::i;:::-;646:6186:13;18898:45:12;18894:95;;646:6186:13;;;;;;;;;17575:15:12;646:6186:13;;;;;;17749:135:12;;2646:10:18;;16763:479:12;2646:10:18;;16763:479:12;;19193:69;19189:189;;646:6186:13;19544:195:12;;646:6186:13;;;;;20108:18:12;646:6186:13;;;;;;;;;;;;;;;;;;;;;;;;;1525:2:12;646:6186:13;;;;;;2443:8:12;13323:336;;;;;;646:6186:13;;;;20872:377:12;;;;21263:13;21259:58;;22488:14;;22484:192;;646:6186:13;;;22484:192:12;22527:56;;;:::i;:::-;22526:57;22522:154;;22484:192;;;;646:6186:13;;;22522:154:12;37961:94;22612:47;37961:94;;;21259:58;37961:94;;21286:30;37961:94;;;19544:195;;;;;;19189:189;646:6186:13;;;;;;;;;;;15931:18:12;646:6186:13;;;;;2646:10:18;646:6186:13;;;;;;;;;;19281:44:12;19277:101;;19189:189;;;;;;;;;;;19277:101;37961:94;;19335:42;37961:94;;;18894:95;37961:94;;18953:35;37961:94;;;2634:81:18;2693:10;2646;2693;:::i;:::-;2634:81;;;2693:10;2646;2693;:::i;:::-;2634:81;;646:6186:13;;;;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;:::i;:::-;;;;:::i;:::-;;;;;;;;;;;;;;;;:::i;:::-;915:10:15;;;;646:6186:13;;897:17:15;646:6186:13;;;;;;;;896:30:15;892:96;;2243:13:13;;;2257:19;;;;;;646:6186;;;2243:13;2312:11;2356:7;2312:11;646:6186;2312:11;;;;:::i;:::-;646:6186;2356:7;;;:::i;:::-;1525:2:12;2243:13:13;;892:96:15;646:6186:13;950:26:15;;;;646:6186:13;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;:::i;:::-;;;;:::i;:::-;2923:8:18;;;;:::i;:::-;35877:10:12;646:6186:13;;15514:18:12;646:6186:13;;;;;;;;;;;;;;15514:60:12;646:6186:13;;;;;;;;;;;;;;;;;;15514:60:12;646:6186:13;;;;;;15590:55:12;646:6186:13;35877:10:12;15590:55;;646:6186:13;;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;;;1566:78:15;;646:6186:13;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;646:6186:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;;2496:78:0;646:6186:13;;;;;;;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;2496:78:0;646:6186:13;;620:10:0;:25;616:83;;3654:85;;646:6186:13;;;;;;;;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;;5372:82:15;646:6186:13;;;;;;;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;2496:78:0;646:6186:13;;620:10:0;:25;616:83;;4186:24:15;;;;;646:6186:13;;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;15931:18:12;646:6186:13;;;;;2946:10;646:6186;;;;;;;;;;2922:35;2918:90;;3022:13;;13323:336:12;;;;-1:-1:-1;3022:13:13;3036:19;;;;;;646:6186;;;3022:13;3091:11;;;;;:::i;:::-;646:6186;10888:27:12;;;;;;:::i;:::-;646:6186:13;3122:24;3119:56;;31186:27:12;;;;:::i;:::-;646:6186:13;;;;;17575:15:12;646:6186:13;;;;;;17749:135:12;;31894:195;;3022:13:13;646:6186;;;;32680:18:12;646:6186:13;;;;;1652:3:12;646:6186:13;;;;;;;;;;;1525:2:12;646:6186:13;;;;;;;;33099:43:12;13323:336;;;;646:6186:13;;;;33243:35:12;;;;1525:2;3022:13:13;;31894:195:12;;;;;;3119:56:13;646:6186;;;3157:15;;;;2918:90;646:6186;;;2981:15;;;;646:6186;;;;;;;-1:-1:-1;;646:6186:13;;;;;;2496:78:0;646:6186:13;;620:10:0;:25;616:83;;646:6186:13;;4988:41;646:6186;;;;;5011:17;646:6186;;;;4988:41;646:6186;;616:83:0;646:6186:13;;669:18:0;;;;646:6186:13;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;;:::i;:::-;;6349:19:12;;;6345:69;;646:6186:13;;1387:13:12;646:6186:13;;;;;6432:18:12;646:6186:13;;;;6432:55:12;646:6186:13;;;;;;6345:69:12;37961:94;6378:35;37961:94;;;646:6186:13;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;:::i;:::-;;;;:::i;:::-;;;;:::i;:::-;;;2496:78:0;646:6186:13;;620:10:0;:25;616:83;;646:6186:13;;;2889:69:15;;;;;646:6186:13;;;2889:69:15;;646:6186:13;;;;2889:69:15;;;646:6186:13;;;;;;;;;;;;;;-1:-1:-1;646:6186:13;;;;;;;;2889:69:15;;;;;;;;;;;;646:6186:13;;616:83:0;646:6186:13;;;669:18:0;;;;646:6186:13;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;2496:78:0;646:6186:13;;620:10:0;:25;616:83;;3910:36:13;;;3907:74;;3997:17;;;4015:25;;;;;;646:6186;;;3997:17;4076;;;;;:::i;:::-;646:6186;;;;;;;;;4095:15;646:6186;4095:15;;;;;;:::i;:::-;646:6186;620:10:0;;4095:15:13;:::i;:::-;1525:2:12;3997:17:13;;646:6186;;;;3907:74;646:6186;3957:21;;;;646:6186;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;:::i;:::-;;;;;;;;;;;;15931:18:12;646:6186:13;;;;;2586:10;646:6186;;;;;;;;;;2562:35;2558:90;;10888:27:12;;;;:::i;:::-;646:6186:13;2661:24;2658:56;;31186:27:12;;;;;;;:::i;:::-;646:6186:13;;;;;17575:15:12;646:6186:13;;;;;;17749:135:12;;31894:195;;646:6186:13;;;;;32680:18:12;646:6186:13;;;;;1652:3:12;646:6186:13;;;;;;;;1525:2:12;646:6186:13;;;;;;;33099:43:12;13323:336;;;;;;646:6186:13;;;;33243:35:12;;;;646:6186:13;;31894:195:12;;;;;;2658:56:13;646:6186;;2696:15;;;;646:6186;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;10888:27:12;646:6186:13;;;10888:27:12;:::i;:::-;646:6186:13;;;;;;;;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;:::i;:::-;;;:::i;:::-;;;;2496:78:0;646:6186:13;;620:10:0;:25;616:83;;646:6186:13;;;3476:73:15;;;;;;646:6186:13;;;3476:73:15;646:6186:13;3476:73:15;;;;646:6186:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3476:73:15;;;;;;;;;;;;;646:6186:13;;616:83:0;646:6186:13;;;669:18:0;;;;646:6186:13;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;:::i;:::-;;;;2496:78:0;646:6186:13;;620:10:0;:25;616:83;;646:6186:13;;;;2363:26:15;646:6186:13;;4902:82:15;;646:6186:13;;;;;;;;;;;;2363:26:15;646:6186:13;;616:83:0;646:6186:13;;669:18:0;;;;646:6186:13;;;;;;;;;;:::i;:::-;915:10:15;;;;;646:6186:13;;897:17:15;646:6186:13;;;;;;;;896:30:15;892:96;;2017:7:13;;;;;;:::i;:::-;646:6186;;892:96:15;646:6186:13;;;950:26:15;;;;646:6186:13;;;;;;;-1:-1:-1;;646:6186:13;;;;;3258:85:0;646:6186:13;;;;;;;;765:10:0;;;:28;761:86;;2496:78;;;646:6186:13;;;;;;;;;;;;;;;;1724:49:0;;;;646:6186:13;;;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;2496:78:0;646:6186:13;;620:10:0;:25;616:83;;120:42:19;;;;4779:74:13;;;;;;646:6186;;;;;;;4779:74;;;;;646:6186;4779:74;;4837:4;4779:74;;;646:6186;4779:74;;;;;;;;;;646:6186;;4779:74;646:6186;;;;616:83:0;646:6186:13;;;669:18:0;;;;646:6186:13;;;;;:::i;:::-;;;;;;;;;;2646:10:18;2638:18;;;2634:81;;;;646:6186:13;;;;;;;;;;;;;;;;;;;;;;;;2634:81:18;;;;18683:27:12;;;;;:::i;646:6186:13:-;;;;;;;;;;2634:81:18;2693:10;2646;2693;:::i;:::-;2634:81;;646:6186:13;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;;120:42:19;646:6186:13;;;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;;;;;;;;;;;;:::i;:::-;;;2496:78:0;646:6186:13;;620:10:0;:25;616:83;;4754:532:9;2582:5;4754:532;;;;;;;;;;;;;;;646:6186:13;;4754:532:9;;;;;;;;;;;;;646:6186:13;;;;;;-1:-1:-1;;646:6186:13;;;;;;2496:78:0;646:6186:13;;620:10:0;;:25;616:83;;4421:21:15;;;;;;4388:59;;;;;:::i;:::-;;4462:5;4458:61;;646:6186:13;;;4458:61:15;646:6186:13;4491:16:15;;;;616:83:0;646:6186:13;;669:18:0;;;;646:6186:13;;;;;;-1:-1:-1;;646:6186:13;;;;;;;:::i;:::-;;;:::i;:::-;;;:::i;:::-;;;;;2496:78:0;646:6186:13;;620:10:0;:25;616:83;;646:6186:13;;;;;;3175:69:15;;;;;646:6186:13;3175:69:15;646:6186:13;;;3175:69:15;;;;;;;646:6186:13;3175:69:15;;;;646:6186:13;;;;;;;;;;;;;;;;;;;3175:69:15;;;;;;;;;;;;;646:6186:13;;;3175:69:15;;;;:::i;646:6186:13:-;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;;;;;3522:799:9;;;;;;646:6186:13;3522:799:9;;;;;;;;;;;646:6186:13;3522:799:9;2582:5;3522:799;;;;;;;;;;;;;;;;646:6186:13;3522:799:9;;;;;646:6186:13;;;;;;;;;;;;;;;;;;;3522:799:9;;;;;2582:5;3522:799;;;;;;;646:6186:13;;;;;:::i;:::-;;;;;;;;;2646:10:18;;2638:18;;2634:81;;646:6186:13;18683:27:12;;;;;:::i;:::-;646:6186:13;18898:45:12;18894:95;;646:6186:13;;;17575:15:12;646:6186:13;;;;;;17749:135:12;;2646:10:18;;16763:479:12;2646:10:18;;16763:479:12;;19193:69;19189:189;;646:6186:13;19544:195:12;;646:6186:13;;;;;20108:18:12;646:6186:13;;;;;;;;;;;;;;;;;;;;;1525:2:12;646:6186:13;;1525:2:12;646:6186:13;;;;;;;;2443:8:12;13323:336;;;;;;646:6186:13;;;;20872:377:12;;;;21263:13;21259:58;;646:6186:13;;;21259:58:12;37961:94;21286:30;37961:94;;;19544:195;;;;;;19189:189;646:6186:13;;;;;15931:18:12;646:6186:13;;;;;2646:10:18;646:6186:13;;;;;;;;;;19281:44:12;19277:101;;19189:189;;;;;19277:101;37961:94;;19335:42;37961:94;;;18894:95;37961:94;;18953:35;37961:94;;;2634:81:18;2693:10;2646;2693;:::i;:::-;2634:81;;646:6186:13;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;;5555:12:12;646:6186:13;1652:3:12;;646:6186:13;;;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;:::i;:::-;;;;2923:8:18;;;;:::i;:::-;646:6186:13;10888:27:12;;;;;:::i;:::-;646:6186:13;35877:10:12;;;30212:28;30191:201;;646:6186:13;;;;;30404:15:12;646:6186:13;;;;;;;;;;;;;;;30455:28:12;;;;646:6186:13;;30191:201:12;646:6186:13;;;15931:18:12;646:6186:13;;;;;35877:10:12;646:6186:13;;;;;;;;;;30191:201:12;30255:137;37961:94;30333:42;37961:94;;;646:6186:13;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;;;;;;;;;;;;16385:10:12;;;:43;;;;646:6186:13;14952:17:12;;14948:73;;646:6186:13;;;;;;;;15041:15:12;646:6186:13;;;;;;;;;;;14948:73:12;37961:94;14979:41;37961:94;;;16385:43;2163:8;16399:24;;;:29;16385:43;;;646:6186:13;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;;;1226:74:15;646:6186:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;646:6186:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;;;;;;;;;;6665:43;;6680:28;6665:43;;:102;;;;;646:6186;6665:156;;;;;646:6186;;;;;;;;;6665:156;8878:25:12;;;646:6186:13;8878:25:12;;:102;;;;;6665:156:13;8878:179:12;;;;6665:156:13;;;;;;8878:179:12;646:6186:13;9032:25:12;;;8878:179;;;:102;646:6186:13;8955:25:12;;;-1:-1:-1;8878:102:12;;6665::13;1995:45:15;;;2010:30;1995:45;;:100;;;;;6665:102:13;1995:161:15;;;;;6665:102:13;;;;;1995:161:15;2168:25:0;646:6186:13;2168:25:0;;1995:161:15;;:100;2953:186:9;;646:6186:13;2953:186:9;;;;;;;;1995:100:15;;;646:6186:13;;;;;;;;-1:-1:-1;;646:6186:13;;;;;;;;;;;;:::i;:::-;;;;801:49:15;646:6186:13;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;-1:-1:-1;;646:6186:13;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;:::o;:::-;-1:-1:-1;;646:6186:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;12253:371:12:-;-1:-1:-1;646:6186:13;12356:17:12;646:6186:13;;;-1:-1:-1;646:6186:13;;12474:10:12;;;:43;;;12253:371;12470:89;;12577:38;-1:-1:-1;37961:94:12;12356:17;-1:-1:-1;37961:94:12;12470:89;12534:13;:::o;12474:43::-;12488:24;2163:8;12488:24;;:29;12474:43;;646:6186:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;:::i;25966:2138:12:-;;-1:-1:-1;646:6186:13;;;;26057:17:12;646:6186:13;;;;;;26054:71:12;;646:6186:13;13323:336:12;;;646:6186:13;;;;13975:154:12;13323:336;;;;;;646:6186:13;;;;;27008:12:12;;;27005:257;646:6186:13;;;;;;;27041:18:12;646:6186:13;;;;;27068:32:12;646:6186:13;;;;;27005:257:12;26734:1;646:6186:13;;1525:2:12;646:6186:13;;27482:13:12;;27478:54;;27605:420;;;;25966:2138::o;27478:54::-;37961:94;27505:26;26057:17;37961:94;;;27005:257;646:6186:13;;;27142:18:12;646:6186:13;;;;;26734:1:12;646:6186:13;;;;;;;;;;1525:2:12;646:6186:13;;;;;27005:257:12;;26054:71;26057:17;37961:94;26097:27;37961:94;;;646:6186:13;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;-1:-1:-1;646:6186:13;;;;:::o;:::-;;;:::o;24767:737:12:-;;;24951:87;24767:737;646:6186:13;24767:737:12;646:6186:13;;;;;;;;24951:87:12;;;;35877:10;24951:87;;;646:6186:13;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;24951:87:12;-1:-1:-1;;646:6186:13;;;;24951:87:12;;;;;;;24767:737;-1:-1:-1;24947:550:12;;25185:312;;;:::i;:::-;646:6186:13;;;25232:18:12;25228:115;;25405:81;;;;24951:87;25405:81;;25228:115;37961:94;25279:47;24951:87;37961:94;;;24947:550;646:6186:13;;25109:63:12;;-1:-1:-1;25102:70:12:o;24951:87::-;;;;;;;;;;;;;;;;;;:::i;:::-;;;646:6186:13;;;;;;;;;;;;24951:87:12;;;;;;;-1:-1:-1;24951:87:12;;646:6186:13;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;3038:638:18;120:42:19;3227:45:18;;3223:447;;3038:638;;:::o;3223:447::-;646:6186:13;;;3523:67:18;;3574:4;3523:67;;;646:6186:13;;;;;;;;;3523:67:18;;646:6186:13;;;;;;3523:67:18;;;;;;;3275:1;3523:67;;;3223:447;3522:68;;3518:142;;3038:638;:::o;3518:142::-;646:6186:13;;;;;3617:28:18;;;;646:6186:13;3523:67:18;3617:28;;646:6186:13;3617:28:18;3523:67;;;;;;;;;;;;;;;:::i;:::-;;;646:6186:13;;;;;;;;;;;;;3523:67:18;;;;;;;-1:-1:-1;3523:67:18;;;646:6186:13;;;3275:1:18;646:6186:13;;;;
Swarm Source
ipfs://0fc0f51e10d57820e8bba2fd82a70d77a994c34804a2fe0e1f26200c17d84e33
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 29 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.