1. Why sealed-bid auctions?

Auctions are a core primitive for fixed-rate lending markets, intents price discovery, token launchpads, NFT and RWA sales, and perp liquidations. Today most onchain auctions are transparent Dutch or English formats that can be manipulated and often fail to produce optimal price discovery. Sealed-bid auctions solve those issues, but existing implementations are typically offchain and centralised, which exposes them to security risks and manipulation. This section explains how to run a fully onchain and leaderless sealed-bid auction system native to Arbitrum One and Orbit. We combine:
  • FairyRing threshold key management + identity-based encryption to issue per-auction IDs and a corresponding decryption key once the bidding window closes.
  • Stylus native decryption contracts that perform onchain verification and decryption.
  • Gateway Contract + FairyPort relayer for seamless message passing between FairyRing and Arbitrum.
The result is DeBid: Bidders submit encrypted bids that stay private until the reveal time. When the bidding window closes, the decryption key is generated and used to decrypt and process all bids directly on chain.

2. Quick-start variables

Below are the environment variables used in the process.

3. Toolchain & environment setup

Install required tools and packages for the test setup.

4. Building components

Clone all required repos and build them exactly once:

5. Local FairyRing devnet

Run an instance of FairyRing devnet using the below commnad:

6. Deploying the Gateway on Arbitrum Sepolia

Use the printed Gateway address as GATEWAY_ADDRESS.

7. Configuring & running FairyPort

Use the below script to configure and run FairyPort:

8. Deploying the decrypter contracts and MultiAuctionV2

8.1 Decrypter

Use the printed decrypter address as DEPLOYED_DECRYPTER_ADDRESS.

8.2 MultiAuctionV2

MultiAuctionV2 is a generalized auction contract capable of managing multiple concurrent sealed-bid auctions. It handles encrypted bid storage, auction lifecycle tracking, and bid reveal logic. Use the below command to deploy the MultiAuctionV2:
Important: This auction contract is a minimal reference implementation intended for demonstration only. Deploying to production will require further hardening and feature completion.

9. Auction lifecycle

9.1 Create FAIRYRING_ID

To create a unique ID for an auction, first get the GATEWAY_ID corresponding to the AUCTIONEER_ADDR by calling addressGeneralID() on Gateway contract (GATEWAY_ID is a sequence that increments each time the user requests an ID). Then submit a request to the Gateway contract through requestGeneralID()and wait until the ID is generated. Once the ID is ready, it can be read from Gateway contract by calling the fids() with the AUCTIONEER_ADDR and GATEWAY_ID. This generated ID (FAIRYRING_ID) will be used by bidders to encrypt their bids.

9.2 Create an auction

9.3 Encrypt & submit bids

In order to submit a bid, first fetch the latest active encryption key from Gateway contract. Next, use the encrypter tool (ArbitrumContracts/encrypter) to encrypt the bid using the encryption key and FAIRYRING_ID specific to this auction. Then reformat the encrypted data using the ArbitrumContracts/test-simple-auction-solidity/convert_to_array.py python script. The final encrypted bid data can be submitted to the corresponding auction using the AUCTION_ID (a sequence number that increments with each auction creation).

9.4 Request key & reveal bids

Once the auction deadline is reached, the auctioneer can request and get the decryption key from Gateway contract. Then reformat the key using the same python script used for the bid data. The final decryption key can be submitted to the auction using revealBids() to decrypt the bids in batched of at most 3. If the number of submitted bids is more than 3, this function should be called repeatedly until all bids are decrypted and processed. Once this step is complete, the winner bidder and bid value can be read from the auction contract.

10. Full end-to-end deployment script

We provide a single script that handles every step from cloning the repositories to finalising several test auctions. To perform this end-to-end test, ask the team to give you access to clone the DeBid repository and run the script: (The script will ask you to add the environment variables in the .env file as needed.)