TieredSeaDropToken

0x6581b6fa83e714956935cd1e16ac8f6f5c44c484

Verification
Verified
v0.8.17+commit.8df45f5f
Type
Contract
21,337 bytes
ABI entries
111
28 read · 32 write
License
none

Contract information

Address
0x6581b6fa83e714956935cd1e16ac8f6f5c44c484
Chain
Robinhood Chain (4663)
Compiler
v0.8.17+commit.8df45f5f
Optimization
Enabled
Creation tx
0x25929cc1c7…89815b3443

Token

Not a token

This contract does not expose ERC-20 metadata.

Read contract (28)

TIER1_MAX_SUPPLY()uint256
TIER_1()uint8
TIER_2()uint8
balanceOf(address)uint256
baseURI()string
contractURI()string
getApproved(uint256)address
getMintStats(address)uint256, uint256, uint256
getTransferValidationFunction()bytes4, bool
getTransferValidator()address
isApprovedForAll(address, address)bool
maxSupply()uint256
name()string
owner()address
ownerOf(uint256)address
provenanceHash()bytes32
royaltyAddress()address
royaltyBasisPoints()uint256
royaltyInfo(uint256, uint256)address, uint256
supportsInterface(bytes4)bool
symbol()string
tier1MintEnded()bool
tier2BaseURI()string
tier2Minted()uint256
tierOf(uint256)uint8
tokenURI(uint256)string
totalSupply()uint256
upgradesPaused()bool

Events (15)

AllowedSeaDropUpdatedApprovalApprovalForAllBatchMetadataUpdateConsecutiveTransferContractURIUpdatedMaxSupplyUpdatedOwnershipTransferredPotentialOwnerUpdatedProvenanceHashUpdatedRoyaltyInfoUpdatedSeaDropTokenDeployedTierUpgradedTransferTransferValidatorUpdated

ABI

