SeaDrop Smart Contract Framework

repository·main·Indexed 43 days ago

https://github.com/projectopensea/seadrop

A specialized smart contract framework for managing primary NFT drops on EVM-compatible chains. SeaDrop v1.0.0 supports public, allowlist, and token-gated minting mechanisms, as well as server-side signed mints. It provides the ERC721SeaDrop base contract for efficient multi-quantity minting and includes features like provenance hashes for metadata security and upgradeable contract support via the Diamond storage pattern (EIP-2535).

Tokens
5K
Snippets
20
Records
25
Agent score
55%

What's inside SeaDrop

  1. What is SeaDrop?

    main

    SeaDrop is a smart contract designed to facilitate primary NFT drops on EVM-compatible blockchains. It supports various drop types, including:

    • Public drops
    • Allow list stages
    • Token gated drops
    • Server-side signed mints

    To use SeaDrop, an implementing token contract must include methods to interface with the SeaDrop contract via an authorized user, such as an Owner or Administrator.

  2. What is a Provenance Hash and how to use it

    main

    A provenance hash is an optional security feature that allows token creators to prove that token metadata has not been altered since the minting process began.

    Key constraints:

    • It can only be set before the first item is minted.
    • Once set, the hash is expected to match the hash of the actual metadata used by tokenURI().

    Best Practice: Token creators should set the provenance hash to the keccak256 hash of the IPFS hash of the metadata folder. To ensure consistency, use CID version 1 and sha2-256 when generating IPFS hashes.

  3. Use SeaDrop extensions like Burnable and RandomOffset

    main

    SeaDrop provides several functional extensions located in src/extensions that you can incorporate into your custom token contract. Examples include:

    • Burnable: Adds functionality to burn tokens.
    • RandomOffset: Provides specialized offset logic.

    These extensions are designed to work alongside the core ERC721SeaDrop functionality.

  4. How to use SeaDrop with Upgradeable contracts

    main

    The upgradeable variant of SeaDrop (starting from ERC721A v4) utilizes the Diamond storage pattern as defined in EIP-2535.

    Key implementation rules:

    1. Naming Convention: Every file and contract in the src-upgradeable package includes the suffix Upgradeable.
    2. Initialization: Standard constructors are replaced by internal initializer functions following the pattern __{ContractName}_init.
    3. Public Initializers: Because the parent initializers are internal, you must implement your own public initializer function that calls the parent class's initializer.
    4. Modifier Usage: If integrating with other upgradeable libraries, you must use their specific initializer modifier on your initialize() function in addition to the onlyInitializing modifier.
  5. Run Foundry fuzzing tests

    main

    SeaDrop uses Foundry for Solidity-based fuzzing tests.

    Prerequisites

    Install Foundry via the official installer:

    curl -L https://foundry.paradigm.xyz | bash
    foundryup

    Running Tests

    1. Install dependencies: forge install
    2. Run tests: forge test
    3. Run gas snapshot: forge snapshot

    Verbosity Levels

    You can increase verbosity using the -v flag:

    • -vv: Logs emitted during tests.
    • -vvv: Stack traces for failing tests.
    • -vvvv: Stack traces for all tests and setup traces for failing tests.
    • -vvvvv: Stack traces and setup traces are always displayed.
    forge install
    forge test
    forge snapshot
    # Example with verbosity
    forge test -vv
  6. Deploy and configure an ERC721SeaDrop token

    main

    To deploy a token compatible with SeaDrop, use the ERC721SeaDrop contract. This contract assigns the Owner role to the deployer, granting them authorization for all configuration methods.

    Deployment Steps

    1. Deploy the contract: Use src/ERC721SeaDrop.sol with the constructor arguments string name, string symbol, and address[] allowedSeaDrop (an array of SeaDrop authorized addresses).
    2. Configure core parameters: Set the max supply, creator payout address, contract URI, and base URI.
    3. Configure drop stages:
      • Set an allow list stage using updateAllowList().
      • Set a token gated stage using updateTokenGatedDrop().
      • Set a public stage using updatePublicDrop().
      • Set the drop URI using updateDropURI().
    4. Optional configurations:
      • Set a provenance hash for random metadata reveals via setProvenanceHash() (must be done before the first mint).
      • Add server-side signers via updateSignedMintValidationParams().

    Example Deployment Command

    forge create --rpc-url ${RPC_URL} src/ERC721SeaDrop.sol:ERC721SeaDrop --constructor-args "TokenTest1" "TEST1" [${SEADROP_ADDRESS}] --private-key ${PK} --etherscan-api-key ${ETHERSCAN_API_KEY} --verify
  7. Deploy and Upgrade SeaDrop Upgradeable contracts

    main

    To deploy or upgrade contracts in the src-upgradeable directory, use Hardhat with the OpenZeppelin Upgrade Plugins.

    Environment Setup

    Ensure your .env file contains the following variables:

    • PRIVATE_KEY: Your wallet private key.
    • SEPOLIA_RPC_URL: Your RPC provider URL (e.g., Infura or Alchemy).
    • ETHERSCAN_API_KEY: Your Etherscan API key for verification.

    Deployment Commands

    Run these commands from the src-upgradeable directory:

    To Deploy:

    npx hardhat run --config hardhat.config.ts --network sepolia scripts/deploy.ts

    To Upgrade:

    npx hardhat run --config hardhat.config.ts --network sepolia scripts/upgrade.ts
  8. Install SeaDrop dependencies and compile contracts

    main

    To set up the local development environment, install dependencies and compile the contracts using yarn:

    git clone --recurse-submodules https://github.com/ProjectOpenSea/seadrop && cd seadrop
    yarn install
    yarn build
  9. Extend SeaDrop functionality by inheriting ERC721SeaDrop

    main

    If you want to use your own custom token contract logic while maintaining compatibility with SeaDrop, you should inherit from ERC721SeaDrop.

    SeaDrop tokens are built on top of ERC721A to enable efficient minting of multiple quantities. They also include specialized tracking metadata, such as the number of tokens minted by a specific address, which SeaDrop uses to enforce wallet limits.

    Important Compatibility Requirement: To ensure your contract remains secure and compatible with the SeaDrop protocol, do not override or modify any SeaDrop-specific functions, specifically getMintStats().

    // Example pattern for custom SeaDrop tokens
    import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
    import "@seadrop/erc721-seadrop/ERC721SeaDrop.sol";
    
    contract MyCustomSeaDropToken is ERC721SeaDrop {
        // Implement your custom logic here
        // DO NOT override getMintStats()
    }