defirisk.co
rubric v1.7.0

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.

Data & output #

Data source
Slither `reentrancy-eth` + `reentrancy-no-eth` detectors on Etherscan-verified source
Output format
Green / Yellow / Red
Evidence artifact
Slither output JSON + list of flagged function names
Confidence signal
green = 0 reentrancy findings; yellow = findings present but only in low-TVL peripheral contracts; red = reentrancy finding in core (borrow/withdraw/mint) function; gray = source unverified

Scored protocols 0 carry this factor#

No protocols have been scored for this factor yet.

Linked hacks 2 historical incidents#

relatedMakina Finance: Permissionless share price oracle update (updateTotalAum) + flash loan Curve pool manipulation → share price inflation → LP drain2026-01-20 · $4M · Permissionless share price oracle update (updateTotalAum) + flash loan Curve pool manipulation → share price inflation → LP drain · Reentrancy guard absence [via cross-hack: Factor 14: Public Permissionless Functions That Can Re-Trigger Vulnerable State]
illustrativeCompound Finance: Governance-introduced bug — updated Comptroller vault incorrectly distributed COMP rewards; any user could call `drip()` to refill the vulnerable vault from the Reservoir2021-09-29 · $147M · Governance-introduced bug — updated Comptroller vault incorrectly distributed COMP rewards; any user could call `drip()` to refill the vulnerable vault from the Reservoir · Reentrancy guard absence [via cross-hack: Factor 14: Public Permissionless Functions That Can Re-Trigger Vulnerable State]
rubric_version v1.7.0factor RD-F-014category 1carried 0critical no