[
  {
    "inputs": [
      {
        "internalType": "address[]",
        "name": "allowedSeaDrop",
        "type": "address[]"
      },
      {
        "internalType": "address",
        "name": "royaltyReceiver",
        "type": "address"
      },
      {
        "internalType": "uint96",
        "name": "royaltyBps",
        "type": "uint96"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "constructor"
  },
  {
    "inputs": [],
    "name": "AlreadyInitialized",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "ApprovalCallerNotOwnerNorApproved",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "ApprovalQueryForNonexistentToken",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "BalanceQueryForZeroAddress",
    "type": "error"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "newMaxSupply",
        "type": "uint256"
      }
    ],
    "name": "CannotExceedMaxSupplyOfUint64",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "CannotReopenMintAfterUpgrades",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "ExceedsTier1MaxSupply",
    "type": "error"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "basisPoints",
        "type": "uint256"
      }
    ],
    "name": "InvalidRoyaltyBasisPoints",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "MintAlreadyEnded",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "MintERC2309QuantityExceedsLimit",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "MintNotYetEnded",
    "type": "error"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "total",
        "type": "uint256"
      },
      {
        "internalType": "uint256",
        "name": "maxSupply",
        "type": "uint256"
      }
    ],
    "name": "MintQuantityExceedsMaxSupply",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "MintToZeroAddress",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "MintZeroQuantity",
    "type": "error"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "got",
        "type": "uint256"
      },
      {
        "internalType": "uint256",
        "name": "totalMinted",
        "type": "uint256"
      }
    ],
    "name": "NewMaxSupplyCannotBeLessThenTotalMinted",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "NewOwnerIsZeroAddress",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "NotNextOwner",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "NotTier1",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "NotTokenOwner",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "OnlyAllowedSeaDrop",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "OnlyOwner",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "OwnerQueryForNonexistentToken",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "OwnershipNotInitializedForExtraData",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "ProvenanceHashCannotBeSetAfterMintStarted",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "RoyaltyAddressCannotBeZeroAddress",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "SameTokenId",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "SameTransferValidator",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "SignersMismatch",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "TokenGatedMismatch",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "TransferCallerNotOwnerNorApproved",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "TransferFromIncorrectOwner",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "TransferToNonERC721ReceiverImplementer",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "TransferToZeroAddress",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "URIQueryForNonexistentToken",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "UpgradesPaused",
    "type": "error"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "address[]",
        "name": "allowedSeaDrop",
        "type": "address[]"
      }
    ],
    "name": "AllowedSeaDropUpdated",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "owner",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "approved",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "Approval",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "owner",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "operator",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "bool",
        "name": "approved",
        "type": "bool"
      }
    ],
    "name": "ApprovalForAll",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "_fromTokenId",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "_toTokenId",
        "type": "uint256"
      }
    ],
    "name": "BatchMetadataUpdate",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "uint256",
        "name": "fromTokenId",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "toTokenId",
        "type": "uint256"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "from",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "to",
        "type": "address"
      }
    ],
    "name": "ConsecutiveTransfer",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "string",
        "name": "newContractURI",
        "type": "string"
      }
    ],
    "name": "ContractURIUpdated",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "newMaxSupply",
        "type": "uint256"
      }
    ],
    "name": "MaxSupplyUpdated",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "previousOwner",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "newOwner",
        "type": "address"
      }
    ],
    "name": "OwnershipTransferred",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "address",
        "name": "newPotentialAdministrator",
        "type": "address"
      }
    ],
    "name": "PotentialOwnerUpdated",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "bytes32",
        "name": "previousHash",
        "type": "bytes32"
      },
      {
        "indexed": false,
        "internalType": "bytes32",
        "name": "newHash",
        "type": "bytes32"
      }
    ],
    "name": "ProvenanceHashUpdated",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "address",
        "name": "receiver",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "bps",
        "type": "uint256"
      }
    ],
    "name": "RoyaltyInfoUpdated",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [],
    "name": "SeaDropTokenDeployed",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "owner",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "burnedTokenIdA",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "burnedTokenIdB",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "newTokenId",
        "type": "uint256"
      }
    ],
    "name": "TierUpgraded",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "from",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "Transfer",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "address",
        "name": "oldValidator",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "address",
        "name": "newValidator",
        "type": "address"
      }
    ],
    "name": "TransferValidatorUpdated",
    "type": "event"
  },
  {
    "inputs": [],
    "name": "TIER1_MAX_SUPPLY",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "TIER_1",
    "outputs": [
      {
        "internalType": "uint8",
        "name": "",
        "type": "uint8"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "TIER_2",
    "outputs": [
      {
        "internalType": "uint8",
        "name": "",
        "type": "uint8"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "acceptOwnership",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "approve",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "owner",
        "type": "address"
      }
    ],
    "name": "balanceOf",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "baseURI",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "burn",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "cancelOwnershipTransfer",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "contractURI",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "fromTokenId",
        "type": "uint256"
      },
      {
        "internalType": "uint256",
        "name": "toTokenId",
        "type": "uint256"
      }
    ],
    "name": "emitBatchMetadataUpdate",
    "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": "minter",
        "type": "address"
      }
    ],
    "name": "getMintStats",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "minterNumMinted",
        "type": "uint256"
      },
      {
        "internalType": "uint256",
        "name": "currentTotalSupply",
        "type": "uint256"
      },
      {
        "internalType": "uint256",
        "name": "maxSupply",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "getTransferValidationFunction",
    "outputs": [
      {
        "internalType": "bytes4",
        "name": "functionSignature",
        "type": "bytes4"
      },
      {
        "internalType": "bool",
        "name": "isViewFunction",
        "type": "bool"
      }
    ],
    "stateMutability": "pure",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "getTransferValidator",
    "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": [],
    "name": "maxSupply",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "minter",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "quantity",
        "type": "uint256"
      }
    ],
    "name": "mintSeaDrop",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "components": [
          {
            "internalType": "uint256",
            "name": "maxSupply",
            "type": "uint256"
          },
          {
            "internalType": "string",
            "name": "baseURI",
            "type": "string"
          },
          {
            "internalType": "string",
            "name": "contractURI",
            "type": "string"
          },
          {
            "internalType": "address",
            "name": "seaDropImpl",
            "type": "address"
          },
          {
            "components": [
              {
                "internalType": "uint80",
                "name": "mintPrice",
                "type": "uint80"
              },
              {
                "internalType": "uint48",
                "name": "startTime",
                "type": "uint48"
              },
              {
                "internalType": "uint48",
                "name": "endTime",
                "type": "uint48"
              },
              {
                "internalType": "uint16",
                "name": "maxTotalMintableByWallet",
                "type": "uint16"
              },
              {
                "internalType": "uint16",
                "name": "feeBps",
                "type": "uint16"
              },
              {
                "internalType": "bool",
                "name": "restrictFeeRecipients",
                "type": "bool"
              }
            ],
            "internalType": "struct PublicDrop",
            "name": "publicDrop",
            "type": "tuple"
          },
          {
            "internalType": "string",
            "name": "dropURI",
            "type": "string"
          },
          {
            "components": [
              {
                "internalType": "bytes32",
                "name": "merkleRoot",
                "type": "bytes32"
              },
              {
                "internalType": "string[]",
                "name": "publicKeyURIs",
                "type": "string[]"
              },
              {
                "internalType": "string",
                "name": "allowListURI",
                "type": "string"
              }
            ],
            "internalType": "struct AllowListData",
            "name": "allowListData",
            "type": "tuple"
          },
          {
            "internalType": "address",
            "name": "creatorPayoutAddress",
            "type": "address"
          },
          {
            "internalType": "bytes32",
            "name": "provenanceHash",
            "type": "bytes32"
          },
          {
            "internalType": "address[]",
            "name": "allowedFeeRecipients",
            "type": "address[]"
          },
          {
            "internalType": "address[]",
            "name": "disallowedFeeRecipients",
            "type": "address[]"
          },
          {
            "internalType": "address[]",
            "name": "allowedPayers",
            "type": "address[]"
          },
          {
            "internalType": "address[]",
            "name": "disallowedPayers",
            "type": "address[]"
          },
          {
            "internalType": "address[]",
            "name": "tokenGatedAllowedNftTokens",
            "type": "address[]"
          },
          {
            "components": [
              {
                "internalType": "uint80",
                "name": "mintPrice",
                "type": "uint80"
              },
              {
                "internalType": "uint16",
                "name": "maxTotalMintableByWallet",
                "type": "uint16"
              },
              {
                "internalType": "uint48",
                "name": "startTime",
                "type": "uint48"
              },
              {
                "internalType": "uint48",
                "name": "endTime",
                "type": "uint48"
              },
              {
                "internalType": "uint8",
                "name": "dropStageIndex",
                "type": "uint8"
              },
              {
                "internalType": "uint32",
                "name": "maxTokenSupplyForStage",
                "type": "uint32"
              },
              {
                "internalType": "uint16",
                "name": "feeBps",
                "type": "uint16"
              },
              {
                "internalType": "bool",
                "name": "restrictFeeRecipients",
                "type": "bool"
              }
            ],
            "internalType": "struct TokenGatedDropStage[]",
            "name": "tokenGatedDropStages",
            "type": "tuple[]"
          },
          {
            "internalType": "address[]",
            "name": "disallowedTokenGatedAllowedNftTokens",
            "type": "address[]"
          },
          {
            "internalType": "address[]",
            "name": "signers",
            "type": "address[]"
          },
          {
            "components": [
              {
                "internalType": "uint80",
                "name": "minMintPrice",
                "type": "uint80"
              },
              {
                "internalType": "uint24",
                "name": "maxMaxTotalMintableByWallet",
                "type": "uint24"
              },
              {
                "internalType": "uint40",
                "name": "minStartTime",
                "type": "uint40"
              },
              {
                "internalType": "uint40",
                "name": "maxEndTime",
                "type": "uint40"
              },
              {
                "internalType": "uint40",
                "name": "maxMaxTokenSupplyForStage",
                "type": "uint40"
              },
              {
                "internalType": "uint16",
                "name": "minFeeBps",
                "type": "uint16"
              },
              {
                "internalType": "uint16",
                "name": "maxFeeBps",
                "type": "uint16"
              }
            ],
            "internalType": "struct SignedMintValidationParams[]",
            "name": "signedMintValidationParams",
            "type": "tuple[]"
          },
          {
            "internalType": "address[]",
            "name": "disallowedSigners",
            "type": "address[]"
          }
        ],
        "internalType": "struct ERC721SeaDropStructsErrorsAndEvents.MultiConfigureStruct",
        "name": "config",
        "type": "tuple"
      }
    ],
    "name": "multiConfigure",
    "outputs": [],
    "stateMutability": "nonpayable",
    "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": [],
    "name": "provenanceHash",
    "outputs": [
      {
        "internalType": "bytes32",
        "name": "",
        "type": "bytes32"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "renounceOwnership",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "royaltyAddress",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "royaltyBasisPoints",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      },
      {
        "internalType": "uint256",
        "name": "_salePrice",
        "type": "uint256"
      }
    ],
    "name": "royaltyInfo",
    "outputs": [
      {
        "internalType": "address",
        "name": "receiver",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "royaltyAmount",
        "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": "safeTransferFrom",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "from",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      },
      {
        "internalType": "bytes",
        "name": "_data",
        "type": "bytes"
      }
    ],
    "name": "safeTransferFrom",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "operator",
        "type": "address"
      },
      {
        "internalType": "bool",
        "name": "approved",
        "type": "bool"
      }
    ],
    "name": "setApprovalForAll",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "string",
        "name": "newBaseURI",
        "type": "string"
      }
    ],
    "name": "setBaseURI",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "string",
        "name": "newContractURI",
        "type": "string"
      }
    ],
    "name": "setContractURI",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "newMaxSupply",
        "type": "uint256"
      }
    ],
    "name": "setMaxSupply",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "bytes32",
        "name": "newProvenanceHash",
        "type": "bytes32"
      }
    ],
    "name": "setProvenanceHash",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "components": [
          {
            "internalType": "address",
            "name": "royaltyAddress",
            "type": "address"
          },
          {
            "internalType": "uint96",
            "name": "royaltyBps",
            "type": "uint96"
          }
        ],
        "internalType": "struct ISeaDropTokenContractMetadata.RoyaltyInfo",
        "name": "newInfo",
        "type": "tuple"
      }
    ],
    "name": "setRoyaltyInfo",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "bool",
        "name": "ended",
        "type": "bool"
      }
    ],
    "name": "setTier1MintEnded",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "string",
        "name": "newTier2BaseURI",
        "type": "string"
      }
    ],
    "name": "setTier2BaseURI",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "newValidator",
        "type": "address"
      }
    ],
    "name": "setTransferValidator",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "bool",
        "name": "paused",
        "type": "bool"
      }
    ],
    "name": "setUpgradesPaused",
    "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": "tier1MintEnded",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "tier2BaseURI",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "tier2Minted",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "name": "tierOf",
    "outputs": [
      {
        "internalType": "uint8",
        "name": "",
        "type": "uint8"
      }
    ],
    "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": "newPotentialOwner",
        "type": "address"
      }
    ],
    "name": "transferOwnership",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "seaDropImpl",
        "type": "address"
      },
      {
        "components": [
          {
            "internalType": "bytes32",
            "name": "merkleRoot",
            "type": "bytes32"
          },
          {
            "internalType": "string[]",
            "name": "publicKeyURIs",
            "type": "string[]"
          },
          {
            "internalType": "string",
            "name": "allowListURI",
            "type": "string"
          }
        ],
        "internalType": "struct AllowListData",
        "name": "allowListData",
        "type": "tuple"
      }
    ],
    "name": "updateAllowList",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "seaDropImpl",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "feeRecipient",
        "type": "address"
      },
      {
        "internalType": "bool",
        "name": "allowed",
        "type": "bool"
      }
    ],
    "name": "updateAllowedFeeRecipient",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address[]",
        "name": "allowedSeaDrop",
        "type": "address[]"
      }
    ],
    "name": "updateAllowedSeaDrop",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "seaDropImpl",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "payoutAddress",
        "type": "address"
      }
    ],
    "name": "updateCreatorPayoutAddress",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "seaDropImpl",
        "type": "address"
      },
      {
        "internalType": "string",
        "name": "dropURI",
        "type": "string"
      }
    ],
    "name": "updateDropURI",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "seaDropImpl",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "payer",
        "type": "address"
      },
      {
        "internalType": "bool",
        "name": "allowed",
        "type": "bool"
      }
    ],
    "name": "updatePayer",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "seaDropImpl",
        "type": "address"
      },
      {
        "components": [
          {
            "internalType": "uint80",
            "name": "mintPrice",
            "type": "uint80"
          },
          {
            "internalType": "uint48",
            "name": "startTime",
            "type": "uint48"
          },
          {
            "internalType": "uint48",
            "name": "endTime",
            "type": "uint48"
          },
          {
            "internalType": "uint16",
            "name": "maxTotalMintableByWallet",
            "type": "uint16"
          },
          {
            "internalType": "uint16",
            "name": "feeBps",
            "type": "uint16"
          },
          {
            "internalType": "bool",
            "name": "restrictFeeRecipients",
            "type": "bool"
          }
        ],
        "internalType": "struct PublicDrop",
        "name": "publicDrop",
        "type": "tuple"
      }
    ],
    "name": "updatePublicDrop",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "seaDropImpl",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "signer",
        "type": "address"
      },
      {
        "components": [
          {
            "internalType": "uint80",
            "name": "minMintPrice",
            "type": "uint80"
          },
          {
            "internalType": "uint24",
            "name": "maxMaxTotalMintableByWallet",
            "type": "uint24"
          },
          {
            "internalType": "uint40",
            "name": "minStartTime",
            "type": "uint40"
          },
          {
            "internalType": "uint40",
            "name": "maxEndTime",
            "type": "uint40"
          },
          {
            "internalType": "uint40",
            "name": "maxMaxTokenSupplyForStage",
            "type": "uint40"
          },
          {
            "internalType": "uint16",
            "name": "minFeeBps",
            "type": "uint16"
          },
          {
            "internalType": "uint16",
            "name": "maxFeeBps",
            "type": "uint16"
          }
        ],
        "internalType": "struct SignedMintValidationParams",
        "name": "signedMintValidationParams",
        "type": "tuple"
      }
    ],
    "name": "updateSignedMintValidationParams",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "seaDropImpl",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "allowedNftToken",
        "type": "address"
      },
      {
        "components": [
          {
            "internalType": "uint80",
            "name": "mintPrice",
            "type": "uint80"
          },
          {
            "internalType": "uint16",
            "name": "maxTotalMintableByWallet",
            "type": "uint16"
          },
          {
            "internalType": "uint48",
            "name": "startTime",
            "type": "uint48"
          },
          {
            "internalType": "uint48",
            "name": "endTime",
            "type": "uint48"
          },
          {
            "internalType": "uint8",
            "name": "dropStageIndex",
            "type": "uint8"
          },
          {
            "internalType": "uint32",
            "name": "maxTokenSupplyForStage",
            "type": "uint32"
          },
          {
            "internalType": "uint16",
            "name": "feeBps",
            "type": "uint16"
          },
          {
            "internalType": "bool",
            "name": "restrictFeeRecipients",
            "type": "bool"
          }
        ],
        "internalType": "struct TokenGatedDropStage",
        "name": "dropStage",
        "type": "tuple"
      }
    ],
    "name": "updateTokenGatedDrop",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "tokenIdA",
        "type": "uint256"
      },
      {
        "internalType": "uint256",
        "name": "tokenIdB",
        "type": "uint256"
      }
    ],
    "name": "upgrade",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "upgradesPaused",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  }
]

