Private On-Chain OTC Protocol for Bitcoin Block Trades on Starknet
VB Desk is a private, verifiable over-the-counter (OTC) trading protocol built on Starknet. It introduces sealed-bid batch auctions to the on-chain OTC market — a mechanism that eliminates front-running, conceals order intent until execution, and produces cryptographically verifiable, deterministic clearing outcomes.
At its core, VB Desk operates through a commit-reveal-clear-settle cycle. Participants submit cryptographic commitments to their orders, reveal them within a time window, and receive fills determined by a deterministic matching engine — all with on-chain settlement and Merkle-proof-based claims.
The protocol solves four critical problems in today's OTC market: front-running and MEV (via commit-reveal), strategy leakage (via private notes), unverifiable clearing (via deterministic algorithms + Merkle roots), and fragmented liquidity (via batch auctions).
┌──────────────────────────────────────────────────┐
│ Frontend (React) │
│ Landing Page │ Auction List │ Auction Detail │
│ Create Auction │ My Bids │ Wallet Integration │
└──────────────────────┬───────────────────────────┘
│ REST API / WebSocket
▼
┌──────────────────────────────────────────────────┐
│ Backend (NestJS) │
│ Commit · Reveal · Batch · Clearing Engine │
└─────────┬────────────────────────┬───────────────┘
│ PostgreSQL │ Starknet RPC
▼ ▼
┌──────────────┐ ┌─────────────────────┐
│ Database │ │ Starknet │
└──────────────┘ │ Vault.cairo │
│ Settlement.cairo │
│ NoteRegistry.cairo │
└─────────────────────┘
| Repository | Description | Stack |
|---|---|---|
| vb-desk-contract | Smart contracts for custody, settlement, and note registry | Cairo, Starknet |
| vb-desk-backend | Auction engine, clearing, batch lifecycle API | NestJS, TypeScript, PostgreSQL |
| vb-desk-landing | Marketing landing page and dashboard | React, Vite, Three.js, Tailwind |
| github-importer | Full trading dApp frontend | React, Vite, starknet.js |
Each auction operates through four sequential phases with strict time-based transitions:
|── COMMIT PHASE ──|── REVEAL PHASE ──|── CLEARING ──|── SETTLED ──|
t0 t1 t2 t3 t4
1. Commit Phase (t0 → t1) — Participants submit a Poseidon hash of their order (price, quantity, direction, salt, wallet). No order information is visible to any party during this phase.
2. Reveal Phase (t1 → t2) — Participants reveal their actual order. The backend verifies the reveal matches the earlier commitment. Upon successful verification, the participant's tokens are locked in the on-chain Vault as collateral:
- BUY orders: lock
quantity × max_pricein quote token (USDC) - SELL orders: lock
quantityin base token (BTC)
3. Clearing (t2 → t3) — The clearing engine executes a deterministic pay-as-bid matching algorithm with multi-price execution:
- Sort buy orders by price descending, sell orders by price ascending
- Match crossing orders until no further crosses exist
- Apply partial fills where allowed
- Compute individual fill amounts for each matched order
- Construct a Poseidon Merkle tree of all fill results
- Publish the Merkle root and clearing price on-chain
4. Settlement & Claims (t3 → t4) — Each participant presents a Merkle proof to claim their filled tokens directly from the Vault. Verifiable receipts are generated so any participant can independently verify the fairness of the entire batch from public data alone.
Participant Backend Starknet
│ │ │
│── deposit ────────▶│───────────────────────▶│ Vault.deposit()
│ │ │
│── submit commit ──▶│ │
│ │── store hash + verify │
│ │ │
│── submit reveal ──▶│ │
│ │── verify preimage │
│ │── reserve collateral ─▶│ Vault.reserve()
│ │ │
│ │── run pay-as-bid │
│ │── build Merkle tree │
│ │── publish batch ──────▶│ Settlement.submit_batch()
│ │── publish allocations │
│ │ │
│── get proof ──────▶│ │
│◀── Merkle proof ───│ │
│── claim fill ─────▶│───────────────────────▶│ Settlement.claim_fill()
│◀── tokens ─────────│◀───────────────────────│ Vault.transfer_to()
│ │ │
│── withdraw ───────▶│───────────────────────▶│ Vault.withdraw()
│◀── tokens ─────────│◀───────────────────────│
VB Desk implements a privacy layer that makes depositor identity and trading activity computationally unlinkable:
| Feature | Description |
|---|---|
| Private Notes | Commitment-based balances replace public balance tracking. Each deposit creates a cryptographic note known only to its owner. Spending requires publishing a nullifier (derived from the owner's secret key) that prevents double-spending without revealing the note's value. The NoteRegistry contract maintains an insertion-only Merkle tree of note commitments and a nullifier set on-chain. |
| Ephemeral Deposit Addresses | Each deposit request generates a unique one-time address. The user sends tokens from any external wallet to this address. Once confirmed, funds are swept into the Vault and the ephemeral address is discarded — no on-chain link to subsequent trading activity. |
| Stealth Withdrawals | On withdrawal, users receive tokens at a stealth address cryptographically derived from their spending key but publicly unassociated with their identity. A (spending key, viewing key) pair allows scanning the chain for funds without exposing the spending key. |
| Guarantee | Mechanism |
|---|---|
| No front-running | Commit-reveal hides price and quantity until all commitments are locked |
| No strategy leakage | Private notes eliminate on-chain balance inference |
| Verifiable clearing | Deterministic algorithm + Merkle root + public allocations hash |
| No counterparty risk | Full collateralization at reveal time via Vault reserves |
| No double-claims | Nullifier set tracked on-chain by Settlement contract |
| Operator cannot steal | Tokens only releasable via valid Merkle proofs verified on-chain |
Built for the Starknet Re{define} Hackathon.
This project is licensed under the MIT License.