Skip to free scan

Security Patterns

Checks-Effects-Interactions (CEI)

Checks-Effects-Interactions (CEI) is a Solidity function-ordering pattern that structures a function into three phases to prevent reentrancy and other state-inconsistency bugs.

The Three Phases

  1. Checks — validate all conditions and inputs (require statements, access control).
  2. Effects — update the contract's own state (balances, flags).
  3. Interactions — make external calls (token transfers, calls to other contracts) last.

Because state is finalized before any external call, a re-entrant call sees the already-updated state and cannot exploit an intermediate value.

function withdraw(uint256 amount) external {
    require(balances[msg.sender] >= amount); // Checks
    balances[msg.sender] -= amount;          // Effects
    (bool ok, ) = msg.sender.call{value: amount}(""); // Interactions (last)
    require(ok, "transfer failed");
}

Why It Matters

The classic DAO hack succeeded because the vulnerable code sent ETH (an interaction) before updating the balance (an effect), letting the attacker re-enter and withdraw repeatedly. CEI eliminates that window.

Frequently Asked Questions

Q: Is CEI better than a reentrancy guard?

A: They complement each other. CEI removes the root cause by finalizing state before external calls; a reentrancy guard adds defense-in-depth. Use both.


Q: Does CEI prevent read-only reentrancy?

A: Correct CEI ordering helps, because state is consistent before external calls. But read-only reentrancy also depends on how integrators read your getters, so exposing a reentrancy lock is still recommended.

Related terms

Firepan

Scan Your Contracts

Run a free surface scan — results in minutes, no credit card required.

Run Free Scan →