Source code

// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import { ERC721SeaDrop } from "seadrop/ERC721SeaDrop.sol";

error ExceedsTier1MaxSupply();
error NotTokenOwner();
error SameTokenId();
error NotTier1();
error MintNotYetEnded();
error MintAlreadyEnded();
error UpgradesPaused();
error CannotReopenMintAfterUpgrades();

/**
 * @title  TieredSeaDropToken
 * @notice ERC721SeaDrop collection (public/allowlist minting, whitelist,
 *         pricing, and phases are all managed via the shared SeaDrop
 *         contract / OpenSea Studio - see updateAllowedSeaDrop and the
 *         update* functions inherited from ERC721SeaDrop).
 *
 *         Adds one thing SeaDrop doesn't have: burn 2 owned Tier 1 tokens to
 *         mint 1 Tier 2 token.
 */
contract TieredSeaDropToken is ERC721SeaDrop {
    uint8 public constant TIER_1 = 1;
    uint8 public constant TIER_2 = 2;

    // Hard cap on Tier 1 tokens ever minted (via SeaDrop's public/allowlist
    // mint, or claim). ERC721A's own `_totalMinted()` / `maxSupply()` cover
    // the whole collection lifetime (Tier 1 + Tier 2), so Tier 1 needs its
    // own cap - enforced in `mintSeaDrop` and reported via `getMintStats`
    // below so SeaDrop's own pre-mint checks agree with it.
    uint256 public constant TIER1_MAX_SUPPLY = 7777;

    // Total Tier 2 tokens ever minted via upgrade().
    uint256 public tier2Minted;

    // Tier 1 minting and upgrading are mutually exclusive phases: mintSeaDrop
    // only works while this is false, upgrade() only works once it's true.
    // Keeps the two from ever overlapping, which is what makes it safe for
    // mintSeaDrop to check Tier 1 supply against ERC721A's combined
    // _totalMinted() counter (see mintSeaDrop below) - if upgrades could
    // happen mid-mint, each one would eat into the Tier 1 budget too.
    bool public tier1MintEnded;

    // Emergency stop for upgrade() specifically, independent of the above.
    bool public upgradesPaused;

    mapping(uint256 => uint8) public tierOf;

    string private _tier2BaseURI;

    event TierUpgraded(
        address indexed owner,
        uint256 burnedTokenIdA,
        uint256 burnedTokenIdB,
        uint256 newTokenId
    );

    constructor(
        address[] memory allowedSeaDrop,
        address royaltyReceiver,
        uint96 royaltyBps
    ) ERC721SeaDrop("MonkeyHood", "MonkeyHood", allowedSeaDrop) {
        _royaltyInfo = RoyaltyInfo({
            royaltyAddress: royaltyReceiver,
            royaltyBps: royaltyBps
        });
        // 7777 possible Tier 1, plus up to 3888 possible Tier 2 (2 burned -> 1 minted).
        _maxSupply = TIER1_MAX_SUPPLY + (TIER1_MAX_SUPPLY / 2);
    }

    /**
     * @notice Burns two owned Tier 1 tokens and mints one Tier 2 token to the caller.
     */
    function upgrade(uint256 tokenIdA, uint256 tokenIdB) external {
        if (!tier1MintEnded) revert MintNotYetEnded();
        if (upgradesPaused) revert UpgradesPaused();
        if (tokenIdA == tokenIdB) revert SameTokenId();
        if (ownerOf(tokenIdA) != msg.sender || ownerOf(tokenIdB) != msg.sender) {
            revert NotTokenOwner();
        }
        if (tierOf[tokenIdA] != TIER_1 || tierOf[tokenIdB] != TIER_1) {
            revert NotTier1();
        }

        _burn(tokenIdA, true);
        _burn(tokenIdB, true);
        delete tierOf[tokenIdA];
        delete tierOf[tokenIdB];

        uint256 newTokenId = _nextTokenId();
        tierOf[newTokenId] = TIER_2;
        tier2Minted += 1;
        _safeMint(msg.sender, 1);

        emit TierUpgraded(msg.sender, tokenIdA, tokenIdB, newTokenId);
    }

    /// @dev Full reimplementation (not a `super` delegation - `mintSeaDrop` is
    /// declared `external`, and Solidity's `super.foo()` dispatch doesn't
    /// reach external-only functions; routing through `this.mintSeaDrop()`
    /// instead would reset `msg.sender` to this contract's own address and
    /// break the `_onlyAllowedSeaDrop` check below). Enforces the Tier
    /// 1-specific cap instead of the collection-wide `maxSupply` (which is
    /// set higher to leave headroom for Tier 2 upgrades), and tags each
    /// minted token as Tier 1 before minting (so a reentrant call during
    /// _safeMint's receiver callback never sees an untagged token).
    ///
    /// Note: `getMintStats`, which SeaDrop.sol consults before calling this,
    /// is not `virtual` in ERC721SeaDrop and so can't be overridden to
    /// report the Tier 1 cap instead of the raw `maxSupply`. That's harmless
    /// here since this function is still the binding check, but it does mean
    /// SeaDrop's own bookkeeping (and OpenSea's UI) may reference the full
    /// `maxSupply` (7777 + headroom) rather than the true Tier 1 cap.
    function mintSeaDrop(address minter, uint256 quantity)
        external
        virtual
        override
        nonReentrant
    {
        _onlyAllowedSeaDrop(msg.sender);

        if (tier1MintEnded) revert MintAlreadyEnded();
        if (_totalMinted() + quantity > TIER1_MAX_SUPPLY) {
            revert ExceedsTier1MaxSupply();
        }

        uint256 startTokenId = _nextTokenId();
        for (uint256 i = 0; i < quantity; ) {
            tierOf[startTokenId + i] = TIER_1;
            unchecked {
                ++i;
            }
        }

        _safeMint(minter, quantity);
    }

    /**
     * @notice Ends Tier 1 minting and enables upgrade(), or reverses that -
     *         but only until the first upgrade happens. Once tier2Minted > 0,
     *         re-opening Tier 1 minting is permanently blocked, since doing
     *         so would let further mints eat into the Tier 1 budget that
     *         upgrades have already been counted against (see mintSeaDrop).
     */
    function setTier1MintEnded(bool ended) external onlyOwner {
        if (!ended && tier2Minted > 0) revert CannotReopenMintAfterUpgrades();
        tier1MintEnded = ended;
    }

    /**
     * @notice Emergency stop for upgrade() specifically, independent of
     *         whether Tier 1 minting has ended.
     */
    function setUpgradesPaused(bool paused) external onlyOwner {
        upgradesPaused = paused;
    }

    /**
     * @notice Sets the base URI for Tier 2 token metadata. Only callable by
     *         the owner. (Tier 1's base URI is the inherited `setBaseURI`.)
     */
    function setTier2BaseURI(string calldata newTier2BaseURI) external {
        _onlyOwnerOrSelf();
        _tier2BaseURI = newTier2BaseURI;
    }

    function tier2BaseURI() external view returns (string memory) {
        return _tier2BaseURI;
    }

    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        string memory base = tierOf[tokenId] == TIER_2 ? _tier2BaseURI : _baseURI();

        if (bytes(base).length == 0) {
            return "";
        }

        if (bytes(base)[bytes(base).length - 1] != bytes("/")[0]) {
            return base;
        }

        return string(abi.encodePacked(base, _toString(tokenId)));
    }
}
Chain explorer4908msChain node78ms