Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 212879 | 695 days ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ZoraCreatorMerkleMinterStrategy
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 50 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
import {Enjoy} from "_imagine/mint/Enjoy.sol";
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";
import {IMinterErrors} from "../../interfaces/IMinterErrors.sol";
/*
░░░░░░░░░░░░░░
░░▒▒░░░░░░░░░░░░░░░░░░░░
░░▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░
░░▒▒▒▒░░░░░░░░░░░░░░ ░░░░░░░░
░▓▓▒▒▒▒░░░░░░░░░░░░ ░░░░░░░
░▓▓▓▒▒▒▒░░░░░░░░░░░░ ░░░░░░░░
░▓▓▓▒▒▒▒░░░░░░░░░░░░░░ ░░░░░░░░░░
░▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░
░▓▓▓▓▓▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░
░▓▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░
░░▓▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░
░░▓▓▓▓▓▓▒▒▒▒▒▒▒▒░░░░░░░░░▒▒▒▒▒░░
░░▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░
░░▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░░
OURS TRULY,
github.com/ourzora/zora-1155-contracts
*/
/// @title ZoraCreatorMerkleMinterStrategy
/// @notice Mints tokens based on a merkle tree, for presales for example
/// @author @iainnash / @tbtstl
contract ZoraCreatorMerkleMinterStrategy is Enjoy, SaleStrategy, LimitedMintPerAddress, IMinterErrors {
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;
/// @notice ContractURI for contract information with the strategy
function contractURI() external pure override returns (string memory) {
return "https://github.com/ourzora/zora-1155-contracts/";
}
/// @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.0.0";
}
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(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
pragma solidity 0.8.17;
/*
░░░░░░░░░░░░░░
░░▒▒░░░░░░░░░░░░░░░░░░░░
░░▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░
░░▒▒▒▒░░░░░░░░░░░░░░ ░░░░░░░░
░▓▓▒▒▒▒░░░░░░░░░░░░ ░░░░░░░
░▓▓▓▒▒▒▒░░░░░░░░░░░░ ░░░░░░░░
░▓▓▓▒▒▒▒░░░░░░░░░░░░░░ ░░░░░░░░░░
░▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░
░▓▓▓▓▓▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░
░▓▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░
░░▓▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░
░░▓▓▓▓▓▓▒▒▒▒▒▒▒▒░░░░░░░░░▒▒▒▒▒░░
░░▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░
░░▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░░
OURS TRULY,
*/
interface Enjoy {
}// 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 "@zoralabs/openzeppelin-contracts-upgradeable/contracts/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 "@zoralabs/openzeppelin-contracts-upgradeable/contracts/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
/// @author @iainnash / @tbtstl
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
/// @author @iainnash / @tbtstl
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
pragma solidity ^0.8.17;
interface IMinterErrors {
error CallerNotZoraCreator1155();
error MinterContractAlreadyExists();
error MinterContractDoesNotExist();
error SaleEnded();
error SaleHasNotStarted();
error WrongValueSent();
error InvalidMerkleProof(address mintTo, bytes32[] merkleProof, bytes32 merkleRoot);
}// 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 IHasContractName {
/// @notice Contract name returns the pretty contract name
function contractName() external returns (string memory);
}
interface IContractMetadata is IHasContractName {
/// @notice Contract URI returns the uri for more information about the given contract
function contractURI() 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 "@zoralabs/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC165Upgradeable.sol";
interface ILimitedMintPerAddressErrors {
error UserExceedsMintLimit(address user, uint256 limit, uint256 requestedAmount);
}
interface ILimitedMintPerAddress is IERC165Upgradeable, ILimitedMintPerAddressErrors {
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": [
"ds-test/=node_modules/ds-test/src/",
"forge-std/=node_modules/forge-std/src/",
"@zoralabs/openzeppelin-contracts-upgradeable/=node_modules/@zoralabs/openzeppelin-contracts-upgradeable/",
"@zoralabs/protocol-rewards/src/=node_modules/@zoralabs/protocol-rewards/src/",
"@zoralabs/zora-1155-contracts/src/=node_modules/@zoralabs/zora-1155-contracts/src/",
"@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
"_imagine/=node_modules/@zoralabs/zora-1155-contracts/_imagine/",
"solemate/=/node_modules/solemate/src/",
"solady/=node_modules/solady/src/",
"solmate/=node_modules/solmate/"
],
"optimizer": {
"enabled": true,
"runs": 50
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs"
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "london",
"viaIR": true,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"CallerNotZoraCreator1155","type":"error"},{"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":"MinterContractAlreadyExists","type":"error"},{"inputs":[],"name":"MinterContractDoesNotExist","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 ZoraCreatorMerkleMinterStrategy.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":"contractURI","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 ZoraCreatorMerkleMinterStrategy.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 ZoraCreatorMerkleMinterStrategy.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
6080806040523461001657610d14908161001c8239f35b600080fdfe608080604052600436101561001357600080fd5b60003560e01c90816301ffc9a714610b015750806319b45c4f14610a4e578063515740a614610923578063611efc091461087b5780636890e5b31461028557806370fe2a261461020f57806375d0c0dc146101b55780637b49ff2c14610152578063a0a8e4601461010c5763e8a3d4851461008d57600080fd5b34610107576000366003190112610107576101036040516100ad81610bb0565b602f81527f68747470733a2f2f6769746875622e636f6d2f6f75727a6f72612f7a6f72612d60208201526e313135352d636f6e7472616374732f60881b6040820152604051918291602083526020830190610c3f565b0390f35b600080fd5b346101075760003660031901126101075761010360405161012c81610b95565b60058152640312e302e360dc1b6020820152604051918291602083526020830190610c3f565b346101075760603660031901126101075761016b610bec565b6001600160a01b0360443581811692908390036101075716600052600060205260406000206024356000526020526040600020906000526020526020604060002054604051908152f35b34610107576000366003190112610107576101036040516101d581610b95565b60198152784d65726b6c6520547265652053616c6520537472617465677960381b6020820152604051918291602083526020830190610c3f565b346101075760403660031901126101075760806001600160a01b0380610233610bec565b16600052600160205260406000206024356000526020526040600020600281549260018301541691015490604051926001600160401b0390818116855260401c16602084015260408301526060820152f35b346101075760a03660031901126101075761029e610bec565b506001600160401b03608435116101075736602360843501121561010757608435600401356001600160401b038111610107576084350160248101368111610107576080604051926102ef84610b95565b60608452600060208501526084359003126101075760843560240135916001600160a01b038316830361010757608480350135906001600160401b0382116101075782604383608435010112156101075760248260843501013561035281610c7f565b926103606040519485610bcb565b8184526020840190819560448460051b836084350101011161010757906044826084350101915b60448460051b826084350101018310610866575050505033600052600160205260406000206024356000526020526040600020604051906103c782610b7a565b60026001600160401b038254818116855260401c169182602085015260018060a01b036001820154166040850152015460608301524211610854576001600160401b03815116421061084257606081015160405190959061045381610445608435606481013590604401356001600160a01b03871660208501610c96565b03601f198101835282610bcb565b60208151910120946000955b85518710156104c2576104728787610cb4565b5190818110156104b15760005260205260406000205b95600019811461049b576001019561045f565b634e487b7160e01b600052601160045260246000fd5b906000526020526040600020610488565b90878692036107dc57505060446084350135610701575b6064608435013560443581810291818304149015171561049b57606435036106ef5760408201516001600160a01b031615801591906106e65760ff60025b1661052181610c7f565b9061052f6040519283610bcb565b80825261053e601f1991610c7f565b0160005b8181106106c157505084526040516105af916105789082906104459060443590602435906001600160a01b031660208501610c96565b6040519061058582610b95565b60028252602082015284516020860151916001830160208801526105a98383610cb4565b52610cb4565b5061065a575b50604051602081526060810182519060406020840152815180915260808301602060808360051b86010193019160005b8181106105fc576020870151604087015285850386f35b90919293607f19868203018452845190815191600383101561064457610638826040602080959460019782965201519181858201520190610c3f565b960194019291016105e5565b634e487b7160e01b600052602160045260246000fd5b60409081015181516001600160a01b039091166020820152606435818301529081526106ba9061068981610bb0565b6040519061069682610b95565b60018252602082015282516020840151916001830160208601526105a98383610cb4565b50816105b5565b6020906040516106d081610b95565b6000815260608382015282828601015201610542565b60ff6001610517565b604051632f4613eb60e01b8152600490fd5b3360005260006020526040600020602435600052602052604060002060018060a01b038216600052602052604060002080546044358101811161049b576044350190553360005260006020526040600020602435600052602052604060002060018060a01b0382166000526020526044608435013560406000205411156104d95733600090815260208181526040808320602435845282528083206001600160a01b039490941680845293909152908190205490516338b6455960e21b81529182916107d891608435604401359060048501610c96565b0390fd5b60608401516040519263076e3ab960e51b8452606484019460018060a01b03166004850152606060248501525180945260848301916000945b80861061082a57505082935060448301520390fd5b90926020806001928651815201940195019490610815565b6040516374626dc160e11b8152600490fd5b604051630bd8a3eb60e01b8152600490fd5b60208060449385358152019301929150610387565b3461010757604036600319011261010757610103610897610bec565b600060606040516108a781610b7a565b828152826020820152826040820152015260018060a01b038091166000526001602052604060002060243560005260205260026040600020604051926108ec84610b7a565b81546001600160401b0390818116865260401c16602085015260018201541660408401520154606082015260405191829182610c02565b346101075760a0366003190112610107576004356080366023190112610107576040516001600160401b036080820181811183821017610a38576040526024358181168103610107578252604435818116810361010757602083019081526001600160a01b039060643582811681036101075760029260408601918252606086019260843584523360005260016020526040600020886000526020526040600020958751168654916001600160401b0360401b905160401b169160018060801b031916171785556001850191511660018060a01b0319825416179055519101557f82ae5a22c3160d46d62997cfa6f39886b3126a3701c0e42ff3ce4f0b1b6ad0e360405180610a33339482610c02565b0390a3005b634e487b7160e01b600052604160045260246000fd5b34610107576020806003193601126101075760043590336000526001815260406000208260005281526000600260408220828155826001820155015533600052600181526040600020826000528152600260406000206040519281546001600160401b0390818116865260401c169084015260018060a01b036001820154166040840152015460608201527f82ae5a22c3160d46d62997cfa6f39886b3126a3701c0e42ff3ce4f0b1b6ad0e360803392a3005b34610107576020366003190112610107576004359063ffffffff60e01b821680920361010757602091631ed27fcb60e21b8114908115610b75575b8115610b4a575b5015158152f35b636890e5b360e01b811491508115610b64575b5083610b43565b6301ffc9a760e01b14905083610b5d565b610b3c565b608081019081106001600160401b03821117610a3857604052565b604081019081106001600160401b03821117610a3857604052565b606081019081106001600160401b03821117610a3857604052565b90601f801991011681019081106001600160401b03821117610a3857604052565b600435906001600160a01b038216820361010757565b91909160608060808301946001600160401b03808251168552602082015116602085015260018060a01b0360408201511660408501520151910152565b919082519283825260005b848110610c6b575050826000602080949584010152601f8019910116010190565b602081830181015184830182015201610c4a565b6001600160401b038111610a385760051b60200190565b604091949392606082019560018060a01b0316825260208201520152565b8051821015610cc85760209160051b010190565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220f647d23958d5df18c6ac6ed4cba67c54f94790782901589fb26f1153bf57a40964736f6c63430008110033
Deployed Bytecode
0x608080604052600436101561001357600080fd5b60003560e01c90816301ffc9a714610b015750806319b45c4f14610a4e578063515740a614610923578063611efc091461087b5780636890e5b31461028557806370fe2a261461020f57806375d0c0dc146101b55780637b49ff2c14610152578063a0a8e4601461010c5763e8a3d4851461008d57600080fd5b34610107576000366003190112610107576101036040516100ad81610bb0565b602f81527f68747470733a2f2f6769746875622e636f6d2f6f75727a6f72612f7a6f72612d60208201526e313135352d636f6e7472616374732f60881b6040820152604051918291602083526020830190610c3f565b0390f35b600080fd5b346101075760003660031901126101075761010360405161012c81610b95565b60058152640312e302e360dc1b6020820152604051918291602083526020830190610c3f565b346101075760603660031901126101075761016b610bec565b6001600160a01b0360443581811692908390036101075716600052600060205260406000206024356000526020526040600020906000526020526020604060002054604051908152f35b34610107576000366003190112610107576101036040516101d581610b95565b60198152784d65726b6c6520547265652053616c6520537472617465677960381b6020820152604051918291602083526020830190610c3f565b346101075760403660031901126101075760806001600160a01b0380610233610bec565b16600052600160205260406000206024356000526020526040600020600281549260018301541691015490604051926001600160401b0390818116855260401c16602084015260408301526060820152f35b346101075760a03660031901126101075761029e610bec565b506001600160401b03608435116101075736602360843501121561010757608435600401356001600160401b038111610107576084350160248101368111610107576080604051926102ef84610b95565b60608452600060208501526084359003126101075760843560240135916001600160a01b038316830361010757608480350135906001600160401b0382116101075782604383608435010112156101075760248260843501013561035281610c7f565b926103606040519485610bcb565b8184526020840190819560448460051b836084350101011161010757906044826084350101915b60448460051b826084350101018310610866575050505033600052600160205260406000206024356000526020526040600020604051906103c782610b7a565b60026001600160401b038254818116855260401c169182602085015260018060a01b036001820154166040850152015460608301524211610854576001600160401b03815116421061084257606081015160405190959061045381610445608435606481013590604401356001600160a01b03871660208501610c96565b03601f198101835282610bcb565b60208151910120946000955b85518710156104c2576104728787610cb4565b5190818110156104b15760005260205260406000205b95600019811461049b576001019561045f565b634e487b7160e01b600052601160045260246000fd5b906000526020526040600020610488565b90878692036107dc57505060446084350135610701575b6064608435013560443581810291818304149015171561049b57606435036106ef5760408201516001600160a01b031615801591906106e65760ff60025b1661052181610c7f565b9061052f6040519283610bcb565b80825261053e601f1991610c7f565b0160005b8181106106c157505084526040516105af916105789082906104459060443590602435906001600160a01b031660208501610c96565b6040519061058582610b95565b60028252602082015284516020860151916001830160208801526105a98383610cb4565b52610cb4565b5061065a575b50604051602081526060810182519060406020840152815180915260808301602060808360051b86010193019160005b8181106105fc576020870151604087015285850386f35b90919293607f19868203018452845190815191600383101561064457610638826040602080959460019782965201519181858201520190610c3f565b960194019291016105e5565b634e487b7160e01b600052602160045260246000fd5b60409081015181516001600160a01b039091166020820152606435818301529081526106ba9061068981610bb0565b6040519061069682610b95565b60018252602082015282516020840151916001830160208601526105a98383610cb4565b50816105b5565b6020906040516106d081610b95565b6000815260608382015282828601015201610542565b60ff6001610517565b604051632f4613eb60e01b8152600490fd5b3360005260006020526040600020602435600052602052604060002060018060a01b038216600052602052604060002080546044358101811161049b576044350190553360005260006020526040600020602435600052602052604060002060018060a01b0382166000526020526044608435013560406000205411156104d95733600090815260208181526040808320602435845282528083206001600160a01b039490941680845293909152908190205490516338b6455960e21b81529182916107d891608435604401359060048501610c96565b0390fd5b60608401516040519263076e3ab960e51b8452606484019460018060a01b03166004850152606060248501525180945260848301916000945b80861061082a57505082935060448301520390fd5b90926020806001928651815201940195019490610815565b6040516374626dc160e11b8152600490fd5b604051630bd8a3eb60e01b8152600490fd5b60208060449385358152019301929150610387565b3461010757604036600319011261010757610103610897610bec565b600060606040516108a781610b7a565b828152826020820152826040820152015260018060a01b038091166000526001602052604060002060243560005260205260026040600020604051926108ec84610b7a565b81546001600160401b0390818116865260401c16602085015260018201541660408401520154606082015260405191829182610c02565b346101075760a0366003190112610107576004356080366023190112610107576040516001600160401b036080820181811183821017610a38576040526024358181168103610107578252604435818116810361010757602083019081526001600160a01b039060643582811681036101075760029260408601918252606086019260843584523360005260016020526040600020886000526020526040600020958751168654916001600160401b0360401b905160401b169160018060801b031916171785556001850191511660018060a01b0319825416179055519101557f82ae5a22c3160d46d62997cfa6f39886b3126a3701c0e42ff3ce4f0b1b6ad0e360405180610a33339482610c02565b0390a3005b634e487b7160e01b600052604160045260246000fd5b34610107576020806003193601126101075760043590336000526001815260406000208260005281526000600260408220828155826001820155015533600052600181526040600020826000528152600260406000206040519281546001600160401b0390818116865260401c169084015260018060a01b036001820154166040840152015460608201527f82ae5a22c3160d46d62997cfa6f39886b3126a3701c0e42ff3ce4f0b1b6ad0e360803392a3005b34610107576020366003190112610107576004359063ffffffff60e01b821680920361010757602091631ed27fcb60e21b8114908115610b75575b8115610b4a575b5015158152f35b636890e5b360e01b811491508115610b64575b5083610b43565b6301ffc9a760e01b14905083610b5d565b610b3c565b608081019081106001600160401b03821117610a3857604052565b604081019081106001600160401b03821117610a3857604052565b606081019081106001600160401b03821117610a3857604052565b90601f801991011681019081106001600160401b03821117610a3857604052565b600435906001600160a01b038216820361010757565b91909160608060808301946001600160401b03808251168552602082015116602085015260018060a01b0360408201511660408501520151910152565b919082519283825260005b848110610c6b575050826000602080949584010152601f8019910116010190565b602081830181015184830182015201610c4a565b6001600160401b038111610a385760051b60200190565b604091949392606082019560018060a01b0316825260208201520152565b8051821015610cc85760209160051b010190565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220f647d23958d5df18c6ac6ed4cba67c54f94790782901589fb26f1153bf57a40964736f6c63430008110033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
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.