Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 19146675 | 294 days ago | IN | 0 ETH | 0.07969487 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
ERC721LA
Compiler Version
v0.8.15+commit.e14f2714
Optimization Enabled:
Yes with 100 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; import "../extensions/Burnable.sol"; import "../extensions/WithOperatorRegistry.sol"; import "../extensions/AirDropable.sol"; import "./IERC721LA.sol"; import "../extensions/Pausable.sol"; import "../extensions/Whitelistable.sol"; // import "../extensions/PermissionedTransfers.sol"; import "../extensions/LAInitializable.sol"; import "../libraries/LANFTUtils.sol"; import "../libraries/BPS.sol"; import "../libraries/CustomErrors.sol"; import "../platform/royalties/RoyaltiesState.sol"; import "./ERC721State.sol"; import "./ERC721LACore.sol"; /** * @notice LiveArt ERC721 implementation contract * Supports multiple edtioned NFTs and gas optimized batch minting */ contract ERC721LA is ERC721LACore, Burnable, AirDropable, Whitelistable { /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Royalties * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ function setRoyaltyRegistryAddress( address _royaltyRegistry ) public onlyAdmin { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); state._royaltyRegistry = IRoyaltiesRegistry(_royaltyRegistry); } function royaltyRegistryAddress() public view returns (IRoyaltiesRegistry) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); return state._royaltyRegistry; } /// @dev see: EIP-2981 function royaltyInfo( uint256 _tokenId, uint256 _value ) external view returns (address _receiver, uint256 _royaltyAmount) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); return state._royaltyRegistry.royaltyInfo(address(this), _tokenId, _value); } function registerCollectionRoyaltyReceivers( RoyaltiesState.RoyaltyReceiver[] memory royaltyReceivers ) public onlyAdmin { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); IRoyaltiesRegistry(state._royaltyRegistry) .registerCollectionRoyaltyReceivers( address(this), msg.sender, royaltyReceivers ); } function primaryRoyaltyInfo( uint256 tokenId ) public view returns (address payable[] memory, uint256[] memory) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); return IRoyaltiesRegistry(state._royaltyRegistry).primaryRoyaltyInfo( address(this), tokenId ); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.2) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates merkle trees that are safe * against this attack out of the box. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} * * _Available since v4.7._ */ function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} * * _Available since v4.7._ */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). * * _Available since v4.7._ */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { require(proofPos == proofLen, "MerkleProof: invalid multiproof"); unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { require(proofPos == proofLen, "MerkleProof: invalid multiproof"); unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; import "./IAccessControl.sol"; abstract contract AccessControl is IAccessControl{ bytes32 public constant COLLECTION_ADMIN_ROLE = keccak256("COLLECTION_ADMIN_ROLE"); function _getAccessControlState() internal pure returns (RoleState storage state) { bytes32 position = keccak256("liveart.AccessControl"); assembly { state.slot := position } } /** * @notice Checks that msg.sender has a specific role. * Reverts with a AccessControlNotAllowed. * */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @notice Checks that msg.sender has COLLECTION_ADMIN_ROLE * Reverts with a AccessControlNotAllowed. * */ modifier onlyAdmin() { _checkRole(COLLECTION_ADMIN_ROLE); _; } function isAdmin(address theAddress) public view returns (bool) { return hasRole(COLLECTION_ADMIN_ROLE, theAddress); } /** * @notice Checks if role is assigned to account * */ function hasRole(bytes32 role, address account) public view returns (bool) { RoleState storage state = _getAccessControlState(); return state._roles[role][account]; } /** * @notice Revert with a AccessControlNotAllowed message if `msg.sender` is missing `role`. * */ function _checkRole(bytes32 role) internal view virtual { if (!hasRole(role, msg.sender)) { revert AccessControlNotAllowed(); } } /** * @notice Grants `role` to `account`. * * @dev If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public onlyAdmin { _grantRole(role, account); } /** * @notice Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have COLLECTION_ADMIN_ROLE role. */ function revokeRole(bytes32 role, address account) public onlyAdmin { _revokeRole(role, account); } /** * @notice Revokes `role` from the calling account. * * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual { if (account != msg.sender) { revert AccessControlNotAllowed(); } _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. */ function _grantRole(bytes32 role, address account) internal { RoleState storage state = _getAccessControlState(); if (!hasRole(role, account)) { state._roles[role][account] = true; emit RoleGranted(role, account, msg.sender); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. */ function _revokeRole(bytes32 role, address account) internal { RoleState storage state = _getAccessControlState(); if (hasRole(role, account)) { state._roles[role][account] = false; emit RoleRevoked(role, account, msg.sender); } } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; import "../libraries/CustomErrors.sol"; import "../libraries/BPS.sol"; import "../libraries/CustomErrors.sol"; import "../libraries/LANFTUtils.sol"; import "../tokens/ERC721State.sol"; import "../tokens/ERC721LACore.sol"; import "./IAirDropable.sol"; import "../platform/royalties/RoyaltiesState.sol"; abstract contract AirDropable is IAirDropable, ERC721LACore { uint256 public constant AIRDROP_MAX_BATCH_SIZE = 100; function airdrop( uint256 editionId, address[] calldata recipients, uint24 quantityPerAddress ) external onlyAdmin { if (recipients.length > AIRDROP_MAX_BATCH_SIZE) { revert TooManyAddresses(); } for (uint256 i = 0; i < recipients.length; i++) { _safeMint(editionId, quantityPerAddress, recipients[i]); } } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; import "../libraries/CustomErrors.sol"; import "../libraries/BPS.sol"; import "../tokens/ERC721LACore.sol"; import "../libraries/LANFTUtils.sol"; import "../tokens/ERC721State.sol"; abstract contract Burnable is ERC721LACore { /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * BURNABLE * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function burn(uint256 tokenId) public { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); address owner = ownerOf(tokenId); if (!_isApprovedOrOwner(msg.sender, tokenId)) { revert CustomErrors.TransferError(); } _transferCore(owner, ERC721LACore.burnAddress, tokenId); // Looksrare and other marketplace require the owner to be null address emit Transfer(owner, address(0), tokenId); (uint256 editionId, ) = parseEditionFromTokenId(tokenId); // Update the number of tokens burned for this edition state._editions[editionId].burnedSupply += 1; } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * @param tokenIds array of tokenIds to burn * Requirements: * - `tokenId` must exist. * Emits a {Transfer} event. */ function burnMultiple(uint256[] calldata tokenIds) public { for (uint i = 0; i < tokenIds.length; i++) { uint256 tokenId = tokenIds[i]; burn(tokenId); } } function burnRedeemEditionTokens( uint256 _editionId, uint24 _quantity, uint256[] calldata tokenIdsToBurn ) public whenPublicMintOpened(_editionId) whenNotPaused { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); ERC721State.Edition memory edition = getEdition(_editionId); if (edition.burnableEditionId == 0 || tokenIdsToBurn.length == 0) { revert CustomErrors.BurnRedeemNotAvailable(); } uint256 mintableAmount = tokenIdsToBurn.length / edition.amountToBurn; if (mintableAmount < _quantity) { revert CustomErrors.BurnRedeemNotAvailable(); } // Check max mint per wallet restrictions (if maxMintPerWallet is 0, no restriction apply) uint256 mintedCountKey = uint256( keccak256(abi.encodePacked(_editionId, msg.sender)) ); if (edition.maxMintPerWallet != 0) { if ( state._mintedPerWallet[mintedCountKey] + _quantity > edition.maxMintPerWallet ) { revert CustomErrors.MaximumMintAmountReached(); } } state._mintedPerWallet[mintedCountKey] += _quantity; // We iterate and burn only the required amount of tokens (preventing burning more than necessary) // burn will revert if the sender is not the owner of a given token for (uint256 i; i < edition.amountToBurn * _quantity; i++) { burn(tokenIdsToBurn[i]); } _safeMint(_editionId, _quantity, msg.sender); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; interface IAccessControl { error AccessControlNotAllowed(); struct RoleState { mapping(bytes32 => mapping(address => bool)) _roles; } /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role */ event RoleGranted( bytes32 indexed role, address indexed account, address indexed sender ); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked( bytes32 indexed role, address indexed account, address indexed sender ); /** * @notice Checks if role is assigned to account * */ function hasRole(bytes32 role, address account) external returns (bool); /** * @notice Grants `role` to `account`. * * @dev If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @notice Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have COLLECTION_ADMIN_ROLE role. */ function revokeRole(bytes32 role, address account) external; /** * @notice Revokes `role` from the calling account. * * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; function isAdmin(address theAddress) external view returns (bool); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; interface IAirDropable { error TooManyAddresses(); function airdrop(uint256 editionId, address[] calldata recipients, uint24 quantityPerAddres) external; }
/// @title EIP-721 Metadata Update Extension 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: UNLICENSED pragma solidity ^0.8.4; interface IWhitelistable { /** * Raised when trying create a WhiteList config that already exisit (mint amounts are the same) */ error WhiteListAlreadyExists(); error NotWhitelisted(); error InvalidMintDuration(); function whitelistMint( uint256 editionId, uint8 maxAmount, uint24 mintPriceInFinney, bytes32[] calldata merkleProof, uint24 quantity, address receiver, uint24 tokenId, uint24 mintPriceWithPrintInFinney ) external payable; function setWLConfig( uint256 editionId, uint8 amount, uint24 mintPriceInFinney, uint32 mintStartTS, uint32 mintEndTS, bytes32 merkleRoot, uint24 mintPriceWithPrintInFinney ) external; function updateWLConfig( uint256 editionId, uint8 amount, uint24 mintPriceInFinney, uint8 newAmount, uint24 newMintPriceInFinney, uint32 newMintStartTS, uint32 newMintEndTS, bytes32 newMerkleRoot, uint24 mintPriceWithPrintInFinney, uint24 newMintPriceWithPrintInFinney ) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; abstract contract LAInitializable { error AlreadyInitialized(); struct InitializableState { bool _initialized; } function _getInitializableState() internal pure returns (InitializableState storage state) { bytes32 position = keccak256("liveart.Initializable"); assembly { state.slot := position } } modifier notInitialized() { InitializableState storage state = _getInitializableState(); if (state._initialized) { revert AlreadyInitialized(); } _; state._initialized = true; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; abstract contract Ownable { error CallerIsNotOwner(); error NewOwnerIsZeroAddress(); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); struct OwnableState { address owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } function owner() public view returns(address){ OwnableState storage state = _getOwnableState(); return state.owner; } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if(newOwner == address(0)){ revert NewOwnerIsZeroAddress(); } _transferOwnership(newOwner); } function _getOwnableState() internal pure returns (OwnableState storage state) { bytes32 position = keccak256("liveart.Ownable"); assembly { state.slot := position } } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if(owner() != msg.sender) { revert CallerIsNotOwner(); } } function _setOwner(address newOwner) internal { OwnableState storage state = _getOwnableState(); state.owner = newOwner; } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal { address previousOwner = owner(); _setOwner(newOwner); emit OwnershipTransferred(previousOwner, newOwner); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ contract Pausable { event Paused(address account); event Unpaused(address account); struct PausableState { bool _paused; } function _getPausableState() internal pure returns (PausableState storage state) { bytes32 position = keccak256("liveart.Pausable"); assembly { state.slot := position } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * MODIFIERS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view returns (bool) { PausableState storage state = _getPausableState(); return state._paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal whenNotPaused { PausableState storage state = _getPausableState(); state._paused = true; emit Paused(msg.sender); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal whenPaused { PausableState storage state = _getPausableState(); state._paused = false; emit Unpaused(msg.sender); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; import "../libraries/BPS.sol"; import "../libraries/CustomErrors.sol"; import "../libraries/LANFTUtils.sol"; import "../tokens/ERC721State.sol"; import "../tokens/ERC721LACore.sol"; import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import "./IWhitelistable.sol"; import "./WhitelistableState.sol"; import "hardhat/console.sol"; interface ILiveArtXcard { function balanceOf(address owner) external view returns (uint256); } abstract contract Whitelistable is IWhitelistable, ERC721LACore { /** * Create a Whitelist configuration * @param _editionId the edition ID * @param amount How many mint allowed per Whitelist spot * @param mintPriceInFinney Price of the whitelist mint in Finney * @param mintStartTS Starting time of the Whitelist mint * @param mintEndTS Starting time of the Whitelist mint * @param merkleRoot The whitelist merkle root * @param mintPriceWithPrintInFinney The mint price with print in Finney * */ function setWLConfig( uint256 _editionId, uint8 amount, uint24 mintPriceInFinney, uint32 mintStartTS, uint32 mintEndTS, bytes32 merkleRoot, uint24 mintPriceWithPrintInFinney ) public onlyAdmin { WhitelistableState.WLState storage state = WhitelistableState ._getWhitelistableState(); // This reverts if edition does not exist getEdition(_editionId); uint256 wlId = uint256( keccak256( abi.encodePacked( _editionId, amount, mintPriceInFinney, mintPriceWithPrintInFinney ) ) ); if (state._whitelistConfig[wlId].amount != 0) { revert WhiteListAlreadyExists(); } if (mintEndTS != 0 && mintEndTS < mintStartTS) { revert InvalidMintDuration(); } WhitelistableState.WhitelistConfig memory whitelistConfig = WhitelistableState.WhitelistConfig({ merkleRoot: merkleRoot, amount: amount, mintPriceInFinney: mintPriceInFinney, mintStartTS: mintStartTS, mintEndTS: mintEndTS, mintPriceWithPrintInFinney: mintPriceWithPrintInFinney }); state._whitelistConfig[wlId] = whitelistConfig; } /** * Update a Whitelist configuration * @param _editionId Edition ID of the WL to be updated * @param _amount Amount of the WL to be updated * @param mintPriceInFinney Price of the WL to be updated * @param newAmount New Amount * @param newMintPriceInFinney New mint price in Finney * @param newMintStartTS New Mint time * @param newMerkleRoot New Merkle root * * Note: When changing a single property of the WL config, * make sure to also pass the value of the property that did not change. * */ function updateWLConfig( uint256 _editionId, uint8 _amount, uint24 mintPriceInFinney, uint8 newAmount, uint24 newMintPriceInFinney, uint32 newMintStartTS, uint32 newMintEndTS, bytes32 newMerkleRoot, uint24 mintPriceWithPrintInFinney, uint24 newMintPriceWithPrintInFinney ) public onlyAdmin { WhitelistableState.WLState storage state = WhitelistableState ._getWhitelistableState(); // This reverts if edition does not exist getEdition(_editionId); uint256 wlId = uint256( keccak256( abi.encodePacked( _editionId, _amount, mintPriceInFinney, mintPriceWithPrintInFinney ) ) ); WhitelistableState.WhitelistConfig memory whitelistConfig; // If amount or price differ, then set previous WL config key to amount 0, which effectively disable the WL if ( _amount != newAmount || mintPriceInFinney != newMintPriceInFinney || mintPriceWithPrintInFinney != newMintPriceWithPrintInFinney ) { state._whitelistConfig[wlId] = WhitelistableState.WhitelistConfig({ merkleRoot: newMerkleRoot, amount: 0, mintPriceInFinney: newMintPriceInFinney, mintStartTS: newMintStartTS, mintEndTS: newMintEndTS, mintPriceWithPrintInFinney: newMintPriceWithPrintInFinney }); wlId = uint256( keccak256( abi.encodePacked( _editionId, newAmount, newMintPriceInFinney, newMintPriceWithPrintInFinney ) ) ); state._whitelistConfig[wlId] = whitelistConfig; } if (newMintEndTS != 0 && newMintEndTS < newMintStartTS) { revert InvalidMintDuration(); } whitelistConfig = WhitelistableState.WhitelistConfig({ merkleRoot: newMerkleRoot, amount: newAmount, mintPriceInFinney: newMintPriceInFinney, mintStartTS: newMintStartTS, mintEndTS: newMintEndTS, mintPriceWithPrintInFinney: newMintPriceWithPrintInFinney }); state._whitelistConfig[wlId] = whitelistConfig; } /** * Whitelist mint function * @param _editionId the edition ID * @param _maxAmount How many mint allowed per Whitelist spot * @param _merkleProof the merkle proof of the minter * @param _quantity How many NFTs to mint * @param _recipient The recipient of the NFTs * @param _xCardTokenId The XCard token ID * @param _mintPriceWithPrintInFinney The mint price with print in Finney */ function whitelistMint( uint256 _editionId, uint8 _maxAmount, uint24 _mintPriceInFinney, bytes32[] calldata _merkleProof, uint24 _quantity, address _recipient, uint24 _xCardTokenId, uint24 _mintPriceWithPrintInFinney ) public payable { _validateWhitelistMintingParameters( _editionId, _maxAmount, _mintPriceInFinney, _merkleProof, _quantity, _mintPriceWithPrintInFinney ); _validateMintPrice(_mintPriceInFinney, _quantity); uint256 firstTokenId = _safeMint(_editionId, _quantity, _recipient); _sendRoyaltiesAfterMint(firstTokenId); } /** * Whitelist mint with print function * @param _editionId the edition ID * @param _maxAmount How many mint allowed per Whitelist spot * @param _merkleProof the merkle proof of the minter * @param _quantity How many NFTs to mint * @param _recipient The recipient of the NFTs * @param _xCardTokenId The XCard token ID * @param _mintPriceWithPrintInFinney The mint price with print in Finney */ function whitelistMintWithPrint( uint256 _editionId, uint8 _maxAmount, uint24 _mintPriceInFinney, bytes32[] calldata _merkleProof, uint24 _quantity, address _recipient, uint24 _xCardTokenId, uint24 _mintPriceWithPrintInFinney ) public payable { ERC721State.EditionWithPrintData memory printData = getEditionPrintData( _editionId ); _validateWhitelistMintingParameters( _editionId, _maxAmount, _mintPriceInFinney, _merkleProof, _quantity, _mintPriceWithPrintInFinney ); _validateEditionPrintData(printData); _validateMintPrice(_mintPriceWithPrintInFinney, _quantity); uint256 firstTokenId = _safeMint(_editionId, _quantity, _recipient); _sendRoyaltiesAfterMint(firstTokenId); _mintPrintVouchers(_editionId, _quantity, firstTokenId); } /** * Get WL config for given editionId, amout, and mintPrice. * Should not be used internally when trying to modify the state as it returns a memory copy of the structs */ function getWLConfig( uint256 editionId, uint8 amount, uint24 mintPriceInFinney, uint24 mintPriceWithPrintInFinney ) public view returns (WhitelistableState.WhitelistConfig memory) { WhitelistableState.WLState storage state = WhitelistableState ._getWhitelistableState(); // This reverts if edition does not exist getEdition(editionId); uint256 wlId = uint256( keccak256( abi.encodePacked( editionId, amount, mintPriceInFinney, mintPriceWithPrintInFinney ) ) ); WhitelistableState.WhitelistConfig storage whitelistConfig = state ._whitelistConfig[wlId]; if (whitelistConfig.amount == 0) { revert CustomErrors.NotFound(); } return whitelistConfig; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INTERNAL FUNCTIONS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ function _validateWhitelistMintingParameters( uint256 _editionId, uint8 maxAmount, uint24 mintPriceInFinney, bytes32[] calldata merkleProof, uint24 _quantity, uint24 mintPriceWithPrintInFinney ) internal { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); // This reverts if WL does not exist (or is disabled) WhitelistableState.WhitelistConfig memory whitelistConfig = getWLConfig( _editionId, maxAmount, mintPriceInFinney, mintPriceWithPrintInFinney ); // Check for allowed mint count uint256 mintCountKey = uint256( keccak256(abi.encodePacked(_editionId, msg.sender)) ); if ( state._mintedPerWallet[mintCountKey] + _quantity > whitelistConfig.amount ) { revert CustomErrors.MaximumMintAmountReached(); } if ( whitelistConfig.mintStartTS == 0 || block.timestamp < whitelistConfig.mintStartTS ) { revert CustomErrors.MintClosed(); } if ( whitelistConfig.mintEndTS != 0 && block.timestamp > whitelistConfig.mintEndTS ) { revert CustomErrors.MintClosed(); } // We use msg.sender for the WL merkle root // Ran only if the user is not an XCard holder bytes32 leaf = keccak256(abi.encodePacked(msg.sender)); console.log( !MerkleProof.verify( merkleProof, whitelistConfig.merkleRoot, leaf)); if ( !MerkleProof.verify( merkleProof, whitelistConfig.merkleRoot, leaf ) && ILiveArtXcard(state._xCardContractAddress).balanceOf(msg.sender) == 0 ) { revert NotWhitelisted(); } state._mintedPerWallet[mintCountKey] += _quantity; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; library WhitelistableState { struct WhitelistConfig { bytes32 merkleRoot; uint8 amount; uint24 mintPriceInFinney; uint32 mintStartTS; uint32 mintEndTS; uint24 mintPriceWithPrintInFinney; } struct WLState { // hash(EditionId + mintable amount + price) mapping(uint256 => WhitelistConfig) _whitelistConfig; } /** * @dev Get storage data from dedicated slot. * This pattern avoids storage conflict during proxy upgrades * and give more flexibility when creating extensions */ function _getWhitelistableState() internal pure returns (WLState storage state) { bytes32 storageSlot = keccak256("liveart.Whitelistable"); assembly { state.slot := storageSlot } } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; import "../extensions/AccessControl.sol"; /** * Used to set Winter whitelisted minting addresses */ contract Winter is AccessControl { struct WinterState { address[] winterAddresses; } function _getWinterState() internal pure returns (WinterState storage state) { bytes32 position = keccak256("liveart.Winter"); assembly { state.slot := position } } // function addWinterWallets(address[] calldata newAddresses) public onlyAdmin { // for(uint256 i; i < newAddresses.length; i += 1) { // _setWinterWallet(newAddresses[i]); // } // } function addWinterWallet(address newAddress) public onlyAdmin { _setWinterWallet(newAddress); } function _setWinterWallet(address newAddress) internal { WinterState storage state = _getWinterState(); state.winterAddresses.push(newAddress); } function deleteWinterWallet(address newAddress) public onlyAdmin { WinterState storage state = _getWinterState(); for (uint256 i; i < state.winterAddresses.length; i += 1) { if (newAddress == state.winterAddresses[i]) { delete state.winterAddresses[i]; } } state.winterAddresses.push(newAddress); } function _isWinterWallet() internal view returns (bool) { WinterState storage state = _getWinterState(); for (uint256 i; i < state.winterAddresses.length; i += 1) { if (msg.sender == state.winterAddresses[i]) { return true; } } return false; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; import "../libraries/CustomErrors.sol"; import "./WithOperatorRegistryState.sol"; import "../libraries/LANFTUtils.sol"; import "../extensions/AccessControl.sol"; import "operator-filter-registry/src/IOperatorFilterRegistry.sol"; import {CANONICAL_CORI_SUBSCRIPTION} from "operator-filter-registry/src/lib/Constants.sol"; contract WithOperatorRegistry is AccessControl { address constant DEFAULT_OPERATOR_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E; /// @dev The upgradeable initialize function that should be called when the contract is being upgraded. function _initOperatorRegsitry() internal { WithOperatorRegistryState.OperatorRegistryState storage registryState = WithOperatorRegistryState ._getOperatorRegistryState(); IOperatorFilterRegistry registry = IOperatorFilterRegistry( DEFAULT_OPERATOR_REGISTRY_ADDRESS ); registryState.operatorFilterRegistry = registry; if (address(registry).code.length > 0) { registry.registerAndSubscribe( address(this), CANONICAL_CORI_SUBSCRIPTION ); } } function initOperatorRegsitry() public onlyAdmin { _initOperatorRegsitry(); } /** * @dev A helper modifier to check if the 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 modifier to check if the operator approval is allowed. */ modifier onlyAllowedOperatorApproval(address operator) virtual { _checkFilterOperator(operator); _; } /** * @dev A helper function to check if the operator is allowed. */ function _checkFilterOperator(address operator) internal view virtual { WithOperatorRegistryState.OperatorRegistryState storage registryState = WithOperatorRegistryState ._getOperatorRegistryState(); // Check registry code length to facilitate testing in environments without a deployed registry. if (address(registryState.operatorFilterRegistry).code.length > 0) { // under normal circumstances, this function will revert rather than return false, but inheriting or // upgraded contracts may specify their own OperatorFilterRegistry implementations, which may behave // differently if ( !registryState.operatorFilterRegistry.isOperatorAllowed( address(this), operator ) ) { revert CustomErrors.NotAllowed(); } } } /** * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero * address, checks will be bypassed. OnlyOwner. */ function updateOperatorFilterRegistryAddress(address newRegistry) public onlyAdmin { WithOperatorRegistryState.OperatorRegistryState storage registryState = WithOperatorRegistryState ._getOperatorRegistryState(); IOperatorFilterRegistry registry = IOperatorFilterRegistry( newRegistry ); registryState.operatorFilterRegistry = registry; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; import "operator-filter-registry/src/IOperatorFilterRegistry.sol"; library WithOperatorRegistryState { struct OperatorRegistryState { IOperatorFilterRegistry operatorFilterRegistry; } /** * @dev Get storage data from dedicated slot. * This pattern avoids storage conflict during proxy upgrades * and give more flexibility when creating extensions */ function _getOperatorRegistryState() internal pure returns (OperatorRegistryState storage state) { bytes32 storageSlot = keccak256("liveart.OperatorRegistryState"); assembly { state.slot := storageSlot } } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; import "./BitScan.sol"; /** * Derived from: https://github.com/estarriolvetch/solidity-bits */ /** * @dev This Library is a modified version of Openzeppelin's BitMaps library. * Functions of finding the index of the closest set bit from a given index are added. * The indexing of each bucket is modifed to count from the MSB to the LSB instead of from the LSB to the MSB. * The modification of indexing makes finding the closest previous set bit more efficient in gas usage. */ /** * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential. * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor]. */ error BitMapHeadNotFound(); library BitMaps { using BitScan for uint256; uint256 private constant MASK_INDEX_ZERO = (1 << 255); struct BitMap { mapping(uint256 => uint256) _data; } /** * @dev Returns whether the bit at `index` is set. */ function get(BitMap storage bitmap, uint256 index) internal view returns (bool) { uint256 bucket = index >> 8; uint256 mask = MASK_INDEX_ZERO >> (index & 0xff); return bitmap._data[bucket] & mask != 0; } /** * @dev Sets the bit at `index` to the boolean `value`. */ function setTo( BitMap storage bitmap, uint256 index, bool value ) internal { if (value) { set(bitmap, index); } else { unset(bitmap, index); } } /** * @dev Sets the bit at `index`. */ function set(BitMap storage bitmap, uint256 index) internal { uint256 bucket = index >> 8; uint256 mask = MASK_INDEX_ZERO >> (index & 0xff); bitmap._data[bucket] |= mask; } /** * @dev Unsets the bit at `index`. */ function unset(BitMap storage bitmap, uint256 index) internal { uint256 bucket = index >> 8; uint256 mask = MASK_INDEX_ZERO >> (index & 0xff); bitmap._data[bucket] &= ~mask; } /** * @dev Find the closest index of the set bit before `index`. */ function scanForward( BitMap storage bitmap, uint256 index, uint256 lowerBound ) internal view returns (uint256 matchedIndex) { uint256 bucket = index >> 8; uint256 lowerBoundBucket = lowerBound >> 8; // index within the bucket uint256 bucketIndex = (index & 0xff); // load a bitboard from the bitmap. uint256 bb = bitmap._data[bucket]; // offset the bitboard to scan from `bucketIndex`. bb = bb >> (0xff ^ bucketIndex); // bb >> (255 - bucketIndex) if (bb > 0) { unchecked { return (bucket << 8) | (bucketIndex - bb.bitScanForward256()); } } else { while (true) { // require(bucket > lowerBound, "BitMaps: The set bit before the index doesn't exist."); if (bucket < lowerBoundBucket) { revert BitMapHeadNotFound(); } unchecked { bucket--; } // No offset. Always scan from the least significiant bit now. bb = bitmap._data[bucket]; if (bb > 0) { unchecked { return (bucket << 8) | (255 - bb.bitScanForward256()); } } } } } }
// SPDX-License-Identifier: UNLICENSED /** _____ ___ ___ __ ____ _ __ / ___/____ / (_)___/ (_) /___ __ / __ )(_) /______ \__ \/ __ \/ / / __ / / __/ / / / / __ / / __/ ___/ ___/ / /_/ / / / /_/ / / /_/ /_/ / / /_/ / / /_(__ ) /____/\____/_/_/\__,_/_/\__/\__, / /_____/_/\__/____/ /____/ - npm: https://www.npmjs.com/package/solidity-bits - github: https://github.com/estarriolvetch/solidity-bits */ pragma solidity ^0.8.4; library BitScan { uint256 constant private DEBRUIJN_256 = 0x818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff; bytes constant private LOOKUP_TABLE_256 = hex"0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8"; /** @dev Isolate the least significant set bit. */ function isolateLS1B256(uint256 bb) pure internal returns (uint256) { require(bb > 0); unchecked { return bb & (0 - bb); } } /** @dev Isolate the most significant set bit. */ function isolateMS1B256(uint256 bb) pure internal returns (uint256) { require(bb > 0); unchecked { bb |= bb >> 256; bb |= bb >> 128; bb |= bb >> 64; bb |= bb >> 32; bb |= bb >> 16; bb |= bb >> 8; bb |= bb >> 4; bb |= bb >> 2; bb |= bb >> 1; return (bb >> 1) + 1; } } /** @dev Find the index of the lest significant set bit. (trailing zero count) */ function bitScanForward256(uint256 bb) pure internal returns (uint8) { unchecked { return uint8(LOOKUP_TABLE_256[(isolateLS1B256(bb) * DEBRUIJN_256) >> 248]); } } /** @dev Find the index of the most significant set bit. */ function bitScanReverse256(uint256 bb) pure internal returns (uint8) { unchecked { return 255 - uint8(LOOKUP_TABLE_256[((isolateMS1B256(bb) * DEBRUIJN_256) >> 248)]); } } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; library BPS { function _calculatePercentage(uint256 number, uint256 percentage) internal pure returns (uint256) { // https://ethereum.stackexchange.com/a/55702 // https://www.investopedia.com/terms/b/basispoint.asp return (number * percentage) / 10000; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; library CustomErrors { /** * Raised when trying to manipulate editions (CRUD) with invalid data */ error InvalidEditionData(); error MaxSupplyError(); error InvalidEditionId(); /** * Raised when trying to mint with invalid data */ error InvalidMintData(); /** * Raised when trying to transfer an NFT to a non ERC721Receiver */ error NotERC721Receiver(); /** * Raised when trying to query a non minted token */ error TokenNotFound(); /** * Raised when transfer fail */ error TransferError(); /** * Generic Not Allowed action */ error NotAllowed(); /** * Generic Not Found error */ error NotFound(); /** * Raised when direct minting with insufficient funds */ error InsufficientFunds(); /** * Raised when fund transfer fails */ error FundTransferError(); /** * Raised when trying to mint a print with invalid data */ error InvalidPrintData(); error MintClosed(); error MaximumMintAmountReached(); error BurnRedeemNotAvailable(); error NotXCardOwner(); error TokenStaked(); /** * Raised in the PrintVoucher contract */ error InvalidCaller(); error NotTokenOwner(); error MintNotOpened(); error NFTContractNotSet(); error NotContract(); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; import "./CustomErrors.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; library LANFTUtils { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is an EOA * */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) internal returns (bool) { if (LANFTUtils.isContract(to)) { try IERC721Receiver(to).onERC721Received( msg.sender, from, tokenId, _data ) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert CustomErrors.NotERC721Receiver(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } function bytes32ToHexString( bytes32 _bytes ) internal pure returns (string memory) { bytes memory byteArray = new bytes(64); for (uint i = 0; i < 32; i++) { bytes1 currentByte = bytes1( uint8(uint(_bytes) / (2 ** (8 * (31 - i)))) ); bytes1 hi = bytes1(uint8(currentByte) / 16); bytes1 lo = bytes1(uint8(currentByte) - 16 * uint8(hi)); byteArray[i * 2] = char(hi); byteArray[i * 2 + 1] = char(lo); } return string(abi.encodePacked("0x", string(byteArray))); } function char(bytes1 b) private pure returns (bytes1 c) { if (uint8(b) < 10) return bytes1(uint8(b) + 0x30); else return bytes1(uint8(b) + 0x57); } function addressToString( address _address ) internal pure returns (string memory) { bytes32 _bytes = bytes32(uint256(uint160(_address))); bytes memory HEX = "0123456789abcdef"; bytes memory _string = new bytes(42); _string[0] = "0"; _string[1] = "x"; for (uint i = 0; i < 20; i++) { _string[2 + i * 2] = HEX[uint8(_bytes[i + 12] >> 4)]; _string[3 + i * 2] = HEX[uint8(_bytes[i + 12] & 0x0f)]; } return string(_string); } /* @dev blocksRemainingTillMaxBlock cannot be greater than 2^24 - 1 */ function formatExtraDataByBlockNumber( uint256 _blockNumber ) internal view returns (uint24) { // takes the block number and returns the number of blocks remaining until the max block number. uint256 maxBlockNumber = (block.chainid == 1) ? 30000000 : 20000000; // eth & sepolia uint256 blocksRemainingTillMaxBlock = maxBlockNumber - _blockNumber; return uint24(blocksRemainingTillMaxBlock); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import "./specs/IRarible.sol"; import "./RoyaltiesState.sol"; /// @dev Royalty registry interface interface IRoyaltiesRegistry is IERC165 { /// @dev Raised when trying to set a royalty override for a token error NotApproved(); error NotOwner(); /// @dev Raised when providing multiple royalty overrides when only one is expected error MultipleRoyaltyRecievers(); /// @dev Raised when sales percentage is not between 0 and 100 error PrimarySalePercentageOutOfRange(); error SecondarySalePercentageOutOfRange(); /// @dev Raised accumulated primary royalty percentage is not 100 error PrimarySalePercentageNotEqualToMax(); /** * Raised trying to set edition or token royalties */ error NotEditionCreator(); // ============================== // EVENTS // ============================== event RoyaltyOverride( address owner, address tokenAddress, address royaltyAddress ); event RoyaltyTokenOverride( address owner, address tokenAddress, uint256 tokenId, address royaltyAddress ); // ============================== // IERC165 // ============================== /// @dev See {IERC165-supportsInterface}. function supportsInterface( bytes4 interfaceId ) external view override returns (bool); // ============================== // SECONDARY ROYALTY // ============================== /* @notice Called with the sale price to determine how much royalty is owed and to whom. @param _contractAddress - The collection address @param _tokenId - the NFT asset queried for royalty information @param _value - the sale price of the NFT asset specified by _tokenId @return _receiver - address of who should be sent the royalty payment @return _royaltyAmount - the royalty payment amount for value sale price */ function royaltyInfo( address _contractAddress, uint256 _tokenId, uint256 _value ) external view returns (address _receiver, uint256 _royaltyAmount); /** * Return RoyaltyReceivers for primary sales * */ function primaryRoyaltyInfo( address collectionAddress, uint256 tokenId ) external view returns (address payable[] memory, uint256[] memory); /** * @dev CreatorCore - Supports Manifold, ArtBlocks * * getRoyalties */ function getRoyalties( address collectionAddress, uint256 tokenId ) external view returns (address payable[] memory, uint256[] memory); /** * @dev Foundation * * getFees */ function getFees( address collectionAddress, uint256 editionId ) external view returns (address payable[] memory, uint256[] memory); /** * @dev Rarible: RoyaltiesV1 * * getFeeBps */ function getFeeBps( address collectionAddress, uint256 tokenId ) external view returns (uint256[] memory); /** * @dev Rarible: RoyaltiesV1 * * getFeeRecipients */ function getFeeRecipients( address collectionAddress, uint256 editionId ) external view returns (address payable[] memory); /** * @dev Rarible: RoyaltiesV2 * * getRaribleV2Royalties */ function getRaribleV2Royalties( address collectionAddress, uint256 tokenId ) external view returns (IRaribleV2.Part[] memory); /** * @dev CreatorCore - Support for KODA * * getKODAV2RoyaltyInfo */ function getKODAV2RoyaltyInfo( address collectionAddress, uint256 tokenId ) external view returns (address payable[] memory recipients_, uint256[] memory bps); /** * @dev CreatorCore - Support for Zora * * convertBidShares */ function convertBidShares( address collectionAddress, uint256 tokenId ) external view returns (address payable[] memory recipients_, uint256[] memory bps); /* @notice Called from a collection contract to set a primary royalty override @param collectionAddress - The collection address @param sender - The address of the caller @param RoyaltyReceiver[] - The royalty receivers details */ function registerCollectionRoyaltyReceivers( address collectionAddress, address sender, RoyaltiesState.RoyaltyReceiver[] memory royaltyReceivers ) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; library RoyaltiesState { struct RoyaltyReceiver { address payable wallet; uint48 primarySalePercentage; uint48 secondarySalePercentage; } /** * @dev Storage layout * This pattern allow us to extend current contract using DELETGATE_CALL * without worrying about storage slot conflicts */ struct RoyaltiesRegistryState { // contractAddress => RoyaltyReceiver mapping(address => RoyaltyReceiver[]) _collectionRoyaltyReceivers; // contractAddress => editionId => RoyaltyReceiver mapping(address => mapping(uint256 => RoyaltyReceiver[])) _editionRoyaltyReceivers; // contractAddress => editionId => tokenNumber => RoyaltyReceiver mapping(address => mapping(uint256 => mapping(uint256 => RoyaltyReceiver[]))) _tokenRoyaltyReceivers; } /** * @dev Get storage data from dedicated slot. * This pattern avoids storage conflict during proxy upgrades * and give more flexibility when creating extensions */ function _getRoyaltiesState() internal pure returns (RoyaltiesRegistryState storage state) { bytes32 storageSlot = keccak256("liveart.RoyalitiesState"); assembly { state.slot := storageSlot } } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; interface IRaribleV1 { /* * bytes4(keccak256('getFeeBps(uint256)')) == 0x0ebd4c7f * bytes4(keccak256('getFeeRecipients(uint256)')) == 0xb9c4d9fb * * => 0x0ebd4c7f ^ 0xb9c4d9fb == 0xb7799584 */ function getFeeBps(uint256 id) external view returns (uint256[] memory); function getFeeRecipients(uint256 id) external view returns (address payable[] memory); } interface IRaribleV2 { /* * bytes4(keccak256('getRaribleV2Royalties(uint256)')) == 0xcad96cca */ struct Part { address payable account; uint96 value; } function getRaribleV2Royalties(uint256 id) external view returns (Part[] memory); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; import "../extensions/AccessControl.sol"; import "../extensions/Winter.sol"; import "./IERC721LA.sol"; import "../extensions/Pausable.sol"; import "../extensions/IERC4906.sol"; import "../extensions/Ownable.sol"; import "../extensions/LAInitializable.sol"; import "../libraries/LANFTUtils.sol"; import "../libraries/BPS.sol"; import "../libraries/CustomErrors.sol"; import "./IERC721Events.sol"; import "./ERC721State.sol"; import "../extensions/WithOperatorRegistry.sol"; interface IStakingContract { function isTokenStaked(uint256 tokenId) external view returns (bool); } interface IPrintVoucherContract { function mintPrintVoucher( address _recipient, uint256[] calldata _tokenIds ) external; } /** * @notice LiveArt ERC721 implementation contract * Supports multiple edtioned NFTs and gas optimized batch minting */ abstract contract ERC721LACore is LAInitializable, AccessControl, WithOperatorRegistry, Winter, Pausable, Ownable, IERC721LA, IERC4906 { /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * LIBRARIES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ using BitMaps for BitMaps.BitMap; using ERC721State for ERC721State.ERC721LAState; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * LIBRARIES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ using BitMaps for BitMaps.BitMap; using ERC721State for ERC721State.ERC721LAState; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * CONSTANTS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ bytes32 public constant IERC721METADATA_INTERFACE = hex"5b5e139f"; bytes32 public constant IERC721_INTERFACE = hex"80ac58cd"; bytes32 public constant IERC2981_INTERFACE = hex"2a55205a"; bytes32 public constant IERC165_INTERFACE = hex"01ffc9a7"; bytes32 public constant IERC4906_INTERFACE = hex"49064906"; // Used for separating editionId and tokenNumber from the tokenId (cf. createEdition) uint24 public constant DEFAULT_EDITION_TOKEN_MULTIPLIER = 10e5; // Used to differenciate burnt tokens in the bitmap logic (Null address being used for unminted tokens) address public constant burnAddress = address(0xDEAD); // Logic contracts addresses address public constant SEPOLIA_LOGIC_CONTRACT = address(0x87D59A09ec4053c208980E4e63fCb4De97d2C7bD); address public constant MAINNET_LOGIC_CONTRACT = address(0xE291354a3aeB7EB49da0f1333d667F17fa33F1c5); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INITIALIZERS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** * @dev Initialize function. Should be called by the factory when deploying new instances. * @param _collectionAdmin is the address of the default admin for this contract */ function initialize( string calldata _name, string calldata _symbol, address _collectionAdmin, address _royaltyRegistry, address _xcardAddress ) external notInitialized { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); state._name = _name; state._symbol = _symbol; state._royaltyRegistry = IRoyaltiesRegistry(_royaltyRegistry); state._xCardContractAddress = _xcardAddress; state._editionCounter = 1; state._edition_max_tokens = DEFAULT_EDITION_TOKEN_MULTIPLIER; _grantRole(COLLECTION_ADMIN_ROLE, _collectionAdmin); _setOwner(_collectionAdmin); _setWinterWallet(0xdAb1a1854214684acE522439684a145E62505233); _initOperatorRegsitry(); } /** * @dev Overload `initialize` function with `_edition_max_tokens` argument */ // function initialize( // string calldata _name, // string calldata _symbol, // address _collectionAdmin, // address _royaltyRegistry, // uint24 _edition_max_tokens // ) external notInitialized { // ERC721State.ERC721LAState storage state = ERC721State // ._getERC721LAState(); // state._name = _name; // state._symbol = _symbol; // state._royaltyRegistry = IRoyaltiesRegistry(_royaltyRegistry); // state._editionCounter = 1; // state._edition_max_tokens = _edition_max_tokens; // _grantRole(COLLECTION_ADMIN_ROLE, _collectionAdmin); // _setOwner(_collectionAdmin); // _setWinterWallet(0xdAb1a1854214684acE522439684a145E62505233); // _initOperatorRegsitry(); // } /// @dev See {IERC165-supportsInterface}. // function supportsInterface( // bytes4 interfaceId // ) external pure override returns (bool) { // return // interfaceId == IERC4906_INTERFACE || // interfaceId == IERC2981_INTERFACE || // interfaceId == IERC721_INTERFACE || // interfaceId == IERC721METADATA_INTERFACE || // interfaceId == IERC165_INTERFACE; // } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * LogicContract * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ function _delegateLogic() internal virtual { address implementation = getLogicContract(); assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall( gas(), implementation, 0, calldatasize(), 0, 0 ) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } function getLogicContract() internal view returns (address) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); if (state._logicContractAddress != address(0)) { return state._logicContractAddress; } if (block.chainid == 11155111) { return SEPOLIA_LOGIC_CONTRACT; } return MAINNET_LOGIC_CONTRACT; } function setLogicContractAddress(address newAddress) external onlyAdmin { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); state._logicContractAddress = newAddress; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * IERC721Metadata * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ function name() external view override returns (string memory) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); return state._name; } function symbol() external view returns (string memory) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); return state._symbol; } // function setName(string calldata _name) public onlyAdmin { // ERC721State.ERC721LAState storage state = ERC721State // ._getERC721LAState(); // state._name = _name; // } // function setSymbol(string calldata _symbol) public onlyAdmin { // ERC721State.ERC721LAState storage state = ERC721State // ._getERC721LAState(); // state._symbol = _symbol; // } function tokenURI( uint256 tokenId ) external view override returns (string memory) { if (!_exists(tokenId)) { revert CustomErrors.TokenNotFound(); } ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); (uint256 editionId, ) = parseEditionFromTokenId(tokenId); ERC721State.Edition memory edition = getEdition(editionId); if (edition.perTokenMetadata) { return string( abi.encodePacked( state._baseURIByEdition[editionId], LANFTUtils.toString(tokenId) ) ); } return state._baseURIByEdition[editionId]; } function totalSupply() external view override returns (uint256) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); uint256 _count; for (uint256 i = 1; i < state._editionCounter; i += 1) { _count += editionMintedTokens(i); } return _count; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * EDITIONS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** * @notice Backward compatibility with the frontend */ function EDITION_TOKEN_MULTIPLIER() public view returns (uint24) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); return state._edition_max_tokens; } function EDITION_MAX_SIZE() public view returns (uint24) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); return state._edition_max_tokens - 1; } /** * @notice Creates a new Edition * Editions can be seen as collections within a collection. * The token Ids for the a given edition have the following format: * `[editionId][tokenNumber]` * eg.: The Id of the 2nd token of the 5th edition is: `5000002` * */ function createEdition( string calldata _baseURI, uint24 _maxSupply, uint24 _publicMintPriceInFinney, uint32 _publicMintStartTS, uint32 _publicMintEndTS, uint8 _maxMintPerWallet, bool _perTokenMetadata, uint8 _burnableEditionId, uint8 _amountToBurn ) public onlyAdmin returns (uint256) { _delegateLogic(); } /** * @notice updates an edition base URI */ function updateEditionBaseURI( uint256 editionId, string calldata _baseURI ) public onlyAdmin { _delegateLogic(); } /** * @notice updates an edition base URI */ function updateEditionPrintData( uint256 _editionId, address _newPrintVoucherAddress, uint24 _newPublicMintPriceWithPrintInFinney ) public onlyAdmin { _delegateLogic(); } /** * @notice updates edition parameter. Careful: This will overwrite all previously set values on that edition. */ function updateEdition( uint256 editionId, uint24 _publicMintPriceInFinney, uint32 _publicMintStartTS, uint32 _publicMintEndTS, uint8 _maxMintPerWallet, uint24 _maxSupply, bool _perTokenMetadata ) public onlyAdmin { _delegateLogic(); } /** * @notice fetch edition struct data by editionId */ function getEdition( uint256 _editionId ) public view override returns (ERC721State.Edition memory) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); if (_editionId > state._editionCounter) { revert CustomErrors.InvalidEditionId(); } return state._editions[_editionId]; } /** * @notice fetch edition struct data by editionId */ function getEditionWithURI( uint256 _editionId ) public view override returns (ERC721State.EditionWithURI memory editionWithURI) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); if (_editionId > state._editionCounter) { revert CustomErrors.InvalidEditionId(); } editionWithURI = ERC721State.EditionWithURI({ data: state._editions[_editionId], baseURI: state._baseURIByEdition[_editionId] }); } function getEditionPrintData( uint256 _editionId ) public view override returns (ERC721State.EditionWithPrintData memory editionPrintData) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); if (_editionId > state._editionCounter) { revert CustomErrors.InvalidEditionId(); } editionPrintData = ERC721State.EditionWithPrintData({ printVoucherContractAddress: state ._printDataByEdition[_editionId] .printVoucherContractAddress, publicMintPriceWithPrintInFinney: state ._printDataByEdition[_editionId] .publicMintPriceWithPrintInFinney }); } /** * @notice Returns the total number of editions */ function totalEditions() external view returns (uint256 total) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); total = state._editionCounter - 1; } /** * @notice Returns the current supply of a given edition */ function editionMintedTokens( uint256 editionId ) public view returns (uint256 supply) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); ERC721State.Edition memory edition = state._editions[editionId]; return edition.currentSupply - edition.burnedSupply; } /** * @dev Given an editionId and tokenNumber, returns tokenId in the following format: * `[editionId][tokenNumber]` where `tokenNumber` is between 1 and state._edition_max_tokens - 1 * eg.: The second token from the 5th edition would be `500002` * */ function editionedTokenId( uint256 editionId, uint256 tokenNumber ) public view returns (uint256 tokenId) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); uint256 paddedEditionID = editionId * state._edition_max_tokens; tokenId = paddedEditionID + tokenNumber; } /** * @dev Given a tokenId return editionId and tokenNumber. * eg.: 3000005 => editionId 3 and tokenNumber 5 */ function parseEditionFromTokenId( uint256 tokenId ) public view returns (uint256 editionId, uint256 tokenNumber) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); // Divide first to lose the decimal. ie. 1000001 / 1000000 = 1 editionId = tokenId / state._edition_max_tokens; tokenNumber = tokenId - (editionId * state._edition_max_tokens); } /// @dev Is public mint open for given edition function isPublicMintStarted( uint256 editionId ) public view override returns (bool) { ERC721State.Edition memory edition = getEdition(editionId); bool started = (edition.publicMintStartTS != 0 && edition.publicMintStartTS <= block.timestamp) && (edition.publicMintEndTS == 0 || edition.publicMintEndTS > block.timestamp); return started; } /** * @notice sets the staking contract address **/ function setStakingContractAddress( address stakingContractAddress ) external onlyAdmin { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); state._stakingContractAddress = stakingContractAddress; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * STAKING * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** * @notice toggle staking on/off for an edition **/ function toggleStakingByEdition(uint256 editionId) external onlyAdmin { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); state._editions[editionId].stakingEnabled = !state ._editions[editionId] .stakingEnabled; } function getStakingContractAddress() external view returns (address) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); return state._stakingContractAddress; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * STAKING * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ modifier whenPublicMintOpened(uint256 editionId) { if (!isPublicMintStarted(editionId)) { revert CustomErrors.MintClosed(); } _; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * MINTABLE * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** * @dev Internal batch minting function */ function _safeMint( uint256 _editionId, uint24 _quantity, address _recipient ) internal virtual returns (uint256 firstTokenId) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); ERC721State.Edition storage edition = state._editions[_editionId]; uint256 tokenNumber = edition.currentSupply + 1; if (_editionId > state._editionCounter) { revert CustomErrors.InvalidEditionId(); } if (_quantity == 0 || _recipient == address(0)) { revert CustomErrors.InvalidMintData(); } if (tokenNumber > edition.maxSupply) { revert CustomErrors.MaxSupplyError(); } firstTokenId = editionedTokenId(_editionId, tokenNumber); if (edition.currentSupply + _quantity > edition.maxSupply) { revert CustomErrors.MaxSupplyError(); } edition.currentSupply += _quantity; state._owners[firstTokenId] = _recipient; state._batchHead.set(firstTokenId); state._balances[_recipient] += _quantity; // Emit events for ( uint256 tokenId = firstTokenId; tokenId < firstTokenId + _quantity; tokenId++ ) { emit Transfer(address(0), _recipient, tokenId); LANFTUtils._checkOnERC721Received( address(0), _recipient, tokenId, "" ); } } function mintEditionTokens( uint256 _editionId, uint24 _quantity, address _recipient ) public payable whenPublicMintOpened(_editionId) whenNotPaused { ERC721State.Edition memory edition = getEdition(_editionId); _validatePublicMintParams( _editionId, _quantity, edition.maxMintPerWallet ); _validateMintPrice(edition.publicMintPriceInFinney, _quantity); uint256 firstTokenId = _safeMint(_editionId, _quantity, _recipient); _sendRoyaltiesAfterMint(firstTokenId); } function mintEditionTokensWithPrints( uint256 _editionId, uint24 _quantity, address _recipient ) public payable whenPublicMintOpened(_editionId) whenNotPaused { ERC721State.Edition memory edition = getEdition(_editionId); ERC721State.EditionWithPrintData memory printData = getEditionPrintData( _editionId ); _validatePublicMintParams( _editionId, _quantity, edition.maxMintPerWallet ); _validateEditionPrintData(printData); _validateMintPrice( printData.publicMintPriceWithPrintInFinney, _quantity ); uint256 firstTokenId = _safeMint(_editionId, _quantity, _recipient); _sendRoyaltiesAfterMint(firstTokenId); _mintPrintVouchers(_editionId, _quantity, firstTokenId); } function adminMint( uint256 _editionId, uint24 _quantity, address _recipient ) public onlyAdmin { _safeMint(_editionId, _quantity, _recipient); } function getMintedCount( uint256 _editionId, address _recipient ) public view returns (uint256) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); uint256 mintedCountKey = uint256( keccak256(abi.encodePacked(_editionId, _recipient)) ); return state._mintedPerWallet[mintedCountKey]; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PAUSABLE * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ function pauseContract() public onlyAdmin { _pause(); } function unpauseContract() public onlyAdmin { _unpause(); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ERC721 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /// @dev See {IERC721-approve}. function approve( address to, uint256 tokenId ) external override onlyAllowedOperatorApproval(to) { address owner = ownerOf(tokenId); if ( msg.sender == to || (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) ) { revert CustomErrors.NotAllowed(); } _approve(to, tokenId); } /// @dev See {IERC721-transferFrom}. function transferFrom( address from, address to, uint256 tokenId ) external override onlyAllowedOperator(from) { if (!_isApprovedOrOwner(msg.sender, tokenId)) { revert CustomErrors.TransferError(); } _transfer(from, to, tokenId); } /// @dev See {IERC721-ownerOf}. function ownerOf(uint256 tokenId) public view override returns (address) { (address owner, ) = _ownerAndBatchHeadOf(tokenId); return owner; } /// @dev Returns the number of tokens in ``owner``'s account. function balanceOf( address owner ) external view returns (uint256 tokenBalance) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); tokenBalance = state._balances[owner]; } /// @dev See {IERC721-getApproved}. function getApproved( uint256 tokenId ) public view override returns (address) { if (!_exists(tokenId)) { revert CustomErrors.TokenNotFound(); } ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); if (!_isTransferAllowed(tokenId)) { revert CustomErrors.TokenStaked(); } return state._tokenApprovals[tokenId]; } /// @dev See {IERC721-isApprovedForAll}. function isApprovedForAll( address owner, address operator ) public view override returns (bool) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); return state._operatorApprovals[owner][operator]; } /// @dev See {IERC721-setApprovalForAll}. function setApprovalForAll( address operator, bool approved ) external override onlyAllowedOperatorApproval(operator) { if (operator == msg.sender) { revert CustomErrors.NotAllowed(); } ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); state._operatorApprovals[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } /// @dev See {IERC721-safeTransferFrom}. function safeTransferFrom( address from, address to, uint256 tokenId ) external override onlyAllowedOperator(from) { safeTransferFrom(from, to, tokenId, ""); } /// @dev See {IERC721-safeTransferFrom}. function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public override onlyAllowedOperator(from) { if (!_isApprovedOrOwner(msg.sender, tokenId)) { revert CustomErrors.NotAllowed(); } _safeTransfer(from, to, tokenId, _data); } function batchSafeTransferFrom( address from, address to, uint256[] calldata tokenIds ) public onlyAllowedOperator(from) { for (uint256 i = 0; i < tokenIds.length; i++) { if (!_isApprovedOrOwner(msg.sender, tokenIds[i])) { revert CustomErrors.NotAllowed(); } safeTransferFrom(from, to, tokenIds[i], ""); } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INTERNAL / PUBLIC HELPERS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /// @dev Returns whether `tokenId` exists. function _exists(uint256 tokenId) internal view virtual returns (bool) { (uint256 editionId, uint256 tokenNumber) = parseEditionFromTokenId( tokenId ); if (isBurned(tokenId)) { return false; } ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); ERC721State.Edition memory edition = state._editions[editionId]; return tokenNumber <= edition.currentSupply; } /** * @dev Returns the index of the batch for a given token. * If the token was not bought in a batch tokenId == tokenIdBatchHead */ function _getBatchHead( uint256 tokenId ) internal view returns (uint256 tokenIdBatchHead) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); (uint256 editionId, ) = parseEditionFromTokenId(tokenId); tokenIdBatchHead = state._batchHead.scanForward( tokenId, editionId * state._edition_max_tokens ); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); state._tokenApprovals[tokenId] = to; emit Approval(ownerOf(tokenId), to, tokenId); } /** * @dev Returns the index of the batch for a given token. * and the batch owner address */ function _ownerAndBatchHeadOf( uint256 tokenId ) internal view returns (address owner, uint256 tokenIdBatchHead) { if (!_exists(tokenId)) { revert CustomErrors.TokenNotFound(); } ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); tokenIdBatchHead = _getBatchHead(tokenId); owner = state._owners[tokenIdBatchHead]; } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner( address spender, uint256 tokenId ) internal view returns (bool) { if (!_exists(tokenId)) { revert CustomErrors.TokenNotFound(); } address owner = ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Transfers `tokenId` from `from` to `to`. * Internal function intened to split the logic for different transfer use cases * Emits a {Transfer} event. */ function _transferCore(address from, address to, uint256 tokenId) internal { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); (, uint256 tokenIdBatchHead) = _ownerAndBatchHeadOf(tokenId); address owner = ownerOf(tokenId); if (owner != from) { revert CustomErrors.TransferError(); } // We check if the token after the one being transfer // belong to the batch, if it does, we have to update it's owner // while being careful to not overflow the edition maxSupply uint256 nextTokenId = tokenId + 1; (, uint256 nextTokenNumber) = parseEditionFromTokenId(nextTokenId); (uint256 currentEditionId, ) = parseEditionFromTokenId(tokenId); ERC721State.Edition memory edition = state._editions[currentEditionId]; if ( nextTokenNumber <= edition.maxSupply && !state._batchHead.get(nextTokenId) ) { state._owners[nextTokenId] = from; state._batchHead.set(nextTokenId); } // Finaly we update the owners and balances state._owners[tokenId] = to; if (tokenId != tokenIdBatchHead) { state._batchHead.set(tokenId); } state._balances[to] += 1; state._balances[from] -= 1; } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal { _beforeTokenTransfer(from, to, tokenId); // Remove approval _approve(address(0), tokenId); emit Transfer(from, to, tokenId); _transferCore(from, to, tokenId); } function _safeTransfer( address from, address to, uint256 tokenId, bytes memory _data ) internal virtual { _transfer(from, to, tokenId); LANFTUtils._checkOnERC721Received(from, to, tokenId, _data); } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * 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, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual { if (!_isTransferAllowed(tokenId)) { revert CustomErrors.TokenStaked(); } } /** * Check if the token is staked */ function _isTransferAllowed(uint256 tokenId) internal view returns (bool) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); (uint256 currentEditionId, ) = parseEditionFromTokenId(tokenId); ERC721State.Edition memory edition = state._editions[currentEditionId]; // If the token is staked, we don't allow transfer if (edition.stakingEnabled) { bool tokenIsStaked = IStakingContract(state._stakingContractAddress) .isTokenStaked(tokenId); if (tokenIsStaked) { return false; } } return true; } function _mintPrintVouchers( uint256 _editionId, uint24 _quantity, uint256 _firstTokenId ) internal { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); address printVoucherContractAddress = state ._printDataByEdition[_editionId] .printVoucherContractAddress; // Mint print vouchers uint256[] memory tokenArray = new uint256[](_quantity); for (uint256 i = 0; i < _quantity; i++) { tokenArray[i] = _firstTokenId + i; } IPrintVoucherContract(printVoucherContractAddress).mintPrintVoucher( tx.origin, tokenArray ); } function _validatePublicMintParams( uint256 _editionId, uint24 _quantity, uint8 _maxMintPerWallet ) internal { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); // Check max mint per wallet restrictions (if maxMintPerWallet is 0, no restriction apply) if (_maxMintPerWallet != 0 && !_isWinterWallet()) { uint256 mintedCountKey = uint256( keccak256(abi.encodePacked(_editionId, msg.sender)) ); if ( state._mintedPerWallet[mintedCountKey] + _quantity > _maxMintPerWallet ) { revert CustomErrors.MaximumMintAmountReached(); } state._mintedPerWallet[mintedCountKey] += _quantity; } } function _validateEditionPrintData( ERC721State.EditionWithPrintData memory printData ) internal pure { if ( printData.printVoucherContractAddress == address(0) || printData.publicMintPriceWithPrintInFinney == 0 ) { revert CustomErrors.InvalidPrintData(); } } function _validateMintPrice( uint256 _mintPriceInFinney, uint24 _quantity ) internal view { uint256 mintPriceInWei = uint256(_mintPriceInFinney) * 10e14; if (mintPriceInWei * _quantity > msg.value) { revert CustomErrors.InsufficientFunds(); } } function _sendRoyaltiesAfterMint(uint256 _firstTokenId) internal { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); // Send primary royalties ( address payable[] memory wallets, uint256[] memory primarySalePercentages ) = state._royaltyRegistry.primaryRoyaltyInfo( address(this), _firstTokenId ); uint256 nReceivers = wallets.length; for (uint256 i = 0; i < nReceivers; i++) { uint256 royalties = BPS._calculatePercentage( msg.value, primarySalePercentages[i] ); (bool sent, ) = wallets[i].call{value: royalties}(""); if (!sent) { revert CustomErrors.FundTransferError(); } } } /** * Check if the token is staked */ // function _areAllNFTsStaked(address from) internal view returns(bool) { // ERC721State.ERC721LAState storage state = ERC721State // ._getERC721LAState(); // (uint256 currentEditionId, ) = parseEditionFromTokenId(tokenId); // ERC721State.Edition memory edition = state._editions[currentEditionId]; // // If the token is staked, we don't allow transfer // if (edition.stakingEnabled) { // bool tokenIsStaked = IStakingContract(state._stakingContractAddress) // .isTokenStaked(tokenId); // if (tokenIsStaked) { // return false; // } // } // return true; // } function isBurned(uint256 tokenId) public view returns (bool) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); address owner = state._owners[tokenId]; return owner == burnAddress; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ETHER * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ function balance() public view returns (uint256) { return address(this).balance; } function withdrawAmount( address payable recipient, uint256 amount ) external onlyAdmin { (bool succeed, ) = recipient.call{value: amount}(""); if (!succeed) { revert CustomErrors.FundTransferError(); } } function withdrawAll(address payable recipient) external onlyAdmin { (bool succeed, ) = recipient.call{value: balance()}(""); if (!succeed) { revert CustomErrors.FundTransferError(); } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * X-CARD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ function setXCardContractAddress( address xCardContractAddress ) public override onlyAdmin { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); state._xCardContractAddress = xCardContractAddress; } function getXCardContractAddress() public view override returns (address) { ERC721State.ERC721LAState storage state = ERC721State ._getERC721LAState(); return state._xCardContractAddress; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; import "../libraries/BitMaps/BitMaps.sol"; import "../platform/royalties/IRoyaltiesRegistry.sol"; library ERC721State { using BitMaps for BitMaps.BitMap; struct Edition { // Max. number of token mintable per edition uint24 maxSupply; // Currently minted token coutner uint24 currentSupply; // Burned token counter uint24 burnedSupply; // Public mint price uint24 publicMintPriceInFinney; // Public mint start time in seconds uint32 publicMintStartTS; // Public mint ending time in seconds uint32 publicMintEndTS; // Max mint per wallet. If 0, no limit uint8 maxMintPerWallet; // If perTokenMetadata == false, all tokens in this edition will have the same metadata bool perTokenMetadata; // An edition Id associated with this collection that is approved to be burned in order to mint on the current edition. uint24 burnableEditionId; // Amount to burn uint24 amountToBurn; // determines if this edition supports staking bool stakingEnabled; } struct EditionWithURI { Edition data; string baseURI; } /** * @dev Storage layout * This pattern allow us to extend current contract using DELETGATE_CALL * without worrying about storage slot conflicts */ struct ERC721LAState { // The number of edition created, indexed from 1 uint64 _editionCounter; // Max token by edition. Defines the number of 0 in token Id (see editions) uint24 _edition_max_tokens; // Contract Name string _name; // Ticker string _symbol; // Edtion by editionId mapping(uint256 => Edition) _editions; // Owner by tokenId mapping(uint256 => address) _owners; // Token Id to operator address mapping(uint256 => address) _tokenApprovals; // Owned token count by address mapping(address => uint256) _balances; // Allower to allowee mapping(address => mapping(address => bool)) _operatorApprovals; // Tracking of batch heads BitMaps.BitMap _batchHead; // LiveArt global royalty registry address IRoyaltiesRegistry _royaltyRegistry; // Amount of ETH withdrawn by edition mapping(uint256 => uint256) _withdrawnBalancesByEdition; // EditionID => Base URI mapping(uint256 => string) _baseURIByEdition; // Minted counter per wallet/edition. hash(address, editionId) => counter mapping(uint256 => uint256) _mintedPerWallet; // xCardContract Address address _xCardContractAddress; // Staking contract address address _stakingContractAddress; // Logic contract address address _logicContractAddress; // EditionPrintData by editionId mapping(uint256 => EditionWithPrintData) _printDataByEdition; } struct EditionWithPrintData { address printVoucherContractAddress; uint24 publicMintPriceWithPrintInFinney; } /** * @dev Get storage data from dedicated slot. * This pattern avoids storage conflict during proxy upgrades * and give more flexibility when creating extensions */ function _getERC721LAState() internal pure returns (ERC721LAState storage state) { bytes32 storageSlot = keccak256("liveart.ERC721LA"); assembly { state.slot := storageSlot } } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; import "../libraries/BitMaps/BitMaps.sol"; import "../platform/royalties/IRoyaltiesRegistry.sol"; interface IERC721Events { event EditionCreated( address indexed contractAddress, uint256 editionId, uint24 maxSupply, string baseURI, uint24 contractMintPrice, bool perTokenMetadata ); event EditionUpdated( address indexed contractAddress, uint256 editionId, uint256 maxSupply, string baseURI ); /** * @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 ); }
// SPDX-License-Identifier: UNLICENSED import "../libraries/BitMaps/BitMaps.sol"; import "../platform/royalties/IRoyaltiesRegistry.sol"; import "./IERC721Events.sol"; import "./ERC721State.sol"; pragma solidity ^0.8.4; /** * @dev Interface of an ERC721LA compliant contract. */ abstract contract IERC721LA is IERC721Events { using BitMaps for BitMaps.BitMap; // ============================== // IERC165 // ============================== /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ // function supportsInterface( // bytes4 interfaceId // ) external view virtual returns (bool); // ============================== // IERC721 // ============================== /** * @dev Returns the total amount of tokens stored by the contract. * * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens. */ function totalSupply() external view virtual returns (uint256); /** * @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 virtual returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external virtual; /** * @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 ) external virtual; /** * @dev Transfers `tokenId` token 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 virtual; /** * @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 virtual; /** * @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 virtual; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved( uint256 tokenId ) external view virtual 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 virtual returns (bool); // ============================== // IERC721Metadata // ============================== /** * @dev Returns the token collection name. */ function name() external view virtual returns (string memory); /** * @dev Returns the token collection symbol. */ // function symbol() external view virtual returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI( uint256 tokenId ) external view virtual returns (string memory); // ============================== // Editions // ============================== /** * @dev fetch edition struct data by editionId */ function getEdition( uint256 _editionId ) external view virtual returns (ERC721State.Edition memory); /** * @dev fetch edition struct data by editionId */ function getEditionWithURI( uint256 _editionId ) external view virtual returns (ERC721State.EditionWithURI memory); /** * @dev fetch editionPrintData struct data by editionId */ function getEditionPrintData( uint256 _editionId ) external view virtual returns (ERC721State.EditionWithPrintData memory editionPrintData); // ============================== // Helpers // ============================== function setXCardContractAddress( address xCardContractAddress ) external virtual; function getXCardContractAddress() external view virtual returns (address); function isPublicMintStarted( uint256 editionId ) external view virtual returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; library console { address constant CONSOLE_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67; function _sendLogPayloadImplementation(bytes memory payload) internal view { address consoleAddress = CONSOLE_ADDRESS; /// @solidity memory-safe-assembly assembly { pop( staticcall( gas(), consoleAddress, add(payload, 32), mload(payload), 0, 0 ) ) } } function _castToPure( function(bytes memory) internal view fnIn ) internal pure returns (function(bytes memory) pure fnOut) { assembly { fnOut := fnIn } } function _sendLogPayload(bytes memory payload) internal pure { _castToPure(_sendLogPayloadImplementation)(payload); } function log() internal pure { _sendLogPayload(abi.encodeWithSignature("log()")); } function logInt(int256 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); } function logUint(uint256 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); } function logString(string memory p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function logBool(bool p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function logAddress(address p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function logBytes(bytes memory p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); } function logBytes1(bytes1 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); } function logBytes2(bytes2 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); } function logBytes3(bytes3 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); } function logBytes4(bytes4 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); } function logBytes5(bytes5 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); } function logBytes6(bytes6 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); } function logBytes7(bytes7 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); } function logBytes8(bytes8 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); } function logBytes9(bytes9 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); } function logBytes10(bytes10 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); } function logBytes11(bytes11 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); } function logBytes12(bytes12 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); } function logBytes13(bytes13 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); } function logBytes14(bytes14 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); } function logBytes15(bytes15 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); } function logBytes16(bytes16 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); } function logBytes17(bytes17 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); } function logBytes18(bytes18 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); } function logBytes19(bytes19 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); } function logBytes20(bytes20 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); } function logBytes21(bytes21 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); } function logBytes22(bytes22 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); } function logBytes23(bytes23 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); } function logBytes24(bytes24 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); } function logBytes25(bytes25 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); } function logBytes26(bytes26 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); } function logBytes27(bytes27 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); } function logBytes28(bytes28 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); } function logBytes29(bytes29 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); } function logBytes30(bytes30 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); } function logBytes31(bytes31 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); } function logBytes32(bytes32 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); } function log(uint256 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); } function log(string memory p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function log(bool p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function log(address p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function log(uint256 p0, uint256 p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1)); } function log(uint256 p0, string memory p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1)); } function log(uint256 p0, bool p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1)); } function log(uint256 p0, address p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1)); } function log(string memory p0, uint256 p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); } function log(string memory p0, string memory p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); } function log(string memory p0, bool p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); } function log(string memory p0, address p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); } function log(bool p0, uint256 p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1)); } function log(bool p0, string memory p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); } function log(bool p0, bool p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); } function log(bool p0, address p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); } function log(address p0, uint256 p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1)); } function log(address p0, string memory p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); } function log(address p0, bool p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); } function log(address p0, address p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); } function log(uint256 p0, uint256 p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2)); } function log(uint256 p0, string memory p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2)); } function log(uint256 p0, string memory p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2)); } function log(uint256 p0, string memory p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2)); } function log(uint256 p0, string memory p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2)); } function log(uint256 p0, bool p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2)); } function log(uint256 p0, bool p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2)); } function log(uint256 p0, bool p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2)); } function log(uint256 p0, bool p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2)); } function log(uint256 p0, address p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2)); } function log(uint256 p0, address p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2)); } function log(uint256 p0, address p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2)); } function log(uint256 p0, address p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2)); } function log(string memory p0, uint256 p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2)); } function log(string memory p0, uint256 p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2)); } function log(string memory p0, uint256 p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2)); } function log(string memory p0, uint256 p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2)); } function log(string memory p0, string memory p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2)); } function log(string memory p0, string memory p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); } function log(string memory p0, string memory p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); } function log(string memory p0, string memory p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); } function log(string memory p0, bool p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2)); } function log(string memory p0, bool p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); } function log(string memory p0, bool p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); } function log(string memory p0, bool p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); } function log(string memory p0, address p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2)); } function log(string memory p0, address p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); } function log(string memory p0, address p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); } function log(string memory p0, address p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); } function log(bool p0, uint256 p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2)); } function log(bool p0, uint256 p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2)); } function log(bool p0, uint256 p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2)); } function log(bool p0, uint256 p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2)); } function log(bool p0, string memory p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2)); } function log(bool p0, string memory p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); } function log(bool p0, string memory p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); } function log(bool p0, string memory p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); } function log(bool p0, bool p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2)); } function log(bool p0, bool p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); } function log(bool p0, bool p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); } function log(bool p0, bool p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); } function log(bool p0, address p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2)); } function log(bool p0, address p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); } function log(bool p0, address p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); } function log(bool p0, address p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); } function log(address p0, uint256 p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2)); } function log(address p0, uint256 p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2)); } function log(address p0, uint256 p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2)); } function log(address p0, uint256 p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2)); } function log(address p0, string memory p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2)); } function log(address p0, string memory p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); } function log(address p0, string memory p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); } function log(address p0, string memory p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); } function log(address p0, bool p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2)); } function log(address p0, bool p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); } function log(address p0, bool p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); } function log(address p0, bool p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); } function log(address p0, address p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2)); } function log(address p0, address p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); } function log(address p0, address p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); } function log(address p0, address p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); } }
// 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;
{ "optimizer": { "enabled": true, "runs": 100 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"AccessControlNotAllowed","type":"error"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"BitMapHeadNotFound","type":"error"},{"inputs":[],"name":"BurnRedeemNotAvailable","type":"error"},{"inputs":[],"name":"CallerIsNotOwner","type":"error"},{"inputs":[],"name":"FundTransferError","type":"error"},{"inputs":[],"name":"InsufficientFunds","type":"error"},{"inputs":[],"name":"InvalidEditionId","type":"error"},{"inputs":[],"name":"InvalidMintData","type":"error"},{"inputs":[],"name":"InvalidMintDuration","type":"error"},{"inputs":[],"name":"InvalidPrintData","type":"error"},{"inputs":[],"name":"MaxSupplyError","type":"error"},{"inputs":[],"name":"MaximumMintAmountReached","type":"error"},{"inputs":[],"name":"MintClosed","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NotAllowed","type":"error"},{"inputs":[],"name":"NotERC721Receiver","type":"error"},{"inputs":[],"name":"NotFound","type":"error"},{"inputs":[],"name":"NotWhitelisted","type":"error"},{"inputs":[],"name":"TokenNotFound","type":"error"},{"inputs":[],"name":"TokenStaked","type":"error"},{"inputs":[],"name":"TooManyAddresses","type":"error"},{"inputs":[],"name":"TransferError","type":"error"},{"inputs":[],"name":"WhiteListAlreadyExists","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":"address","name":"contractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"editionId","type":"uint256"},{"indexed":false,"internalType":"uint24","name":"maxSupply","type":"uint24"},{"indexed":false,"internalType":"string","name":"baseURI","type":"string"},{"indexed":false,"internalType":"uint24","name":"contractMintPrice","type":"uint24"},{"indexed":false,"internalType":"bool","name":"perTokenMetadata","type":"bool"}],"name":"EditionCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"contractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"editionId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxSupply","type":"uint256"},{"indexed":false,"internalType":"string","name":"baseURI","type":"string"}],"name":"EditionUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"MetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"AIRDROP_MAX_BATCH_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"COLLECTION_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_EDITION_TOKEN_MULTIPLIER","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EDITION_MAX_SIZE","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EDITION_TOKEN_MULTIPLIER","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IERC165_INTERFACE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IERC2981_INTERFACE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IERC4906_INTERFACE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IERC721METADATA_INTERFACE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IERC721_INTERFACE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAINNET_LOGIC_CONTRACT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SEPOLIA_LOGIC_CONTRACT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"addWinterWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_editionId","type":"uint256"},{"internalType":"uint24","name":"_quantity","type":"uint24"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"adminMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"editionId","type":"uint256"},{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint24","name":"quantityPerAddress","type":"uint24"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"balance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"tokenBalance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"batchSafeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burnAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"burnMultiple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_editionId","type":"uint256"},{"internalType":"uint24","name":"_quantity","type":"uint24"},{"internalType":"uint256[]","name":"tokenIdsToBurn","type":"uint256[]"}],"name":"burnRedeemEditionTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"},{"internalType":"uint24","name":"_maxSupply","type":"uint24"},{"internalType":"uint24","name":"_publicMintPriceInFinney","type":"uint24"},{"internalType":"uint32","name":"_publicMintStartTS","type":"uint32"},{"internalType":"uint32","name":"_publicMintEndTS","type":"uint32"},{"internalType":"uint8","name":"_maxMintPerWallet","type":"uint8"},{"internalType":"bool","name":"_perTokenMetadata","type":"bool"},{"internalType":"uint8","name":"_burnableEditionId","type":"uint8"},{"internalType":"uint8","name":"_amountToBurn","type":"uint8"}],"name":"createEdition","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"deleteWinterWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"editionId","type":"uint256"}],"name":"editionMintedTokens","outputs":[{"internalType":"uint256","name":"supply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"editionId","type":"uint256"},{"internalType":"uint256","name":"tokenNumber","type":"uint256"}],"name":"editionedTokenId","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_editionId","type":"uint256"}],"name":"getEdition","outputs":[{"components":[{"internalType":"uint24","name":"maxSupply","type":"uint24"},{"internalType":"uint24","name":"currentSupply","type":"uint24"},{"internalType":"uint24","name":"burnedSupply","type":"uint24"},{"internalType":"uint24","name":"publicMintPriceInFinney","type":"uint24"},{"internalType":"uint32","name":"publicMintStartTS","type":"uint32"},{"internalType":"uint32","name":"publicMintEndTS","type":"uint32"},{"internalType":"uint8","name":"maxMintPerWallet","type":"uint8"},{"internalType":"bool","name":"perTokenMetadata","type":"bool"},{"internalType":"uint24","name":"burnableEditionId","type":"uint24"},{"internalType":"uint24","name":"amountToBurn","type":"uint24"},{"internalType":"bool","name":"stakingEnabled","type":"bool"}],"internalType":"struct ERC721State.Edition","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_editionId","type":"uint256"}],"name":"getEditionPrintData","outputs":[{"components":[{"internalType":"address","name":"printVoucherContractAddress","type":"address"},{"internalType":"uint24","name":"publicMintPriceWithPrintInFinney","type":"uint24"}],"internalType":"struct ERC721State.EditionWithPrintData","name":"editionPrintData","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_editionId","type":"uint256"}],"name":"getEditionWithURI","outputs":[{"components":[{"components":[{"internalType":"uint24","name":"maxSupply","type":"uint24"},{"internalType":"uint24","name":"currentSupply","type":"uint24"},{"internalType":"uint24","name":"burnedSupply","type":"uint24"},{"internalType":"uint24","name":"publicMintPriceInFinney","type":"uint24"},{"internalType":"uint32","name":"publicMintStartTS","type":"uint32"},{"internalType":"uint32","name":"publicMintEndTS","type":"uint32"},{"internalType":"uint8","name":"maxMintPerWallet","type":"uint8"},{"internalType":"bool","name":"perTokenMetadata","type":"bool"},{"internalType":"uint24","name":"burnableEditionId","type":"uint24"},{"internalType":"uint24","name":"amountToBurn","type":"uint24"},{"internalType":"bool","name":"stakingEnabled","type":"bool"}],"internalType":"struct ERC721State.Edition","name":"data","type":"tuple"},{"internalType":"string","name":"baseURI","type":"string"}],"internalType":"struct ERC721State.EditionWithURI","name":"editionWithURI","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_editionId","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"getMintedCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"editionId","type":"uint256"},{"internalType":"uint8","name":"amount","type":"uint8"},{"internalType":"uint24","name":"mintPriceInFinney","type":"uint24"},{"internalType":"uint24","name":"mintPriceWithPrintInFinney","type":"uint24"}],"name":"getWLConfig","outputs":[{"components":[{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"uint8","name":"amount","type":"uint8"},{"internalType":"uint24","name":"mintPriceInFinney","type":"uint24"},{"internalType":"uint32","name":"mintStartTS","type":"uint32"},{"internalType":"uint32","name":"mintEndTS","type":"uint32"},{"internalType":"uint24","name":"mintPriceWithPrintInFinney","type":"uint24"}],"internalType":"struct WhitelistableState.WhitelistConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getXCardContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initOperatorRegsitry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_collectionAdmin","type":"address"},{"internalType":"address","name":"_royaltyRegistry","type":"address"},{"internalType":"address","name":"_xcardAddress","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"theAddress","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"isBurned","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"editionId","type":"uint256"}],"name":"isPublicMintStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_editionId","type":"uint256"},{"internalType":"uint24","name":"_quantity","type":"uint24"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"mintEditionTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_editionId","type":"uint256"},{"internalType":"uint24","name":"_quantity","type":"uint24"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"mintEditionTokensWithPrints","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"parseEditionFromTokenId","outputs":[{"internalType":"uint256","name":"editionId","type":"uint256"},{"internalType":"uint256","name":"tokenNumber","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"primaryRoyaltyInfo","outputs":[{"internalType":"address payable[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address payable","name":"wallet","type":"address"},{"internalType":"uint48","name":"primarySalePercentage","type":"uint48"},{"internalType":"uint48","name":"secondarySalePercentage","type":"uint48"}],"internalType":"struct RoyaltiesState.RoyaltyReceiver[]","name":"royaltyReceivers","type":"tuple[]"}],"name":"registerCollectionRoyaltyReceivers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyRegistryAddress","outputs":[{"internalType":"contract IRoyaltiesRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"setLogicContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_royaltyRegistry","type":"address"}],"name":"setRoyaltyRegistryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stakingContractAddress","type":"address"}],"name":"setStakingContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_editionId","type":"uint256"},{"internalType":"uint8","name":"amount","type":"uint8"},{"internalType":"uint24","name":"mintPriceInFinney","type":"uint24"},{"internalType":"uint32","name":"mintStartTS","type":"uint32"},{"internalType":"uint32","name":"mintEndTS","type":"uint32"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"uint24","name":"mintPriceWithPrintInFinney","type":"uint24"}],"name":"setWLConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"xCardContractAddress","type":"address"}],"name":"setXCardContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"editionId","type":"uint256"}],"name":"toggleStakingByEdition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalEditions","outputs":[{"internalType":"uint256","name":"total","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":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpauseContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"editionId","type":"uint256"},{"internalType":"uint24","name":"_publicMintPriceInFinney","type":"uint24"},{"internalType":"uint32","name":"_publicMintStartTS","type":"uint32"},{"internalType":"uint32","name":"_publicMintEndTS","type":"uint32"},{"internalType":"uint8","name":"_maxMintPerWallet","type":"uint8"},{"internalType":"uint24","name":"_maxSupply","type":"uint24"},{"internalType":"bool","name":"_perTokenMetadata","type":"bool"}],"name":"updateEdition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"editionId","type":"uint256"},{"internalType":"string","name":"_baseURI","type":"string"}],"name":"updateEditionBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_editionId","type":"uint256"},{"internalType":"address","name":"_newPrintVoucherAddress","type":"address"},{"internalType":"uint24","name":"_newPublicMintPriceWithPrintInFinney","type":"uint24"}],"name":"updateEditionPrintData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRegistry","type":"address"}],"name":"updateOperatorFilterRegistryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_editionId","type":"uint256"},{"internalType":"uint8","name":"_amount","type":"uint8"},{"internalType":"uint24","name":"mintPriceInFinney","type":"uint24"},{"internalType":"uint8","name":"newAmount","type":"uint8"},{"internalType":"uint24","name":"newMintPriceInFinney","type":"uint24"},{"internalType":"uint32","name":"newMintStartTS","type":"uint32"},{"internalType":"uint32","name":"newMintEndTS","type":"uint32"},{"internalType":"bytes32","name":"newMerkleRoot","type":"bytes32"},{"internalType":"uint24","name":"mintPriceWithPrintInFinney","type":"uint24"},{"internalType":"uint24","name":"newMintPriceWithPrintInFinney","type":"uint24"}],"name":"updateWLConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_editionId","type":"uint256"},{"internalType":"uint8","name":"_maxAmount","type":"uint8"},{"internalType":"uint24","name":"_mintPriceInFinney","type":"uint24"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"},{"internalType":"uint24","name":"_quantity","type":"uint24"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint24","name":"_xCardTokenId","type":"uint24"},{"internalType":"uint24","name":"_mintPriceWithPrintInFinney","type":"uint24"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_editionId","type":"uint256"},{"internalType":"uint8","name":"_maxAmount","type":"uint8"},{"internalType":"uint24","name":"_mintPriceInFinney","type":"uint24"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"},{"internalType":"uint24","name":"_quantity","type":"uint24"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint24","name":"_xCardTokenId","type":"uint24"},{"internalType":"uint24","name":"_mintPriceWithPrintInFinney","type":"uint24"}],"name":"whitelistMintWithPrint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address payable","name":"recipient","type":"address"}],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawAmount","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50615eeb80620000216000396000f3fe6080604052600436106104895760003560e01c8063736fe56511610255578063b88d4fde11610144578063dc47a410116100c1578063ed842d8411610085578063ed842d8414610e2e578063f2fde38b14610e56578063f343958f14610e76578063f45e3ebd14610e8b578063fa09e63014610ec0578063fc45635314610ee057600080fd5b8063dc47a41014610d3b578063e18827cd14610dc2578063e720a4b014610de2578063e985e9c514610df9578063eb44774014610e1957600080fd5b8063c8c6cbd711610108578063c8c6cbd714610c9b578063d49232a114610cbb578063d547741f14610cdb578063db0ed6a014610cfb578063db44fe0714610d1b57600080fd5b8063b88d4fde14610bfb578063b8d1e53214610c1b578063be5dea8a14610c3b578063c6879ff914610c5b578063c87b56dd14610c7b57600080fd5b8063946a3cbb116101d2578063a642c03211610196578063a642c03214610b66578063a9359de814610b93578063ae005af914610bb3578063b33712c514610bd3578063b69ef8a814610be857600080fd5b8063946a3cbb14610ae857806395d89b4114610b03578063999873f714610b18578063a22cb46514610b33578063a34931c114610b5357600080fd5b80638da5cb5b116102195780638da5cb5b14610a355780638fc614ec14610a4a578063910eec1f14610a6a57806391d1485414610ab3578063933a261114610ad357600080fd5b8063736fe5651461098357806373d31507146109a35780637cb796eb146109c35780637f12460f146109de57806380cd807c14610a0c57600080fd5b80633596b4ac1161037c57806351d329dc116102f957806363a5c0eb116102bd57806363a5c0eb146108d857806365308579146108f85780636ab49a5b146109185780636afe57951461093857806370a082311461094d57806370d5ae051461096d57600080fd5b806351d329dc1461085957806357c492771461086e5780635b353be21461088e5780635c975abb146108a35780636352211e146108b857600080fd5b806342966c681161034057806342966c68146107d1578063434e3603146107f1578063439766ce146108115780634cb30db1146108265780634d213ff11461083957600080fd5b80633596b4ac1461073657806336568abe1461075e5780633cbb1bb21461077e5780633ebd45861461079e57806342842e0e146107b157600080fd5b806323b872dd1161040a5780632a55205a116103ce5780632a55205a146106795780632f2ff15d146106a7578063322ff140146106c75780633474bd1e146106f457806335742d741461071457600080fd5b806323b872dd146105db57806324d7806c146105fb57806325acc72e1461062b57806328205b2f1461064b578063287ea4341461066657600080fd5b80630b213c07116104515780630b213c071461053d57806318160ddd1461055d5780631a9968a9146105805780631c1f8aa3146105a05780631e8f5530146105c057600080fd5b8063033da70b1461048e57806306fdde03146104b0578063081812fc146104db578063095ea7b3146105085780630a62f21414610528575b600080fd5b34801561049a57600080fd5b506104ae6104a9366004614ad4565b610efb565b005b3480156104bc57600080fd5b506104c5610f41565b6040516104d29190614b49565b60405180910390f35b3480156104e757600080fd5b506104fb6104f6366004614b5c565b610fe2565b6040516104d29190614b75565b34801561051457600080fd5b506104ae610523366004614b89565b611059565b34801561053457600080fd5b506104fb6110d0565b34801561054957600080fd5b506104ae610558366004614ad4565b6110ee565b34801561056957600080fd5b50610572611111565b6040519081526020016104d2565b34801561058c57600080fd5b506104ae61059b366004614bcd565b611163565b3480156105ac57600080fd5b506104ae6105bb366004614ad4565b611187565b3480156105cc57600080fd5b506105726380ac58cd60e01b81565b3480156105e757600080fd5b506104ae6105f6366004614c0b565b6111cd565b34801561060757600080fd5b5061061b610616366004614ad4565b611219565b60405190151581526020016104d2565b34801561063757600080fd5b50610572610646366004614c4c565b611239565b34801561065757600080fd5b50610572632483248360e11b81565b6104ae610674366004614cc3565b611277565b34801561068557600080fd5b50610699610694366004614c4c565b6112b9565b6040516104d2929190614d75565b3480156106b357600080fd5b506104ae6106c2366004614d8e565b61134f565b3480156106d357600080fd5b506106e76106e2366004614b5c565b611374565b6040516104d29190614e9e565b34801561070057600080fd5b506104ae61070f366004614ad4565b611521565b34801561072057600080fd5b50610572600080516020615d7683398151915281565b34801561074257600080fd5b506104fb73e291354a3aeb7eb49da0f1333d667f17fa33f1c581565b34801561076a57600080fd5b506104ae610779366004614d8e565b611567565b34801561078a57600080fd5b50610572610799366004614f30565b611599565b6104ae6107ac366004614ffb565b6115c8565b3480156107bd57600080fd5b506104ae6107cc366004614c0b565b611668565b3480156107dd57600080fd5b506104ae6107ec366004614b5c565b61169d565b3480156107fd57600080fd5b506104ae61080c36600461503b565b611770565b34801561081d57600080fd5b506104ae611917565b6104ae610834366004614ffb565b611938565b34801561084557600080fd5b506104ae6108543660046150b3565b6119b6565b34801561086557600080fd5b50610572611a45565b34801561087a57600080fd5b50610572610889366004614d8e565b611a79565b34801561089a57600080fd5b50610572606481565b3480156108af57600080fd5b5061061b611acd565b3480156108c457600080fd5b506104fb6108d3366004614b5c565b611ae2565b3480156108e457600080fd5b506104ae6108f3366004614ad4565b611af6565b34801561090457600080fd5b5061061b610913366004614b5c565b611b3c565b34801561092457600080fd5b506104ae610933366004615110565b611ba0565b34801561094457600080fd5b506104fb611be4565b34801561095957600080fd5b50610572610968366004614ad4565b611c02565b34801561097957600080fd5b506104fb61dead81565b34801561098f57600080fd5b506104ae61099e366004614b89565b611c2f565b3480156109af57600080fd5b506104ae6109be366004615151565b611cba565b3480156109cf57600080fd5b506105726301ffc9a760e01b81565b3480156109ea57600080fd5b506109fe6109f9366004614b5c565b61206d565b6040516104d2929190615227565b348015610a1857600080fd5b50610a216120fe565b60405162ffffff90911681526020016104d2565b348015610a4157600080fd5b506104fb61211c565b348015610a5657600080fd5b506104ae610a65366004615287565b61214a565b348015610a7657600080fd5b50610a8a610a85366004614b5c565b61231b565b6040805182516001600160a01b0316815260209283015162ffffff1692810192909252016104d2565b348015610abf57600080fd5b5061061b610ace366004614d8e565b6123af565b348015610adf57600080fd5b50610a216123e5565b348015610af457600080fd5b5061057263152a902d60e11b81565b348015610b0f57600080fd5b506104c5612413565b348015610b2457600080fd5b506104ae61059b3660046152e0565b348015610b3f57600080fd5b506104ae610b4e36600461532b565b612430565b6104ae610b61366004614cc3565b6124df565b348015610b7257600080fd5b50610b86610b81366004614b5c565b612543565b6040516104d29190615359565b348015610b9f57600080fd5b506104ae610bae366004614ad4565b61264c565b348015610bbf57600080fd5b506104ae610bce366004614ffb565b612724565b348015610bdf57600080fd5b506104ae612746565b348015610bf457600080fd5b5047610572565b348015610c0757600080fd5b506104ae610c163660046153d6565b612765565b348015610c2757600080fd5b506104ae610c36366004614ad4565b6127b2565b348015610c4757600080fd5b50610572610c56366004614b5c565b6127f5565b348015610c6757600080fd5b506104ae610c76366004614b5c565b6128de565b348015610c8757600080fd5b506104c5610c96366004614b5c565b61292e565b348015610ca757600080fd5b506104ae610cb6366004615499565b612a6d565b348015610cc757600080fd5b506104ae610cd63660046154ca565b612b16565b348015610ce757600080fd5b506104ae610cf6366004614d8e565b612b35565b348015610d0757600080fd5b506104ae610d1636600461554d565b612b4c565b348015610d2757600080fd5b5061061b610d36366004614b5c565b612c6b565b348015610d4757600080fd5b50610d5b610d563660046155e5565b612c98565b6040516104d29190600060c0820190508251825260ff6020840151166020830152604083015162ffffff80821660408501526060850151915063ffffffff8083166060860152806080870151166080860152508060a08601511660a0850152505092915050565b348015610dce57600080fd5b506104ae610ddd366004615660565b612d88565b348015610dee57600080fd5b50610a21620f424081565b348015610e0557600080fd5b5061061b610e14366004615739565b612e0e565b348015610e2557600080fd5b506104ae612e4d565b348015610e3a57600080fd5b506104fb7387d59a09ec4053c208980e4e63fcb4de97d2c7bd81565b348015610e6257600080fd5b506104ae610e71366004614ad4565b612e6c565b348015610e8257600080fd5b506104fb612ea4565b348015610e9757600080fd5b50610eab610ea6366004614b5c565b612ec2565b604080519283526020830191909152016104d2565b348015610ecc57600080fd5b506104ae610edb366004614ad4565b612f17565b348015610eec57600080fd5b50610572635b5e139f60e01b81565b610f12600080516020615d76833981519152612f9e565b6000610f1c612fc4565b600f0180546001600160a01b0319166001600160a01b03939093169290921790915550565b60606000610f4d612fc4565b9050806001018054610f5e90615767565b80601f0160208091040260200160405190810160405280929190818152602001828054610f8a90615767565b8015610fd75780601f10610fac57610100808354040283529160200191610fd7565b820191906000526020600020905b815481529060010190602001808311610fba57829003601f168201915b505050505091505090565b6000610fed82612fe8565b61100a57604051630cbdb7b360e41b815260040160405180910390fd5b6000611014612fc4565b905061101f836130ee565b61103c5760405163538fd4df60e01b815260040160405180910390fd5b60009283526005016020525060409020546001600160a01b031690565b8161106381613267565b600061106e83611ae2565b9050336001600160a01b03851614806110a25750336001600160a01b038216148015906110a257506110a08133612e0e565b155b156110c057604051631eb49d6d60e11b815260040160405180910390fd5b6110ca8484613315565b50505050565b6000806110db612fc4565b600901546001600160a01b031692915050565b611105600080516020615d76833981519152612f9e565b61110e81613393565b50565b60008061111c612fc4565b9050600060015b82546001600160401b031681101561115c5761113e816127f5565b61114890836157b7565b91506111556001826157b7565b9050611123565b5092915050565b61117a600080516020615d76833981519152612f9e565b6111826133d2565b505050565b61119e600080516020615d76833981519152612f9e565b60006111a8612fc4565b600e0180546001600160a01b0319166001600160a01b03939093169290921790915550565b826001600160a01b03811633146111e7576111e733613267565b6111f13383613402565b61120e576040516313ff771f60e21b815260040160405180910390fd5b6110ca848484613480565b6000611233600080516020615d76833981519152836123af565b92915050565b600080611244612fc4565b805490915060009061126290600160401b900462ffffff16866157cf565b905061126e84826157b7565b95945050505050565b611286898989898989876134d0565b6112958762ffffff1685613776565b60006112a28a86866137ba565b90506112ad816139f6565b50505050505050505050565b60008060006112c6612fc4565b60098101546040516329c5eaf560e11b815230600482015260248101889052604481018790529192506001600160a01b03169063538bd5ea906064016040805180830381865afa15801561131e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134291906157ee565b92509250505b9250929050565b611366600080516020615d76833981519152612f9e565b6113708282613b5a565b5050565b61137c614a0e565b6000611386612fc4565b80549091506001600160401b03168311156113b457604051631a3973a960e01b815260040160405180910390fd5b6040805160008581526003840160209081528382206101a0840185525462ffffff8082168587019081526301000000830482166060870152600160301b830482166080870152600160481b8304821660a087015263ffffffff600160601b8404811660c0880152600160801b84041660e087015260ff600160a01b84048116610100880152600160a81b840481161515610120880152600160b01b84048316610140880152600160c81b8404909216610160870152600160e01b9092041615156101808501528352868252600b850181529290208054919283019161149890615767565b80601f01602080910402602001604051908101604052809291908181526020018280546114c490615767565b80156115115780601f106114e657610100808354040283529160200191611511565b820191906000526020600020905b8154815290600101906020018083116114f457829003601f168201915b5050505050815250915050919050565b611538600080516020615d76833981519152612f9e565b6000611542612fc4565b60090180546001600160a01b0319166001600160a01b03939093169290921790915550565b6001600160a01b038116331461158f57604051623fff3d60e91b815260040160405180910390fd5b6113708282613bce565b60006115b2600080516020615d76833981519152612f9e565b6115ba6133d2565b9a9950505050505050505050565b826115d281611b3c565b6115ef5760405163589ed34b60e01b815260040160405180910390fd5b6115f7613c40565b600061160285612543565b9050600061160f8661231b565b905061162086868460c00151613c8d565b61162981613d59565b61163c816020015162ffffff1686613776565b60006116498787876137ba565b9050611654816139f6565b61165f878783613d95565b50505050505050565b826001600160a01b03811633146116825761168233613267565b6110ca84848460405180602001604052806000815250612765565b60006116a7612fc4565b905060006116b483611ae2565b90506116c03384613402565b6116dd576040516313ff771f60e21b815260040160405180910390fd5b6116ea8161dead85613eae565b60405183906000906001600160a01b03841690600080516020615d96833981519152908390a4600061171b84612ec2565b5060008181526003850160205260409020805491925060019160069061174e908490600160301b900462ffffff1661581c565b92506101000a81548162ffffff021916908362ffffff16021790555050505050565b611787600080516020615d76833981519152612f9e565b600061179161410c565b905061179c88612543565b506000888888856040516020016117b69493929190615843565b60408051601f19818403018152918152815160209283012060008181529285905291206001015490915060ff16156118015760405163ad983fdf60e01b815260040160405180910390fd5b63ffffffff85161580159061182157508563ffffffff168563ffffffff16105b1561183f57604051633e9d06f360e11b815260040160405180910390fd5b6040805160c08101825294855260ff988916602080870191825262ffffff998a1687840190815263ffffffff998a1660608901908152988a1660808901908152968b1660a08901908152600095865295909152919092209451855590516001909401805491519551935192519490981663ffffffff199091161761010094871694909402939093176bffffffffffffffff000000001916600160201b9185169190910263ffffffff60401b191617600160401b92909316919091029190911762ffffff60601b1916600160601b919092160217905550565b61192e600080516020615d76833981519152612f9e565b611936614130565b565b8261194281611b3c565b61195f5760405163589ed34b60e01b815260040160405180910390fd5b611967613c40565b600061197285612543565b905061198385858360c00151613c8d565b611996816060015162ffffff1685613776565b60006119a38686866137ba565b90506119ae816139f6565b505050505050565b6119cd600080516020615d76833981519152612f9e565b60648211156119ef57604051637e1d76fb60e01b815260040160405180910390fd5b60005b82811015611a3e57611a2b8583868685818110611a1157611a11615880565b9050602002016020810190611a269190614ad4565b6137ba565b5080611a3681615896565b9150506119f2565b5050505050565b600080611a50612fc4565b8054909150611a6a906001906001600160401b03166158af565b6001600160401b031691505090565b600080611a84612fc4565b905060008484604051602001611a9b9291906158d7565b60408051601f1981840301815291815281516020928301206000908152600c9094019091529091205491505092915050565b600080611ad861418b565b5460ff1692915050565b600080611aee836141af565b509392505050565b611b0d600080516020615d76833981519152612f9e565b6000611b17612fc4565b600d0180546001600160a01b0319166001600160a01b03939093169290921790915550565b600080611b4883612543565b90506000816080015163ffffffff16600014158015611b71575042826080015163ffffffff1611155b8015611b98575060a082015163ffffffff161580611b985750428260a0015163ffffffff16115b949350505050565b60005b81811015611182576000838383818110611bbf57611bbf615880565b905060200201359050611bd18161169d565b5080611bdc81615896565b915050611ba3565b600080611bef612fc4565b600e01546001600160a01b031692915050565b600080611c0d612fc4565b6001600160a01b03909316600090815260069093016020525050604090205490565b611c46600080516020615d76833981519152612f9e565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611c93576040519150601f19603f3d011682016040523d82523d6000602084013e611c98565b606091505b505090508061118257604051630f9310f960e01b815260040160405180910390fd5b611cd1600080516020615d76833981519152612f9e565b6000611cdb61410c565b9050611ce68b612543565b5060008b8b8b86604051602001611d009493929190615843565b6040516020818303038152906040528051906020012060001c9050611d23614a2e565b8960ff168c60ff16141580611d4257508862ffffff168b62ffffff1614155b80611d5757508362ffffff168562ffffff1614155b15611f4d576040518060c00160405280878152602001600060ff1681526020018a62ffffff1681526020018963ffffffff1681526020018863ffffffff1681526020018562ffffff168152508360000160008481526020019081526020016000206000820151816000015560208201518160010160006101000a81548160ff021916908360ff16021790555060408201518160010160016101000a81548162ffffff021916908362ffffff16021790555060608201518160010160046101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160086101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600101600c6101000a81548162ffffff021916908362ffffff1602179055509050508c8a8a86604051602001611e959493929190615843565b60408051808303601f1901815291815281516020928301206000818152868452829020845181559284015160019093018054928501516060860151608087015160a088015160ff90971663ffffffff199096169590951761010062ffffff93841602176bffffffffffffffff000000001916600160201b63ffffffff9283160263ffffffff60401b191617600160401b91909516029390931762ffffff60601b1916600160601b939094169290920292909217905591505b63ffffffff871615801590611f6d57508763ffffffff168763ffffffff16105b15611f8b57604051633e9d06f360e11b815260040160405180910390fd5b506040805160c08101825295865260ff998a16602080880191825262ffffff9a8b1688840190815263ffffffff9a8b1660608a01908152998b1660808a01908152968c1660a08a01908152600095865295909152919092209551865590516001909501805491519651935192518916600160601b0262ffffff60601b19938916600160401b0263ffffffff60401b1995909916600160201b02949094166bffffffffffffffff0000000019979099166101000263ffffffff19909216959099169490941793909317939093169490941792909217919091161790915550505050565b606080600061207a612fc4565b6009810154604051632e44189760e11b81529192506001600160a01b031690635c88312e906120af9030908890600401614d75565b600060405180830381865afa1580156120cc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120f49190810190615958565b9250925050915091565b600080612109612fc4565b54600160401b900462ffffff1692915050565b7fcb8952d7e709d77cf862c59597b58044638bae7291440245a00835d98a0e72b3546001600160a01b031690565b8361215481611b3c565b6121715760405163589ed34b60e01b815260040160405180910390fd5b612179613c40565b6000612183612fc4565b9050600061219087612543565b905080610100015162ffffff16600014806121a9575083155b156121c757604051630713314160e01b815260040160405180910390fd5b6101208101516000906121df9062ffffff1686615a32565b90508662ffffff1681101561220757604051630713314160e01b815260040160405180910390fd5b6000883360405160200161221c9291906158d7565b6040516020818303038152906040528051906020012060001c90508260c0015160ff166000146122915760c08301516000828152600c8601602052604090205460ff909116906122729062ffffff8b16906157b7565b111561229157604051635ac0a89b60e11b815260040160405180910390fd5b6000818152600c850160205260408120805462ffffff8b1692906122b69084906157b7565b90915550600090505b888461012001516122d09190615a46565b62ffffff1681101561230f576122fd8888838181106122f1576122f1615880565b9050602002013561169d565b8061230781615896565b9150506122bf565b506112ad8989336137ba565b60408051808201909152600080825260208201526000612339612fc4565b80549091506001600160401b031683111561236757604051631a3973a960e01b815260040160405180910390fd5b60408051808201825260008581526010939093016020818152928420546001600160a01b038116835295909352918152600160a01b90930462ffffff16928101929092525090565b6000806123ba614212565b6000948552602090815260408086206001600160a01b03959095168652939052505090205460ff1690565b6000806123f0612fc4565b805490915061240d90600190600160401b900462ffffff16615a71565b91505090565b6060600061241f612fc4565b9050806002018054610f5e90615767565b8161243a81613267565b336001600160a01b0384160361246357604051631eb49d6d60e11b815260040160405180910390fd5b600061246d612fc4565b33600081815260078301602090815260408083206001600160a01b038a1680855290835292819020805460ff1916891515908117909155905190815293945090927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a350505050565b60006124ea8a61231b565b90506124fb8a8a8a8a8a8a886134d0565b61250481613d59565b6125138262ffffff1686613776565b60006125208b87876137ba565b905061252b816139f6565b6125368b8783613d95565b5050505050505050505050565b61254b614a63565b6000612555612fc4565b80549091506001600160401b031683111561258357604051631a3973a960e01b815260040160405180910390fd5b60009283526003016020908152604092839020835161016081018552905462ffffff808216835263010000008204811693830193909352600160301b8104831694820194909452600160481b84048216606082015263ffffffff600160601b850481166080830152600160801b85041660a082015260ff600160a01b8504811660c0830152600160a81b85048116151560e0830152600160b01b85048316610100830152600160c81b8504909216610120820152600160e01b9093041615156101408301525090565b612663600080516020615d76833981519152612f9e565b600061266d614236565b905060005b81548110156126f05781600001818154811061269057612690615880565b6000918252602090912001546001600160a01b03908116908416036126de578160000181815481106126c4576126c4615880565b600091825260209091200180546001600160a01b03191690555b6126e96001826157b7565b9050612672565b508054600181018255600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055565b61273b600080516020615d76833981519152612f9e565b6110ca8383836137ba565b61275d600080516020615d76833981519152612f9e565b61193661425a565b836001600160a01b038116331461277f5761277f33613267565b6127893384613402565b6127a657604051631eb49d6d60e11b815260040160405180910390fd5b611a3e858585856142a7565b6127c9600080516020615d76833981519152612f9e565b60006127d36142be565b80546001600160a01b0319166001600160a01b03939093169290921790915550565b600080612800612fc4565b6000848152600382016020908152604091829020825161016081018452905462ffffff8082168352630100000082048116938301849052600160301b82048116948301859052600160481b82048116606084015263ffffffff600160601b830481166080850152600160801b83041660a084015260ff600160a01b8304811660c0850152600160a81b83048116151560e0850152600160b01b83048216610100850152600160c81b8304909116610120840152600160e01b9091041615156101408201529293506128d19190615a71565b62ffffff16949350505050565b6128f5600080516020615d76833981519152612f9e565b60006128ff612fc4565b60009283526003016020525060409020805460ff60e01b198116600160e01b9182900460ff1615909102179055565b606061293982612fe8565b61295657604051630cbdb7b360e41b815260040160405180910390fd5b6000612960612fc4565b9050600061296d84612ec2565b509050600061297b82612543565b90508060e00151156129ca576000828152600b8401602052604090206129a0866142e2565b6040516020016129b1929190615a8d565b6040516020818303038152906040529350505050919050565b6000828152600b84016020526040902080546129e590615767565b80601f0160208091040260200160405190810160405280929190818152602001828054612a1190615767565b8015612a5e5780601f10612a3357610100808354040283529160200191612a5e565b820191906000526020600020905b815481529060010190602001808311612a4157829003601f168201915b50505050509350505050919050565b836001600160a01b0381163314612a8757612a8733613267565b60005b828110156119ae57612ab433858584818110612aa857612aa8615880565b90506020020135613402565b612ad157604051631eb49d6d60e11b815260040160405180910390fd5b612b048686868685818110612ae857612ae8615880565b9050602002013560405180602001604052806000815250612765565b80612b0e81615896565b915050612a8a565b612b2d600080516020615d76833981519152612f9e565b61165f6133d2565b61158f600080516020615d76833981519152612f9e565b7fe64551584c98548d769652536a405149aacacb81302f284a40bda60ebfbfbd3b805460ff1615612b8f5760405162dc149f60e41b815260040160405180910390fd5b6000612b99612fc4565b905060018101612baa898b83615b51565b5060028101612bba878983615b51565b506009810180546001600160a01b038087166001600160a01b031992831617909255600d830180549286169290911691909117905580546a0f424000000000000000016affffffffffffffffffffff19909116178155612c28600080516020615d7683398151915286613b5a565b612c31856143e2565b612c4e73dab1a1854214684ace522439684a145e62505233613393565b612c5661440a565b50805460ff1916600117905550505050505050565b600080612c76612fc4565b6000938452600401602052505060409020546001600160a01b031661dead1490565b612ca0614a2e565b6000612caa61410c565b9050612cb586612543565b50600086868686604051602001612ccf9493929190615843565b60408051601f19818403018152918152815160209283012060008181529285905290822060018101549193509160ff9091169003612d205760405163c5723b5160e01b815260040160405180910390fd5b6040805160c0810182528254815260019092015460ff8116602084015262ffffff610100820481169284019290925263ffffffff600160201b820481166060850152600160401b8204166080840152600160601b90041660a082015292505050949350505050565b612d9f600080516020615d76833981519152612f9e565b6000612da9612fc4565b600981015460405163dfc9f91360e01b81529192506001600160a01b03169063dfc9f91390612de090309033908790600401615c10565b600060405180830381600087803b158015612dfa57600080fd5b505af11580156119ae573d6000803e3d6000fd5b600080612e19612fc4565b6001600160a01b03948516600090815260079190910160209081526040808320959096168252939093525050205460ff1690565b612e64600080516020615d76833981519152612f9e565b61193661440a565b612e74614484565b6001600160a01b038116612e9b57604051633a247dd760e11b815260040160405180910390fd5b61110e816144b4565b600080612eaf612fc4565b600d01546001600160a01b031692915050565b6000806000612ecf612fc4565b8054909150612eea90600160401b900462ffffff1685615a32565b8154909350612f0590600160401b900462ffffff16846157cf565b612f0f9085615c93565b915050915091565b612f2e600080516020615d76833981519152612f9e565b60006001600160a01b03821647604051600081818185875af1925050503d8060008114612f77576040519150601f19603f3d011682016040523d82523d6000602084013e612f7c565b606091505b505090508061137057604051630f9310f960e01b815260040160405180910390fd5b612fa881336123af565b61110e57604051623fff3d60e91b815260040160405180910390fd5b7fbc7d0e8ed4dcaf65aa37ff076afe36b4e8fbc0e9b704cfd2ecde67415414d07a90565b6000806000612ff684612ec2565b9150915061300384612c6b565b15613012575060009392505050565b600061301c612fc4565b60009384526003016020908152604093849020845161016081018652905462ffffff8082168352630100000082048116938301849052600160301b8204811696830196909652600160481b81048616606083015263ffffffff600160601b820481166080840152600160801b82041660a083015260ff600160a01b8204811660c0840152600160a81b82048116151560e0840152600160b01b82048716610100840152600160c81b8204909616610120830152600160e01b900490941615156101409094019390935250111592915050565b6000806130f9612fc4565b9050600061310684612ec2565b506000818152600384016020908152604091829020825161016081018452905462ffffff808216835263010000008204811693830193909352600160301b8104831693820193909352600160481b83048216606082015263ffffffff600160601b840481166080830152600160801b84041660a082015260ff600160a01b8404811660c0830152600160a81b84048116151560e0830152600160b01b84048316610100830152600160c81b8404909216610120820152600160e01b909204161580156101408301529192509061325c57600e830154604051633c29490960e21b8152600481018790526000916001600160a01b03169063f0a5242490602401602060405180830381865afa158015613222573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132469190615caa565b9050801561325a5750600095945050505050565b505b506001949350505050565b60006132716142be565b80549091506001600160a01b03163b15611370578054604051633185c44d60e21b81523060048201526001600160a01b0384811660248301529091169063c617113490604401602060405180830381865afa1580156132d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132f89190615caa565b61137057604051631eb49d6d60e11b815260040160405180910390fd5b600061331f612fc4565b6000838152600582016020526040902080546001600160a01b0319166001600160a01b038616908117909155909150829061335982611ae2565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600061339d614236565b8054600181018255600091825260209091200180546001600160a01b0319166001600160a01b03939093169290921790915550565b60006133dc61450d565b90503660008037600080366000845af43d6000803e8080156133fd573d6000f35b3d6000fd5b600061340d82612fe8565b61342a57604051630cbdb7b360e41b815260040160405180910390fd5b600061343583611ae2565b9050806001600160a01b0316846001600160a01b031614806134705750836001600160a01b031661346584610fe2565b6001600160a01b0316145b80611b985750611b988185612e0e565b61348b838383614580565b613496600082613315565b80826001600160a01b0316846001600160a01b0316600080516020615d9683398151915260405160405180910390a4611182838383613eae565b60006134da612fc4565b905060006134ea89898986612c98565b9050600089336040516020016135019291906158d7565b6040516020818303038152906040528051906020012060001c9050816020015160ff168562ffffff1684600c0160008481526020019081526020016000205461354a91906157b7565b111561356957604051635ac0a89b60e11b815260040160405180910390fd5b606082015163ffffffff1615806135895750816060015163ffffffff1642105b156135a75760405163589ed34b60e01b815260040160405180910390fd5b608082015163ffffffff16158015906135c95750816080015163ffffffff1642115b156135e75760405163589ed34b60e01b815260040160405180910390fd5b6040516001600160601b03193360601b16602082015260009060340160405160208183030381529060405280519060200120905061366461365e89898080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050875191508590506145a6565b156145be565b6136a488888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050865191508490506145a6565b1580156137215750600d8401546040516370a0823160e01b81526001600160a01b03909116906370a08231906136de903390600401614b75565b602060405180830381865afa1580156136fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371f9190615cc7565b155b1561373f57604051630b094f2760e31b815260040160405180910390fd5b6000828152600c850160205260408120805462ffffff891692906137649084906157b7565b90915550505050505050505050505050565b60006137898366038d7ea4c680006157cf565b90503461379b62ffffff8416836157cf565b11156111825760405163356680b760e01b815260040160405180910390fd5b6000806137c5612fc4565b600086815260038201602052604081208054929350916137f2906301000000900462ffffff16600161581c565b835462ffffff9190911691506001600160401b031687111561382757604051631a3973a960e01b815260040160405180910390fd5b62ffffff8616158061384057506001600160a01b038516155b1561385e5760405163b732d5e160e01b815260040160405180910390fd5b815462ffffff1681111561388557604051631f6e464360e31b815260040160405180910390fd5b61388f8782611239565b825490945062ffffff808216916138af918991630100000090041661581c565b62ffffff1611156138d357604051631f6e464360e31b815260040160405180910390fd5b8154869083906003906138f39084906301000000900462ffffff1661581c565b82546101009290920a62ffffff818102199093169190921691909102179055506000848152600484016020526040902080546001600160a01b0319166001600160a01b03871617905561394960088401856145ff565b6001600160a01b03851660009081526006840160205260408120805462ffffff891692906139789084906157b7565b909155508490505b61398f62ffffff8816866157b7565b8110156139eb5760405181906001600160a01b03881690600090600080516020615d96833981519152908290a46139d8600087836040518060200160405280600081525061462b565b50806139e381615896565b915050613980565b505050509392505050565b6000613a00612fc4565b6009810154604051632e44189760e11b815291925060009182916001600160a01b031690635c88312e90613a3a9030908890600401614d75565b600060405180830381865afa158015613a57573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613a7f9190810190615958565b8151919350915060005b818110156119ae576000613ab634858481518110613aa957613aa9615880565b602002602001015161472a565b90506000858381518110613acc57613acc615880565b60200260200101516001600160a01b03168260405160006040518083038185875af1925050503d8060008114613b1e576040519150601f19603f3d011682016040523d82523d6000602084013e613b23565b606091505b5050905080613b4557604051630f9310f960e01b815260040160405180910390fd5b50508080613b5290615896565b915050613a89565b6000613b64614212565b9050613b7083836123af565b611182576000838152602082815260408083206001600160a01b0386168085529252808320805460ff1916600117905551339286917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a4505050565b6000613bd8614212565b9050613be483836123af565b15611182576000838152602082815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4505050565b613c48611acd565b156119365760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064015b60405180910390fd5b6000613c97612fc4565b905060ff821615801590613cb05750613cae614743565b155b156110ca5760008433604051602001613cca9291906158d7565b60408051601f1981840301815291815281516020928301206000818152600c860190935291205490915060ff841690613d099062ffffff8716906157b7565b1115613d2857604051635ac0a89b60e11b815260040160405180910390fd5b6000818152600c830160205260408120805462ffffff87169290613d4d9084906157b7565b90915550505050505050565b80516001600160a01b03161580613d775750602081015162ffffff16155b1561110e576040516306d423a960e21b815260040160405180910390fd5b6000613d9f612fc4565b60008581526010820160205260408120549192506001600160a01b039091169062ffffff85166001600160401b03811115613ddc57613ddc615368565b604051908082528060200260200182016040528015613e05578160200160208202803683370190505b50905060005b8562ffffff16811015613e5157613e2281866157b7565b828281518110613e3457613e34615880565b602090810291909101015280613e4981615896565b915050613e0b565b50604051630adf035760e41b81526001600160a01b0383169063adf0357090613e809032908590600401615ce0565b600060405180830381600087803b158015613e9a57600080fd5b505af11580156112ad573d6000803e3d6000fd5b6000613eb8612fc4565b90506000613ec5836141af565b9150506000613ed384611ae2565b9050856001600160a01b0316816001600160a01b031614613f07576040516313ff771f60e21b815260040160405180910390fd5b6000613f148560016157b7565b90506000613f2182612ec2565b9150506000613f2f87612ec2565b506000818152600388016020908152604091829020825161016081018452905462ffffff80821680845263010000008304821694840194909452600160301b8204811694830194909452600160481b81048416606083015263ffffffff600160601b820481166080840152600160801b82041660a083015260ff600160a01b8204811660c0840152600160a81b82048116151560e0840152600160b01b82048516610100840152600160c81b8204909416610120830152600160e01b900490921615156101408301529192509083118015906140285750600884811c60009081529088016020526040902054600160ff1b60ff86161c16155b15614063576000848152600488016020526040902080546001600160a01b0319166001600160a01b038c1617905561406360088801856145ff565b6000888152600488016020526040902080546001600160a01b0319166001600160a01b038b161790558588146140a0576140a060088801896145ff565b6001600160a01b038916600090815260068801602052604081208054600192906140cb9084906157b7565b90915550506001600160a01b038a16600090815260068801602052604081208054600192906140fb908490615c93565b909155505050505050505050505050565b7f5cdb56131f6a8cb8897cc0bafef07a5b2973e186f281253cea0806ea1443c13e90565b614138613c40565b600061414261418b565b805460ff191660011781556040519091507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890614180903390614b75565b60405180910390a150565b7f2ce935bb7ebbf5d9759d0bf10b40148186ea48e69aeea9281cb4f3267f07abf390565b6000806141bb83612fe8565b6141d857604051630cbdb7b360e41b815260040160405180910390fd5b60006141e2612fc4565b90506141ed846147b0565b600081815260049092016020526040909120546001600160a01b031694909350915050565b7f8113889f0b868eeca4f3f98876bebc5d45f78186a7ac12c94ed39d8b17ef258e90565b7f92140bce112f095179820a95d551eb064f38e1596fa0b63a05d6960156840a9a90565b6142626147f5565b600061426c61418b565b805460ff191681556040519091507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90614180903390614b75565b6142b2848484613480565b611a3e8484848461462b565b7fd1c7a1698d3d2d2fdb5cc2360b499ff16d810b81a494d1feedda8dbe4b67fb7890565b6060816000036143095750506040805180820190915260018152600360fc1b602082015290565b8160005b8115614333578061431d81615896565b915061432c9050600a83615a32565b915061430d565b6000816001600160401b0381111561434d5761434d615368565b6040519080825280601f01601f191660200182016040528015614377576020820181803683370190505b5090505b8415611b985761438c600183615c93565b9150614399600a86615d04565b6143a49060306157b7565b60f81b8183815181106143b9576143b9615880565b60200101906001600160f81b031916908160001a9053506143db600a86615a32565b945061437b565b60007fcb8952d7e709d77cf862c59597b58044638bae7291440245a00835d98a0e72b36127d3565b60006144146142be565b80546001600160a01b0319166daaeb6d7670e522a718067333cd4e9081178255909150803b1561137057604051633e9f1edf60e11b8152306004820152733cc6cdda760b79bafa08df41ecfa224f810dceb660248201526001600160a01b03821690637d3e3dbe90604401612de0565b3361448d61211c565b6001600160a01b03161461193657604051636db2465f60e01b815260040160405180910390fd5b60006144be61211c565b90506144c9826143e2565b816001600160a01b0316816001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080614518612fc4565b600f8101549091506001600160a01b03161561454057600f01546001600160a01b0316919050565b4662aa36a703614565577387d59a09ec4053c208980e4e63fcb4de97d2c7bd91505090565b73e291354a3aeb7eb49da0f1333d667f17fa33f1c591505090565b614589816130ee565b6111825760405163538fd4df60e01b815260040160405180910390fd5b6000826145b38584614840565b1490505b9392505050565b604051811515602482015261110e9060440160408051601f198184030181529190526020810180516001600160e01b03166332458eed60e01b179052614885565b600881901c600090815260209290925260409091208054600160ff1b60ff9093169290921c9091179055565b60006001600160a01b0384163b1561472257604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061466f903390899088908890600401615d18565b6020604051808303816000875af19250505080156146aa575060408051601f3d908101601f191682019092526146a791810190615d4b565b60015b614708573d8080156146d8576040519150601f19603f3d011682016040523d82523d6000602084013e6146dd565b606091505b50805160000361470057604051630568cbab60e01b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611b98565b506001611b98565b600061271061473983856157cf565b6145b79190615a32565b60008061474e614236565b905060005b81548110156147a75781600001818154811061477157614771615880565b6000918252602090912001546001600160a01b031633036147955760019250505090565b6147a06001826157b7565b9050614753565b50600091505090565b6000806147bb612fc4565b905060006147c884612ec2565b508254909150611b989085906147ea90600160401b900462ffffff16846157cf565b60088501919061488e565b6147fd611acd565b6119365760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401613c84565b600081815b8451811015611aee576148718286838151811061486457614864615880565b602002602001015161493c565b91508061487d81615896565b915050614845565b61110e8161496b565b600882811c600081815260208690526040812054909284901c9060ff808716919082181c80156148d7576148c18161498c565b60ff168203600885901b179450505050506145b7565b828410156148f857604051630f78a15d60e31b815260040160405180910390fd5b506000199092016000818152602088905260409020549092908015614937576149208161498c565b60ff0360ff16600885901b179450505050506145b7565b6148d7565b60008183106149585760008281526020849052604090206145b7565b60008381526020839052604090206145b7565b60006a636f6e736f6c652e6c6f679050600080835160208501845afa505050565b60006040518061012001604052806101008152602001615db6610100913960f87e818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff6149d5856149f6565b02901c815181106149e8576149e8615880565b016020015160f81c92915050565b6000808211614a0457600080fd5b5060008190031690565b6040518060400160405280614a21614a63565b8152602001606081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915290565b6001600160a01b038116811461110e57600080fd5b600060208284031215614ae657600080fd5b81356145b781614abf565b60005b83811015614b0c578181015183820152602001614af4565b838111156110ca5750506000910152565b60008151808452614b35816020860160208601614af1565b601f01601f19169290920160200192915050565b6020815260006145b76020830184614b1d565b600060208284031215614b6e57600080fd5b5035919050565b6001600160a01b0391909116815260200190565b60008060408385031215614b9c57600080fd5b8235614ba781614abf565b946020939093013593505050565b803562ffffff81168114614bc857600080fd5b919050565b600080600060608486031215614be257600080fd5b833592506020840135614bf481614abf565b9150614c0260408501614bb5565b90509250925092565b600080600060608486031215614c2057600080fd5b8335614c2b81614abf565b92506020840135614c3b81614abf565b929592945050506040919091013590565b60008060408385031215614c5f57600080fd5b50508035926020909101359150565b803560ff81168114614bc857600080fd5b60008083601f840112614c9157600080fd5b5081356001600160401b03811115614ca857600080fd5b6020830191508360208260051b850101111561134857600080fd5b60008060008060008060008060006101008a8c031215614ce257600080fd5b89359850614cf260208b01614c6e565b9750614d0060408b01614bb5565b965060608a01356001600160401b03811115614d1b57600080fd5b614d278c828d01614c7f565b9097509550614d3a905060808b01614bb5565b935060a08a0135614d4a81614abf565b9250614d5860c08b01614bb5565b9150614d6660e08b01614bb5565b90509295985092959850929598565b6001600160a01b03929092168252602082015260400190565b60008060408385031215614da157600080fd5b823591506020830135614db381614abf565b809150509250929050565b805162ffffff1682526020810151614ddd602084018262ffffff169052565b506040810151614df4604084018262ffffff169052565b506060810151614e0b606084018262ffffff169052565b506080810151614e23608084018263ffffffff169052565b5060a0810151614e3b60a084018263ffffffff169052565b5060c0810151614e5060c084018260ff169052565b5060e0810151614e6460e084018215159052565b506101008181015162ffffff81168483015250506101208181015162ffffff811684830152505061014081810151801515848301526110ca565b60208152614eb0602082018351614dbe565b602082015161018082810152600090611b986101a0840182614b1d565b60008083601f840112614edf57600080fd5b5081356001600160401b03811115614ef657600080fd5b60208301915083602082850101111561134857600080fd5b803563ffffffff81168114614bc857600080fd5b801515811461110e57600080fd5b6000806000806000806000806000806101208b8d031215614f5057600080fd5b8a356001600160401b03811115614f6657600080fd5b614f728d828e01614ecd565b909b509950614f85905060208c01614bb5565b9750614f9360408c01614bb5565b9650614fa160608c01614f0e565b9550614faf60808c01614f0e565b9450614fbd60a08c01614c6e565b935060c08b0135614fcd81614f22565b9250614fdb60e08c01614c6e565b9150614fea6101008c01614c6e565b90509295989b9194979a5092959850565b60008060006060848603121561501057600080fd5b8335925061502060208501614bb5565b9150604084013561503081614abf565b809150509250925092565b600080600080600080600060e0888a03121561505657600080fd5b8735965061506660208901614c6e565b955061507460408901614bb5565b945061508260608901614f0e565b935061509060808901614f0e565b925060a088013591506150a560c08901614bb5565b905092959891949750929550565b600080600080606085870312156150c957600080fd5b8435935060208501356001600160401b038111156150e657600080fd5b6150f287828801614c7f565b9094509250615105905060408601614bb5565b905092959194509250565b6000806020838503121561512357600080fd5b82356001600160401b0381111561513957600080fd5b61514585828601614c7f565b90969095509350505050565b6000806000806000806000806000806101408b8d03121561517157600080fd5b8a35995061518160208c01614c6e565b985061518f60408c01614bb5565b975061519d60608c01614c6e565b96506151ab60808c01614bb5565b95506151b960a08c01614f0e565b94506151c760c08c01614f0e565b935060e08b013592506151dd6101008c01614bb5565b9150614fea6101208c01614bb5565b600081518084526020808501945080840160005b8381101561521c57815187529582019590820190600101615200565b509495945050505050565b604080825283519082018190526000906020906060840190828701845b828110156152695781516001600160a01b031684529284019290840190600101615244565b5050508381038285015261527d81866151ec565b9695505050505050565b6000806000806060858703121561529d57600080fd5b843593506152ad60208601614bb5565b925060408501356001600160401b038111156152c857600080fd5b6152d487828801614c7f565b95989497509550505050565b6000806000604084860312156152f557600080fd5b8335925060208401356001600160401b0381111561531257600080fd5b61531e86828701614ecd565b9497909650939450505050565b6000806040838503121561533e57600080fd5b823561534981614abf565b91506020830135614db381614f22565b61016081016112338284614dbe565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156153a0576153a0615368565b60405290565b604051601f8201601f191681016001600160401b03811182821017156153ce576153ce615368565b604052919050565b600080600080608085870312156153ec57600080fd5b84356153f781614abf565b935060208581013561540881614abf565b93506040860135925060608601356001600160401b038082111561542b57600080fd5b818801915088601f83011261543f57600080fd5b81358181111561545157615451615368565b615463601f8201601f191685016153a6565b9150808252898482850101111561547957600080fd5b808484018584013760008482840101525080935050505092959194509250565b600080600080606085870312156154af57600080fd5b84356154ba81614abf565b935060208501356152ad81614abf565b600080600080600080600060e0888a0312156154e557600080fd5b873596506154f560208901614bb5565b955061550360408901614f0e565b945061551160608901614f0e565b935061551f60808901614c6e565b925061552d60a08901614bb5565b915060c088013561553d81614f22565b8091505092959891949750929550565b600080600080600080600060a0888a03121561556857600080fd5b87356001600160401b038082111561557f57600080fd5b61558b8b838c01614ecd565b909950975060208a01359150808211156155a457600080fd5b506155b18a828b01614ecd565b90965094505060408801356155c581614abf565b925060608801356155d581614abf565b9150608088013561553d81614abf565b600080600080608085870312156155fb57600080fd5b8435935061560b60208601614c6e565b925061561960408601614bb5565b915061510560608601614bb5565b60006001600160401b0382111561564057615640615368565b5060051b60200190565b803565ffffffffffff81168114614bc857600080fd5b6000602080838503121561567357600080fd5b82356001600160401b0381111561568957600080fd5b8301601f8101851361569a57600080fd5b80356156ad6156a882615627565b6153a6565b818152606091820283018401918482019190888411156156cc57600080fd5b938501935b8385101561572d5780858a0312156156e95760008081fd5b6156f161537e565b85356156fc81614abf565b815261570986880161564a565b87820152604061571a81880161564a565b90820152835293840193918501916156d1565b50979650505050505050565b6000806040838503121561574c57600080fd5b823561575781614abf565b91506020830135614db381614abf565b600181811c9082168061577b57607f821691505b60208210810361579b57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b600082198211156157ca576157ca6157a1565b500190565b60008160001904831182151516156157e9576157e96157a1565b500290565b6000806040838503121561580157600080fd5b825161580c81614abf565b6020939093015192949293505050565b600062ffffff80831681851680830382111561583a5761583a6157a1565b01949350505050565b93845260f89290921b6001600160f81b031916602084015260e890811b6001600160e81b0319908116602185015291901b16602482015260270190565b634e487b7160e01b600052603260045260246000fd5b6000600182016158a8576158a86157a1565b5060010190565b60006001600160401b03838116908316818110156158cf576158cf6157a1565b039392505050565b91825260601b6001600160601b031916602082015260340190565b600082601f83011261590357600080fd5b815160206159136156a883615627565b82815260059290921b8401810191818101908684111561593257600080fd5b8286015b8481101561594d5780518352918301918301615936565b509695505050505050565b6000806040838503121561596b57600080fd5b82516001600160401b038082111561598257600080fd5b818501915085601f83011261599657600080fd5b815160206159a66156a883615627565b82815260059290921b840181019181810190898411156159c557600080fd5b948201945b838610156159ec5785516159dd81614abf565b825294820194908201906159ca565b91880151919650909350505080821115615a0557600080fd5b50615a12858286016158f2565b9150509250929050565b634e487b7160e01b600052601260045260246000fd5b600082615a4157615a41615a1c565b500490565b600062ffffff80831681851681830481118215151615615a6857615a686157a1565b02949350505050565b600062ffffff838116908316818110156158cf576158cf6157a1565b6000808454615a9b81615767565b60018281168015615ab35760018114615ac857615af7565b60ff1984168752821515830287019450615af7565b8860005260208060002060005b85811015615aee5781548a820152908401908201615ad5565b50505082870194505b50505050835161583a818360208801614af1565b601f82111561118257600081815260208120601f850160051c81016020861015615b325750805b601f850160051c820191505b818110156119ae57828155600101615b3e565b6001600160401b03831115615b6857615b68615368565b615b7c83615b768354615767565b83615b0b565b6000601f841160018114615bb05760008515615b985750838201355b600019600387901b1c1916600186901b178355611a3e565b600083815260209020601f19861690835b82811015615be15786850135825560209485019460019092019101615bc1565b5086821015615bfe5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6000606080830160018060a01b03808816855260208188168187015260408481880152838851808652608089019150838a01955060005b81811015615c825786518051871684528581015165ffffffffffff908116878601529085015116848401529584019591870191600101615c47565b50909b9a5050505050505050505050565b600082821015615ca557615ca56157a1565b500390565b600060208284031215615cbc57600080fd5b81516145b781614f22565b600060208284031215615cd957600080fd5b5051919050565b6001600160a01b0383168152604060208201819052600090611b98908301846151ec565b600082615d1357615d13615a1c565b500690565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061527d90830184614b1d565b600060208284031215615d5d57600080fd5b81516001600160e01b0319811681146145b757600080fdfeea8e1b953cb200117b202dd78c6958f9c14d952d5bdaa146141d2a5f9ee220dbddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8a2646970667358221220f77fca2882af9dfdf4dc60225056e54ed000b2e0fd32c3c1dce8b98fb9733ca064736f6c634300080f0033
Deployed Bytecode
0x6080604052600436106104895760003560e01c8063736fe56511610255578063b88d4fde11610144578063dc47a410116100c1578063ed842d8411610085578063ed842d8414610e2e578063f2fde38b14610e56578063f343958f14610e76578063f45e3ebd14610e8b578063fa09e63014610ec0578063fc45635314610ee057600080fd5b8063dc47a41014610d3b578063e18827cd14610dc2578063e720a4b014610de2578063e985e9c514610df9578063eb44774014610e1957600080fd5b8063c8c6cbd711610108578063c8c6cbd714610c9b578063d49232a114610cbb578063d547741f14610cdb578063db0ed6a014610cfb578063db44fe0714610d1b57600080fd5b8063b88d4fde14610bfb578063b8d1e53214610c1b578063be5dea8a14610c3b578063c6879ff914610c5b578063c87b56dd14610c7b57600080fd5b8063946a3cbb116101d2578063a642c03211610196578063a642c03214610b66578063a9359de814610b93578063ae005af914610bb3578063b33712c514610bd3578063b69ef8a814610be857600080fd5b8063946a3cbb14610ae857806395d89b4114610b03578063999873f714610b18578063a22cb46514610b33578063a34931c114610b5357600080fd5b80638da5cb5b116102195780638da5cb5b14610a355780638fc614ec14610a4a578063910eec1f14610a6a57806391d1485414610ab3578063933a261114610ad357600080fd5b8063736fe5651461098357806373d31507146109a35780637cb796eb146109c35780637f12460f146109de57806380cd807c14610a0c57600080fd5b80633596b4ac1161037c57806351d329dc116102f957806363a5c0eb116102bd57806363a5c0eb146108d857806365308579146108f85780636ab49a5b146109185780636afe57951461093857806370a082311461094d57806370d5ae051461096d57600080fd5b806351d329dc1461085957806357c492771461086e5780635b353be21461088e5780635c975abb146108a35780636352211e146108b857600080fd5b806342966c681161034057806342966c68146107d1578063434e3603146107f1578063439766ce146108115780634cb30db1146108265780634d213ff11461083957600080fd5b80633596b4ac1461073657806336568abe1461075e5780633cbb1bb21461077e5780633ebd45861461079e57806342842e0e146107b157600080fd5b806323b872dd1161040a5780632a55205a116103ce5780632a55205a146106795780632f2ff15d146106a7578063322ff140146106c75780633474bd1e146106f457806335742d741461071457600080fd5b806323b872dd146105db57806324d7806c146105fb57806325acc72e1461062b57806328205b2f1461064b578063287ea4341461066657600080fd5b80630b213c07116104515780630b213c071461053d57806318160ddd1461055d5780631a9968a9146105805780631c1f8aa3146105a05780631e8f5530146105c057600080fd5b8063033da70b1461048e57806306fdde03146104b0578063081812fc146104db578063095ea7b3146105085780630a62f21414610528575b600080fd5b34801561049a57600080fd5b506104ae6104a9366004614ad4565b610efb565b005b3480156104bc57600080fd5b506104c5610f41565b6040516104d29190614b49565b60405180910390f35b3480156104e757600080fd5b506104fb6104f6366004614b5c565b610fe2565b6040516104d29190614b75565b34801561051457600080fd5b506104ae610523366004614b89565b611059565b34801561053457600080fd5b506104fb6110d0565b34801561054957600080fd5b506104ae610558366004614ad4565b6110ee565b34801561056957600080fd5b50610572611111565b6040519081526020016104d2565b34801561058c57600080fd5b506104ae61059b366004614bcd565b611163565b3480156105ac57600080fd5b506104ae6105bb366004614ad4565b611187565b3480156105cc57600080fd5b506105726380ac58cd60e01b81565b3480156105e757600080fd5b506104ae6105f6366004614c0b565b6111cd565b34801561060757600080fd5b5061061b610616366004614ad4565b611219565b60405190151581526020016104d2565b34801561063757600080fd5b50610572610646366004614c4c565b611239565b34801561065757600080fd5b50610572632483248360e11b81565b6104ae610674366004614cc3565b611277565b34801561068557600080fd5b50610699610694366004614c4c565b6112b9565b6040516104d2929190614d75565b3480156106b357600080fd5b506104ae6106c2366004614d8e565b61134f565b3480156106d357600080fd5b506106e76106e2366004614b5c565b611374565b6040516104d29190614e9e565b34801561070057600080fd5b506104ae61070f366004614ad4565b611521565b34801561072057600080fd5b50610572600080516020615d7683398151915281565b34801561074257600080fd5b506104fb73e291354a3aeb7eb49da0f1333d667f17fa33f1c581565b34801561076a57600080fd5b506104ae610779366004614d8e565b611567565b34801561078a57600080fd5b50610572610799366004614f30565b611599565b6104ae6107ac366004614ffb565b6115c8565b3480156107bd57600080fd5b506104ae6107cc366004614c0b565b611668565b3480156107dd57600080fd5b506104ae6107ec366004614b5c565b61169d565b3480156107fd57600080fd5b506104ae61080c36600461503b565b611770565b34801561081d57600080fd5b506104ae611917565b6104ae610834366004614ffb565b611938565b34801561084557600080fd5b506104ae6108543660046150b3565b6119b6565b34801561086557600080fd5b50610572611a45565b34801561087a57600080fd5b50610572610889366004614d8e565b611a79565b34801561089a57600080fd5b50610572606481565b3480156108af57600080fd5b5061061b611acd565b3480156108c457600080fd5b506104fb6108d3366004614b5c565b611ae2565b3480156108e457600080fd5b506104ae6108f3366004614ad4565b611af6565b34801561090457600080fd5b5061061b610913366004614b5c565b611b3c565b34801561092457600080fd5b506104ae610933366004615110565b611ba0565b34801561094457600080fd5b506104fb611be4565b34801561095957600080fd5b50610572610968366004614ad4565b611c02565b34801561097957600080fd5b506104fb61dead81565b34801561098f57600080fd5b506104ae61099e366004614b89565b611c2f565b3480156109af57600080fd5b506104ae6109be366004615151565b611cba565b3480156109cf57600080fd5b506105726301ffc9a760e01b81565b3480156109ea57600080fd5b506109fe6109f9366004614b5c565b61206d565b6040516104d2929190615227565b348015610a1857600080fd5b50610a216120fe565b60405162ffffff90911681526020016104d2565b348015610a4157600080fd5b506104fb61211c565b348015610a5657600080fd5b506104ae610a65366004615287565b61214a565b348015610a7657600080fd5b50610a8a610a85366004614b5c565b61231b565b6040805182516001600160a01b0316815260209283015162ffffff1692810192909252016104d2565b348015610abf57600080fd5b5061061b610ace366004614d8e565b6123af565b348015610adf57600080fd5b50610a216123e5565b348015610af457600080fd5b5061057263152a902d60e11b81565b348015610b0f57600080fd5b506104c5612413565b348015610b2457600080fd5b506104ae61059b3660046152e0565b348015610b3f57600080fd5b506104ae610b4e36600461532b565b612430565b6104ae610b61366004614cc3565b6124df565b348015610b7257600080fd5b50610b86610b81366004614b5c565b612543565b6040516104d29190615359565b348015610b9f57600080fd5b506104ae610bae366004614ad4565b61264c565b348015610bbf57600080fd5b506104ae610bce366004614ffb565b612724565b348015610bdf57600080fd5b506104ae612746565b348015610bf457600080fd5b5047610572565b348015610c0757600080fd5b506104ae610c163660046153d6565b612765565b348015610c2757600080fd5b506104ae610c36366004614ad4565b6127b2565b348015610c4757600080fd5b50610572610c56366004614b5c565b6127f5565b348015610c6757600080fd5b506104ae610c76366004614b5c565b6128de565b348015610c8757600080fd5b506104c5610c96366004614b5c565b61292e565b348015610ca757600080fd5b506104ae610cb6366004615499565b612a6d565b348015610cc757600080fd5b506104ae610cd63660046154ca565b612b16565b348015610ce757600080fd5b506104ae610cf6366004614d8e565b612b35565b348015610d0757600080fd5b506104ae610d1636600461554d565b612b4c565b348015610d2757600080fd5b5061061b610d36366004614b5c565b612c6b565b348015610d4757600080fd5b50610d5b610d563660046155e5565b612c98565b6040516104d29190600060c0820190508251825260ff6020840151166020830152604083015162ffffff80821660408501526060850151915063ffffffff8083166060860152806080870151166080860152508060a08601511660a0850152505092915050565b348015610dce57600080fd5b506104ae610ddd366004615660565b612d88565b348015610dee57600080fd5b50610a21620f424081565b348015610e0557600080fd5b5061061b610e14366004615739565b612e0e565b348015610e2557600080fd5b506104ae612e4d565b348015610e3a57600080fd5b506104fb7387d59a09ec4053c208980e4e63fcb4de97d2c7bd81565b348015610e6257600080fd5b506104ae610e71366004614ad4565b612e6c565b348015610e8257600080fd5b506104fb612ea4565b348015610e9757600080fd5b50610eab610ea6366004614b5c565b612ec2565b604080519283526020830191909152016104d2565b348015610ecc57600080fd5b506104ae610edb366004614ad4565b612f17565b348015610eec57600080fd5b50610572635b5e139f60e01b81565b610f12600080516020615d76833981519152612f9e565b6000610f1c612fc4565b600f0180546001600160a01b0319166001600160a01b03939093169290921790915550565b60606000610f4d612fc4565b9050806001018054610f5e90615767565b80601f0160208091040260200160405190810160405280929190818152602001828054610f8a90615767565b8015610fd75780601f10610fac57610100808354040283529160200191610fd7565b820191906000526020600020905b815481529060010190602001808311610fba57829003601f168201915b505050505091505090565b6000610fed82612fe8565b61100a57604051630cbdb7b360e41b815260040160405180910390fd5b6000611014612fc4565b905061101f836130ee565b61103c5760405163538fd4df60e01b815260040160405180910390fd5b60009283526005016020525060409020546001600160a01b031690565b8161106381613267565b600061106e83611ae2565b9050336001600160a01b03851614806110a25750336001600160a01b038216148015906110a257506110a08133612e0e565b155b156110c057604051631eb49d6d60e11b815260040160405180910390fd5b6110ca8484613315565b50505050565b6000806110db612fc4565b600901546001600160a01b031692915050565b611105600080516020615d76833981519152612f9e565b61110e81613393565b50565b60008061111c612fc4565b9050600060015b82546001600160401b031681101561115c5761113e816127f5565b61114890836157b7565b91506111556001826157b7565b9050611123565b5092915050565b61117a600080516020615d76833981519152612f9e565b6111826133d2565b505050565b61119e600080516020615d76833981519152612f9e565b60006111a8612fc4565b600e0180546001600160a01b0319166001600160a01b03939093169290921790915550565b826001600160a01b03811633146111e7576111e733613267565b6111f13383613402565b61120e576040516313ff771f60e21b815260040160405180910390fd5b6110ca848484613480565b6000611233600080516020615d76833981519152836123af565b92915050565b600080611244612fc4565b805490915060009061126290600160401b900462ffffff16866157cf565b905061126e84826157b7565b95945050505050565b611286898989898989876134d0565b6112958762ffffff1685613776565b60006112a28a86866137ba565b90506112ad816139f6565b50505050505050505050565b60008060006112c6612fc4565b60098101546040516329c5eaf560e11b815230600482015260248101889052604481018790529192506001600160a01b03169063538bd5ea906064016040805180830381865afa15801561131e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134291906157ee565b92509250505b9250929050565b611366600080516020615d76833981519152612f9e565b6113708282613b5a565b5050565b61137c614a0e565b6000611386612fc4565b80549091506001600160401b03168311156113b457604051631a3973a960e01b815260040160405180910390fd5b6040805160008581526003840160209081528382206101a0840185525462ffffff8082168587019081526301000000830482166060870152600160301b830482166080870152600160481b8304821660a087015263ffffffff600160601b8404811660c0880152600160801b84041660e087015260ff600160a01b84048116610100880152600160a81b840481161515610120880152600160b01b84048316610140880152600160c81b8404909216610160870152600160e01b9092041615156101808501528352868252600b850181529290208054919283019161149890615767565b80601f01602080910402602001604051908101604052809291908181526020018280546114c490615767565b80156115115780601f106114e657610100808354040283529160200191611511565b820191906000526020600020905b8154815290600101906020018083116114f457829003601f168201915b5050505050815250915050919050565b611538600080516020615d76833981519152612f9e565b6000611542612fc4565b60090180546001600160a01b0319166001600160a01b03939093169290921790915550565b6001600160a01b038116331461158f57604051623fff3d60e91b815260040160405180910390fd5b6113708282613bce565b60006115b2600080516020615d76833981519152612f9e565b6115ba6133d2565b9a9950505050505050505050565b826115d281611b3c565b6115ef5760405163589ed34b60e01b815260040160405180910390fd5b6115f7613c40565b600061160285612543565b9050600061160f8661231b565b905061162086868460c00151613c8d565b61162981613d59565b61163c816020015162ffffff1686613776565b60006116498787876137ba565b9050611654816139f6565b61165f878783613d95565b50505050505050565b826001600160a01b03811633146116825761168233613267565b6110ca84848460405180602001604052806000815250612765565b60006116a7612fc4565b905060006116b483611ae2565b90506116c03384613402565b6116dd576040516313ff771f60e21b815260040160405180910390fd5b6116ea8161dead85613eae565b60405183906000906001600160a01b03841690600080516020615d96833981519152908390a4600061171b84612ec2565b5060008181526003850160205260409020805491925060019160069061174e908490600160301b900462ffffff1661581c565b92506101000a81548162ffffff021916908362ffffff16021790555050505050565b611787600080516020615d76833981519152612f9e565b600061179161410c565b905061179c88612543565b506000888888856040516020016117b69493929190615843565b60408051601f19818403018152918152815160209283012060008181529285905291206001015490915060ff16156118015760405163ad983fdf60e01b815260040160405180910390fd5b63ffffffff85161580159061182157508563ffffffff168563ffffffff16105b1561183f57604051633e9d06f360e11b815260040160405180910390fd5b6040805160c08101825294855260ff988916602080870191825262ffffff998a1687840190815263ffffffff998a1660608901908152988a1660808901908152968b1660a08901908152600095865295909152919092209451855590516001909401805491519551935192519490981663ffffffff199091161761010094871694909402939093176bffffffffffffffff000000001916600160201b9185169190910263ffffffff60401b191617600160401b92909316919091029190911762ffffff60601b1916600160601b919092160217905550565b61192e600080516020615d76833981519152612f9e565b611936614130565b565b8261194281611b3c565b61195f5760405163589ed34b60e01b815260040160405180910390fd5b611967613c40565b600061197285612543565b905061198385858360c00151613c8d565b611996816060015162ffffff1685613776565b60006119a38686866137ba565b90506119ae816139f6565b505050505050565b6119cd600080516020615d76833981519152612f9e565b60648211156119ef57604051637e1d76fb60e01b815260040160405180910390fd5b60005b82811015611a3e57611a2b8583868685818110611a1157611a11615880565b9050602002016020810190611a269190614ad4565b6137ba565b5080611a3681615896565b9150506119f2565b5050505050565b600080611a50612fc4565b8054909150611a6a906001906001600160401b03166158af565b6001600160401b031691505090565b600080611a84612fc4565b905060008484604051602001611a9b9291906158d7565b60408051601f1981840301815291815281516020928301206000908152600c9094019091529091205491505092915050565b600080611ad861418b565b5460ff1692915050565b600080611aee836141af565b509392505050565b611b0d600080516020615d76833981519152612f9e565b6000611b17612fc4565b600d0180546001600160a01b0319166001600160a01b03939093169290921790915550565b600080611b4883612543565b90506000816080015163ffffffff16600014158015611b71575042826080015163ffffffff1611155b8015611b98575060a082015163ffffffff161580611b985750428260a0015163ffffffff16115b949350505050565b60005b81811015611182576000838383818110611bbf57611bbf615880565b905060200201359050611bd18161169d565b5080611bdc81615896565b915050611ba3565b600080611bef612fc4565b600e01546001600160a01b031692915050565b600080611c0d612fc4565b6001600160a01b03909316600090815260069093016020525050604090205490565b611c46600080516020615d76833981519152612f9e565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611c93576040519150601f19603f3d011682016040523d82523d6000602084013e611c98565b606091505b505090508061118257604051630f9310f960e01b815260040160405180910390fd5b611cd1600080516020615d76833981519152612f9e565b6000611cdb61410c565b9050611ce68b612543565b5060008b8b8b86604051602001611d009493929190615843565b6040516020818303038152906040528051906020012060001c9050611d23614a2e565b8960ff168c60ff16141580611d4257508862ffffff168b62ffffff1614155b80611d5757508362ffffff168562ffffff1614155b15611f4d576040518060c00160405280878152602001600060ff1681526020018a62ffffff1681526020018963ffffffff1681526020018863ffffffff1681526020018562ffffff168152508360000160008481526020019081526020016000206000820151816000015560208201518160010160006101000a81548160ff021916908360ff16021790555060408201518160010160016101000a81548162ffffff021916908362ffffff16021790555060608201518160010160046101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160086101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600101600c6101000a81548162ffffff021916908362ffffff1602179055509050508c8a8a86604051602001611e959493929190615843565b60408051808303601f1901815291815281516020928301206000818152868452829020845181559284015160019093018054928501516060860151608087015160a088015160ff90971663ffffffff199096169590951761010062ffffff93841602176bffffffffffffffff000000001916600160201b63ffffffff9283160263ffffffff60401b191617600160401b91909516029390931762ffffff60601b1916600160601b939094169290920292909217905591505b63ffffffff871615801590611f6d57508763ffffffff168763ffffffff16105b15611f8b57604051633e9d06f360e11b815260040160405180910390fd5b506040805160c08101825295865260ff998a16602080880191825262ffffff9a8b1688840190815263ffffffff9a8b1660608a01908152998b1660808a01908152968c1660a08a01908152600095865295909152919092209551865590516001909501805491519651935192518916600160601b0262ffffff60601b19938916600160401b0263ffffffff60401b1995909916600160201b02949094166bffffffffffffffff0000000019979099166101000263ffffffff19909216959099169490941793909317939093169490941792909217919091161790915550505050565b606080600061207a612fc4565b6009810154604051632e44189760e11b81529192506001600160a01b031690635c88312e906120af9030908890600401614d75565b600060405180830381865afa1580156120cc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120f49190810190615958565b9250925050915091565b600080612109612fc4565b54600160401b900462ffffff1692915050565b7fcb8952d7e709d77cf862c59597b58044638bae7291440245a00835d98a0e72b3546001600160a01b031690565b8361215481611b3c565b6121715760405163589ed34b60e01b815260040160405180910390fd5b612179613c40565b6000612183612fc4565b9050600061219087612543565b905080610100015162ffffff16600014806121a9575083155b156121c757604051630713314160e01b815260040160405180910390fd5b6101208101516000906121df9062ffffff1686615a32565b90508662ffffff1681101561220757604051630713314160e01b815260040160405180910390fd5b6000883360405160200161221c9291906158d7565b6040516020818303038152906040528051906020012060001c90508260c0015160ff166000146122915760c08301516000828152600c8601602052604090205460ff909116906122729062ffffff8b16906157b7565b111561229157604051635ac0a89b60e11b815260040160405180910390fd5b6000818152600c850160205260408120805462ffffff8b1692906122b69084906157b7565b90915550600090505b888461012001516122d09190615a46565b62ffffff1681101561230f576122fd8888838181106122f1576122f1615880565b9050602002013561169d565b8061230781615896565b9150506122bf565b506112ad8989336137ba565b60408051808201909152600080825260208201526000612339612fc4565b80549091506001600160401b031683111561236757604051631a3973a960e01b815260040160405180910390fd5b60408051808201825260008581526010939093016020818152928420546001600160a01b038116835295909352918152600160a01b90930462ffffff16928101929092525090565b6000806123ba614212565b6000948552602090815260408086206001600160a01b03959095168652939052505090205460ff1690565b6000806123f0612fc4565b805490915061240d90600190600160401b900462ffffff16615a71565b91505090565b6060600061241f612fc4565b9050806002018054610f5e90615767565b8161243a81613267565b336001600160a01b0384160361246357604051631eb49d6d60e11b815260040160405180910390fd5b600061246d612fc4565b33600081815260078301602090815260408083206001600160a01b038a1680855290835292819020805460ff1916891515908117909155905190815293945090927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a350505050565b60006124ea8a61231b565b90506124fb8a8a8a8a8a8a886134d0565b61250481613d59565b6125138262ffffff1686613776565b60006125208b87876137ba565b905061252b816139f6565b6125368b8783613d95565b5050505050505050505050565b61254b614a63565b6000612555612fc4565b80549091506001600160401b031683111561258357604051631a3973a960e01b815260040160405180910390fd5b60009283526003016020908152604092839020835161016081018552905462ffffff808216835263010000008204811693830193909352600160301b8104831694820194909452600160481b84048216606082015263ffffffff600160601b850481166080830152600160801b85041660a082015260ff600160a01b8504811660c0830152600160a81b85048116151560e0830152600160b01b85048316610100830152600160c81b8504909216610120820152600160e01b9093041615156101408301525090565b612663600080516020615d76833981519152612f9e565b600061266d614236565b905060005b81548110156126f05781600001818154811061269057612690615880565b6000918252602090912001546001600160a01b03908116908416036126de578160000181815481106126c4576126c4615880565b600091825260209091200180546001600160a01b03191690555b6126e96001826157b7565b9050612672565b508054600181018255600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055565b61273b600080516020615d76833981519152612f9e565b6110ca8383836137ba565b61275d600080516020615d76833981519152612f9e565b61193661425a565b836001600160a01b038116331461277f5761277f33613267565b6127893384613402565b6127a657604051631eb49d6d60e11b815260040160405180910390fd5b611a3e858585856142a7565b6127c9600080516020615d76833981519152612f9e565b60006127d36142be565b80546001600160a01b0319166001600160a01b03939093169290921790915550565b600080612800612fc4565b6000848152600382016020908152604091829020825161016081018452905462ffffff8082168352630100000082048116938301849052600160301b82048116948301859052600160481b82048116606084015263ffffffff600160601b830481166080850152600160801b83041660a084015260ff600160a01b8304811660c0850152600160a81b83048116151560e0850152600160b01b83048216610100850152600160c81b8304909116610120840152600160e01b9091041615156101408201529293506128d19190615a71565b62ffffff16949350505050565b6128f5600080516020615d76833981519152612f9e565b60006128ff612fc4565b60009283526003016020525060409020805460ff60e01b198116600160e01b9182900460ff1615909102179055565b606061293982612fe8565b61295657604051630cbdb7b360e41b815260040160405180910390fd5b6000612960612fc4565b9050600061296d84612ec2565b509050600061297b82612543565b90508060e00151156129ca576000828152600b8401602052604090206129a0866142e2565b6040516020016129b1929190615a8d565b6040516020818303038152906040529350505050919050565b6000828152600b84016020526040902080546129e590615767565b80601f0160208091040260200160405190810160405280929190818152602001828054612a1190615767565b8015612a5e5780601f10612a3357610100808354040283529160200191612a5e565b820191906000526020600020905b815481529060010190602001808311612a4157829003601f168201915b50505050509350505050919050565b836001600160a01b0381163314612a8757612a8733613267565b60005b828110156119ae57612ab433858584818110612aa857612aa8615880565b90506020020135613402565b612ad157604051631eb49d6d60e11b815260040160405180910390fd5b612b048686868685818110612ae857612ae8615880565b9050602002013560405180602001604052806000815250612765565b80612b0e81615896565b915050612a8a565b612b2d600080516020615d76833981519152612f9e565b61165f6133d2565b61158f600080516020615d76833981519152612f9e565b7fe64551584c98548d769652536a405149aacacb81302f284a40bda60ebfbfbd3b805460ff1615612b8f5760405162dc149f60e41b815260040160405180910390fd5b6000612b99612fc4565b905060018101612baa898b83615b51565b5060028101612bba878983615b51565b506009810180546001600160a01b038087166001600160a01b031992831617909255600d830180549286169290911691909117905580546a0f424000000000000000016affffffffffffffffffffff19909116178155612c28600080516020615d7683398151915286613b5a565b612c31856143e2565b612c4e73dab1a1854214684ace522439684a145e62505233613393565b612c5661440a565b50805460ff1916600117905550505050505050565b600080612c76612fc4565b6000938452600401602052505060409020546001600160a01b031661dead1490565b612ca0614a2e565b6000612caa61410c565b9050612cb586612543565b50600086868686604051602001612ccf9493929190615843565b60408051601f19818403018152918152815160209283012060008181529285905290822060018101549193509160ff9091169003612d205760405163c5723b5160e01b815260040160405180910390fd5b6040805160c0810182528254815260019092015460ff8116602084015262ffffff610100820481169284019290925263ffffffff600160201b820481166060850152600160401b8204166080840152600160601b90041660a082015292505050949350505050565b612d9f600080516020615d76833981519152612f9e565b6000612da9612fc4565b600981015460405163dfc9f91360e01b81529192506001600160a01b03169063dfc9f91390612de090309033908790600401615c10565b600060405180830381600087803b158015612dfa57600080fd5b505af11580156119ae573d6000803e3d6000fd5b600080612e19612fc4565b6001600160a01b03948516600090815260079190910160209081526040808320959096168252939093525050205460ff1690565b612e64600080516020615d76833981519152612f9e565b61193661440a565b612e74614484565b6001600160a01b038116612e9b57604051633a247dd760e11b815260040160405180910390fd5b61110e816144b4565b600080612eaf612fc4565b600d01546001600160a01b031692915050565b6000806000612ecf612fc4565b8054909150612eea90600160401b900462ffffff1685615a32565b8154909350612f0590600160401b900462ffffff16846157cf565b612f0f9085615c93565b915050915091565b612f2e600080516020615d76833981519152612f9e565b60006001600160a01b03821647604051600081818185875af1925050503d8060008114612f77576040519150601f19603f3d011682016040523d82523d6000602084013e612f7c565b606091505b505090508061137057604051630f9310f960e01b815260040160405180910390fd5b612fa881336123af565b61110e57604051623fff3d60e91b815260040160405180910390fd5b7fbc7d0e8ed4dcaf65aa37ff076afe36b4e8fbc0e9b704cfd2ecde67415414d07a90565b6000806000612ff684612ec2565b9150915061300384612c6b565b15613012575060009392505050565b600061301c612fc4565b60009384526003016020908152604093849020845161016081018652905462ffffff8082168352630100000082048116938301849052600160301b8204811696830196909652600160481b81048616606083015263ffffffff600160601b820481166080840152600160801b82041660a083015260ff600160a01b8204811660c0840152600160a81b82048116151560e0840152600160b01b82048716610100840152600160c81b8204909616610120830152600160e01b900490941615156101409094019390935250111592915050565b6000806130f9612fc4565b9050600061310684612ec2565b506000818152600384016020908152604091829020825161016081018452905462ffffff808216835263010000008204811693830193909352600160301b8104831693820193909352600160481b83048216606082015263ffffffff600160601b840481166080830152600160801b84041660a082015260ff600160a01b8404811660c0830152600160a81b84048116151560e0830152600160b01b84048316610100830152600160c81b8404909216610120820152600160e01b909204161580156101408301529192509061325c57600e830154604051633c29490960e21b8152600481018790526000916001600160a01b03169063f0a5242490602401602060405180830381865afa158015613222573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132469190615caa565b9050801561325a5750600095945050505050565b505b506001949350505050565b60006132716142be565b80549091506001600160a01b03163b15611370578054604051633185c44d60e21b81523060048201526001600160a01b0384811660248301529091169063c617113490604401602060405180830381865afa1580156132d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132f89190615caa565b61137057604051631eb49d6d60e11b815260040160405180910390fd5b600061331f612fc4565b6000838152600582016020526040902080546001600160a01b0319166001600160a01b038616908117909155909150829061335982611ae2565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600061339d614236565b8054600181018255600091825260209091200180546001600160a01b0319166001600160a01b03939093169290921790915550565b60006133dc61450d565b90503660008037600080366000845af43d6000803e8080156133fd573d6000f35b3d6000fd5b600061340d82612fe8565b61342a57604051630cbdb7b360e41b815260040160405180910390fd5b600061343583611ae2565b9050806001600160a01b0316846001600160a01b031614806134705750836001600160a01b031661346584610fe2565b6001600160a01b0316145b80611b985750611b988185612e0e565b61348b838383614580565b613496600082613315565b80826001600160a01b0316846001600160a01b0316600080516020615d9683398151915260405160405180910390a4611182838383613eae565b60006134da612fc4565b905060006134ea89898986612c98565b9050600089336040516020016135019291906158d7565b6040516020818303038152906040528051906020012060001c9050816020015160ff168562ffffff1684600c0160008481526020019081526020016000205461354a91906157b7565b111561356957604051635ac0a89b60e11b815260040160405180910390fd5b606082015163ffffffff1615806135895750816060015163ffffffff1642105b156135a75760405163589ed34b60e01b815260040160405180910390fd5b608082015163ffffffff16158015906135c95750816080015163ffffffff1642115b156135e75760405163589ed34b60e01b815260040160405180910390fd5b6040516001600160601b03193360601b16602082015260009060340160405160208183030381529060405280519060200120905061366461365e89898080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050875191508590506145a6565b156145be565b6136a488888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050865191508490506145a6565b1580156137215750600d8401546040516370a0823160e01b81526001600160a01b03909116906370a08231906136de903390600401614b75565b602060405180830381865afa1580156136fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061371f9190615cc7565b155b1561373f57604051630b094f2760e31b815260040160405180910390fd5b6000828152600c850160205260408120805462ffffff891692906137649084906157b7565b90915550505050505050505050505050565b60006137898366038d7ea4c680006157cf565b90503461379b62ffffff8416836157cf565b11156111825760405163356680b760e01b815260040160405180910390fd5b6000806137c5612fc4565b600086815260038201602052604081208054929350916137f2906301000000900462ffffff16600161581c565b835462ffffff9190911691506001600160401b031687111561382757604051631a3973a960e01b815260040160405180910390fd5b62ffffff8616158061384057506001600160a01b038516155b1561385e5760405163b732d5e160e01b815260040160405180910390fd5b815462ffffff1681111561388557604051631f6e464360e31b815260040160405180910390fd5b61388f8782611239565b825490945062ffffff808216916138af918991630100000090041661581c565b62ffffff1611156138d357604051631f6e464360e31b815260040160405180910390fd5b8154869083906003906138f39084906301000000900462ffffff1661581c565b82546101009290920a62ffffff818102199093169190921691909102179055506000848152600484016020526040902080546001600160a01b0319166001600160a01b03871617905561394960088401856145ff565b6001600160a01b03851660009081526006840160205260408120805462ffffff891692906139789084906157b7565b909155508490505b61398f62ffffff8816866157b7565b8110156139eb5760405181906001600160a01b03881690600090600080516020615d96833981519152908290a46139d8600087836040518060200160405280600081525061462b565b50806139e381615896565b915050613980565b505050509392505050565b6000613a00612fc4565b6009810154604051632e44189760e11b815291925060009182916001600160a01b031690635c88312e90613a3a9030908890600401614d75565b600060405180830381865afa158015613a57573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613a7f9190810190615958565b8151919350915060005b818110156119ae576000613ab634858481518110613aa957613aa9615880565b602002602001015161472a565b90506000858381518110613acc57613acc615880565b60200260200101516001600160a01b03168260405160006040518083038185875af1925050503d8060008114613b1e576040519150601f19603f3d011682016040523d82523d6000602084013e613b23565b606091505b5050905080613b4557604051630f9310f960e01b815260040160405180910390fd5b50508080613b5290615896565b915050613a89565b6000613b64614212565b9050613b7083836123af565b611182576000838152602082815260408083206001600160a01b0386168085529252808320805460ff1916600117905551339286917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a4505050565b6000613bd8614212565b9050613be483836123af565b15611182576000838152602082815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4505050565b613c48611acd565b156119365760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064015b60405180910390fd5b6000613c97612fc4565b905060ff821615801590613cb05750613cae614743565b155b156110ca5760008433604051602001613cca9291906158d7565b60408051601f1981840301815291815281516020928301206000818152600c860190935291205490915060ff841690613d099062ffffff8716906157b7565b1115613d2857604051635ac0a89b60e11b815260040160405180910390fd5b6000818152600c830160205260408120805462ffffff87169290613d4d9084906157b7565b90915550505050505050565b80516001600160a01b03161580613d775750602081015162ffffff16155b1561110e576040516306d423a960e21b815260040160405180910390fd5b6000613d9f612fc4565b60008581526010820160205260408120549192506001600160a01b039091169062ffffff85166001600160401b03811115613ddc57613ddc615368565b604051908082528060200260200182016040528015613e05578160200160208202803683370190505b50905060005b8562ffffff16811015613e5157613e2281866157b7565b828281518110613e3457613e34615880565b602090810291909101015280613e4981615896565b915050613e0b565b50604051630adf035760e41b81526001600160a01b0383169063adf0357090613e809032908590600401615ce0565b600060405180830381600087803b158015613e9a57600080fd5b505af11580156112ad573d6000803e3d6000fd5b6000613eb8612fc4565b90506000613ec5836141af565b9150506000613ed384611ae2565b9050856001600160a01b0316816001600160a01b031614613f07576040516313ff771f60e21b815260040160405180910390fd5b6000613f148560016157b7565b90506000613f2182612ec2565b9150506000613f2f87612ec2565b506000818152600388016020908152604091829020825161016081018452905462ffffff80821680845263010000008304821694840194909452600160301b8204811694830194909452600160481b81048416606083015263ffffffff600160601b820481166080840152600160801b82041660a083015260ff600160a01b8204811660c0840152600160a81b82048116151560e0840152600160b01b82048516610100840152600160c81b8204909416610120830152600160e01b900490921615156101408301529192509083118015906140285750600884811c60009081529088016020526040902054600160ff1b60ff86161c16155b15614063576000848152600488016020526040902080546001600160a01b0319166001600160a01b038c1617905561406360088801856145ff565b6000888152600488016020526040902080546001600160a01b0319166001600160a01b038b161790558588146140a0576140a060088801896145ff565b6001600160a01b038916600090815260068801602052604081208054600192906140cb9084906157b7565b90915550506001600160a01b038a16600090815260068801602052604081208054600192906140fb908490615c93565b909155505050505050505050505050565b7f5cdb56131f6a8cb8897cc0bafef07a5b2973e186f281253cea0806ea1443c13e90565b614138613c40565b600061414261418b565b805460ff191660011781556040519091507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890614180903390614b75565b60405180910390a150565b7f2ce935bb7ebbf5d9759d0bf10b40148186ea48e69aeea9281cb4f3267f07abf390565b6000806141bb83612fe8565b6141d857604051630cbdb7b360e41b815260040160405180910390fd5b60006141e2612fc4565b90506141ed846147b0565b600081815260049092016020526040909120546001600160a01b031694909350915050565b7f8113889f0b868eeca4f3f98876bebc5d45f78186a7ac12c94ed39d8b17ef258e90565b7f92140bce112f095179820a95d551eb064f38e1596fa0b63a05d6960156840a9a90565b6142626147f5565b600061426c61418b565b805460ff191681556040519091507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90614180903390614b75565b6142b2848484613480565b611a3e8484848461462b565b7fd1c7a1698d3d2d2fdb5cc2360b499ff16d810b81a494d1feedda8dbe4b67fb7890565b6060816000036143095750506040805180820190915260018152600360fc1b602082015290565b8160005b8115614333578061431d81615896565b915061432c9050600a83615a32565b915061430d565b6000816001600160401b0381111561434d5761434d615368565b6040519080825280601f01601f191660200182016040528015614377576020820181803683370190505b5090505b8415611b985761438c600183615c93565b9150614399600a86615d04565b6143a49060306157b7565b60f81b8183815181106143b9576143b9615880565b60200101906001600160f81b031916908160001a9053506143db600a86615a32565b945061437b565b60007fcb8952d7e709d77cf862c59597b58044638bae7291440245a00835d98a0e72b36127d3565b60006144146142be565b80546001600160a01b0319166daaeb6d7670e522a718067333cd4e9081178255909150803b1561137057604051633e9f1edf60e11b8152306004820152733cc6cdda760b79bafa08df41ecfa224f810dceb660248201526001600160a01b03821690637d3e3dbe90604401612de0565b3361448d61211c565b6001600160a01b03161461193657604051636db2465f60e01b815260040160405180910390fd5b60006144be61211c565b90506144c9826143e2565b816001600160a01b0316816001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080614518612fc4565b600f8101549091506001600160a01b03161561454057600f01546001600160a01b0316919050565b4662aa36a703614565577387d59a09ec4053c208980e4e63fcb4de97d2c7bd91505090565b73e291354a3aeb7eb49da0f1333d667f17fa33f1c591505090565b614589816130ee565b6111825760405163538fd4df60e01b815260040160405180910390fd5b6000826145b38584614840565b1490505b9392505050565b604051811515602482015261110e9060440160408051601f198184030181529190526020810180516001600160e01b03166332458eed60e01b179052614885565b600881901c600090815260209290925260409091208054600160ff1b60ff9093169290921c9091179055565b60006001600160a01b0384163b1561472257604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061466f903390899088908890600401615d18565b6020604051808303816000875af19250505080156146aa575060408051601f3d908101601f191682019092526146a791810190615d4b565b60015b614708573d8080156146d8576040519150601f19603f3d011682016040523d82523d6000602084013e6146dd565b606091505b50805160000361470057604051630568cbab60e01b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611b98565b506001611b98565b600061271061473983856157cf565b6145b79190615a32565b60008061474e614236565b905060005b81548110156147a75781600001818154811061477157614771615880565b6000918252602090912001546001600160a01b031633036147955760019250505090565b6147a06001826157b7565b9050614753565b50600091505090565b6000806147bb612fc4565b905060006147c884612ec2565b508254909150611b989085906147ea90600160401b900462ffffff16846157cf565b60088501919061488e565b6147fd611acd565b6119365760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401613c84565b600081815b8451811015611aee576148718286838151811061486457614864615880565b602002602001015161493c565b91508061487d81615896565b915050614845565b61110e8161496b565b600882811c600081815260208690526040812054909284901c9060ff808716919082181c80156148d7576148c18161498c565b60ff168203600885901b179450505050506145b7565b828410156148f857604051630f78a15d60e31b815260040160405180910390fd5b506000199092016000818152602088905260409020549092908015614937576149208161498c565b60ff0360ff16600885901b179450505050506145b7565b6148d7565b60008183106149585760008281526020849052604090206145b7565b60008381526020839052604090206145b7565b60006a636f6e736f6c652e6c6f679050600080835160208501845afa505050565b60006040518061012001604052806101008152602001615db6610100913960f87e818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff6149d5856149f6565b02901c815181106149e8576149e8615880565b016020015160f81c92915050565b6000808211614a0457600080fd5b5060008190031690565b6040518060400160405280614a21614a63565b8152602001606081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915290565b6001600160a01b038116811461110e57600080fd5b600060208284031215614ae657600080fd5b81356145b781614abf565b60005b83811015614b0c578181015183820152602001614af4565b838111156110ca5750506000910152565b60008151808452614b35816020860160208601614af1565b601f01601f19169290920160200192915050565b6020815260006145b76020830184614b1d565b600060208284031215614b6e57600080fd5b5035919050565b6001600160a01b0391909116815260200190565b60008060408385031215614b9c57600080fd5b8235614ba781614abf565b946020939093013593505050565b803562ffffff81168114614bc857600080fd5b919050565b600080600060608486031215614be257600080fd5b833592506020840135614bf481614abf565b9150614c0260408501614bb5565b90509250925092565b600080600060608486031215614c2057600080fd5b8335614c2b81614abf565b92506020840135614c3b81614abf565b929592945050506040919091013590565b60008060408385031215614c5f57600080fd5b50508035926020909101359150565b803560ff81168114614bc857600080fd5b60008083601f840112614c9157600080fd5b5081356001600160401b03811115614ca857600080fd5b6020830191508360208260051b850101111561134857600080fd5b60008060008060008060008060006101008a8c031215614ce257600080fd5b89359850614cf260208b01614c6e565b9750614d0060408b01614bb5565b965060608a01356001600160401b03811115614d1b57600080fd5b614d278c828d01614c7f565b9097509550614d3a905060808b01614bb5565b935060a08a0135614d4a81614abf565b9250614d5860c08b01614bb5565b9150614d6660e08b01614bb5565b90509295985092959850929598565b6001600160a01b03929092168252602082015260400190565b60008060408385031215614da157600080fd5b823591506020830135614db381614abf565b809150509250929050565b805162ffffff1682526020810151614ddd602084018262ffffff169052565b506040810151614df4604084018262ffffff169052565b506060810151614e0b606084018262ffffff169052565b506080810151614e23608084018263ffffffff169052565b5060a0810151614e3b60a084018263ffffffff169052565b5060c0810151614e5060c084018260ff169052565b5060e0810151614e6460e084018215159052565b506101008181015162ffffff81168483015250506101208181015162ffffff811684830152505061014081810151801515848301526110ca565b60208152614eb0602082018351614dbe565b602082015161018082810152600090611b986101a0840182614b1d565b60008083601f840112614edf57600080fd5b5081356001600160401b03811115614ef657600080fd5b60208301915083602082850101111561134857600080fd5b803563ffffffff81168114614bc857600080fd5b801515811461110e57600080fd5b6000806000806000806000806000806101208b8d031215614f5057600080fd5b8a356001600160401b03811115614f6657600080fd5b614f728d828e01614ecd565b909b509950614f85905060208c01614bb5565b9750614f9360408c01614bb5565b9650614fa160608c01614f0e565b9550614faf60808c01614f0e565b9450614fbd60a08c01614c6e565b935060c08b0135614fcd81614f22565b9250614fdb60e08c01614c6e565b9150614fea6101008c01614c6e565b90509295989b9194979a5092959850565b60008060006060848603121561501057600080fd5b8335925061502060208501614bb5565b9150604084013561503081614abf565b809150509250925092565b600080600080600080600060e0888a03121561505657600080fd5b8735965061506660208901614c6e565b955061507460408901614bb5565b945061508260608901614f0e565b935061509060808901614f0e565b925060a088013591506150a560c08901614bb5565b905092959891949750929550565b600080600080606085870312156150c957600080fd5b8435935060208501356001600160401b038111156150e657600080fd5b6150f287828801614c7f565b9094509250615105905060408601614bb5565b905092959194509250565b6000806020838503121561512357600080fd5b82356001600160401b0381111561513957600080fd5b61514585828601614c7f565b90969095509350505050565b6000806000806000806000806000806101408b8d03121561517157600080fd5b8a35995061518160208c01614c6e565b985061518f60408c01614bb5565b975061519d60608c01614c6e565b96506151ab60808c01614bb5565b95506151b960a08c01614f0e565b94506151c760c08c01614f0e565b935060e08b013592506151dd6101008c01614bb5565b9150614fea6101208c01614bb5565b600081518084526020808501945080840160005b8381101561521c57815187529582019590820190600101615200565b509495945050505050565b604080825283519082018190526000906020906060840190828701845b828110156152695781516001600160a01b031684529284019290840190600101615244565b5050508381038285015261527d81866151ec565b9695505050505050565b6000806000806060858703121561529d57600080fd5b843593506152ad60208601614bb5565b925060408501356001600160401b038111156152c857600080fd5b6152d487828801614c7f565b95989497509550505050565b6000806000604084860312156152f557600080fd5b8335925060208401356001600160401b0381111561531257600080fd5b61531e86828701614ecd565b9497909650939450505050565b6000806040838503121561533e57600080fd5b823561534981614abf565b91506020830135614db381614f22565b61016081016112338284614dbe565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156153a0576153a0615368565b60405290565b604051601f8201601f191681016001600160401b03811182821017156153ce576153ce615368565b604052919050565b600080600080608085870312156153ec57600080fd5b84356153f781614abf565b935060208581013561540881614abf565b93506040860135925060608601356001600160401b038082111561542b57600080fd5b818801915088601f83011261543f57600080fd5b81358181111561545157615451615368565b615463601f8201601f191685016153a6565b9150808252898482850101111561547957600080fd5b808484018584013760008482840101525080935050505092959194509250565b600080600080606085870312156154af57600080fd5b84356154ba81614abf565b935060208501356152ad81614abf565b600080600080600080600060e0888a0312156154e557600080fd5b873596506154f560208901614bb5565b955061550360408901614f0e565b945061551160608901614f0e565b935061551f60808901614c6e565b925061552d60a08901614bb5565b915060c088013561553d81614f22565b8091505092959891949750929550565b600080600080600080600060a0888a03121561556857600080fd5b87356001600160401b038082111561557f57600080fd5b61558b8b838c01614ecd565b909950975060208a01359150808211156155a457600080fd5b506155b18a828b01614ecd565b90965094505060408801356155c581614abf565b925060608801356155d581614abf565b9150608088013561553d81614abf565b600080600080608085870312156155fb57600080fd5b8435935061560b60208601614c6e565b925061561960408601614bb5565b915061510560608601614bb5565b60006001600160401b0382111561564057615640615368565b5060051b60200190565b803565ffffffffffff81168114614bc857600080fd5b6000602080838503121561567357600080fd5b82356001600160401b0381111561568957600080fd5b8301601f8101851361569a57600080fd5b80356156ad6156a882615627565b6153a6565b818152606091820283018401918482019190888411156156cc57600080fd5b938501935b8385101561572d5780858a0312156156e95760008081fd5b6156f161537e565b85356156fc81614abf565b815261570986880161564a565b87820152604061571a81880161564a565b90820152835293840193918501916156d1565b50979650505050505050565b6000806040838503121561574c57600080fd5b823561575781614abf565b91506020830135614db381614abf565b600181811c9082168061577b57607f821691505b60208210810361579b57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b600082198211156157ca576157ca6157a1565b500190565b60008160001904831182151516156157e9576157e96157a1565b500290565b6000806040838503121561580157600080fd5b825161580c81614abf565b6020939093015192949293505050565b600062ffffff80831681851680830382111561583a5761583a6157a1565b01949350505050565b93845260f89290921b6001600160f81b031916602084015260e890811b6001600160e81b0319908116602185015291901b16602482015260270190565b634e487b7160e01b600052603260045260246000fd5b6000600182016158a8576158a86157a1565b5060010190565b60006001600160401b03838116908316818110156158cf576158cf6157a1565b039392505050565b91825260601b6001600160601b031916602082015260340190565b600082601f83011261590357600080fd5b815160206159136156a883615627565b82815260059290921b8401810191818101908684111561593257600080fd5b8286015b8481101561594d5780518352918301918301615936565b509695505050505050565b6000806040838503121561596b57600080fd5b82516001600160401b038082111561598257600080fd5b818501915085601f83011261599657600080fd5b815160206159a66156a883615627565b82815260059290921b840181019181810190898411156159c557600080fd5b948201945b838610156159ec5785516159dd81614abf565b825294820194908201906159ca565b91880151919650909350505080821115615a0557600080fd5b50615a12858286016158f2565b9150509250929050565b634e487b7160e01b600052601260045260246000fd5b600082615a4157615a41615a1c565b500490565b600062ffffff80831681851681830481118215151615615a6857615a686157a1565b02949350505050565b600062ffffff838116908316818110156158cf576158cf6157a1565b6000808454615a9b81615767565b60018281168015615ab35760018114615ac857615af7565b60ff1984168752821515830287019450615af7565b8860005260208060002060005b85811015615aee5781548a820152908401908201615ad5565b50505082870194505b50505050835161583a818360208801614af1565b601f82111561118257600081815260208120601f850160051c81016020861015615b325750805b601f850160051c820191505b818110156119ae57828155600101615b3e565b6001600160401b03831115615b6857615b68615368565b615b7c83615b768354615767565b83615b0b565b6000601f841160018114615bb05760008515615b985750838201355b600019600387901b1c1916600186901b178355611a3e565b600083815260209020601f19861690835b82811015615be15786850135825560209485019460019092019101615bc1565b5086821015615bfe5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6000606080830160018060a01b03808816855260208188168187015260408481880152838851808652608089019150838a01955060005b81811015615c825786518051871684528581015165ffffffffffff908116878601529085015116848401529584019591870191600101615c47565b50909b9a5050505050505050505050565b600082821015615ca557615ca56157a1565b500390565b600060208284031215615cbc57600080fd5b81516145b781614f22565b600060208284031215615cd957600080fd5b5051919050565b6001600160a01b0383168152604060208201819052600090611b98908301846151ec565b600082615d1357615d13615a1c565b500690565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061527d90830184614b1d565b600060208284031215615d5d57600080fd5b81516001600160e01b0319811681146145b757600080fdfeea8e1b953cb200117b202dd78c6958f9c14d952d5bdaa146141d2a5f9ee220dbddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8a2646970667358221220f77fca2882af9dfdf4dc60225056e54ed000b2e0fd32c3c1dce8b98fb9733ca064736f6c634300080f0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.