Six steps, from launch to claim
Every sale follows the same path, and every path ends with each bidder able to claim.
Step 1. Set the sale terms
CreatorChoose the supply for sale, floor price, minimum raise, bid window and per-account caps. The contract deploys the token with a fixed supply to its own sub-account,
<sale_id>.<contract>. Every parameter is locked at creation, and there is no admin key.Step 2. Get USDC on NEAR
BidderUse USDC you already hold on NEAR, or fund from SOL, ETH, BTC or USDC on another chain through NEAR Intents 1Click. The USDC lands in your own NEAR account.
Step 3. Submit a sealed bid
BidderOne transfer carries a public USDC deposit plus an encrypted payload containing your max price, max spend and a random salt. The browser seals it to the sale’s enclave key. When the gas relayer covers the transaction, you need USDC and no NEAR.
Step 4. Close the bid window
AnyoneAfter the window ends, anyone can call close. The bid set is frozen on-chain and the contract stores its hash.
Step 5. Calculate the clearing price
OutLayer TEEThe enclave decrypts the bids, computes the clearing price and fills, and returns the result. The contract accepts a result from OutLayer for the job hash pinned at deployment. It checks the arithmetic it can see, then settles.
Step 6. Claim tokens and refunds
Every bidderWinners get tokens at the clearing price plus any unspent USDC. Valid bids that lose get a full refund, and so does every valid bid if the minimum raise is missed. A void bid gets its deposit back less 1 %. If clearing never arrives, everyone is refunded in full.
The clearing rule
One price for everyone: the highest price, at or above the floor, at which the bids willing to pay at least that much still buy the whole supply.
The sum runs over every bid with pi ≥ P.
- P*
- Clearing price
- The one price every winner pays.
- F
- Floor price
- Fixed at launch. Nothing fills below it.
- S
- Sale supply
- The tokens for sale.
- pi
- Max price of bid i
- In USDC per token. Sealed.
- mi
- Max spend of bid i
- In USDC. Sealed, and can be lower than the deposit.
Who gets what
- Max price above P*
- Filled in full at P*.
- Max price exactly P*
- Ties share what is left, pro rata to how many tokens each bid could buy at that price.
- Max price below P*
- Not filled. The whole deposit comes back.
- Rounding
- Every share is rounded down to the smallest token unit. Leftover units go out one at a time, in bid order.
- Undersubscribed
- If demand at the floor is below S, then P* is the floor, every valid bid fills in full, and the unsold tokens are burned. That rule is fixed at launch.
- What you pay
- spent = ⌈ tokens × P* ⌉, in USDC base units. It is never above your max spend. The rest of your deposit is refunded.
- Invalid bids
- A bid that fails to decrypt, copies another bidder’s ciphertext, sets a zero max spend or one above its deposit, or a max price below the floor counts as zero. Its deposit is refunded less a 1 % penalty, rounded up, the same as a commit-reveal bid that is not revealed. The app refuses to send such a bid, so an honest bidder never pays it.
- Minimum raise
- If the total raise is below the minimum, the sale fails and every valid bid is refunded in full.
Integer math only: USDC has 6 decimals, tokens 18. Prices step in whole USDC base units, so in rare cases the bids above P* alone want more than S; then they are prorated the same way. The enclave runs a Rust port of the same TypeScript code that runs below, and the two must agree on every random bid set.
Worked example
Edit any number. The clearing runs live in your browser with the reference code from @fairground/clearing.
- Tokens
- 5,000
- Spent
- 10
- Refund
- 0
- Tokens
- 4,000
- Spent
- 8
- Refund
- 0
- Tokens
- 600
- Spent
- 1.2
- Refund
- 4.8
- Tokens
- 400
- Spent
- 0.8
- Refund
- 3.2
- Tokens
- 0
- Spent
- 0
- Refund
- 5
- Tokens
- 0
- Spent
- 0
- Refund
- 3
| Bidder | Max price | Max spend | Tokens | Spent | Refund | Outcome | Remove |
|---|---|---|---|---|---|---|---|
| 5,000 | 10 | 0 | Filled in full | ||||
| 4,000 | 8 | 0 | Filled in full | ||||
| 600 | 1.2 | 4.8 | At P*, pro rata | ||||
| 400 | 0.8 | 3.2 | At P*, pro rata | ||||
| 0 | 0 | 5 | Below P*, refunded | ||||
| 0 | 0 | 3 | Below P*, refunded |
In a real sale only the enclave sees these prices. Prices are in USDC per token, and each deposit equals its max spend.
2 bids sit exactly at P*. After the bids above it fill in full, they share the 1,000 tokens left, pro rata: carol.testnet 600 and dave.testnet 400.
Demand at each price
The tokens the bids could buy at each price, on a log scale. The line drops wherever a bid’s max price is passed, and P* is the last price where it still reaches the supply.
What is public, what stays hidden
Deposits are public so the contract can hold and check the money. Prices are sealed so nobody can bid around them.
Max price
- During the sale
- Hidden (encrypted)
- After settlement
- Never published
Max spend
- During the sale
- Hidden (can be lower than the deposit)
- After settlement
- Never published
Deposit amount, bidder account, bid time
- During the sale
- Public on-chain
- After settlement
- Public
Clearing price, each fill, each refund
- During the sale
- Not known yet
- After settlement
- Public
Anonymized demand curve
- During the sale
- Not known yet
- After settlement
- Optional, chosen at launch (planned)
| Data | During the sale | After settlement |
|---|---|---|
| Max price | Hidden (encrypted) | Never published |
| Max spend | Hidden (can be lower than the deposit) | Never published |
| Deposit amount, bidder account, bid time | Public on-chain | Public |
| Clearing price, each fill, each refund | Not known yet | Public |
| Anonymized demand curve | Not known yet | Optional, chosen at launch (planned) |
Bids are encrypted in your browser with a libsodium sealed box to the sale’s own key. No server stores bid contents; the gas relayer keeps only rate-limit counters. Individual max prices are not in the enclave’s output either.
Trust assumptions
The contract holds the money and checks every clearing result. The enclave is trusted only with the hidden prices.
What you trust
OutLayer’s TEE
Keeps bid prices secret and runs the published job inside Intel TDX. The job’s hash is pinned in the contract at deployment and cannot change. OutLayer attests each run (the code hash, the bids that went in, the result that came out), and the contract accepts a result only for the pinned hash. The result page shows that hash next to our reproducible build.
OutLayer’s master secret
Known privacy risk
Each sale’s key is derived inside the enclave from one OutLayer master secret. OutLayer’s own docs say a DAO full-access key can currently obtain that master secret outside an enclave. Whoever holds that key could, in principle, derive a sale’s private key and read its sealed bids. The clearing math and payouts would still be checked by the contract, but price privacy would not hold.
NEAR Intents 1Click
Routes cross-chain funding through solvers. A failed swap refunds to the origin address.
The gas relayer
Pays the network fee for bids, reveals, claims, clearing a commit-reveal sale and refund mode, including the 1 yoctoNEAR a USDC transfer has to attach. It cannot move anyone’s funds and stores only rate-limit counters. A gasless bid needs a wallet that signs a delegate action with a full-access key. Other wallets send the same bid as a normal transaction with a small NEAR fee, and so does everyone while the relayer is down or out of budget. Creating and closing a sale attach NEAR, so they are never relayed.
What the contract checks itself
Everything public is verified before settling. There is no admin key: the contract has no owner methods, and sale parameters cannot change after creation.
- The result came from OutLayer for the pinned enclave code hash
- Its bid-set hash equals the hash stored at close
- The bids were opened with this sale’s published key
- The clearing price is at least the floor
- Tokens filled are at most the sale supply
- There is one fill for every bid in the frozen bid set
- No fill costs more than that bidder’s deposit
- Every charge equals tokens × clearing price
- No bid listed as invalid received tokens
- The total raise meets the minimum, or the sale refunds
This demo runs on a simulated chain in your browser, including a simulated attestation and a simulated gas relayer. The sealed-box encryption and the clearing math are real.
Honest limits
What Sealround does not fix, stated up front.
Money still talks
Sealround removes the speed advantage and the information advantage. It does not remove the capital advantage: a whale can still buy a large share at the clearing price.
Sybils dodge caps, not prices
Per-account deposit caps are demo-grade. Splitting money across many wallets gets around the cap, but every wallet still pays the same clearing price, so there is nothing to gain on price.
Bid slots can be squatted
A sale takes a fixed number of bids, first come, first served, and the contract cannot read a sealed bid. Someone can fill the slots with junk and block real bidders. A void bid loses 1 % of its deposit, at least 0.01 USDC, so it costs them, but not much. The creator’s lever is a higher minimum deposit.
Privacy depends on the TEE
If the enclave or the way its master secret is held is broken, sealed prices can be read. See the trust assumptions above.
Deposits are public
Anyone can add up deposits during the window, so total demand in USDC is visible. Individual max prices and max spends are not.
After the sale is out of scope
A fair price at launch does not stop a dump later. Trading after settlement is not something Sealround controls.
The contract is unaudited
The Sealround contract has not been audited. The demo uses simulated USDC.
Failure cases
Every path ends in Settled or Failed, and both let every bidder claim.
Clearing times out
The enclave never answers
Every sale has a settle timeout, fixed at launch (2 hours by default). Once it passes with no result, anyone can call trigger_refund_mode. The sale moves to Failed and every bidder claims a full refund.
Invalid or copied bids
A bid the enclave cannot accept
A bid that fails to decrypt, names a different bidder or sale (a copied ciphertext), sets a max spend above its deposit, or bids below the floor is void. It counts as zero, and its deposit is refunded less a 1 % penalty, the same as a commit-reveal bid that is not revealed. The penalty is what makes junk bids cost something. The rest of the sale clears normally.
See Lantern’s copycat botA funding swap fails
1Click ends REFUNDED or FAILED
The funds go back to the origin address on the origin chain. No bid was placed, so nothing is locked in Sealround. The funding panel shows every 1Click status in plain words.
Minimum raise missed
Total raise below the minimum
The sale fails. Nobody gets tokens, and every valid bid gets its whole deposit back. A void bid still loses its 1 %.
See DriftwoodFallback: commit-reveal mode
If the TEE cannot be used, a sale can run in commit-reveal mode instead.
Bid as a commitment
Instead of a sealed box, the bid carries
sha256(sale_id ‖ bidder ‖ max_price ‖ max_spend ‖ salt)next to the public deposit.Reveal after close
A reveal window follows the close: 10 minutes by default, set at launch. Each bidder publishes their max price, max spend and salt, and the contract checks them against the commitment. The salt is saved in the browser the bid came from, and can be backed up as a file.
Clear on-chain
Once the window ends, anyone can have the contract run the same clearing rule itself. A bid that was not revealed is void: it is refunded less a 1 % penalty, which stays locked in the contract for good.
Prices during the sale
- TEE
- Hidden (encrypted)
- Commit-reveal
- Hidden (only a hash)
Prices after the sale
- TEE
- Never published
- Commit-reveal
- Public at reveal
Extra step for bidders
- TEE
- None
- Commit-reveal
- Reveal within the window
If a bidder does nothing
- TEE
- Nothing changes
- Commit-reveal
- Void: refund less 1 %
A bid that breaks a rule
- TEE
- Void: refund less 1 %
- Commit-reveal
- Void: refund less 1 %
Who clears
- TEE
- OutLayer enclave, checked by the contract
- Commit-reveal
- The contract alone
| Feature | TEE mode (default) | Commit-reveal fallback |
|---|---|---|
| Prices during the sale | Hidden (encrypted) | Hidden (only a hash) |
| Prices after the sale | Never published | Public at reveal |
| Extra step for bidders | None | Reveal within the window |
| If a bidder does nothing | Nothing changes | Void: refund less 1 % |
| A bid that breaks a rule | Void: refund less 1 % | Void: refund less 1 % |
| Who clears | OutLayer enclave, checked by the contract | The contract alone |
This mode is weaker, and we say so: everyone’s max price becomes public at reveal, and a bidder who misses the reveal window, or loses the salt, pays the 1 % penalty. Each sale’s mode is fixed at launch and shown on its page.
Argue against this idea
The strongest case against Sealround, in our own words.
It is not new
Sealed-bid, single-price batch auctions have run on Ethereum for years.
Money still wins share
They remove speed and information advantages, but not capital. A whale still buys a large share at the clearing price.
Privacy rests on one provider
Sealed prices depend on OutLayer’s TEE and on how its master secret is held today.
A fair launch is not a fair market
Most memecoin launches are speculation. A fair price at launch does not stop a dump later.
Token sales are regulated
In some countries they are. Anything beyond a capped, no-value experiment needs legal advice.
Why we build it anyway
The sniping problem is real at every launch. NEAR is the one stack with a TEE, cross-chain funding and chain signatures together. And the clearing checks live in a contract anyone can read.