Design Proof of Reserves

Hard45 min
1 / 30
understanding9 min read

Problem Statement: Exchange Proof of Reserves

Problem Statement: Exchange Proof of Reserves — proof of reserves interview depth

Problem Statement: Exchange Proof of Reserves

Section 1 covers understanding for a Kraken/Chainlink-class Proof of Reserves platform.

  1. Proof of Reserves (PoR) answers one question: do customer balances on our internal ledger have matching assets we control on-chain?
  2. Post-FTX, exchanges publish wallet lists plus Merkle trees so users verify inclusion without revealing neighbor balances.
  3. Liabilities are the sum of user account balances in the exchange ledger at snapshot time T (integer smallest units).
  4. Assets are provable balances at labeled hot, cold, staking, and treasury wallets—double-counting is the #1 engineering bug.
  5. Coverage ratio = total provable assets / total liabilities; must be ≥ 1.0 with disclosed buffers for operational float.
  6. Merkle leaf typically hashes (user_id_salt, balance) so users get inclusion proofs without publishing the full user list.
  7. Third-party auditor signs the methodology + wallet list + root hash; engineering owns reproducible build pipeline.
  8. Chainlink PoR feeds let DeFi protocols consume attestation roots on-chain—your design should expose a signed publish hook.
  9. Nic Carter's PoR framework stresses liabilities definition, asset definition, and transparency of wallet ownership.
  10. Hot wallets move fast; cold wallets dominate BTC/ETH reserves—both must be in scope or explain exclusion.
  11. Borrowed assets used as collateral must not count as reserves unless you net against user borrow liabilities explicitly.
  12. Stablecoins count at face value only if tokens are held 1:1 in known addresses—no unbacked internal IOUs.
  13. Snapshot requires brief trading freeze or logical snapshot isolation so liabilities do not move mid-tree build.
  14. Reconciliation job compares ledger liabilities to sum of Merkle leaves; mismatch blocks publication.
  15. User verify flow: download proof path + root + auditor signature; client recomputes leaf hash with their account id salt.
  16. CAP: liability snapshot is CP in PostgreSQL; chain balances are AP with quorum RPC and delayed finality buffers.
  17. Idempotent snapshot jobs keyed by snapshot_id; replays must not duplicate Merkle roots in public archive.
  18. Privacy: never publish raw balances in leaves—use salted hashes and optional ZK upgrade path in v2.
  19. Attack: exchange moves funds after snapshot photo—mitigate with continuous wallet monitoring between attestations.
  20. Attack: exclude large liability buckets (margin, earn)—interviewers ask what product lines are in liability definition.
  21. Regulators want historical archive of roots, wallet lists, and coverage ratio time series.
  22. Interview opening: separate custody proof from exchange solvency of corporate equity—PoR is necessary not sufficient.
  23. Staff+ cite Kraken's public Merkle verification tool and Binance's zkPoR direction as industry benchmarks.
  24. Do not confuse PoR with Proof of Solvency (includes off-chain fiat and corporate debt)—state MVP boundary.
  25. Operational metric: time to rebuild Merkle tree for 12M users—shard builders horizontally.

Metrics interviewers expect

  • liabilities ≤ provable assets
  • Merkle leaf per user
  • Kraken-style PoR
  • third-party audit

Engineering notes

PoR pipeline for Problem Statement: Exchange Proof of Reserves: snapshot liabilities at block T, aggregate labeled wallets with RPC quorum, compute coverage ratio, build salted Merkle tree, publish auditor-signed attestation, expose user verify API.

Publish gate halts if coverage < policy buffer or ledger–Merkle reconciliation fails.

Store roots and proofs in immutable object lock buckets for regulatory history.

javaOne Dark Pro
1public record PorContext1(String snapshotId, byte[] merkleRoot, long totalLiabilitiesSat) {}
pythonOne Dark Pro
1def coverage_ratio(assets: int, liabilities: int) -> float:
2 return assets / liabilities if liabilities else 0.0
typescriptOne Dark Pro
1export function leafHash(salt: string, accountId: string, balance: string): string {
2 return sha256(`${salt}:${accountId}:${balance}`);
3}

Why interviewers care

Proof of Reserves interviews reward crisp scope, explicit trade-offs, and failure stories—not generic microservice diagrams.

Interview checkpoint

Name one failure story for Problem Statement: Exchange Proof of Reserves that proves you understand real outages, not happy-path diagrams.

Key Highlights

  • liabilities ≤ provable assets
  • Merkle leaf per user
  • Kraken-style PoR
  • third-party audit
Mention this
For Problem Statement: Exchange Proof of Reserves, state coverage ratio formula and what liabilities you exclude before drawing architecture.
Staff+ signal
Separate asset aggregation, liability snapshot, Merkle build, and verify API—each with independent health metrics.

Section Rescue Kit

Buzzwords to use:

Proof of ReservesMerkle Inclusion Proof

Safe statements:

  • "On Problem Statement: Exchange Proof of Reserves, I'll define liabilities and assets on the board before naming services."
  • "PoR proves backing at snapshot T; I will call out what it does not prove about management honesty."
Design Proof of Reserves - System Design | WinJob | WinJob