Patterns

The 10 canonical bug patterns

The recurring shapes behind most of the archive, each with the grep that finds it and the defence that stops it.

01

Unguarded initializers

Anyone re-runs init and takes ownership of the proxy — Harvest, Parity, Audius, Wormhole.

Find it

  • grep -rn "function initialize\|function init"

Defence: initializer modifier or first-call guard on every init

02

Missing access control on money paths

One forgotten onlyOwner is a full drain — FlippazOne, Enzyme, Alchemix AlEth.

Find it

  • grep -rn "function .*[Ww]ithdraw\|function .*[Rr]escue\|ownerWithdraw"

Defence: every withdraw/rescue/claim has an explicit check

03

balanceOf used as accounting

Donations and flash flows inflate the read — the donation-attack family.

Find it

  • grep -rn "balanceOf(address(this))"

Defence: track balances in storage, not raw reads

04

Reward-accrual checkpoint missed

One skipped checkpoint = unbounded mint — the ve(3,3) class (16 criticals from one poke).

Find it

  • grep -rn "function poke\|function merge\|function reset\|function kill"

Defence: accrue before every mutation

05

Update without revalidation

The state changes but consumers of the old value are never re-run — ThunderNFT, killed gauges.

Find it

  • grep -rn ".push\|[.*] = " near state arrays

Defence: re-run validation after every update

06

Forked constant mismatch

Copy-paste forks break invariants — Uranium, NowSwap, Nimbus.

Find it

  • grep -rn "10000\|1000\|1e3" in math

Defence: diff every constant against the original

07

Rounding direction asymmetry

Ceil-on-the-way-in + floor-on-the-way-out leaks value per user.

Find it

  • grep -rn "mulDivUp\|mulDivDown\|Math.round"

Defence: balance the directions or bound the dust

08

Reentrancy windows

State read before the external call is stale — Lendf.Me, Cream, Omni, Curve read-only.

Find it

  • grep -rn ".call\|safeTransferFrom\|safeTransfer"

Defence: CEI + nonReentrant + transient guards

09

Oracle trust without freshness/spread

Stale/manipulated prices pass — the oracle class that cost billions.

Find it

  • grep -rn "latestRoundData\|getReserves"

Defence: validate roundId+updatedAt+spread+sequencer

10

Privilege relay / hidden backdoors

Ownership relayed through 89 wallets = $7.3M locker drain.

Find it

  • map every onlyOwner/admin function

Defence: timelocks + events + off-chain monitoring