A Guide to Designing Effective NFT Launches

14 min read Original article ↗

Unbundling NFT launches

While we now know what we want in a good launch, we still don’t know how to get there. We can slowly reveal that path (or, as we will see, the many paths) by unbundling what actually happens under the hood.

Every NFT launch consists, at its heart, of four steps:

  1. Bidding: The sale goes live, and users submit their bids to the operator (can be a smart contract).
  2. Clearing: The operator matches the collected bids against remaining supply, determines a clearing price, and selects winning bids.
  3. Distribution: Winners can claim their newly-minted NFTs (or receive them from the operator).
  4. Metadata reveal: The operator reveals the properties of the NFTs.

Look at Loot, for example. Loot went live on block 13,108,877 in an FCFS sale. The collection’s creator dom set the sale price to zero in the smart contract, but users still had to bid with gas. Every block, miners cleared the new bids against the remaining supply, deciding who won and who didn’t. When a bid was successful, the user received the item in the same transaction.

Most users learned the attributes of their item after they received it. However, in practice, a sophisticated user could have read the attributes of their item from the smart contract before minting, thereby allowing them to snipe the rarest items of the collection. This shows that whether the other steps happen sequentially or continuously, the metadata must be revealed only after the item has been bought and settled conclusively.

Next, we will explore the options NFT developers have at each of the four steps. We discuss each choice’s effect on the desirable properties, filtering the good design choices from the bad.

Phase 1: Bidding

In this phase, the operator collects bids (i.e., purchase requests) from its users.

Continuous vs. sequential clearing

Before anything else, the operator has to decide whether they want bidding and clearing to happen continuously within the same or two non-overlapping phases.

Any FCFS, fixed-price sale (which is most NFT launches to date) is an example of continuous clearing. Every block, miners look at the bids and clear them against the remaining supply. This mechanism has several problems: If the operator over-guesses the NFT’s clearing price, the items are too expensive and might not sell out. If the operator under-guesses the NFT’s clearing price, the items are too cheap, and users race each other with either speed (who has the most direct access to blockspace) or gas price (who can pay miners the most for their transaction). As discussed, this leads to massive dead-loss from failed transactions and greatly favors more skilled participants. If you must, the former can be mitigated by routing all user transactions to Flashbots RPC and letting the auction play out in an environment where failed transactions don’t have a cost.

When going with the second option, bidding and clearing happen in two non-overlapping phases. In practice, the operator first collects all the bids and then matches them against the available supply, clearing the market at a fair price. This approach includes mechanisms like batched auctions or raffles. One example of this approach is Jay Pegs Auto Mart, which gave users one week to submit their bids before clearing the market.

The sequential approach has several benefits that are in line with our stated goals:

  1. No race condition: Users have plenty of time to submit their bids, and the outcome is decided by how much users are willing to pay, not by how fast or skilled they are.
  2. Timezone-agnostic: The approach respects people who work or live in other time zones.

Furthermore, because there are no gas auctions, there are no negative externalities on other network users.

However, this approach has downsides, such as requiring more on-chain transactions (depending on the design of the auction) or reducing the fun for participants who now have to wait longer. We recommend not letting the bidding period stretch too long to mitigate the latter concern, probably no longer than 48 hours.

On-chain vs. off-chain bidding

After deciding between continuous or sequential clearing, the next choice is whether users submit their bids on- or off-chain.

As we will see, today’s launches often collect bids on-chain because it is easiest, effectively letting miners clear the winning bids and letting the rest fail. If we assume the network itself is uncensored, there is also the strong guarantee that no valid bid can be omitted from the sale.

However, collecting bids off-chain is equally possible. In this process, users sign a message that contains information like their on-chain address, the number of tokens or tickets they want to buy, their maximum price, etc., with their private key. They send this message to the operator without executing it on-chain, using their signature to prove its validity.

The operator can then use these bids to either clear the market off-chain or bundle the winning bids and submit them to the contract for execution on-chain. With either approach, some level of trust is necessary for the operator to execute the correct bids.

This last approach combines off-chain bid collection with on-chain winner selection robust, gas-efficient, and flexible ways. The only thing users have to trust is that the operator does not omit any bids when submitting them on-chain—a relatively weak assumption to make.

