Reentrancy

SCWE-046: Reentrancy Attacks

Theory

Reentrancy is one of the most well-known and impactful vulnerabilities in Ethereum smart contracts. It occurs when a contract performs an external call before updating its state. This allows the external contract, possibly malicious, to reenter the original function and repeat certain actions, like withdrawals, using the same state. Through such attacks, an attacker can possibly drain all the funds from a contract.

If a smart contract function:

  • modifies balances after sending ETH,

  • changes storage after calling an external contract,

  • depends on invariants that must hold during execution,

then an attacker can exploit this state inconsistency to drain funds, bypass access checks, or repeatedly trigger logic.

How Reentrancy Works at the EVM Level

  1. Contract A executes a function (e.g., withdraw()).

  2. Before updating its state, it performs a CALL to an attacker contract.

  3. The attacker contract’s fallback or receive function is triggered.

  4. The attacker calls back into A — re-entering — while A's state has not yet been updated.

  5. The victim contract is tricked into repeating a sensitive operation (usually transferring funds).

Practice

Single-function Reentrancy

Single-function reentrancy is the simplest and most direct form of the vulnerability. The attacker simply needs an entry point that:

  • performs a state-changing action,

  • but performs an external call before the state update,

  • and uses the affected state variable again upon re-entry.

Below is a minimal example. The contract reads a state variable, performs an external call, and only then updates the state, allowing the attacker to re-trigger the same logic multiple times.

Running the below foundry script will drains the vault by performing a reentrant withdrawal.

Resources

Last updated

Was this helpful?