Overview
APE Balance
APE Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
CreatorMerkleMinterStrategy
Compiler Version
v0.8.25+commit.b61c2a91
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import { MerkleProof } from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import { IMinter1155 } from "../../interfaces/IMinter1155.sol"; import { ICreatorCommands } from "../../interfaces/ICreatorCommands.sol"; import { SaleStrategy } from "../SaleStrategy.sol"; import { ICreatorCommands } from "../../interfaces/ICreatorCommands.sol"; import { SaleCommandHelper } from "../utils/SaleCommandHelper.sol"; import { LimitedMintPerAddress } from "../utils/LimitedMintPerAddress.sol"; /// @title CreatorMerkleMinterStrategy /// @notice Mints tokens based on a merkle tree, for presales for example contract CreatorMerkleMinterStrategy is SaleStrategy, LimitedMintPerAddress { using SaleCommandHelper for ICreatorCommands.CommandSet; /// @notice General merkle sale settings struct MerkleSaleSettings { /// @notice Unix timestamp for the sale start uint64 presaleStart; /// @notice Unix timestamp for the sale end uint64 presaleEnd; /// @notice Funds recipient (0 if no different funds recipient than the contract global) address fundsRecipient; /// @notice Merkle root for bytes32 merkleRoot; } /// @notice Event for sale configuration updated event SaleSet(address indexed mediaContract, uint256 indexed tokenId, MerkleSaleSettings merkleSaleSettings); /// @notice Storage for allowed merkle settings for the sales configuration mapping(address => mapping(uint256 => MerkleSaleSettings)) public allowedMerkles; // target -> tokenId -> settings error SaleEnded(); error SaleHasNotStarted(); error WrongValueSent(); error InvalidMerkleProof(address mintTo, bytes32[] merkleProof, bytes32 merkleRoot); /// @notice The name of the sale strategy function contractName() external pure override returns (string memory) { return "Merkle Tree Sale Strategy"; } /// @notice The version of the sale strategy function contractVersion() external pure override returns (string memory) { return "1"; } error MerkleClaimsExceeded(); /// @notice Compiles and returns the commands needed to mint a token using this sales strategy /// @param tokenId The token ID to mint /// @param quantity The quantity of tokens to mint /// @param ethValueSent The amount of ETH sent with the transaction /// @param minterArguments The arguments passed to the minter, which should be the address to mint to, the max /// quantity, the price per token, and the merkle proof function requestMint( address, uint256 tokenId, uint256 quantity, uint256 ethValueSent, bytes calldata minterArguments ) external returns (ICreatorCommands.CommandSet memory commands) { (address mintTo, uint256 maxQuantity, uint256 pricePerToken, bytes32[] memory merkleProof) = abi.decode(minterArguments, (address, uint256, uint256, bytes32[])); MerkleSaleSettings memory config = allowedMerkles[msg.sender][tokenId]; // Check sale end if (block.timestamp > config.presaleEnd) { revert SaleEnded(); } // Check sale start if (block.timestamp < config.presaleStart) { revert SaleHasNotStarted(); } if ( !MerkleProof.verify( merkleProof, config.merkleRoot, keccak256(bytes.concat(keccak256(abi.encode(mintTo, maxQuantity, pricePerToken)))) ) ) { revert InvalidMerkleProof(mintTo, merkleProof, config.merkleRoot); } if (maxQuantity > 0) { _requireMintNotOverLimitAndUpdate(maxQuantity, quantity, msg.sender, tokenId, mintTo); } if (quantity * pricePerToken != ethValueSent) { revert WrongValueSent(); } // Should transfer funds if funds recipient is set to a non-default address bool shouldTransferFunds = config.fundsRecipient != address(0); // Setup contract commands commands.setSize(shouldTransferFunds ? 2 : 1); // Mint command commands.mint(mintTo, tokenId, quantity); // If we have a non-default funds recipient for this token if (shouldTransferFunds) { commands.transfer(config.fundsRecipient, ethValueSent); } } /// @notice Sets the sale configuration for a token function setSale(uint256 tokenId, MerkleSaleSettings memory merkleSaleSettings) external { allowedMerkles[msg.sender][tokenId] = merkleSaleSettings; // Emit event for new sale emit SaleSet(msg.sender, tokenId, merkleSaleSettings); } /// @notice Resets the sale configuration for a token function resetSale(uint256 tokenId) external override { delete allowedMerkles[msg.sender][tokenId]; // Emit event with empty sale emit SaleSet(msg.sender, tokenId, allowedMerkles[msg.sender][tokenId]); } /// @notice Gets the sale configuration for a token /// @param tokenContract address to look up sale for /// @param tokenId token ID to look up sale for function sale(address tokenContract, uint256 tokenId) external view returns (MerkleSaleSettings memory) { return allowedMerkles[tokenContract][tokenId]; } /// @notice IERC165 interface /// @param interfaceId intrfaceinterface id to match function supportsInterface(bytes4 interfaceId) public pure virtual override(LimitedMintPerAddress, SaleStrategy) returns (bool) { return super.supportsInterface(interfaceId) || LimitedMintPerAddress.supportsInterface(interfaceId) || SaleStrategy.supportsInterface(interfaceId); } }
// 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 pragma solidity ^0.8.17; import { IERC165Upgradeable } from "@openzeppelin/contracts-upgradeable/interfaces/IERC165Upgradeable.sol"; import { ICreatorCommands } from "./ICreatorCommands.sol"; /// @notice Minter standard interface /// @dev Minters need to confirm to the ERC165 selector of type(IMinter1155).interfaceId interface IMinter1155 is IERC165Upgradeable { function requestMint( address sender, uint256 tokenId, uint256 quantity, uint256 ethValueSent, bytes calldata minterArguments ) external returns (ICreatorCommands.CommandSet memory commands); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; /// @notice Creator Commands used by minter modules passed back to the main modules interface ICreatorCommands { /// @notice This enum is used to define supported creator action types. /// This can change in the future enum CreatorActions // No operation - also the default for mintings that may not return a command { NO_OP, // Send ether SEND_ETH, // Mint operation MINT } /// @notice This command is for struct Command { // Method for operation CreatorActions method; // Arguments used for this operation bytes args; } /// @notice This command set is returned from the minter back to the user struct CommandSet { Command[] commands; uint256 at; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import { IERC165Upgradeable } from "@openzeppelin/contracts-upgradeable/interfaces/IERC165Upgradeable.sol"; import { IMinter1155 } from "../interfaces/IMinter1155.sol"; import { IContractMetadata } from "../interfaces/IContractMetadata.sol"; import { IVersionedContract } from "../interfaces/IVersionedContract.sol"; /// @notice Sales Strategy Helper contract template on top of IMinter1155 abstract contract SaleStrategy is IMinter1155, IVersionedContract, IContractMetadata { /// @notice This function resets the sales configuration for a given tokenId and contract. /// @dev This function is intentioned to be called directly from the affected sales contract function resetSale(uint256 tokenId) external virtual; function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) { return interfaceId == type(IMinter1155).interfaceId || interfaceId == type(IERC165Upgradeable).interfaceId; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import { ICreatorCommands } from "../../interfaces/ICreatorCommands.sol"; /// @title SaleCommandHelper /// @notice Helper library for creating commands for the sale contract library SaleCommandHelper { /// @notice Sets the size of commands and initializes command array. Empty entries are skipped by the resolver. /// @dev Beware: this removes all previous command entries from memory /// @param commandSet command set struct storage. /// @param size size to set for the new struct function setSize(ICreatorCommands.CommandSet memory commandSet, uint256 size) internal pure { commandSet.commands = new ICreatorCommands.Command[](size); } /// @notice Creates a command to mint a token /// @param commandSet The command set to add the command to /// @param to The address to mint to /// @param tokenId The token ID to mint /// @param quantity The quantity of tokens to mint function mint( ICreatorCommands.CommandSet memory commandSet, address to, uint256 tokenId, uint256 quantity ) internal pure { unchecked { commandSet.commands[commandSet.at++] = ICreatorCommands.Command({ method: ICreatorCommands.CreatorActions.MINT, args: abi.encode(to, tokenId, quantity) }); } } /// @notice Creates a command to transfer ETH /// @param commandSet The command set to add the command to /// @param to The address to transfer to /// @param amount The amount of ETH to transfer function transfer(ICreatorCommands.CommandSet memory commandSet, address to, uint256 amount) internal pure { unchecked { commandSet.commands[commandSet.at++] = ICreatorCommands.Command({ method: ICreatorCommands.CreatorActions.SEND_ETH, args: abi.encode(to, amount) }); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import { ILimitedMintPerAddress } from "../../interfaces/ILimitedMintPerAddress.sol"; contract LimitedMintPerAddress is ILimitedMintPerAddress { /// @notice Storage for slot to check user mints /// @notice target contract -> tokenId -> minter user -> numberMinted /// @dev No gap or stroage interface since this is used within non-upgradeable contracts mapping(address => mapping(uint256 => mapping(address => uint256))) internal mintedPerAddress; function getMintedPerWallet( address tokenContract, uint256 tokenId, address wallet ) external view returns (uint256) { return mintedPerAddress[tokenContract][tokenId][wallet]; } function _requireMintNotOverLimitAndUpdate( uint256 limit, uint256 numRequestedMint, address tokenContract, uint256 tokenId, address wallet ) internal { mintedPerAddress[tokenContract][tokenId][wallet] += numRequestedMint; if (mintedPerAddress[tokenContract][tokenId][wallet] > limit) { revert UserExceedsMintLimit(wallet, limit, mintedPerAddress[tokenContract][tokenId][wallet]); } } function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) { return interfaceId == type(ILimitedMintPerAddress).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165Upgradeable.sol";
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; interface IContractMetadata { /// @notice Contract name returns the pretty contract name function contractName() external returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; interface IVersionedContract { function contractVersion() external returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import { IERC165Upgradeable } from "@openzeppelin/contracts-upgradeable/interfaces/IERC165Upgradeable.sol"; interface ILimitedMintPerAddress is IERC165Upgradeable { error UserExceedsMintLimit(address user, uint256 limit, uint256 requestedAmount); function getMintedPerWallet(address token, uint256 tokenId, address wallet) external view returns (uint256); }
// 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 IERC165Upgradeable { /** * @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": [ "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "forge-std/=lib/forge-std/src/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "openzeppelin/=lib/openzeppelin-contracts/contracts/", "solmate/=lib/solmate/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": true, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"mintTo","type":"address"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"InvalidMerkleProof","type":"error"},{"inputs":[],"name":"MerkleClaimsExceeded","type":"error"},{"inputs":[],"name":"SaleEnded","type":"error"},{"inputs":[],"name":"SaleHasNotStarted","type":"error"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"limit","type":"uint256"},{"internalType":"uint256","name":"requestedAmount","type":"uint256"}],"name":"UserExceedsMintLimit","type":"error"},{"inputs":[],"name":"WrongValueSent","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"mediaContract","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint64","name":"presaleStart","type":"uint64"},{"internalType":"uint64","name":"presaleEnd","type":"uint64"},{"internalType":"address","name":"fundsRecipient","type":"address"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"indexed":false,"internalType":"struct CreatorMerkleMinterStrategy.MerkleSaleSettings","name":"merkleSaleSettings","type":"tuple"}],"name":"SaleSet","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"allowedMerkles","outputs":[{"internalType":"uint64","name":"presaleStart","type":"uint64"},{"internalType":"uint64","name":"presaleEnd","type":"uint64"},{"internalType":"address","name":"fundsRecipient","type":"address"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"contractVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"wallet","type":"address"}],"name":"getMintedPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"uint256","name":"ethValueSent","type":"uint256"},{"internalType":"bytes","name":"minterArguments","type":"bytes"}],"name":"requestMint","outputs":[{"components":[{"components":[{"internalType":"enum ICreatorCommands.CreatorActions","name":"method","type":"uint8"},{"internalType":"bytes","name":"args","type":"bytes"}],"internalType":"struct ICreatorCommands.Command[]","name":"commands","type":"tuple[]"},{"internalType":"uint256","name":"at","type":"uint256"}],"internalType":"struct ICreatorCommands.CommandSet","name":"commands","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"resetSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"sale","outputs":[{"components":[{"internalType":"uint64","name":"presaleStart","type":"uint64"},{"internalType":"uint64","name":"presaleEnd","type":"uint64"},{"internalType":"address","name":"fundsRecipient","type":"address"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"internalType":"struct CreatorMerkleMinterStrategy.MerkleSaleSettings","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint64","name":"presaleStart","type":"uint64"},{"internalType":"uint64","name":"presaleEnd","type":"uint64"},{"internalType":"address","name":"fundsRecipient","type":"address"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"internalType":"struct CreatorMerkleMinterStrategy.MerkleSaleSettings","name":"merkleSaleSettings","type":"tuple"}],"name":"setSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}]
Contract Creation Code
60808060405234601557610cc6908161001b8239f35b600080fdfe608080604052600436101561001357600080fd5b60003560e01c90816301ffc9a714610b295750806319b45c4f14610a76578063515740a61461091b578063611efc091461083b5780636890e5b31461020557806370fe2a261461018e57806375d0c0dc146101305780637b49ff2c146100cd5763a0a8e4601461008257600080fd5b346100c85760003660031901126100c8576100c46040516100a281610bbd565b60018152603160f81b6020820152604051918291602083526020830190610c0f565b0390f35b600080fd5b346100c85760603660031901126100c8576100e6610bf9565b6001600160a01b0360443581811692908390036100c85716600052600060205260406000206024356000526020526040600020906000526020526020604060002054604051908152f35b346100c85760003660031901126100c8576100c460405161015081610bbd565b601981527f4d65726b6c6520547265652053616c65205374726174656779000000000000006020820152604051918291602083526020830190610c0f565b346100c85760403660031901126100c85760806101a9610bf9565b60018060a01b038091166000526001602052604060002060243560005260205260406000209081549160026001600160401b03926001830154169101549160405193818116855260401c16602084015260408301526060820152f35b346100c85760a03660031901126100c85761021e610bf9565b506084356001600160401b0381116100c857366023820112156100c85780600401356001600160401b0381116100c857810190602482013681116100c8576080826040519461026c86610bbd565b606086526000602087015203126100c8576024820135926001600160a01b03841684036100c8576084830135936001600160401b0385116100c8578260438686010112156100c857602485850101356102c481610c4f565b956102d26040519788610bd8565b8187526020870190819560448460051b838a010101116100c85790604482880101915b60448460051b828a0101018310610826575050505033600052600160205260406000206024356000526020526040600020906040519161033483610ba2565b60026001600160401b038254818116865260401c169182602086015260018060a01b036001820154166040860152015460608401524211610814576001600160401b03825116421061080257606082810151604080516001600160a01b038516602082015260448901359181019190915260648801359281019290925295906103ca81608081015b03601f198101835282610bd8565b6020815191012060405160208101918252602081526103e881610bbd565b519020946000955b885187101561043657610403878a610c66565b51908181101561042357600052602052600160406000205b9601956103f0565b906000526020526001604060002061041b565b908789920361079457505060448101356106ba575b6064810135604435029060646044358304910135146044351517156106a457606435036106925760408201516001600160a01b031615801591906106895760ff60025b1661049881610c4f565b906104a66040519283610bd8565b8082526104b5601f1991610c4f565b0160005b8181106106645750508452604080516001600160a01b03909216602083015260243590820152604435606082015261052f906104f881608081016103bc565b6040519061050582610bbd565b60028252602082015284516020860151916001830160208801526105298383610c66565b52610c66565b506105da575b50604051602081526060810182519060406020840152815180915260808301602060808360051b86010193019160005b81811061057c576020870151604087015285850386f35b90919293607f1986820301845284519081519160038310156105c4576105b8826040602080959460019782965201519181858201520190610c0f565b96019401929101610565565b634e487b7160e01b600052602160045260246000fd5b60409081015181516001600160a01b03909116602082015260643581830152908152606081018181106001600160401b0382111761064e57610647918160405261062382610bbd565b60018252608081015282516020840151916001830160208601526105298383610c66565b5081610535565b634e487b7160e01b600052604160045260246000fd5b60209060405161067381610bbd565b60008152606083820152828286010152016104b9565b60ff600161048e565b604051632f4613eb60e01b8152600490fd5b634e487b7160e01b600052601160045260246000fd5b3360005260006020526040600020602435600052602052604060002060018060a01b03831660005260205260406000208054604435810181116106a4576044350190553360005260006020526040600020602435600052602052604060002060018060a01b0383166000526020526044810135604060002054111561044b57336000908152602081815260408083206024803585529083528184206001600160a01b039690961680855295909252918290205491516338b6455960e21b815260048101949094526044928301359084015290820152606490fd5b60608581015160405163076e3ab960e51b81526001600160a01b03909616600487015260248601919091529151606485018190526000949350608484019291905b8086106107ea57505082935060448301520390fd5b909260208060019286518152019401950194906107d5565b6040516374626dc160e11b8152600490fd5b604051630bd8a3eb60e01b8152600490fd5b602080604493853581520193019291506102f5565b346100c85760403660031901126100c8576100c4610857610bf9565b6000606060405161086781610ba2565b828152826020820152826040820152015260018060a01b038091166000526001602052604060002060243560005260205260026040600020604051926108ac84610ba2565b81546001600160401b0390818116865260401c1660208501526001820154166040840152015460608201526040519182918291909160608060808301946001600160401b03808251168552602082015116602085015260018060a01b0360408201511660408501520151910152565b346100c85760a03660031901126100c85760043560803660231901126100c85760405161094781610ba2565b6001600160401b0360243581811681036100c857825260443581811681036100c857602083019081526001600160a01b039060643582811681036100c85760029260408601918252606086019260843584523360005260016020526040600020886000526020526040600020958751166fffffffffffffffff00000000000000008754925160401b16916fffffffffffffffffffffffffffffffff191617178555600185019151166bffffffffffffffffffffffff60a01b825416179055519101557f82ae5a22c3160d46d62997cfa6f39886b3126a3701c0e42ff3ce4f0b1b6ad0e360405180610a7133948291909160608060808301946001600160401b03808251168552602082015116602085015260018060a01b0360408201511660408501520151910152565b0390a3005b346100c8576020806003193601126100c85760043590336000526001815260406000208260005281526000600260408220828155826001820155015533600052600181526040600020826000528152600260406000206040519281546001600160401b0390818116865260401c169084015260018060a01b036001820154166040840152015460608201527f82ae5a22c3160d46d62997cfa6f39886b3126a3701c0e42ff3ce4f0b1b6ad0e360803392a3005b346100c85760203660031901126100c8576004359063ffffffff60e01b82168092036100c857602091631ed27fcb60e21b8114908115610b9d575b8115610b72575b5015158152f35b636890e5b360e01b811491508115610b8c575b5083610b6b565b6301ffc9a760e01b14905083610b85565b610b64565b608081019081106001600160401b0382111761064e57604052565b604081019081106001600160401b0382111761064e57604052565b90601f801991011681019081106001600160401b0382111761064e57604052565b600435906001600160a01b03821682036100c857565b919082519283825260005b848110610c3b575050826000602080949584010152601f8019910116010190565b602081830181015184830182015201610c1a565b6001600160401b03811161064e5760051b60200190565b8051821015610c7a5760209160051b010190565b634e487b7160e01b600052603260045260246000fdfea264697066735822122041ccba7f608f04f2e008255cb6bb75b8590bdf865e280ed5a861aedb293fcb5f64736f6c63430008190033
Deployed Bytecode
0x608080604052600436101561001357600080fd5b60003560e01c90816301ffc9a714610b295750806319b45c4f14610a76578063515740a61461091b578063611efc091461083b5780636890e5b31461020557806370fe2a261461018e57806375d0c0dc146101305780637b49ff2c146100cd5763a0a8e4601461008257600080fd5b346100c85760003660031901126100c8576100c46040516100a281610bbd565b60018152603160f81b6020820152604051918291602083526020830190610c0f565b0390f35b600080fd5b346100c85760603660031901126100c8576100e6610bf9565b6001600160a01b0360443581811692908390036100c85716600052600060205260406000206024356000526020526040600020906000526020526020604060002054604051908152f35b346100c85760003660031901126100c8576100c460405161015081610bbd565b601981527f4d65726b6c6520547265652053616c65205374726174656779000000000000006020820152604051918291602083526020830190610c0f565b346100c85760403660031901126100c85760806101a9610bf9565b60018060a01b038091166000526001602052604060002060243560005260205260406000209081549160026001600160401b03926001830154169101549160405193818116855260401c16602084015260408301526060820152f35b346100c85760a03660031901126100c85761021e610bf9565b506084356001600160401b0381116100c857366023820112156100c85780600401356001600160401b0381116100c857810190602482013681116100c8576080826040519461026c86610bbd565b606086526000602087015203126100c8576024820135926001600160a01b03841684036100c8576084830135936001600160401b0385116100c8578260438686010112156100c857602485850101356102c481610c4f565b956102d26040519788610bd8565b8187526020870190819560448460051b838a010101116100c85790604482880101915b60448460051b828a0101018310610826575050505033600052600160205260406000206024356000526020526040600020906040519161033483610ba2565b60026001600160401b038254818116865260401c169182602086015260018060a01b036001820154166040860152015460608401524211610814576001600160401b03825116421061080257606082810151604080516001600160a01b038516602082015260448901359181019190915260648801359281019290925295906103ca81608081015b03601f198101835282610bd8565b6020815191012060405160208101918252602081526103e881610bbd565b519020946000955b885187101561043657610403878a610c66565b51908181101561042357600052602052600160406000205b9601956103f0565b906000526020526001604060002061041b565b908789920361079457505060448101356106ba575b6064810135604435029060646044358304910135146044351517156106a457606435036106925760408201516001600160a01b031615801591906106895760ff60025b1661049881610c4f565b906104a66040519283610bd8565b8082526104b5601f1991610c4f565b0160005b8181106106645750508452604080516001600160a01b03909216602083015260243590820152604435606082015261052f906104f881608081016103bc565b6040519061050582610bbd565b60028252602082015284516020860151916001830160208801526105298383610c66565b52610c66565b506105da575b50604051602081526060810182519060406020840152815180915260808301602060808360051b86010193019160005b81811061057c576020870151604087015285850386f35b90919293607f1986820301845284519081519160038310156105c4576105b8826040602080959460019782965201519181858201520190610c0f565b96019401929101610565565b634e487b7160e01b600052602160045260246000fd5b60409081015181516001600160a01b03909116602082015260643581830152908152606081018181106001600160401b0382111761064e57610647918160405261062382610bbd565b60018252608081015282516020840151916001830160208601526105298383610c66565b5081610535565b634e487b7160e01b600052604160045260246000fd5b60209060405161067381610bbd565b60008152606083820152828286010152016104b9565b60ff600161048e565b604051632f4613eb60e01b8152600490fd5b634e487b7160e01b600052601160045260246000fd5b3360005260006020526040600020602435600052602052604060002060018060a01b03831660005260205260406000208054604435810181116106a4576044350190553360005260006020526040600020602435600052602052604060002060018060a01b0383166000526020526044810135604060002054111561044b57336000908152602081815260408083206024803585529083528184206001600160a01b039690961680855295909252918290205491516338b6455960e21b815260048101949094526044928301359084015290820152606490fd5b60608581015160405163076e3ab960e51b81526001600160a01b03909616600487015260248601919091529151606485018190526000949350608484019291905b8086106107ea57505082935060448301520390fd5b909260208060019286518152019401950194906107d5565b6040516374626dc160e11b8152600490fd5b604051630bd8a3eb60e01b8152600490fd5b602080604493853581520193019291506102f5565b346100c85760403660031901126100c8576100c4610857610bf9565b6000606060405161086781610ba2565b828152826020820152826040820152015260018060a01b038091166000526001602052604060002060243560005260205260026040600020604051926108ac84610ba2565b81546001600160401b0390818116865260401c1660208501526001820154166040840152015460608201526040519182918291909160608060808301946001600160401b03808251168552602082015116602085015260018060a01b0360408201511660408501520151910152565b346100c85760a03660031901126100c85760043560803660231901126100c85760405161094781610ba2565b6001600160401b0360243581811681036100c857825260443581811681036100c857602083019081526001600160a01b039060643582811681036100c85760029260408601918252606086019260843584523360005260016020526040600020886000526020526040600020958751166fffffffffffffffff00000000000000008754925160401b16916fffffffffffffffffffffffffffffffff191617178555600185019151166bffffffffffffffffffffffff60a01b825416179055519101557f82ae5a22c3160d46d62997cfa6f39886b3126a3701c0e42ff3ce4f0b1b6ad0e360405180610a7133948291909160608060808301946001600160401b03808251168552602082015116602085015260018060a01b0360408201511660408501520151910152565b0390a3005b346100c8576020806003193601126100c85760043590336000526001815260406000208260005281526000600260408220828155826001820155015533600052600181526040600020826000528152600260406000206040519281546001600160401b0390818116865260401c169084015260018060a01b036001820154166040840152015460608201527f82ae5a22c3160d46d62997cfa6f39886b3126a3701c0e42ff3ce4f0b1b6ad0e360803392a3005b346100c85760203660031901126100c8576004359063ffffffff60e01b82168092036100c857602091631ed27fcb60e21b8114908115610b9d575b8115610b72575b5015158152f35b636890e5b360e01b811491508115610b8c575b5083610b6b565b6301ffc9a760e01b14905083610b85565b610b64565b608081019081106001600160401b0382111761064e57604052565b604081019081106001600160401b0382111761064e57604052565b90601f801991011681019081106001600160401b0382111761064e57604052565b600435906001600160a01b03821682036100c857565b919082519283825260005b848110610c3b575050826000602080949584010152601f8019910116010190565b602081830181015184830182015201610c1a565b6001600160401b03811161064e5760051b60200190565b8051821015610c7a5760209160051b010190565b634e487b7160e01b600052603260045260246000fdfea264697066735822122041ccba7f608f04f2e008255cb6bb75b8590bdf865e280ed5a861aedb293fcb5f64736f6c63430008190033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.