Who is allowed to bid

The third decision to make is who is allowed to bid and how much. As discussed in the goal of Inclusivity and Sybil resistance, projects might want to ensure that a diverse set of users buys their items. To that matter, they may limit the number of items available to users with specific characteristics or reserve items specifically for holders of existing NFT communities.

When the bidding happens off-chain, such KYC rules are easy to implement—you merely ask the user to prove certain information before letting them submit their signature to the server. On-chain KYC is more complex, but advances are being made by initiatives like Gitcoin’s privacy-preserving Proof of Personhood.

Even if a project does not want any form of KYC, they can still take measures to ensure that one dollar buys the same amount of tokens for large and small users alike. This principle is often violated when contracts allow users to buy or claim many NFTs in the same transaction because whales get to amortize gas fees across more tokens, hence paying less per token than smaller users. To mitigate, capping the number of tokens per address or per transaction is usually a good idea.

Bidding cost

Further, the operator must decide when the user has to pay for the token—together with the bid, or after the market has cleared?

In the latter case, the user merely reserves the token in the bidding phase, the market clears, and then they can complete the purchase within a certain time window. One project using this method, together with off-chain bidding, was Parallel. While it worked well in a quieter market, when demand is very high this model can turn into a race condition in which users want to reserve as many tokens as possible, given it is costless to do so.

To mitigate the problem of race conditions, a cost should be associated with the bid itself. The best solution here is to let users submit bids only after locking funds in a smart contract from the same address. The operator can then decide whether to return the funds if the bid was unsuccessful (resembling a limit order on an exchange) or to keep the bid (resembling a raffle ticket that did not pay out).

Granularity of bidding

Finally, one must decide how much granularity they want users to express with their bids. When there are losing bids (because demand exceeds supply), one must further decide what it means to be a winner and a loser. Here are three viable options:

“Dumb” batched auction: People commit an amount of ETH with no further instructions. In the clearing phase, the number of items is divided by the overall ETH committed, and everyone receives fractional tokens in the form of an ERC-20 that can later be redeemed for an ERC-721 NFT. Jay Pegs Auto Mart used this approach, and it has the benefit that there are no losing bids. However, it has the downside of requiring three extra on-chain transactions—two to sell or buy tokens to reach a useful amount (e.g., one “full” ERC-20) and one to redeem the NFT. Most importantly, this approach does not allow buyers to express the price at which they want certain quantities of tokens—a feature one has come to expect in almost every market.

“Smart” batched auction: A similar but arguably better approach was used years earlier by SpankChain for their ICO. Unlike Jay Peg, SpankChain collected bids that allowed specifying the quantity of tokens and price per token. After the bidding phase, they calculated a strike price off-chain and submitted it with the winning bids to a smart contract, allowing people to withdraw either SPANK if they won or their ETH if they didn’t. The downside of this approach is that the computational complexity of matching all the bids is so large that it can only be done off-chain, which requires some trust in the operator.

Raffle: Finally, one can run a raffle or lottery in which users make bids by buying tickets or reservations. Winners are then randomly selected from the pool of all tickets. This way, users receive either a full token or none, saving the three extra transactions that Jay Peg’s $DONA needed. It is also inclusive of smaller wallets that might be unable to afford one full NFT. However, it introduces randomness into the sale, which some users may prefer and others not.

Phase 2: Clearing

In this phase, the operator (or someone on their behalf) matches the bids against the available supply, deciding who gets to buy an item and who doesn’t.

On- vs. off-chain clearing

The last major junction is who gets to select the winners from the pool of all bids. In the FCFS model, this is done by miners, which we showed is broken in several ways.

In Jay Peg’s clearing mechanism, the computational complexity is just low enough to do it on-chain in a fully trustless way.

In SpankChain’s model, winners are selected entirely off-chain. While bidders cannot get filled above their desired price (the smart contract ensures this), they still have to trust the operator to not push them to their maximum fill price, similar to how a sandwich attack on decentralized exchanges works.

The raffle approach is the easiest to clear since all you need is a single random number (e.g., from Chainlink VRF). However, requiring randomness also introduces another trust assumption: whoever produces this randomness could favor their own bids over others. In contrast, this is not possible when the winning bids are simply the highest ones.

