Audit tooling

Pre-audit checklists

Pick a protocol category. You get the root causes that killed similar protocols, the protocols they killed, and the checks that find them.

Staking, Rewards & ve(3,3)

01

Once-per-epoch guard missing

An action that should run once per epoch (poke, reset, checkpoint) runs every time — rewards mint unboundedly.

KilledAlchemix v2 — 16 confirmed criticals from one poke()

Checks

  • grep -rn "onlyNewEpoch\|lastEpoch" <repo> — is the guard on EVERY accrual path?
02

Claim-before-burn missing on merge/withdraw

When a position NFT is burned or merged, unclaimed rewards are not forced out first — they freeze or are stolen.

KilledAlchemix veALCX mergeve(3,3) forks broadly

Checks

  • Trace merge/burn: is _claim called before _burn?
03

totalVoting / bribe accounting desync

withdraw/reset change voting power without decrementing the tracked total — bribe distribution math breaks and users claim unearned bribes.

KilledAlchemix Bribe.sol

Checks

  • For every state-mutating function: does the aggregate (totalVoting/totalSupply) move in the SAME direction? Build the asymmetry table.
04

Checkpoint double-counts balance

A revenue checkpoint adds the current unclaimed balance as new revenue — the same tokens accrue twice.

KilledAlchemix RevenueHandler

Checks

  • Read every "+= balance" in reward math: is the balance already accounted?
05

Killed gauge keeps accruing

After a gauge/strategy is killed, its weight is not revalidated — it keeps eating the reward share.

KilledAlchemix MinterCurve gauge family

Checks

  • After kill: is the weight zeroed or skipped in distribution?
06

Retroactive parameter changes

Fees/lock params change and apply to EXISTING positions with no snapshot — locked users get new terms they never agreed to.

KilledTransmuter fee classMultiple staking protocols

Checks

  • Are params snapshotted per position, or read globally at claim time?