Skip to content

ERC-721 Drop Proposal (Droposal)

A droposal is an ERC-721 Drop Proposal — an on-chain DAO proposal that, if passed, deploys a new NFT collection contract and makes it available for public minting. The contract is based on Zora’s ERC721Drop standard.

Builder has reinstated legacy support for droposals alongside the launch of the coining feature. This means:

  • Standalone mint pages are available for every droposal, allowing creators to share a direct minting link with their audience.
  • Droposals appear in the DAO Gallery tab, tagged with a Drop badge, so they remain discoverable alongside other DAO content.

New droposals can still be created via the Droposal: Single Edition transaction type in the proposal builder.

Every droposal has a dedicated public mint page at: nouns.build/drop/[chain]/[contractAddress]

This page shows the collection media, title, creator, price, and a Mint button. Share this URL directly with your audience — no DAO interface or governance knowledge is required to mint.

Public Droposal Mint Page

The standalone droposal mint page. Share this URL directly with your audience so they can mint without interacting with the DAO governance interface.

Droposals appear in the Gallery tab of any DAO that has created them. Each droposal card is labelled with a Drop badge in the top-right corner to distinguish it from other gallery content types.

Visitors can mint directly from the gallery card without leaving the DAO page, or click through to the full standalone mint page.

Droposals in Gallery

The DAO Gallery tab. Droposals are marked with a Drop badge and include a Mint button directly on the card.

To create a new droposal:

  1. Navigate to your DAO’s dashboard and click Create Proposal.
  2. Write a proposal title and description explaining the drop.
  3. On the Add Transactions step, select Droposal: Single Edition from the transaction type dropdown.
  4. Configure the drop settings (see Sales Configuration below).
  5. Add the transaction to the queue, then review and submit the proposal for a governance vote.
  6. If the proposal passes and is executed, the ERC721Drop contract is deployed and the mint page becomes active.
Droposals Metadata

Select Droposal: Single Edition from the transaction type dropdown on the Add Transactions step.

You can then also define edition parameters and set a royalty payout address.

Edition Parameters Droposals Royalty Payout

The following section covers the ERC721Drop contract standard used by droposals. This is adapted from Zora’s archived documentation.

NFT contracts created from the ZoraNFTCreator are known as ERC721Drop contracts. Each drop contract is cloned from an implementation address and receives its own address. Both Editions and Drops use the same base contract but have different metadata rendering contracts.

Every time an NFT is minted and sold using these contracts, 5% of the primary sale amount is reserved by the Zora DAO. Nothing is taken on secondary sales.

  • Edition: A collection where all NFTs share the same media asset.
  • Drop: A collection where each NFT has its own individual media asset.

The sales configuration is set when the contract is created and holds all minting and sales parameters.

  • publicSaleStart: Start time for public minting
  • publicSaleEnd: End time for public minting
  • presaleStart: Start time for private (allowlist) minting
  • presaleEnd: End time for private minting
  • publicSalePrice: Price in ETH required to mint one NFT
  • maxSalePurchasePerAddress: Max number of NFTs one address can mint during the public sale
  • presaleMerkleRoot: Cryptographic proof used for presale allowlist minting

Note that presaleMerkleRoot can be set to 0x0000000000000000000000000000000000000000000000000000000000000000 if no allowlist minting is planned. Current values can be read by calling salesConfig on the contract, and updated by calling setSaleConfiguration.

function setSaleConfiguration(
uint104 publicSalePrice,
uint32 maxSalePurchasePerAddress,
uint64 publicSaleStart,
uint64 publicSaleEnd,
uint64 presaleStart,
uint64 presaleEnd,
bytes32 presaleMerkleRoot
)

A fixed-size collection has a maximum number of NFTs that can be minted, set via the editionSize parameter at contract creation.

An open edition has no maximum supply but has a defined minting window. Once the window closes, public minting is no longer possible. finalizeOpenEdition must be called by an admin after the window closes.

function finalizeOpenEdition()

Allows an admin to mint a number of NFTs to an address without paying the base price or protocol rewards.

function adminMint(address recipient, uint256 quantity)

Allows an admin to mint one NFT to each of multiple addresses in a single transaction.

function adminMintAirdrop(address[] calldata recipients)

The public minting function, callable by anyone once the public sale has started.

function mintWithRewards(
address recipient,
uint256 quantity,
string calldata comment,
address mintReferral
)

The allowlist minting function, requiring a Merkle proof.

function purchasePresaleWithRewards(
uint256 quantity,
uint256 maxQuantity,
uint256 pricePerToken,
bytes32[] calldata merkleProof,
string memory comment,
address mintReferral
)

The owner has no write access to contract functions. They can only set royalty and contract configurations on third-party platforms that expect an owner field. Defaults to the default admin address at creation, but can be updated by a default admin.

The most privileged role, set at contract initialisation. Capabilities include:

  • Assign and revoke admin roles
  • Call adminMint and adminMintAirdrop
  • Change the owner address
  • Update salesConfig
  • Call finalizeOpenEdition
bytes32 role = 0x0000000000000000000000000000000000000000000000000000000000000000

A restricted admin that can only access the adminMint and adminMintAirdrop functions.

bytes32 role = MINTER_ROLE

A restricted admin that can only update salesConfig and call withdraw.

bytes32 role = SALES_MANAGER_ROLE

Admin roles can only be assigned and revoked by default admins.

function isAdmin(address user)
function hasRole(bytes32 role, address account)
function grantRole(bytes32 role, address account)
function revokeRole(bytes32 role, address account)
function setOwner(address newOwner)

Once minting concludes, funds can be moved out of the contract by calling withdraw. This can be called by a default admin, the fundsRecipient address, a sales manager, or the Zora DAO.

function withdraw()

Funds are pushed to the fundsRecipient address (set to the default admin at initialisation). This can be updated:

function setFundsRecipient(address payable newRecipientAddress)

A Merkle root condenses a large list of allowed addresses into a single small piece of data stored on-chain. Use the following tools to generate a Merkle root and proofs:

It is also possible to upload an allowlist via the manage interface on the create website and access proofs from the API.

Once deployed, the address set as the owner must log in to OpenSea to access and update contract information.

Upgrades are opt-in and can only be initiated by a default admin. Only upgrades listed in the Zora registry are available.

function upgradeTo(address newImplementation)
function upgradeToAndCall(address newImplementation, bytes data)