QuiverGenesis
0x9e8de7742b6c065996a34fc0b11772c62da8c4ef
Verification
Verified
v0.8.35+commit.47b9dedd
Type
Contract
18,488 bytes
ABI entries
86
26 read · 17 write
License
mit
Contract information
- Address
- 0x9e8de7742b6c065996a34fc0b11772c62da8c4ef
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.35+commit.47b9dedd
- Optimization
- Disabled
- Creator
- 0xC074e16d25…c89151535d
- Creation tx
- 0x46d7fc582d…fc81845371
Token
- Name
- Quiver Genesis
- Symbol
- QUIVER
- Decimals
- —
- Holders
- 963
- Market
- View token page →
Read contract (26)
FCFS_PHASE() → uint256
GTD_PHASE() → uint256
INITIAL_SALE_PRICE() → uint96
MAX_SUPPLY() → uint256
PUBLIC_PHASE() → uint256
SALE_SUPPLY() → uint256
TEAM_PHASE() → uint256
TEAM_SUPPLY() → uint256
balanceOf(address) → uint256
getApproved(uint256) → address
isApprovedForAll(address, address) → bool
mintedByPhase(uint256, address) → bool
name() → string
owner() → address
ownerOf(uint256) → address
phases(uint256) → uint64, uint64, bytes32, uint96, bool, bool
revealed() → bool
saleMinted() → uint256
supportsInterface(bytes4) → bool
symbol() → string
teamClaimed() → bool
teamMinted() → uint256
tokenByIndex(uint256) → uint256
tokenOfOwnerByIndex(address, uint256) → uint256
tokenURI(uint256) → string
totalSupply() → uint256
Events (13)
ApprovalApprovalForAllBaseURISetMerkleRootSetOwnershipTransferredPhaseActiveSetPhasePriceDecreasedPreRevealURISetRevealedSetScheduleConfiguredTeamClaimedTransferWithdrawn
ABI
[
{
"inputs": [
{
"internalType": "string",
"name": "name_",
"type": "string"
},
{
"internalType": "string",
"name": "symbol_",
"type": "string"
},
{
"internalType": "string",
"name": "initialPreRevealUri",
"type": "string"
},
{
"internalType": "string",
"name": "initialBaseUri",
"type": "string"
},
{
"internalType": "address",
"name": "initialOwner",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "ERC721EnumerableForbiddenBatchMint",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "ERC721IncorrectOwner",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "ERC721InsufficientApproval",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "approver",
"type": "address"
}
],
"name": "ERC721InvalidApprover",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "operator",
"type": "address"
}
],
"name": "ERC721InvalidOperator",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "ERC721InvalidOwner",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "receiver",
"type": "address"
}
],
"name": "ERC721InvalidReceiver",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "ERC721InvalidSender",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "ERC721NonexistentToken",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "uint256",
"name": "index",
"type": "uint256"
}
],
"name": "ERC721OutOfBoundsIndex",
"type": "error"
},
{
"inputs": [],
"name": "InvalidPayment",
"type": "error"
},
{
"inputs": [],
"name": "InvalidPhase",
"type": "error"
},
{
"inputs": [],
"name": "InvalidPhaseWindow",
"type": "error"
},
{
"inputs": [],
"name": "InvalidProof",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "OwnableInvalidOwner",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "OwnableUnauthorizedAccount",
"type": "error"
},
{
"inputs": [],
"name": "PhaseEnded",
"type": "error"
},
{
"inputs": [],
"name": "PhaseInactive",
"type": "error"
},
{
"inputs": [],
"name": "PhaseNotConfigured",
"type": "error"
},
{
"inputs": [],
"name": "PhaseNotStarted",
"type": "error"
},
{
"inputs": [],
"name": "PhaseOverlap",
"type": "error"
},
{
"inputs": [],
"name": "PriceNotDecreased",
"type": "error"
},
{
"inputs": [],
"name": "PublicProofNotEmpty",
"type": "error"
},
{
"inputs": [],
"name": "ReentrancyGuardReentrantCall",
"type": "error"
},
{
"inputs": [],
"name": "SaleSoldOut",
"type": "error"
},
{
"inputs": [],
"name": "TeamAlreadyClaimed",
"type": "error"
},
{
"inputs": [],
"name": "WalletPhaseLimit",
"type": "error"
},
{
"inputs": [],
"name": "WithdrawFailed",
"type": "error"
},
{
"inputs": [],
"name": "ZeroAddress",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "approved",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "bool",
"name": "approved",
"type": "bool"
}
],
"name": "ApprovalForAll",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "uri",
"type": "string"
}
],
"name": "BaseURISet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "phaseId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "merkleRoot",
"type": "bytes32"
}
],
"name": "MerkleRootSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "phaseId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bool",
"name": "active",
"type": "bool"
}
],
"name": "PhaseActiveSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "phaseId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint96",
"name": "previousPrice",
"type": "uint96"
},
{
"indexed": false,
"internalType": "uint96",
"name": "newPrice",
"type": "uint96"
}
],
"name": "PhasePriceDecreased",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "uri",
"type": "string"
}
],
"name": "PreRevealURISet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bool",
"name": "revealed",
"type": "bool"
}
],
"name": "RevealedSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint64[4]",
"name": "starts",
"type": "uint64[4]"
},
{
"indexed": false,
"internalType": "uint64[4]",
"name": "ends",
"type": "uint64[4]"
}
],
"name": "ScheduleConfigured",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "wallet",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "quantity",
"type": "uint256"
}
],
"name": "TeamClaimed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "Withdrawn",
"type": "event"
},
{
"inputs": [],
"name": "FCFS_PHASE",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "GTD_PHASE",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "INITIAL_SALE_PRICE",
"outputs": [
{
"internalType": "uint96",
"name": "",
"type": "uint96"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_SUPPLY",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "PUBLIC_PHASE",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "SALE_SUPPLY",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "TEAM_PHASE",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "TEAM_SUPPLY",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "approve",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint64[4]",
"name": "starts",
"type": "uint64[4]"
},
{
"internalType": "uint64[4]",
"name": "ends",
"type": "uint64[4]"
}
],
"name": "configureSchedule",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "phaseId",
"type": "uint256"
},
{
"internalType": "uint96",
"name": "newPrice",
"type": "uint96"
}
],
"name": "decreasePhasePrice",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "getApproved",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "operator",
"type": "address"
}
],
"name": "isApprovedForAll",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "phaseId",
"type": "uint256"
},
{
"internalType": "bytes32[]",
"name": "proof",
"type": "bytes32[]"
}
],
"name": "mint",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
},
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "mintedByPhase",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "ownerOf",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "phases",
"outputs": [
{
"internalType": "uint64",
"name": "startAt",
"type": "uint64"
},
{
"internalType": "uint64",
"name": "endAt",
"type": "uint64"
},
{
"internalType": "bytes32",
"name": "merkleRoot",
"type": "bytes32"
},
{
"internalType": "uint96",
"name": "price",
"type": "uint96"
},
{
"internalType": "bool",
"name": "active",
"type": "bool"
},
{
"internalType": "bool",
"name": "configured",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "revealed",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "safeTransferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "safeTransferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "saleMinted",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"internalType": "bool",
"name": "approved",
"type": "bool"
}
],
"name": "setApprovalForAll",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "newUri",
"type": "string"
}
],
"name": "setBaseURI",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "phaseId",
"type": "uint256"
},
{
"internalType": "bytes32",
"name": "merkleRoot",
"type": "bytes32"
}
],
"name": "setMerkleRoot",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "phaseId",
"type": "uint256"
},
{
"internalType": "bool",
"name": "active",
"type": "bool"
}
],
"name": "setPhaseActive",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "newUri",
"type": "string"
}
],
"name": "setPreRevealURI",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bool",
"name": "newRevealed",
"type": "bool"
}
],
"name": "setRevealed",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "interfaceId",
"type": "bytes4"
}
],
"name": "supportsInterface",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "symbol",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "teamClaimed",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32[]",
"name": "proof",
"type": "bytes32[]"
}
],
"name": "teamMint",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "teamMinted",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "index",
"type": "uint256"
}
],
"name": "tokenByIndex",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "uint256",
"name": "index",
"type": "uint256"
}
],
"name": "tokenOfOwnerByIndex",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "tokenURI",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address payable",
"name": "to",
"type": "address"
}
],
"name": "withdraw",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
contract QuiverGenesis is ERC721Enumerable, Ownable, ReentrancyGuard {
using Strings for uint256;
struct Phase {
uint64 startAt;
uint64 endAt;
bytes32 merkleRoot;
uint96 price;
bool active;
bool configured;
}
uint256 public constant MAX_SUPPLY = 2222;
uint256 public constant TEAM_SUPPLY = 100;
uint256 public constant SALE_SUPPLY = 2122;
uint256 public constant TEAM_PHASE = 0;
uint256 public constant GTD_PHASE = 1;
uint256 public constant FCFS_PHASE = 2;
uint256 public constant PUBLIC_PHASE = 3;
uint96 public constant INITIAL_SALE_PRICE = 0.0022 ether;
string private preRevealTokenUri;
string private baseTokenUri;
bool public revealed;
bool public teamClaimed;
uint256 public teamMinted;
uint256 public saleMinted;
mapping(uint256 => Phase) public phases;
mapping(uint256 => mapping(address => bool)) public mintedByPhase;
error InvalidPhase();
error InvalidPhaseWindow();
error PhaseOverlap();
error PhaseNotConfigured();
error PhaseInactive();
error PhaseNotStarted();
error PhaseEnded();
error InvalidProof();
error InvalidPayment();
error TeamAlreadyClaimed();
error WalletPhaseLimit();
error SaleSoldOut();
error PriceNotDecreased();
error ZeroAddress();
error WithdrawFailed();
error PublicProofNotEmpty();
event ScheduleConfigured(uint64[4] starts, uint64[4] ends);
event PhaseActiveSet(uint256 indexed phaseId, bool active);
event MerkleRootSet(uint256 indexed phaseId, bytes32 merkleRoot);
event PhasePriceDecreased(
uint256 indexed phaseId,
uint96 previousPrice,
uint96 newPrice
);
event TeamClaimed(address indexed wallet, uint256 quantity);
event PreRevealURISet(string uri);
event BaseURISet(string uri);
event RevealedSet(bool revealed);
event Withdrawn(address indexed to, uint256 amount);
constructor(
string memory name_,
string memory symbol_,
string memory initialPreRevealUri,
string memory initialBaseUri,
address initialOwner
) ERC721(name_, symbol_) Ownable(initialOwner) {
preRevealTokenUri = initialPreRevealUri;
baseTokenUri = initialBaseUri;
phases[GTD_PHASE].price = INITIAL_SALE_PRICE;
phases[FCFS_PHASE].price = INITIAL_SALE_PRICE;
phases[PUBLIC_PHASE].price = INITIAL_SALE_PRICE;
}
function configureSchedule(
uint64[4] calldata starts,
uint64[4] calldata ends
) external onlyOwner {
for (uint256 phaseId; phaseId < 4; phaseId++) {
if (ends[phaseId] <= starts[phaseId]) {
revert InvalidPhaseWindow();
}
if (phaseId < PUBLIC_PHASE && ends[phaseId] > starts[phaseId + 1]) {
revert PhaseOverlap();
}
}
for (uint256 phaseId; phaseId < 4; phaseId++) {
Phase storage phase = phases[phaseId];
phase.startAt = starts[phaseId];
phase.endAt = ends[phaseId];
phase.configured = true;
}
emit ScheduleConfigured(starts, ends);
}
function setPhaseActive(uint256 phaseId, bool active) external onlyOwner {
_requireFixedPhase(phaseId);
if (!phases[phaseId].configured) revert PhaseNotConfigured();
phases[phaseId].active = active;
emit PhaseActiveSet(phaseId, active);
}
function setMerkleRoot(
uint256 phaseId,
bytes32 merkleRoot
) external onlyOwner {
if (phaseId > FCFS_PHASE) revert InvalidPhase();
phases[phaseId].merkleRoot = merkleRoot;
emit MerkleRootSet(phaseId, merkleRoot);
}
function decreasePhasePrice(
uint256 phaseId,
uint96 newPrice
) external onlyOwner {
if (phaseId < GTD_PHASE || phaseId > PUBLIC_PHASE) {
revert InvalidPhase();
}
Phase storage phase = phases[phaseId];
uint96 previousPrice = phase.price;
if (newPrice >= previousPrice) revert PriceNotDecreased();
phase.price = newPrice;
emit PhasePriceDecreased(phaseId, previousPrice, newPrice);
}
function teamMint(bytes32[] calldata proof) external payable nonReentrant {
_validateLivePhase(TEAM_PHASE);
if (msg.value != 0) revert InvalidPayment();
if (teamClaimed) revert TeamAlreadyClaimed();
if (!_verifyWallet(phases[TEAM_PHASE].merkleRoot, msg.sender, proof)) {
revert InvalidProof();
}
teamClaimed = true;
teamMinted = TEAM_SUPPLY;
_mintMany(msg.sender, TEAM_SUPPLY);
emit TeamClaimed(msg.sender, TEAM_SUPPLY);
}
function mint(
uint256 phaseId,
bytes32[] calldata proof
) external payable nonReentrant {
if (phaseId < GTD_PHASE || phaseId > PUBLIC_PHASE) {
revert InvalidPhase();
}
_validateLivePhase(phaseId);
Phase storage phase = phases[phaseId];
if (msg.value != phase.price) revert InvalidPayment();
if (mintedByPhase[phaseId][msg.sender]) revert WalletPhaseLimit();
if (saleMinted >= SALE_SUPPLY) revert SaleSoldOut();
if (phaseId == PUBLIC_PHASE) {
if (proof.length != 0) revert PublicProofNotEmpty();
} else if (!_verifyWallet(phase.merkleRoot, msg.sender, proof)) {
revert InvalidProof();
}
mintedByPhase[phaseId][msg.sender] = true;
saleMinted += 1;
_safeMint(msg.sender, totalSupply() + 1);
}
function setPreRevealURI(string calldata newUri) external onlyOwner {
preRevealTokenUri = newUri;
emit PreRevealURISet(newUri);
}
function setBaseURI(string calldata newUri) external onlyOwner {
baseTokenUri = newUri;
emit BaseURISet(newUri);
}
function setRevealed(bool newRevealed) external onlyOwner {
revealed = newRevealed;
emit RevealedSet(newRevealed);
}
function withdraw(address payable to) external onlyOwner nonReentrant {
if (to == address(0)) revert ZeroAddress();
uint256 amount = address(this).balance;
(bool sent, ) = to.call{value: amount}("");
if (!sent) revert WithdrawFailed();
emit Withdrawn(to, amount);
}
function tokenURI(
uint256 tokenId
) public view override returns (string memory) {
_requireOwned(tokenId);
if (!revealed) return preRevealTokenUri;
return string.concat(baseTokenUri, tokenId.toString(), ".json");
}
function _validateLivePhase(uint256 phaseId) private view {
Phase storage phase = phases[phaseId];
if (!phase.configured) revert PhaseNotConfigured();
if (!phase.active) revert PhaseInactive();
if (block.timestamp < phase.startAt) revert PhaseNotStarted();
if (block.timestamp >= phase.endAt) revert PhaseEnded();
}
function _verifyWallet(
bytes32 merkleRoot,
address wallet,
bytes32[] calldata proof
) private pure returns (bool) {
bytes32 leaf = keccak256(abi.encodePacked(wallet));
return MerkleProof.verify(proof, merkleRoot, leaf);
}
function _mintMany(address to, uint256 quantity) private {
for (uint256 index; index < quantity; index++) {
_safeMint(to, totalSupply() + 1);
}
}
function _requireFixedPhase(uint256 phaseId) private pure {
if (phaseId > PUBLIC_PHASE) revert InvalidPhase();
}
}
Chain explorer2664msChain node82ms