Every time I look at a proof-of-reserves page I have the same reaction, which is that it tells me exactly half of what I need to know and presents that half like it is the whole thing. The half it shows me is the assets. Here are the wallets, here is what they hold, look how much money we have. The half it usually buries is the liabilities, meaning what the exchange actually owes its customers. Solvency is the gap between those two numbers, not the size of either one alone. An exchange can hold a billion dollars in visible reserves and still be insolvent if it owes its customers two billion. FTX taught a lot of people that the reserve side can look fine right up until the day it doesn't.
So the useful skill is not reading a proof-of-reserves dashboard. It is auditing one yourself, on-chain, and knowing where the honest-looking version still leaves room to lie. You do not need to be a cryptographer. You need a block explorer, some patience, and a healthy suspicion of round numbers that show up right before an attestation date.
Start with the wallet list, and treat it as a claim
The first thing you want is the exchange's published list of on-chain addresses. Serious exchanges publish these, either on a reserves page or in a support article, sometimes broken out by chain. The moment you have that list, remember what it is. It is a set of addresses the exchange asserts belong to it, and that assertion is worth almost nothing until proven. So the first check is proof of control.
The clean way an exchange proves it controls an address is a signed message. They sign a specific string with the address's private key, and anyone can verify that signature against the public address. If the page gives you signed messages, verify a couple rather than assuming. If it just gives you addresses with no signatures, you are trusting a spreadsheet. That is not fatal on its own, plenty of large exchanges are sloppy about signatures, but it moves the whole exercise into lower-confidence territory and you should file it that way.
Once you trust the list, pull each address up in a block explorer. Etherscan for Ethereum-based holdings, the equivalent for whatever chains they use, and check the balances plus token holdings. Add it up. Now you have your own number for the asset side, independent of whatever the exchange's dashboard rendered for you.
The snapshot problem, which is where most of the games live
Here is the failure mode that matters most, and it is almost invisible if you only look on the day of the attestation. Proof of reserves is usually a snapshot. The exchange proves it held X at a specific block height. Nothing stops it from borrowing a large amount right before that block, holding it long enough to be counted, and sending it back after. The wallet looked full at the exact moment someone was checking, and empty a day later.
You catch this by refusing to look at a single point in time. Pull the transaction history of the reserve wallets and look at flows around any attestation date. What you are hunting for is a big inbound transfer shortly before the snapshot and a matching outbound transfer shortly after, especially from and to addresses tied to other exchanges or known market makers. One clean round-trip like that tells you the reserves were rented. Historically this is how several exchanges passed reserve checks while being nowhere near as liquid as the snapshot implied. If you can watch the same wallets over weeks, borrowed reserves stand out, because real customer float does not swing in and out on the calendar of the audit.
A related tell is concentration. If a large share of the reserves sits in the exchange's own thinly-traded token, marked at a price the exchange itself heavily influences, then the reserve number is partly a number the exchange gets to invent. Discount those holdings hard, and see what real assets are left.
The liability side, and why the Merkle tree matters
Assets are the easy half because they are on-chain and public. Liabilities are the hard half because they live in the exchange's private database, and this is where the Merkle-tree attestation comes in. A Merkle tree lets the exchange commit to the total of every customer's balance by publishing a single root hash, and it lets you, as an individual customer, verify that your own balance was included in that total without the exchange revealing everyone else's balances.
The mechanism is worth understanding because its limits are the whole point. The exchange gives you a Merkle proof for your account, a short path of hashes. You combine your balance with those hashes, walk up the tree, and check that you land on the published root. If you do, your money was counted. If a lot of customers do this and all land on the same root, the exchange cannot easily undercount what it owes, because undercounting means leaving real customers out and any excluded customer's proof would fail.
The gap, and it is a large one, is that a Merkle tree of liabilities proves inclusion, not completeness. It stops the exchange from hiding liabilities downward. It does nothing about negative balances or fake accounts. An exchange can quietly insert accounts with negative balances to shrink the total it appears to owe, and a plain Merkle root will not reveal it. This is why stronger versions use a proof of liabilities constructed to be sound against negative entries, and why an attestation reviewed by a credible third party who checks the construction beats a raw root hash the exchange published alone. When you read the attestation, look for whether it addresses negative balances at all. Most consumer-facing pages do not even mention the issue, which tells you how much of the design they actually implemented.
A checklist you can actually run
- Find the published wallet list. No list, no assessment.
- Verify signed proof of control on a sample of addresses. No signatures means lower confidence downstream.
- Sum the balances yourself in a block explorer. Do not trust the dashboard total.
- Pull transaction history around attestation dates and hunt for borrow-and-return round trips.
- Discount or drop any reserves held in the exchange's own token.
- Confirm there is a liability attestation at all, not just an asset page. Assets without liabilities is marketing.
- Check whether the liability proof addresses negative balances and whether a credible third party reviewed the construction.
- Verify your own Merkle proof if you have funds there. It takes minutes and it is the one check nobody can fake for you.
None of this gives you certainty. What it gives you is a graded read on counterparty risk, which is the right frame. An exchange that publishes signed wallets, a soundly constructed liability proof, and reserves that sit stable across snapshots earns a bigger slice of your balance than one that shows a pretty asset total and nothing else. When we surface exchange risk signals inside Blockcircle, this is roughly the hierarchy we score against, because the on-chain flow history usually contradicts the dashboard before anything else does. Keep what you cannot afford to lose in wallets you control, size your exchange exposure to how much an exchange actually lets you verify, and revisit it, because a clean snapshot last quarter is not a promise about this one.