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. Open your DAO, select the Proposals tab 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 collection, artwork, sale and revenue settings. Use Advanced to change the edition type and size, royalties, mint limit per address or default administrator.
  5. If Use revenue split is enabled, select Create split, sign the separate deployment transaction and wait for confirmation. Check that the deployed split address is shown as the payout address.
  6. Add the Droposal transaction to the queue, then review and submit the proposal for a governance vote.
  7. 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.

Droposals use an open edition with unlimited mints per wallet by default. Change these settings under Advanced when the drop needs a fixed supply or per-wallet mint limit.

Enable Use revenue split under Revenue to deploy an optional 0xSplits v1 contract that shares mint proceeds and royalties between multiple recipients.

The Revenue section contains the payout address and the optional split configuration.

Droposal revenue section with the revenue split option

When the split option is enabled, add recipients and their allocations. Recipient addresses must be unique and the allocations must total 100% before you can create the split.

Droposal revenue split toggle

The recipient editor starts with two equal allocations. Enter an address or ENS name for each recipient, adjust the percentages as needed, and use Add recipient for additional recipients. Split evenly resets the allocations to equal shares.

Droposal split recipient configuration

As recipients and allocations become valid, the flow visualization shows each recipient’s share. The width of each flow represents its allocation percentage.

Droposal revenue split flow visualization

Creating the split requires a separate wallet transaction. Once deployed, its address becomes the Droposal’s payout address; the Droposal itself still needs to pass through governance. The split receives sale proceeds and royalties sent to that payout address, but it does not automatically forward them to recipients.

Deployed Droposal revenue split

Distributing and Withdrawing Split Revenue

Section titled “Distributing and Withdrawing Split Revenue”

After the Droposal is executed, open its standalone mint page. The Revenue split contract panel below the mint form shows the split contract, its creation transaction, and every recipient’s allocation.

Droposal page with the Revenue split contract panel below the mint form

The split details and payout controls are available directly on the Droposal page.

To retrieve funds through Builder:

  1. Connect the wallet included as a recipient in the split.
  2. Open the Droposal page and scroll to Revenue split contract.
  3. Use the available action to distribute funds according to the displayed shares, then withdraw the balance allocated to your connected wallet.
  4. Confirm the required wallet transaction or transactions. Funds reach the recipient wallet only after withdrawal completes.

The action reflects the split’s current state. For example, Nothing to distribute appears when the split has no balance ready for distribution.

Revenue split contract panel shown to a connected split recipient, with payout controls and withdrawal guidance

A connected recipient sees the distribution and withdrawal controls.

Logged-out visitors and connected wallets that are not included in the split see the contract, creation transaction, recipients, and allocation percentages without payout controls.

Read-only Revenue split contract panel shown to logged-out visitors and wallets that are not split recipients

The read-only view makes the split configuration publicly verifiable.

You can still use the split address in the Splits app to distribute funds and withdraw a recipient balance, or use a block explorer to confirm the distribution transaction and balances.

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)

Withdrawing Funds from the Droposal Contract

Section titled “Withdrawing Funds from the Droposal Contract”

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.

When fundsRecipient is a split contract, this call moves the proceeds into the split. Recipients can then use the distribution and withdrawal flow described above.

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)