Inspiration

Every market we looked at leaks the one thing participants most need to protect — and each one leaks it differently:

  • eBay publishes bid history by design. Bidder identifiers were only masked after traders were profiled directly off the ledger, and shill bidding remains a prosecuted problem on the platform. The patch addressed the symptom, not the structure.
  • Polymarket demonstrated real demand for forecast markets, and exposed a structural flaw. The running price is the aggregate forecast, so later participants can condition on it rather than forecast independently. A visible-price market measures herding as much as belief.
  • Sealed-bid tenders in real estate and public procurement already require confidentiality — but enforce it by trusting an agent or auctioneer not to disclose a rival bid. The trusted party is the vulnerability.

The common cause is that on a transparent ledger, the bid is the strategy, and the strategy is public. We wanted the properties an auction actually needs — a verifiable winner and provable rules — without the disclosure that currently comes attached.

What it does

Sealed implements sealed-bid auctions and prediction markets as confidential smart contracts on Midnight.

  • Bids exist on-chain only as cryptographic commitments — hiding the amount while binding the bidder to it.
  • Reveals are zero-knowledge proofs. The contract verifies that a bid opens its commitment and tracks the highest, but a losing bid amount is never written to the ledger. Only the winner's pseudonymous identifier and the clearing price become public, because settlement requires them.
  • Five auction mechanisms share one commitment scheme: first-price, Dutch, uniform-price batch, candle, combinatorial, and time-locked variants across 11 circuits in a single contract.
  • Prediction markets accept forecasts from autonomous agents. An agent receives a strategy prompt, runs a research pipeline against a local model, forms a posterior, and commits a forecast (1–100) under a fresh nonce. The closest forecast wins after oracle resolution.
  • Auction intelligence operates on metadata only — arrival timing, reveal behaviour, and cross-auction overlap. Bid amounts are unavailable to the detection system by construction.

How we built it

Stack: Compact 0.31 · Midnight.js 4.1 · local proof server 8.1 · Docker Compose devnet (node + indexer + prover) · zero-framework frontend, no build step.

Three contracts:

Contract Role
sealed-auction.compact Phases, commitments, ZK reveal logic (4 circuits)
auction-house.compact Five mechanisms under one commitment scheme (11 circuits)
number-game.compact Sealed beauty contest with a verified-quotient target

The bid amount, nonce, and identity secret are Compact witnesses — private inputs that never leave the bidder's machine. They live in a local identity file and feed proofs generated by a proof server running on the same host. The chain receives proofs; it never receives inputs.

For the prediction market, agent reasoning runs on a local model via ollama when one is installed, with transparent heuristic personas as a fallback. Prompts are sent to localhost only. The agent's budget, valuation, keys, and the zero-knowledge prover all sit inside the same machine boundary.

Challenges we ran into

Compact circuits provide no division operator. The beauty contest needs a target of $\frac{2}{3}$ of the mean, which is a division. We resolved this with a verified-quotient proof: the caller supplies the target $t$, and the circuit constrains it using multiplication only, given $n$ participants and sum $s$:

$$3 \cdot n \cdot t \le 2 \cdot s < 3 \cdot n \cdot (t+1)$$

An incorrect target admits no satisfying proof, so the correct value is enforced without ever dividing.

Disclosure is all-or-nothing by default. A naive Dutch auction discloses the winner's reservation price on settlement, which lets a seller price-discriminate against that bidder in the next round. claimAtCurrentPrice instead proves reservation ≥ currentPrice with no disclose statement on the amount anywhere in the circuit. The ledger learns one bit of information, including from the winner.

Combinatorial winner determination is NP-hard in general. We fixed the lot set at three, which makes exhaustive enumeration tractable in-circuit: lockAllocation evaluates all five set partitions of ${A, B, C}$ and selects the revenue-maximising allocation. The result is proven optimal rather than asserted by the seller — but only at this size, which we state as a limit rather than a feature.

Fraud detection normally requires the data we deliberately destroyed. Shill detection conventionally works on bid amounts, and we have none. The strongest available signal turned out to survive the privacy constraint intact: an account that repeatedly seals bids and never opens them is driving activity without intending to buy. The BidEvent type carries no amount field at all, so the detection system has nothing extra to leak if compromised.

Proof generation takes 30–60 seconds. We chose to display an honest timer with the real expected duration rather than an indeterminate spinner, and designed the interface around the wait instead of hiding it.

Accomplishments that we're proud of

  • The confidentiality claim is a test assertion, not a paragraph in a README. npm run test:e2e deploys a fresh auction, runs the full lifecycle with reveals in worst-case order (winner first), and asserts that losing bid values appear nowhere in indexer-visible state — searched as big-endian hex, little-endian hex, and decimal, at commit time, after all reveals, and in the final state.
  • Five distinct auction mechanisms under a single commitment scheme. What separates the formats is not the codebase; it is what each circuit proves about a commitment without opening it.
  • A prediction market that cannot be reproduced on a transparent chain. Without commitments, the last participant to submit simply reads the running aggregate off the ledger. Running it off-chain requires a host trusted not to inspect submissions. Sealed provides provably simultaneous submission with no trusted host.
  • A privacy-preserving fraud detection system. Building detection that structurally cannot become a surveillance tool was a harder design constraint than building detection that works.

What we learned

  • Constraints produced the most interesting parts of this project. The verified-quotient proof, the single-bit Dutch claim, and in-circuit winner determination all exist because the circuit language forbade the obvious implementation. None of them would have been written if division, partial disclosure, or an external optimisation step had been available.
  • Zero-knowledge design is mostly deciding what to disclose, not how to prove. The proving is largely mechanical. Determining the minimum disclosure that still permits settlement is the actual work, and it differs for every auction format.
  • An honest threat model is more useful than a complete one. A losing reveal leaks one bit; bidder identifiers are pseudonymous hashes, so cross-auction correlation is possible if an identity is reused; the time-lock depends on seller liveness. Documenting these was more valuable than papering over them.

What's next for Sealed

  • Escrowed settlement — lock funds with the bid and pay the winner atomically. The current implementation determines the winner and clearing price but does not transfer funds.
  • Real timelock encryption to remove the seller-liveness dependency. The present time-lock is commit-reveal gated on a committed tick, not a VDF or threshold committee.
  • A Vickrey second-price variant, which requires all reveals to complete before any price is disclosed.
  • Reveal deadlines with slashing, so non-revealing bidders bear a cost beyond forfeiture.
  • Larger combinatorial lot sets via a proof-of-optimality challenge game rather than exhaustive in-circuit search.
  • A browser wallet integration on Lace.

Built With

Share this project:

Updates