Reentrancy guard on external-calling functions
Curve Finance's assessment for RD-F-014 — scored green on the v1.7.0 rubric. The evidence below is the curator's reasoning for this score.
Evidence summary #
NG contracts (CurveTricryptoOptimizedWETH.vy, CurveStableSwapNG.vy) use @nonreentrant('lock') on all state-mutating externally-callable functions: exchange(), add_liquidity(), remove_liquidity(), remove_liquidity_one_coin(), claim_admin_fees(). Compiled with Vyper 0.3.10 which correctly implements storage slot assignment for reentrancy guards (fix landed in 0.3.1, per official Vyper post-mortem). Legacy pools with broken guards are effectively abandoned post-exploit.
Sources #
- GitHubCurveTricryptoOptimizedWETH.vy source inspectionCurveTricryptoOptimizedWETH.vy — @nonreentrant on exchange, add_liquidity, etc.retrieved 2026-04-28
- Vyper Nonreentrancy Lock Vulnerability Post-MortemVyper post-mortem confirming fix in 0.3.1retrieved 2026-04-28
- CurveStableSwapNG.vy source inspectionCurveStableSwapNG.vy — @nonreentrant('lock') on exchange, add_liquidity, remove_liquidityretrieved 2026-04-28
Methodology #
Determine whether all state-mutating functions that perform external calls carry `nonReentrant` or an equivalent reentrancy guard.
See the full factor methodology and distribution across all protocols →