Phase 3: Distribution

After the market has cleared, the operator must mint the tokens, get them to the user, and return any losing bids if that was the model they went with. This step is generally all about gas efficiency and preventing race conditions.

Instant vs. spaced settlement

If the operator wants to prevent their users from claiming simultaneously, causing gas fees to spike, they can reuse the same randomness from the clearing process to let people claim in batches. This solves a collective action problem because users are better off not claiming all at the same time. Still, curiosity about learning about their metadata and being among the first to sell in the secondary markets might create a race condition anyway. That said, a spaced settlement also increases the waiting time for users.

Claiming vs. receiving a token

The only other thing to mention in distribution is whether users have to claim the token on their own or whether the operator can simply send it to them over time. The latter is a variation on the spaced settlement, but with the added benefit that users don’t need to do anything. The Parallel launch mentioned earlier used this method to good effect, simply requiring users to add a “delivery fee” when they initially paid for their NFTs.

Phase 4: Metadata reveal

Finally, once a token has been distributed, its metadata can be revealed. Of the four phases of NFT launches, this step must come last. It cannot be a shared last step either (e.g., by bundling payment, distribution, and reveal in the same transaction, as Meebit did) as fairness can be exploited by rerolling items with bad attributes through reverting transactions. There must be at least a one-block gap between payment and reveal to make rerolling impossible, although you may choose to increase this gap to protect against reorgs too.

When to reveal the metadata

We have now established that minting the NFT and revealing its metadata cannot happen within the same transaction, raising the question of when to reveal it instead. This is not just important for fairness, but user experience and gas efficiency play a role, too. In general, there are three options:

Full-collection reveal: In a full collection reveal, the operator waits until all NFTs of the collection have been minted before revealing the metadata. This approach is highly gas efficient, requiring only a single random number that can then be used to shuffle metadata for ticket IDs with no further action from users.

However, it has significant downsides. Namely, users have to wait until all NFTs have been minted to see metadata for their tokens. If one sets an upper bound on when to reveal the metadata (e.g., 24 hours), some users might still fail to mint in time, resulting in the collection not selling out.

Per-NFT reveal: To improve the UX of the full-collection reveal, the operator can also allow users to reveal randomness on a per-NFT basis. This is more engaging as users can “open” their item shortly after purchasing it. It also allows “unopened” items to trade in secondary markets (which is popular in trading card games like MTG).

However, this method comes with the burden of requiring users to make additional on-chain transactions, such as calling Chainlink VRF and applying a random number to their NFT. This is unavoidable even for users who don’t feel a particular urgency to reveal or who are not interested in trading unopened items.

Batched reveal: As a potential middle-ground, we propose the concept of the batched reveal. In this method, users have an indefinite period of time to mint but can also reveal their item in the next block if they want to. Every new random number requested automatically reveals the metadata of all items minted and pending assignment, revealing them at virtually the same, constant cost.

As a result, users with high time-preference have the optionality to pay for the extra on-chain transaction to reveal metadata, and this benefits all users before them. Should no user choose to reveal, the operator can also do it according to some schedule, e.g., every full hour.

Source of Randomness

After deciding when to reveal, the remaining question is where to get the randomness. The two options we suggest are using Chainlink VRF or a commit-reveal scheme.

With the former, you can access a verifiable source of randomness on-chain, on-demand. Using any of the reveal mechanisms, you can call Chainlink to request randomness, and once fulfilled, use the randomly generated number as an input to your metadata calculation. This will ensure it is randomized for each NFT.

With the latter, an operator can create one random number (for full-reveal) or several random numbers (for per-NFT or batched reveal) before the sale and pre-commit their hash. Once an NFT has been minted, the operator can reveal these numbers, allowing anyone to verify their authenticity through the hash. Still, this approach requires some trust in the operator to not exploit their privileged insight into the random numbers to mint the best NFTs. To minimize the need for trust, we recommend that some independent randomization in minting order still occur.

Additionally, for off-chain metadata, instead of committing a random number, operators may instead choose to commit a hash of the complete metadata (id-to-attributes for all NFTs). This ensures that metadata is predetermined and not altered during or after the minting process. Still, independent randomization in minting order is necessary to prevent operators from exploiting their knowledge of order and attributes.