Reentrancy guard on external-calling functions
A code & audits factor in the v1.7.0 rubric. Measured per protocol on a s cadence.
Methodology how we score #
**What this measures** This factor assesses whether all functions that perform an external call before completing state updates carry a nonReentrant modifier or an equivalent reentrancy guard. The assessment is performed by static analysis: for each function containing an external CALL or DELEGATECALL opcode, the tool verifies whether a reentrancy lock (storage slot or transient storage flag) is set before the call and cleared after. Functions that follow strict Checks-Effects-Interactions ordering without a lock are reviewed manually.
**Why it matters** Reentrancy is the most persistently exploited vulnerability class in DeFi history, accounting for approximately 15 hacks in the T-01 evidence inventory. The Compound fork reentrancy pattern -- where a callback token triggers a reentrant borrow or exitMarket() before the protocol updates the caller's balance -- was exploited four times across Cream Finance, Voltage/Ola, Hundred Finance, and Fei/Rari Fuse. Each time, the same CEI violation was present in a different fork of the same codebase. The nonReentrant guard is a low-cost, high-coverage defense that eliminates the entire callback-reentrancy class; its absence on externally-calling functions is a clear code quality gap.
**Green / Yellow / Red** Green: all functions that make external calls before completing state updates carry nonReentrant or equivalent guards, confirmed by static analysis of deployed bytecode. Yellow: reentrancy guards are present on primary fund-moving functions but absent on peripheral functions (e.g., reward claims, fee collection) that make external calls. Red: any function that moves user funds or updates critical accounting state makes an external call before completing state updates without a reentrancy guard.
**Common gray cases** Reentrancy guards are not meaningful for protocols with no external call paths (pure computation contracts). This factor is gray for simple token contracts or non-interactive computation modules.
**Notable historical examples** - **Compound Finance** ($147M, 2021): Permissionless state-refill function without reentrancy guard enabled the drip() attack. - **Makina Finance** ($4.13M, 2026): Reentrancy guard absent on permissionless state update function using external pool state.
Measurement what to look for #
Determine whether all state-mutating functions that perform external calls carry `nonReentrant` or an equivalent reentrancy guard.