Skip to content
@Vickrey-Protocol

Vickrey

Sealed-bid Vickrey auctions on STRK20 — the losing bids are never published.

Vickrey

The auction ends and nobody learns what anyone bid

A Vickrey auction — highest bidder wins, pays the second-highest bid — has been the theoretically right way to sell one thing since 1961, and has never worked on a public chain. Sealing the bids meant trusting an auctioneer; revealing them at the end destroyed the privacy the mechanism depends on.

This one settles with a proof. The winner and the clearing price are established on-chain from hash-chain witnesses, and the losing bids are never published — not even the winner's own bid.

Open the live auctions · How it works · Source


The lifecycle

stateDiagram-v2
    direction LR
    [*] --> Open: create_auction
    Open --> Sealed: seal
    Sealed --> Settled: settle
    Settled --> Finalized: finalize
    Settled --> Cancelled: dispute succeeds
    Sealed --> Cancelled: abandon
    Finalized --> [*]: claim lot and refunds
    Cancelled --> [*]: refunds, everyone whole
Loading

create_auction escrows the lot and the auctioneer's bond. Bids arrive as two hashes and escrowed collateral — no amount, no address. seal freezes the set before any seed is sent, so the auctioneer cannot choose the set after seeing its contents. Settlement moves no money; it opens a dispute window, which is the only time a wrong outcome can be challenged.

abandon is the timeout. A sealed auction otherwise has one way out — settlement, which only the auctioneer can perform — so without it an auctioneer who walked away would lock every bidder's collateral permanently. It forfeits the bond to the bidders.

The STRK20 path

flowchart LR
    W["Bidder's wallet<br/>shielded balance"] -->|"one proved transaction"| P["STRK20 pool"]
    P -->|withdraw collateral| A["AuctionAnonymizer<br/><i>our contract</i>"]
    A -->|place_bid| S["SealedBidAuction<br/><i>our contract</i>"]
    A -.->|"emits Routed"| E1["auction_id<br/>operation"]
    S -.->|"emits BidPlaced"| E2["two hash anchors<br/>claim handle"]
    S -->|"refund · surplus · lot"| A
    A -->|"OpenNoteDeposit"| P
Loading

No bidder address ever crosses that boundary — the auction sees only the helper, and every way value returns is credited as a private note inside the pool.

Routed deliberately carries only the auction id and the operation. Not the note_id, which would let an observer tie a private note to an auction action. Not the bid index, which the auction already emits. Not any amount.

Six properties

Each is a place a straightforward implementation breaks.

  1. Bids are real escrowed funds, not promises
  2. Sealed from everyone, including the auctioneer
  3. The bid set is frozen before any amount can be read
  4. Losing bids are never published — only the clearing price
  5. The outcome is proved, not asserted
  6. Refusing to reveal cannot grief the auction

Each one, with why it is hard and how it works

Status

Built for the STRK20 Private Sprint (RFP-08).

Contracts Cairo 2.14, 80 tests, deployed and exercised on Sepolia
Interface Live at vickrey.0xo.in — public rail working, no wallet needed to read anything
Mainnet Not yet declared. Class hashes are frozen and the deployment is scripted
Audited No. The anonymizer in particular is app-team code that handles funds mid-transaction

The repository states what did not ship and why, including a defect found by audit and the reasoning for the fix that was not applied.

Popular repositories Loading

  1. vickrey vickrey Public

    Sealed-bid Vickrey auctions on STRK20 — the losing bids are never published. Live demo and full write-up at vickrey.0xo.in/docs

    TypeScript

  2. .github .github Public

    Organization profile for Vickrey — sealed-bid auctions on STRK20

Repositories

Showing 2 of 2 repositories

Top languages

Loading…

Most used topics

Loading…