Lesson 10 — Putting it together: walk through an exploit's commit log
The closing lesson takes everything from the prior nine and applies it to a real, recent exploit — reading the exploit transaction on-chain, mapping it back to the vulnerable code, and identifying which defence would have caught it.
Theory is necessary but not sufficient. The closing exercise is a guided walk-through of how a competent researcher reads an exploit: starting from the news headline, finding the exploit transaction on a block explorer, decoding the function calls, identifying the vulnerable contract source, and matching the bug to one of the lesson-2-through-9 classes. This is the skill the whole course is building toward.
**Stage 1: identify the on-chain transaction.** Most exploits are reported with a transaction hash. If not, the loss usually shows up as a large outflow from a known protocol contract — visible on Etherscan / Arbiscan / etc. by sorting the contract's outgoing transactions by value. Within minutes of any exploit, accounts like @samczsun, @peckshieldalert, @blocksecteam post the transaction hash. Capture the hash, the block, and the contracts involved.
**Stage 2: decode the exploit transaction.** Open the transaction on a block explorer and click 'Decode Input.' This shows the function being called and its parameters. For exploits with complex multi-step traces, use Phalcon (phalcon.xyz/explorer) or Tenderly's debugger to view the full call graph — every internal call, every storage read/write, every event emission. A typical exploit traces 30-100 internal calls; reading this graph is the primary skill.
**Stage 3: identify the vulnerable contract source.** From the call graph, identify which contract's function had the bug. Check Etherscan for 'Verified Contract' source — most modern protocols verify, so the Solidity source is available. If not, you're reading bytecode (much harder; use evm.codes and a decompiler like dedaub.com or panoramix). Capture the vulnerable function's source.
**Stage 4: map the bug to a lesson class.** Most exploits fit one of: (1) Reentrancy (lesson 4) — look for external calls before state updates. (2) Arithmetic / precision (lesson 5) — look for division-before-multiplication or overflow paths. (3) Access control (lesson 6) — look for missing modifiers or signature verification flaws. (4) Oracle (lesson 7) — look for price reads from manipulable sources. (5) Upgrade (lesson 8) — look for storage corruption or upgrade-authorisation bugs. (6) Lifecycle (lesson 3) — look for flash-loan-amplified governance or share-pricing attacks. Some bugs are combinations; few are genuinely novel.
**Stage 5: identify which defence would have caught the bug.** For each class, the defence is specific. Reentrancy → CEI + ReentrancyGuard. Arithmetic → Solidity 0.8 + multiply-before-divide + decimals normalisation. Access control → modifier + Ownable2Step + EIP-712 with nonce/deadline/chain ID + initializer modifier. Oracle → Chainlink/Pyth with staleness + deviation checks + circuit breakers + conservative LTV. Upgrade → storage-gap + _disableInitializers + timelocked multisig. Lifecycle → prior-block voting snapshots + commit-reveal + multi-block timelocks.
**Stage 6: read the post-mortem.** Within 24-72 hours of any major exploit, the protocol (and often the attacker) publishes a post-mortem. Compare your reconstruction to the official account. Skilled researchers like @samczsun, RektNews, BlockSec Insights, PeckShield typically publish detailed analyses within hours. The act of reconstructing the bug from primary sources first — then comparing to the published analysis — is what trains the skill. Reading post-mortems alone is education; reconstructing from primary sources is training.
**Stage 7: feedback loop.** Every exploit walk-through reveals something about your model. The bug that surprised you — that you didn't classify quickly, or whose defence you didn't immediately name — is the lesson to re-read. Maintain a running list of exploits you've walked through; over 20-30 cases you'll develop fast pattern recognition. The professionals in this space (the Trail of Bits team, ChainSecurity, OpenZeppelin Security, Sherlock judges) all share this pattern: they read every major exploit and absorb the lesson.
Example
Apply the framework to the Euler Finance exploit (March 2023, $197M). Stage 1: transaction hash 0xc310...0e6b on Ethereum mainnet, block 16817996. Stage 2: open in Phalcon / Tenderly. The trace shows a flash loan from Aave, several Euler deposit + borrow + liquidate operations, and a self-liquidation at the end. Stage 3: the vulnerable contract is Euler's eToken module; the specific function is `donateToReserves(uint amount)`. Stage 4: classify the bug. The function let a position donate value to reserves; the bug was that it didn't check whether the resulting position became under-collateralised. The attacker borrowed, donated *their own collateral* into reserves until their position became underwater, then self-liquidated — capturing the liquidation discount on collateral that was effectively theirs. This is a *logic* bug, not cleanly in any of our six classes, but adjacent to access control (no precondition on donation) and lifecycle (flash-loan amplification). Stage 5: the defence would have been a precondition check ensuring the position remains healthy after the donation. Stage 6: post-mortems from BlockSec and the Euler team confirm the reconstruction. Stage 7: this exploit ends up in the 'preconditions on state-changing functions' bucket — a class adjacent to access control but distinct enough to add to one's mental taxonomy. Over time the taxonomy expands; the framework for reading exploits stays the same.
Common mistakes
- Stopping at 'read the post-mortem' without reconstructing. Reading is education; reconstruction is training.
- Skipping the call-graph decoder. A 100-call trace doesn't read itself; Phalcon and Tenderly are essential tools.
- Treating every exploit as novel. The vast majority fit into half a dozen recurring patterns.
- Reading only mainnet exploits. Many of the most-instructive bugs come from L2 / sidechain / chain-of-the-month protocols.
- Confusing reading audits with reading exploits. Audits are predictive; exploits are evidence — both contribute to pattern recognition.
Check your understanding
You're walking through a recent DeFi exploit. The call graph shows: (1) attacker takes a flash loan of $100M USDC, (2) deposits it into protocol P as collateral, (3) calls P's `claimRewards` function — which uses spot reserves from P's main pool to compute reward value, (4) the spot price reads inflated because the flash loan deposit moved it, (5) attacker receives ~$8M of rewards, (6) withdraws the collateral, (7) repays the flash loan. Which lesson class does this fit?
Key terms covered
Sources & further reading
- Primary
- Primary
- SecondaryRekt News — Exploit post-mortem archive
The largest public archive of crypto-exploit post-mortems.
- Secondary
We prioritise primary sources. Where a topic moves quickly (regulation, security incidents), we re-check sources on the cadence shown by the page's "Next review" date.