Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
17794282 | 347 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
BurnRedeemLib
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 150 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; ///////////////////////////////////////////////////////////////////////////////////// // // // // // .%(#. // // #(((#%, // // (#(((((#%* // // /#((((((((##* // // (#((((((((((##%. // // ,##(/*/(////((((#%* // // .###(//****/////(((##%, // // (, ,%#((((((///******/////((##%( // // *((, ,##(///////*********////((###%* // // /(((( ,##(//////************/(((((###% // // /(((( ,##((////***************/((((###% // // ((( .###((///*****************((((#### // // . (##((//*******************((((##%* // // (#. .###((/********************((((##%. %. // // ,%(#. .###(/********,,,,,,,*****/(((###%# ((%, // // /%#/(/ /###(//****,,,,,,,,,,,****/((((((##%%%%#((#%. // // /##(//(#. ,###((/****,,,,,,,,,,,,,***/((/(((((((((#####% // // *%##(/////((###((((/***,,,,,,,,,,,,,,,***//((((((((((####%%%/ // // ####(((//////(//////**,,,,,,.....,,,,,,****/(((((//((####%%%% // // .####(((/((((((/////**,,,,,.......,,,,,,,,*****/////(#####%%%% // // .#%###((////(((//***,,,,,,..........,,,,,,,,*****//((#####%%%% // // /%%%###/////*****,,,,,,,..............,,,,,,,****/(((####%%%% // // /%%###(////****,,,,,,..... ......,,,,,,**(((####%%%% // // ,#%###(///****,,,,,.... .....,,,,,***/(/(##%%( // // (####(//****,,.... ....,,,,,***/(#### // // (###(/***,,,... ...,,,,***(##/ // // #. (#((/**,,,,.. ...,,,,*((#, // // ,#(##(((//,,,,.. ...,,,*/(((#((/ // // *#(((///*,,.... ....,*//(((( // // *(///***,.... ...,***//, // // ,//***,... ..,,*, // // // // // ///////////////////////////////////////////////////////////////////////////////////// import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import "./IBurnRedeemCore.sol"; /** * @title Burn Redeem Lib * @author manifold.xyz * @notice Library for Burn Redeem shared extensions. */ library BurnRedeemLib { event BurnRedeemInitialized(address indexed creatorContract, uint256 indexed instanceId, address initializer); event BurnRedeemUpdated(address indexed creatorContract, uint256 indexed instanceId); event BurnRedeemMint(address indexed creatorContract, uint256 indexed instanceId, uint256 indexed tokenId, uint32 redeemedCount, bytes data); error BurnRedeemAlreadyInitialized(); error InvalidBurnItem(); error InvalidBurnToken(); error InvalidMerkleProof(); error InvalidStorageProtocol(); error InvalidPaymentReceiver(); error InvalidDates(); error InvalidInput(); /** * Initialiazes a burn redeem with base parameters */ function initialize( address creatorContractAddress, uint8 creatorContractVersion, uint256 instanceId, IBurnRedeemCore.BurnRedeem storage burnRedeemInstance, IBurnRedeemCore.BurnRedeemParameters calldata burnRedeemParameters ) public { // Sanity checks if (burnRedeemInstance.storageProtocol != IBurnRedeemCore.StorageProtocol.INVALID) { revert BurnRedeemAlreadyInitialized(); } _validateParameters(burnRedeemParameters); // Create the burn redeem burnRedeemInstance.contractVersion = creatorContractVersion; _setParameters(burnRedeemInstance, burnRedeemParameters); _setBurnGroups(burnRedeemInstance, burnRedeemParameters.burnSet); emit BurnRedeemInitialized(creatorContractAddress, instanceId, msg.sender); } /** * Updates a burn redeem with base parameters */ function update( address creatorContractAddress, uint256 instanceId, IBurnRedeemCore.BurnRedeem storage burnRedeemInstance, IBurnRedeemCore.BurnRedeemParameters calldata burnRedeemParameters ) public { // Sanity checks if (burnRedeemInstance.storageProtocol == IBurnRedeemCore.StorageProtocol.INVALID) { revert IBurnRedeemCore.BurnRedeemDoesNotExist(instanceId); } _validateParameters(burnRedeemParameters); // The current redeemedCount must be divisible by redeemAmount if (burnRedeemInstance.redeemedCount % burnRedeemParameters.redeemAmount != 0) { revert IBurnRedeemCore.InvalidRedeemAmount(); } // Overwrite the existing burnRedeem _setParameters(burnRedeemInstance, burnRedeemParameters); _setBurnGroups(burnRedeemInstance, burnRedeemParameters.burnSet); syncTotalSupply(burnRedeemInstance); emit BurnRedeemUpdated(creatorContractAddress, instanceId); } /** * Helper to update total supply if redeemedCount exceeds totalSupply after airdrop or instance update. */ function syncTotalSupply(IBurnRedeemCore.BurnRedeem storage burnRedeemInstance) public { if ( burnRedeemInstance.totalSupply != 0 && burnRedeemInstance.redeemedCount > burnRedeemInstance.totalSupply ) { burnRedeemInstance.totalSupply = burnRedeemInstance.redeemedCount; } } /* * Helper to validate burn item */ function validateBurnItem(IBurnRedeemCore.BurnItem memory burnItem, address contractAddress, uint256 tokenId, bytes32[] memory merkleProof) public pure { if (burnItem.validationType == IBurnRedeemCore.ValidationType.ANY) { return; } if (contractAddress != burnItem.contractAddress) { revert InvalidBurnToken(); } if (burnItem.validationType == IBurnRedeemCore.ValidationType.CONTRACT) { return; } else if (burnItem.validationType == IBurnRedeemCore.ValidationType.RANGE) { if (tokenId < burnItem.minTokenId || tokenId > burnItem.maxTokenId) { revert IBurnRedeemCore.InvalidToken(tokenId); } return; } else if (burnItem.validationType == IBurnRedeemCore.ValidationType.MERKLE_TREE) { bytes32 leaf = keccak256(abi.encodePacked(tokenId)); if (!MerkleProof.verify(merkleProof, burnItem.merkleRoot, leaf)) { revert InvalidMerkleProof(); } return; } revert InvalidBurnItem(); } /** * Helper to validate the parameters for a burn redeem */ function _validateParameters(IBurnRedeemCore.BurnRedeemParameters calldata burnRedeemParameters) internal pure { if (burnRedeemParameters.storageProtocol == IBurnRedeemCore.StorageProtocol.INVALID) { revert InvalidStorageProtocol(); } if (burnRedeemParameters.paymentReceiver == address(0)) { revert InvalidPaymentReceiver(); } if (burnRedeemParameters.endDate != 0 && burnRedeemParameters.startDate >= burnRedeemParameters.endDate) { revert InvalidDates(); } if (burnRedeemParameters.totalSupply % burnRedeemParameters.redeemAmount != 0) { revert IBurnRedeemCore.InvalidRedeemAmount(); } } /** * Helper to set top level properties for a burn redeem */ function _setParameters(IBurnRedeemCore.BurnRedeem storage burnRedeemInstance, IBurnRedeemCore.BurnRedeemParameters calldata burnRedeemParameters) private { burnRedeemInstance.startDate = burnRedeemParameters.startDate; burnRedeemInstance.endDate = burnRedeemParameters.endDate; burnRedeemInstance.redeemAmount = burnRedeemParameters.redeemAmount; burnRedeemInstance.totalSupply = burnRedeemParameters.totalSupply; burnRedeemInstance.storageProtocol = burnRedeemParameters.storageProtocol; burnRedeemInstance.location = burnRedeemParameters.location; burnRedeemInstance.cost = burnRedeemParameters.cost; burnRedeemInstance.paymentReceiver = burnRedeemParameters.paymentReceiver; } /** * Helper to set the burn groups for a burn redeem */ function _setBurnGroups(IBurnRedeemCore.BurnRedeem storage burnRedeemInstance, IBurnRedeemCore.BurnGroup[] calldata burnGroups) private { delete burnRedeemInstance.burnSet; for (uint256 i; i < burnGroups.length;) { burnRedeemInstance.burnSet.push(); IBurnRedeemCore.BurnGroup storage burnGroup = burnRedeemInstance.burnSet[i]; if (burnGroups[i].requiredCount == 0 || burnGroups[i].requiredCount > burnGroups[i].items.length) { revert InvalidInput(); } burnGroup.requiredCount = burnGroups[i].requiredCount; for (uint256 j; j < burnGroups[i].items.length;) { IBurnRedeemCore.BurnItem memory burnItem = burnGroups[i].items[j]; IBurnRedeemCore.TokenSpec tokenSpec = burnItem.tokenSpec; uint256 amount = burnItem.amount; if ( !( (tokenSpec == IBurnRedeemCore.TokenSpec.ERC1155 && amount > 0) || (tokenSpec == IBurnRedeemCore.TokenSpec.ERC721 && amount == 0) ) || burnItem.validationType == IBurnRedeemCore.ValidationType.INVALID ) { revert InvalidInput(); } burnGroup.items.push(burnGroups[i].items[j]); unchecked { ++j; } } unchecked { ++i; } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (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 rebuild 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 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 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 for 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) { 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 rebuild 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 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 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 for 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) { 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 pragma solidity ^0.8.0; /// @author: manifold.xyz import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; /** * Burn Redeem Core interface */ interface IBurnRedeemCore is IERC165, IERC721Receiver, IERC1155Receiver { error NotAdmin(address); error UnsupportedContractVersion(); error InvalidToken(uint256); error InvalidInput(); error InvalidTokenSpec(); error InvalidBurnSpec(); error InvalidData(); error TransferFailure(); error BurnRedeemDoesNotExist(uint256); error BurnRedeemInactive(uint256); error InvalidBurnAmount(); error InvalidRedeemAmount(); error InvalidPaymentAmount(); enum StorageProtocol { INVALID, NONE, ARWEAVE, IPFS } /** * @notice the validation type used for a `BurnItem` * CONTRACT any token from a specific contract is valid * RANGE token IDs within a range (inclusive) are valid * MERKLE_TREE various individual token IDs included in a merkle tree are valid * ANY any token from any contract */ enum ValidationType { INVALID, CONTRACT, RANGE, MERKLE_TREE, ANY } enum TokenSpec { INVALID, ERC721, ERC1155 } enum BurnSpec { NONE, MANIFOLD, OPENZEPPELIN } /** * @notice a `BurnItem` indicates which tokens are eligible to be burned * @param validationType which type of validation used to check that the burn item is * satisfied * @param tokenSpec whether the token is an ERC721 or ERC1155 * @param burnSpec whether the contract for a token has a `burn` function and, if so, * what interface * @param amount (only for ERC1155 tokens) the amount (value) required to burn * @param minTokenId (only for RANGE validation) the minimum valid token ID * @param maxTokenId (only for RANGE validation) the maximum valid token ID * @param merkleRoot (only for MERKLE_TREE validation) the root of the merkle tree of * valid token IDs */ struct BurnItem { ValidationType validationType; address contractAddress; TokenSpec tokenSpec; BurnSpec burnSpec; uint72 amount; uint256 minTokenId; uint256 maxTokenId; bytes32 merkleRoot; } /** * @notice a `BurnGroup` is a group of valid `BurnItem`s * @param requiredCount the number of `BurnItem`s (0 < requiredCount <= items.length) that * need to be included in a burn * @param items the list of `BurnItem`s */ struct BurnGroup { uint256 requiredCount; BurnItem[] items; } /** * @notice parameters for burn redeem intialization/updates * @param paymentReceiver the address to forward proceeds from paid burn redeems * @param storageProtocol the type of storage used for the redeem token URIs * @param redeemAmount the number of redeem tokens to mint for each burn redeem * @param totalSupply the maximum number of redeem tokens to mint (0 for unlimited) * @param startDate the starting time for the burn redeem (0 for immediately) * @param endDate the end time for the burn redeem (0 for never) * @param cost the cost for each burn redeem * @param location used to construct the token URI (Arweave hash, full URI, etc.) * @param burnSet a list of `BurnGroup`s that must each be satisfied for a burn redeem */ struct BurnRedeemParameters { address payable paymentReceiver; StorageProtocol storageProtocol; uint16 redeemAmount; uint32 totalSupply; uint48 startDate; uint48 endDate; uint160 cost; string location; BurnGroup[] burnSet; } struct BurnRedeem { address payable paymentReceiver; StorageProtocol storageProtocol; uint32 redeemedCount; uint16 redeemAmount; uint32 totalSupply; uint8 contractVersion; uint48 startDate; uint48 endDate; uint160 cost; string location; BurnGroup[] burnSet; } /** * @notice a pointer to a `BurnItem` in a `BurnGroup` used in calls to `burnRedeem` * @param groupIndex the index of the `BurnGroup` in `BurnRedeem.burnSet` * @param itemIndex the index of the `BurnItem` in `BurnGroup.items` * @param contractAddress the address of the contract for the token * @param id the token ID * @param merkleProof the merkle proof for the token ID (only for MERKLE_TREE validation) */ struct BurnToken { uint48 groupIndex; uint48 itemIndex; address contractAddress; uint256 id; bytes32[] merkleProof; } /** * @notice get a burn redeem corresponding to a creator contract and instanceId * @param creatorContractAddress the address of the creator contract * @param instanceId the instanceId of the burn redeem for the creator contract * @return BurnRedeem the burn redeem object */ function getBurnRedeem(address creatorContractAddress, uint256 instanceId) external view returns(BurnRedeem memory); /** * @notice get a burn redeem corresponding to a creator contract and tokenId * @param creatorContractAddress the address of the creator contract * @param tokenId the token to retrieve the burn redeem for * @return the burn redeem instanceId and burn redeem object */ function getBurnRedeemForToken(address creatorContractAddress, uint256 tokenId) external view returns(uint256, BurnRedeem memory); /** * @notice burn tokens and mint a redeem token * @param creatorContractAddress the address of the creator contract * @param instanceId the instanceId of the burn redeem for the creator contract * @param burnRedeemCount the number of burn redeems we want to do * @param burnTokens the tokens to burn with pointers to the corresponding BurnItem requirement */ function burnRedeem(address creatorContractAddress, uint256 instanceId, uint32 burnRedeemCount, BurnToken[] calldata burnTokens) external payable; /** * @notice burn tokens and mint redeem tokens multiple times in a single transaction * @param creatorContractAddresses the addresses of the creator contracts * @param instanceIds the instanceIds of the burn redeems for the corresponding creator contract * @param burnRedeemCounts the burn redeem counts for each burn * @param burnTokens the tokens to burn for each burn redeem with pointers to the corresponding BurnItem requirement */ function burnRedeem(address[] calldata creatorContractAddresses, uint256[] calldata instanceIds, uint32[] calldata burnRedeemCounts, BurnToken[][] calldata burnTokens) external payable; /** * @notice burn tokens and mint a redeem token * @param creatorContractAddress the address of the creator contract * @param instanceId the instanceId of the burn redeem for the creator contract * @param burnRedeemCount the number of burn redeems we want to do * @param burnTokens the tokens to burn with pointers to the corresponding BurnItem requirement * @param data the data to emit with the BurnRedeemMint event */ function burnRedeemWithData(address creatorContractAddress, uint256 instanceId, uint32 burnRedeemCount, BurnToken[] calldata burnTokens, bytes calldata data) external payable; /** * @notice allow admin to airdrop arbitrary tokens * @param creatorContractAddress the creator contract to mint tokens for * @param instanceId the instanceId of the burn redeem for the creator contract * @param recipients addresses to airdrop to * @param amounts number of redeems to perform for each address in recipients */ function airdrop(address creatorContractAddress, uint256 instanceId, address[] calldata recipients, uint32[] calldata amounts) external; /** * @notice recover a token that was sent to the contract without safeTransferFrom * @param tokenAddress the address of the token contract * @param tokenId the id of the token * @param destination the address to send the token to */ function recoverERC721(address tokenAddress, uint256 tokenId, address destination) external; /** * @notice withdraw Manifold fee proceeds from the contract * @param recipient recepient of the funds * @param amount amount to withdraw in Wei */ function withdraw(address payable recipient, uint256 amount) external; /** * @notice set the Manifold Membership contract address * @param addr the address of the Manifold Membership contract */ function setMembershipAddress(address addr) external; }
// 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.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155Receiver is IERC165 { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); }
// 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); }
{ "remappings": [ "@ensdomains/=node_modules/@ensdomains/", "@manifoldxyz/=node_modules/@manifoldxyz/", "@openzeppelin/=node_modules/@openzeppelin/", "create2-helpers/=lib/create2-helpers/src/", "create2-scripts/=lib/create2-helpers/script/", "creator-core-solidity/=lib/creator-core-solidity/contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/", "eth-gas-reporter/=node_modules/eth-gas-reporter/", "forge-std/=lib/forge-std/src/", "hardhat/=node_modules/hardhat/", "libraries-solidity/=lib/libraries-solidity/contracts/", "murky/=lib/murky/src/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "operator-filter-registry/=node_modules/operator-filter-registry/", "truffle/=node_modules/truffle/", "lib/forge-std:ds-test/=lib/forge-std/lib/ds-test/src/", "lib/murky:ds-test/=lib/murky/lib/forge-std/lib/ds-test/src/", "lib/murky:forge-std/=lib/murky/lib/forge-std/src/", "lib/murky:openzeppelin-contracts/=lib/murky/lib/openzeppelin-contracts/", "lib/openzeppelin-contracts:ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/", "lib/openzeppelin-contracts:erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "lib/openzeppelin-contracts:forge-std/=lib/openzeppelin-contracts/lib/forge-std/src/", "lib/openzeppelin-contracts:openzeppelin/=lib/openzeppelin-contracts/contracts/", "lib/openzeppelin-contracts-upgradeable:ds-test/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/", "lib/openzeppelin-contracts-upgradeable:erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/", "lib/openzeppelin-contracts-upgradeable:forge-std/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/", "lib/openzeppelin-contracts-upgradeable:openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/", "lib/operator-filter-registry:ds-test/=lib/operator-filter-registry/lib/ds-test/src/", "lib/operator-filter-registry:erc4626-tests/=lib/operator-filter-registry/lib/openzeppelin-contracts/lib/erc4626-tests/", "lib/operator-filter-registry:forge-std/=lib/operator-filter-registry/lib/forge-std/src/", "lib/operator-filter-registry:openzeppelin-contracts-upgradeable/=lib/operator-filter-registry/lib/openzeppelin-contracts-upgradeable/contracts/", "lib/operator-filter-registry:openzeppelin-contracts/=lib/operator-filter-registry/lib/openzeppelin-contracts/contracts/" ], "optimizer": { "enabled": true, "runs": 150 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"BurnRedeemAlreadyInitialized","type":"error"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"BurnRedeemDoesNotExist","type":"error"},{"inputs":[],"name":"InvalidBurnItem","type":"error"},{"inputs":[],"name":"InvalidBurnToken","type":"error"},{"inputs":[],"name":"InvalidDates","type":"error"},{"inputs":[],"name":"InvalidInput","type":"error"},{"inputs":[],"name":"InvalidMerkleProof","type":"error"},{"inputs":[],"name":"InvalidPaymentReceiver","type":"error"},{"inputs":[],"name":"InvalidRedeemAmount","type":"error"},{"inputs":[],"name":"InvalidStorageProtocol","type":"error"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"InvalidToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"creatorContract","type":"address"},{"indexed":true,"internalType":"uint256","name":"instanceId","type":"uint256"},{"indexed":false,"internalType":"address","name":"initializer","type":"address"}],"name":"BurnRedeemInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"creatorContract","type":"address"},{"indexed":true,"internalType":"uint256","name":"instanceId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"redeemedCount","type":"uint32"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"BurnRedeemMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"creatorContract","type":"address"},{"indexed":true,"internalType":"uint256","name":"instanceId","type":"uint256"}],"name":"BurnRedeemUpdated","type":"event"},{"inputs":[{"components":[{"internalType":"enum IBurnRedeemCore.ValidationType","name":"validationType","type":"IBurnRedeemCore.ValidationType"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"enum IBurnRedeemCore.TokenSpec","name":"tokenSpec","type":"IBurnRedeemCore.TokenSpec"},{"internalType":"enum IBurnRedeemCore.BurnSpec","name":"burnSpec","type":"IBurnRedeemCore.BurnSpec"},{"internalType":"uint72","name":"amount","type":"uint72"},{"internalType":"uint256","name":"minTokenId","type":"uint256"},{"internalType":"uint256","name":"maxTokenId","type":"uint256"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"internalType":"struct IBurnRedeemCore.BurnItem","name":"burnItem","type":"tuple"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"validateBurnItem","outputs":[],"stateMutability":"pure","type":"function"}]
Contract Creation Code
61139761003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100565760003560e01c806314765c6b1461005b57806372acbd281461007d578063b40609bf14610090578063e5c986cd146100b0575b600080fd5b81801561006757600080fd5b5061007b610076366004610b4b565b6100d0565b005b61007b61008b366004610d0d565b610196565b81801561009c57600080fd5b5061007b6100ab366004610de6565b6102f2565b8180156100bc57600080fd5b5061007b6100cb366004610e49565b6103ed565b60008254600160a01b900460ff1660038111156100ef576100ef610e62565b1461010d57604051630dd0d7ed60e21b815260040160405180910390fd5b6101168161044d565b81546001600160f81b0316600160f81b60ff8616021782556101388282610588565b61014f8261014a610100840184610e78565b610714565b60405133815283906001600160a01b038716907ff4d614881eb59d4bcd5ea596b177a55b560306371604a9490ca2a5c2f24df14d9060200160405180910390a35050505050565b6004845160048111156101ab576101ab610e62565b146102ec5783602001516001600160a01b0316836001600160a01b0316146101e6576040516372ba210360e11b815260040160405180910390fd5b6001845160048111156101fb576101fb610e62565b146102ec5760028451600481111561021557610215610e62565b0361025a578360a0015182108061022f57508360c0015182115b156102555760405163124bad6360e31b8152600481018390526024015b60405180910390fd5b6102ec565b60038451600481111561026f5761026f610e62565b036102d35760008260405160200161028991815260200190565b6040516020818303038152906040528051906020012090506102b0828660e00151836109ef565b6102cd5760405163582f497d60e11b815260040160405180910390fd5b506102ec565b604051637778cc5f60e01b815260040160405180910390fd5b50505050565b60008254600160a01b900460ff16600381111561031157610311610e62565b0361033257604051630e50afef60e21b81526004810184905260240161024c565b61033b8161044d565b61034b6060820160408301610ec9565b82546103689161ffff1690600160a81b900463ffffffff16610eed565b63ffffffff161561038c5760405163918e94c560e01b815260040160405180910390fd5b6103968282610588565b6103a88261014a610100840184610e78565b6103b1826103ed565b60405183906001600160a01b038616907fc4487c68aeaaea10bc0e1e6408497e8b1eedeb6aeece8711fdb0da6b6c288dab90600090a350505050565b8054600160d81b900463ffffffff16158015906104205750805463ffffffff600160d81b82048116600160a81b90920416115b1561044a578054600160d81b63ffffffff600160a81b8304160263ffffffff60d81b199091161781555b50565b600061045f6040830160208401610f1e565b600381111561047057610470610e62565b0361048e5760405163cc14845760e01b815260040160405180910390fd5b600061049d6020830183610f3f565b6001600160a01b0316036104c4576040516301ed76a760e61b815260040160405180910390fd5b6104d460c0820160a08301610f5c565b65ffffffffffff161580159061051857506104f560c0820160a08301610f5c565b65ffffffffffff1661050d60a0830160808401610f5c565b65ffffffffffff1610155b156105365760405163364dd21b60e21b815260040160405180910390fd5b6105466060820160408301610ec9565b61ffff1661055a6080830160608401610f84565b6105649190610eed565b63ffffffff161561044a5760405163918e94c560e01b815260040160405180910390fd5b61059860a0820160808301610f5c565b60018301805465ffffffffffff191665ffffffffffff929092169190911790556105c860c0820160a08301610f5c565b60018301805465ffffffffffff929092166601000000000000026bffffffffffff000000000000199092169190911790556106096060820160408301610ec9565b825461ffff91909116600160c81b0261ffff60c81b199091161782556106356080820160608301610f84565b825463ffffffff91909116600160d81b0263ffffffff60d81b199091161782556106656040820160208301610f1e565b8254839060ff60a01b1916600160a01b83600381111561068757610687610e62565b021790555061069960e0820182610faa565b60028401916106a9919083611074565b506106ba60e0820160c08301610f3f565b6001830180546001600160a01b0392909216600160601b026bffffffffffffffffffffffff9092169190911790556106f56020820182610f3f565b82546001600160a01b0319166001600160a01b03919091161790915550565b610722600384016000610a84565b60005b818110156102ec57600384018054600101808255600082815291908390811061075057610750611135565b9060005260206000209060020201905083838381811061077257610772611135565b9050602002810190610784919061114b565b3515806107e7575083838381811061079e5761079e611135565b90506020028101906107b0919061114b565b6107be90602081019061116b565b90508484848181106107d2576107d2611135565b90506020028101906107e4919061114b565b35115b156108055760405163b4fa3fb360e01b815260040160405180910390fd5b83838381811061081757610817611135565b9050602002810190610829919061114b565b35815560005b84848481811061084157610841611135565b9050602002810190610853919061114b565b61086190602081019061116b565b90508110156109e557600085858581811061087e5761087e611135565b9050602002810190610890919061114b565b61089e90602081019061116b565b838181106108ae576108ae611135565b905061010002018036038101906108c591906111b5565b604081015160808201519192509068ffffffffffffffffff1660028260028111156108f2576108f2610e62565b1480156108ff5750600081115b806109245750600182600281111561091957610919610e62565b148015610924575080155b1580610942575060008351600481111561094057610940610e62565b145b156109605760405163b4fa3fb360e01b815260040160405180910390fd5b8460010188888881811061097657610976611135565b9050602002810190610988919061114b565b61099690602081019061116b565b868181106109a6576109a6611135565b835460018101855560009485526020909420610100909102929092019260040290910190506109d5828261125b565b505083600101935050505061082f565b5050600101610725565b6000826109fc8584610a05565b14949350505050565b600081815b8451811015610a4a57610a3682868381518110610a2957610a29611135565b6020026020010151610a52565b915080610a428161133a565b915050610a0a565b509392505050565b6000818310610a6e576000828152602084905260409020610a7d565b60008381526020839052604090205b9392505050565b508054600082556002029060005260206000209081019061044a91905b80821115610ac4576000808255610abb6001830182610ac8565b50600201610aa1565b5090565b508054600082556004029060005260206000209081019061044a91905b80821115610ac457600080825560018201819055600282018190556003820155600401610ae5565b6001600160a01b038116811461044a57600080fd5b8035610b2d81610b0d565b919050565b60006101208284031215610b4557600080fd5b50919050565b600080600080600060a08688031215610b6357600080fd5b8535610b6e81610b0d565b9450602086013560ff81168114610b8457600080fd5b93506040860135925060608601359150608086013567ffffffffffffffff811115610bae57600080fd5b610bba88828901610b32565b9150509295509295909350565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610c0657610c06610bc7565b604052919050565b6005811061044a57600080fd5b6003811061044a57600080fd5b8035610b2d81610c1b565b68ffffffffffffffffff8116811461044a57600080fd5b8035610b2d81610c33565b6000610100808385031215610c6957600080fd5b6040519081019067ffffffffffffffff82118183101715610c8c57610c8c610bc7565b8160405280925083359150610ca082610c0e565b818152610caf60208501610b22565b6020820152610cc060408501610c28565b6040820152610cd160608501610c28565b6060820152610ce260808501610c4a565b608082015260a084013560a082015260c084013560c082015260e084013560e0820152505092915050565b6000806000806101608587031215610d2457600080fd5b610d2e8686610c55565b9350610100850135610d3f81610b0d565b9250610120850135915061014085013567ffffffffffffffff80821115610d6557600080fd5b818701915087601f830112610d7957600080fd5b8135602082821115610d8d57610d8d610bc7565b8160051b9250610d9e818401610bdd565b828152928401810192818101908b851115610db857600080fd5b948201945b84861015610dd657853582529482019490820190610dbd565b989b979a50959850505050505050565b60008060008060808587031215610dfc57600080fd5b8435610e0781610b0d565b93506020850135925060408501359150606085013567ffffffffffffffff811115610e3157600080fd5b610e3d87828801610b32565b91505092959194509250565b600060208284031215610e5b57600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b6000808335601e19843603018112610e8f57600080fd5b83018035915067ffffffffffffffff821115610eaa57600080fd5b6020019150600581901b3603821315610ec257600080fd5b9250929050565b600060208284031215610edb57600080fd5b813561ffff81168114610a7d57600080fd5b600063ffffffff80841680610f1257634e487b7160e01b600052601260045260246000fd5b92169190910692915050565b600060208284031215610f3057600080fd5b813560048110610a7d57600080fd5b600060208284031215610f5157600080fd5b8135610a7d81610b0d565b600060208284031215610f6e57600080fd5b813565ffffffffffff81168114610a7d57600080fd5b600060208284031215610f9657600080fd5b813563ffffffff81168114610a7d57600080fd5b6000808335601e19843603018112610fc157600080fd5b83018035915067ffffffffffffffff821115610fdc57600080fd5b602001915036819003821315610ec257600080fd5b600181811c9082168061100557607f821691505b602082108103610b4557634e487b7160e01b600052602260045260246000fd5b601f82111561106f57600081815260208120601f850160051c8101602086101561104c5750805b601f850160051c820191505b8181101561106b57828155600101611058565b5050505b505050565b67ffffffffffffffff83111561108c5761108c610bc7565b6110a08361109a8354610ff1565b83611025565b6000601f8411600181146110d457600085156110bc5750838201355b600019600387901b1c1916600186901b17835561112e565b600083815260209020601f19861690835b8281101561110557868501358255602094850194600190920191016110e5565b50868210156111225760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b634e487b7160e01b600052603260045260246000fd5b60008235603e1983360301811261116157600080fd5b9190910192915050565b6000808335601e1984360301811261118257600080fd5b83018035915067ffffffffffffffff82111561119d57600080fd5b6020019150600881901b3603821315610ec257600080fd5b600061010082840312156111c857600080fd5b610a7d8383610c55565b600081356111df81610b0d565b92915050565b6003811061044a5761044a610e62565b600081356111df81610c1b565b61120b826111e5565b805460ff60a81b191660a89290921b60ff60a81b16919091179055565b611231826111e5565b805460ff60b01b191660b09290921b60ff60b01b16919091179055565b600081356111df81610c33565b813561126681610c0e565b6005811061127657611276610e62565b60ff1982541660ff82168117835550506112bb611295602084016111d2565b828054610100600160a81b03191660089290921b610100600160a81b0316919091179055565b6112d06112ca604084016111f5565b82611202565b6112e56112df606084016111f5565b82611228565b6113186112f46080840161124e565b8280546001600160b81b031660b89290921b6001600160b81b031916919091179055565b60a0820135600182015560c0820135600282015560e082013560038201555050565b60006001820161135a57634e487b7160e01b600052601160045260246000fd5b506001019056fea26469706673582212206341a1ab274505838622ccaea892bc18cc27596fbf6a96551071e44a8e3a4cbc64736f6c63430008110033
Deployed Bytecode
0x7370b4070953cdf0cf33d69322495df78a83b734e930146080604052600436106100565760003560e01c806314765c6b1461005b57806372acbd281461007d578063b40609bf14610090578063e5c986cd146100b0575b600080fd5b81801561006757600080fd5b5061007b610076366004610b4b565b6100d0565b005b61007b61008b366004610d0d565b610196565b81801561009c57600080fd5b5061007b6100ab366004610de6565b6102f2565b8180156100bc57600080fd5b5061007b6100cb366004610e49565b6103ed565b60008254600160a01b900460ff1660038111156100ef576100ef610e62565b1461010d57604051630dd0d7ed60e21b815260040160405180910390fd5b6101168161044d565b81546001600160f81b0316600160f81b60ff8616021782556101388282610588565b61014f8261014a610100840184610e78565b610714565b60405133815283906001600160a01b038716907ff4d614881eb59d4bcd5ea596b177a55b560306371604a9490ca2a5c2f24df14d9060200160405180910390a35050505050565b6004845160048111156101ab576101ab610e62565b146102ec5783602001516001600160a01b0316836001600160a01b0316146101e6576040516372ba210360e11b815260040160405180910390fd5b6001845160048111156101fb576101fb610e62565b146102ec5760028451600481111561021557610215610e62565b0361025a578360a0015182108061022f57508360c0015182115b156102555760405163124bad6360e31b8152600481018390526024015b60405180910390fd5b6102ec565b60038451600481111561026f5761026f610e62565b036102d35760008260405160200161028991815260200190565b6040516020818303038152906040528051906020012090506102b0828660e00151836109ef565b6102cd5760405163582f497d60e11b815260040160405180910390fd5b506102ec565b604051637778cc5f60e01b815260040160405180910390fd5b50505050565b60008254600160a01b900460ff16600381111561031157610311610e62565b0361033257604051630e50afef60e21b81526004810184905260240161024c565b61033b8161044d565b61034b6060820160408301610ec9565b82546103689161ffff1690600160a81b900463ffffffff16610eed565b63ffffffff161561038c5760405163918e94c560e01b815260040160405180910390fd5b6103968282610588565b6103a88261014a610100840184610e78565b6103b1826103ed565b60405183906001600160a01b038616907fc4487c68aeaaea10bc0e1e6408497e8b1eedeb6aeece8711fdb0da6b6c288dab90600090a350505050565b8054600160d81b900463ffffffff16158015906104205750805463ffffffff600160d81b82048116600160a81b90920416115b1561044a578054600160d81b63ffffffff600160a81b8304160263ffffffff60d81b199091161781555b50565b600061045f6040830160208401610f1e565b600381111561047057610470610e62565b0361048e5760405163cc14845760e01b815260040160405180910390fd5b600061049d6020830183610f3f565b6001600160a01b0316036104c4576040516301ed76a760e61b815260040160405180910390fd5b6104d460c0820160a08301610f5c565b65ffffffffffff161580159061051857506104f560c0820160a08301610f5c565b65ffffffffffff1661050d60a0830160808401610f5c565b65ffffffffffff1610155b156105365760405163364dd21b60e21b815260040160405180910390fd5b6105466060820160408301610ec9565b61ffff1661055a6080830160608401610f84565b6105649190610eed565b63ffffffff161561044a5760405163918e94c560e01b815260040160405180910390fd5b61059860a0820160808301610f5c565b60018301805465ffffffffffff191665ffffffffffff929092169190911790556105c860c0820160a08301610f5c565b60018301805465ffffffffffff929092166601000000000000026bffffffffffff000000000000199092169190911790556106096060820160408301610ec9565b825461ffff91909116600160c81b0261ffff60c81b199091161782556106356080820160608301610f84565b825463ffffffff91909116600160d81b0263ffffffff60d81b199091161782556106656040820160208301610f1e565b8254839060ff60a01b1916600160a01b83600381111561068757610687610e62565b021790555061069960e0820182610faa565b60028401916106a9919083611074565b506106ba60e0820160c08301610f3f565b6001830180546001600160a01b0392909216600160601b026bffffffffffffffffffffffff9092169190911790556106f56020820182610f3f565b82546001600160a01b0319166001600160a01b03919091161790915550565b610722600384016000610a84565b60005b818110156102ec57600384018054600101808255600082815291908390811061075057610750611135565b9060005260206000209060020201905083838381811061077257610772611135565b9050602002810190610784919061114b565b3515806107e7575083838381811061079e5761079e611135565b90506020028101906107b0919061114b565b6107be90602081019061116b565b90508484848181106107d2576107d2611135565b90506020028101906107e4919061114b565b35115b156108055760405163b4fa3fb360e01b815260040160405180910390fd5b83838381811061081757610817611135565b9050602002810190610829919061114b565b35815560005b84848481811061084157610841611135565b9050602002810190610853919061114b565b61086190602081019061116b565b90508110156109e557600085858581811061087e5761087e611135565b9050602002810190610890919061114b565b61089e90602081019061116b565b838181106108ae576108ae611135565b905061010002018036038101906108c591906111b5565b604081015160808201519192509068ffffffffffffffffff1660028260028111156108f2576108f2610e62565b1480156108ff5750600081115b806109245750600182600281111561091957610919610e62565b148015610924575080155b1580610942575060008351600481111561094057610940610e62565b145b156109605760405163b4fa3fb360e01b815260040160405180910390fd5b8460010188888881811061097657610976611135565b9050602002810190610988919061114b565b61099690602081019061116b565b868181106109a6576109a6611135565b835460018101855560009485526020909420610100909102929092019260040290910190506109d5828261125b565b505083600101935050505061082f565b5050600101610725565b6000826109fc8584610a05565b14949350505050565b600081815b8451811015610a4a57610a3682868381518110610a2957610a29611135565b6020026020010151610a52565b915080610a428161133a565b915050610a0a565b509392505050565b6000818310610a6e576000828152602084905260409020610a7d565b60008381526020839052604090205b9392505050565b508054600082556002029060005260206000209081019061044a91905b80821115610ac4576000808255610abb6001830182610ac8565b50600201610aa1565b5090565b508054600082556004029060005260206000209081019061044a91905b80821115610ac457600080825560018201819055600282018190556003820155600401610ae5565b6001600160a01b038116811461044a57600080fd5b8035610b2d81610b0d565b919050565b60006101208284031215610b4557600080fd5b50919050565b600080600080600060a08688031215610b6357600080fd5b8535610b6e81610b0d565b9450602086013560ff81168114610b8457600080fd5b93506040860135925060608601359150608086013567ffffffffffffffff811115610bae57600080fd5b610bba88828901610b32565b9150509295509295909350565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610c0657610c06610bc7565b604052919050565b6005811061044a57600080fd5b6003811061044a57600080fd5b8035610b2d81610c1b565b68ffffffffffffffffff8116811461044a57600080fd5b8035610b2d81610c33565b6000610100808385031215610c6957600080fd5b6040519081019067ffffffffffffffff82118183101715610c8c57610c8c610bc7565b8160405280925083359150610ca082610c0e565b818152610caf60208501610b22565b6020820152610cc060408501610c28565b6040820152610cd160608501610c28565b6060820152610ce260808501610c4a565b608082015260a084013560a082015260c084013560c082015260e084013560e0820152505092915050565b6000806000806101608587031215610d2457600080fd5b610d2e8686610c55565b9350610100850135610d3f81610b0d565b9250610120850135915061014085013567ffffffffffffffff80821115610d6557600080fd5b818701915087601f830112610d7957600080fd5b8135602082821115610d8d57610d8d610bc7565b8160051b9250610d9e818401610bdd565b828152928401810192818101908b851115610db857600080fd5b948201945b84861015610dd657853582529482019490820190610dbd565b989b979a50959850505050505050565b60008060008060808587031215610dfc57600080fd5b8435610e0781610b0d565b93506020850135925060408501359150606085013567ffffffffffffffff811115610e3157600080fd5b610e3d87828801610b32565b91505092959194509250565b600060208284031215610e5b57600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b6000808335601e19843603018112610e8f57600080fd5b83018035915067ffffffffffffffff821115610eaa57600080fd5b6020019150600581901b3603821315610ec257600080fd5b9250929050565b600060208284031215610edb57600080fd5b813561ffff81168114610a7d57600080fd5b600063ffffffff80841680610f1257634e487b7160e01b600052601260045260246000fd5b92169190910692915050565b600060208284031215610f3057600080fd5b813560048110610a7d57600080fd5b600060208284031215610f5157600080fd5b8135610a7d81610b0d565b600060208284031215610f6e57600080fd5b813565ffffffffffff81168114610a7d57600080fd5b600060208284031215610f9657600080fd5b813563ffffffff81168114610a7d57600080fd5b6000808335601e19843603018112610fc157600080fd5b83018035915067ffffffffffffffff821115610fdc57600080fd5b602001915036819003821315610ec257600080fd5b600181811c9082168061100557607f821691505b602082108103610b4557634e487b7160e01b600052602260045260246000fd5b601f82111561106f57600081815260208120601f850160051c8101602086101561104c5750805b601f850160051c820191505b8181101561106b57828155600101611058565b5050505b505050565b67ffffffffffffffff83111561108c5761108c610bc7565b6110a08361109a8354610ff1565b83611025565b6000601f8411600181146110d457600085156110bc5750838201355b600019600387901b1c1916600186901b17835561112e565b600083815260209020601f19861690835b8281101561110557868501358255602094850194600190920191016110e5565b50868210156111225760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b634e487b7160e01b600052603260045260246000fd5b60008235603e1983360301811261116157600080fd5b9190910192915050565b6000808335601e1984360301811261118257600080fd5b83018035915067ffffffffffffffff82111561119d57600080fd5b6020019150600881901b3603821315610ec257600080fd5b600061010082840312156111c857600080fd5b610a7d8383610c55565b600081356111df81610b0d565b92915050565b6003811061044a5761044a610e62565b600081356111df81610c1b565b61120b826111e5565b805460ff60a81b191660a89290921b60ff60a81b16919091179055565b611231826111e5565b805460ff60b01b191660b09290921b60ff60b01b16919091179055565b600081356111df81610c33565b813561126681610c0e565b6005811061127657611276610e62565b60ff1982541660ff82168117835550506112bb611295602084016111d2565b828054610100600160a81b03191660089290921b610100600160a81b0316919091179055565b6112d06112ca604084016111f5565b82611202565b6112e56112df606084016111f5565b82611228565b6113186112f46080840161124e565b8280546001600160b81b031660b89290921b6001600160b81b031916919091179055565b60a0820135600182015560c0820135600282015560e082013560038201555050565b60006001820161135a57634e487b7160e01b600052601160045260246000fd5b506001019056fea26469706673582212206341a1ab274505838622ccaea892bc18cc27596fbf6a96551071e44a8e3a4cbc64736f6c63430008110033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.