‹ Crypto Risk & Custody Lesson 10 of 16
Contents Lesson 10 of 16

4 min read · professional

Which exploit patterns keep repeating?

Nearly every large on-chain loss falls into one of five families. They are not obscure. They are documented, taught, and detected by standard tooling — and they keep happening, which tells you the problem is not knowledge.

1. Reentrancy

A contract sends value to an external address before updating its own internal state. The recipient is itself a contract, and its receive function calls straight back in — at which point the balance has not yet been decremented, so it can withdraw again. And again.

The canonical case is The DAO in June 2016: roughly 3.6 million ETH drained, worth around $60m at the time. The response — a contested hard fork to reverse it — split the network into Ethereum and Ethereum Classic, which remains the most consequential governance decision in the ecosystem's history.

Reentrancy is nearly a decade old and still appears, in newer forms: cross-function reentrancy, cross-contract reentrancy, and read-only reentrancy where a view function returns a stale value mid-transaction.

2. Access control and initialisation

A privileged function left unprotected, or a contract left uninitialised so that anyone can claim ownership.

The Parity multisig wallet library produced both variants within months. In July 2017 a flaw in the wallet initialisation allowed an attacker to take ownership of wallets and remove roughly 150,000 ETH. In November 2017 a user initialised the shared library contract itself and then triggered its self-destruct, permanently freezing roughly 513,000 ETH in every wallet that depended on it. Nothing was stolen in the second incident. For the owners the outcome was identical.

3. Price manipulation with flash loans

A flash loan supplies uncollateralised capital for the duration of a single transaction, on the condition it is repaid before that transaction ends. It makes capital a non-barrier to any attack that begins and ends atomically.

The classic target is a protocol that reads its prices from a spot automated market maker pool. Within one transaction an attacker borrows, moves the pool's price, causes the victim protocol to read the moved price, extracts value, restores the pool and repays. This family produced a long run of eight- and nine-figure losses through 2020 to 2022. Time-weighted and multi-source oracles raise the cost substantially — they do not remove the class, they price it.

4. Logic and accounting errors

Rounding, decimals, an inverted comparison, share-price manipulation on the first deposit into an empty vault. Unglamorous and expensive.

A clean documented example: in September 2021 a Compound protocol upgrade contained a comparison error in the distribution logic that caused roughly $80m of COMP tokens to be distributed in error. The fix required a governance proposal with its own multi-day process — so the bug kept paying out while the remedy went through the constitutionally required delay.

5. Key and signer compromise

The code was correct. Someone obtained the keys, or the signers, or the deployment pipeline. No amount of contract review addresses this, and it accounts for a very large share of the biggest losses — the subject of the next lesson.

The structural point

Four of these families are code problems and one is a people problem, and the industry's spending is nowhere near proportionally allocated.

There is also a trap in the remedy. Immutable code cannot be patched: a discovered bug can only be raced. So protocols add pause functions and upgradeability to be able to respond — and in doing so create exactly the privileged keys that constitute family five. There is no configuration that eliminates both. What exists is a choice, and the useful question about any protocol is which one it made and whether it said so.

Try it now

  1. For a protocol you can read about, find whether it has a pause or emergency function and who can call it. Then state which risk that protocol has chosen: an unpatchable bug, or a privileged key.
  2. Find one public post-mortem of an on-chain exploit and classify it into one of the five families above. Note whether the protocol had been audited, and whether the audit covered the component that failed.
  3. Check whether the protocol derives prices from a single spot pool or from time-weighted or multiple sources. The documentation usually states it; if it does not, that is itself a finding.