Reentrancy Attack Definition: A reentrancy attack is a type of smart contract exploit in which a malicious contract repeatedly calls back into a vulnerable contract before the first call has finished, draining funds by repeatedly triggering a withdrawal-like function while the contract’s internal balance has not yet been updated. The attack exploits a specific ordering mistake: contracts that send funds to an external address before recording that the funds have been sent can be tricked into sending the same balance multiple times within a single transaction.
What Is a Reentrancy Attack?
A smart contract is code that executes on a blockchain in response to incoming transactions. Many contracts handle deposits and withdrawals: a user puts funds in, the contract records the balance, and the user can later withdraw what they put in. The withdrawal involves two operations — sending the funds out, and updating the user’s internal balance. If those steps happen in the wrong order, the door opens for a reentrancy attack.
The vulnerability arises because sending funds to an external contract on Ethereum hands control over to that contract during the transfer. If the recipient is a malicious contract, it can use that moment of control to call back — to re-enter — the original contract’s withdrawal function. The original contract, having not yet updated the balance, sees a still-positive balance and sends another withdrawal. This loop repeats until the contract is drained or the transaction runs out of gas.
Reentrancy is one of the oldest and most consequential smart contract vulnerabilities. The DAO attack of June 2016 exploited a reentrancy bug to drain roughly 3.6 million ETH — about $60 million at the time — from a high-profile decentralised investment fund. The aftermath split the Ethereum community over how to respond and ultimately produced the Ethereum / Ethereum Classic chain split. The lesson — that external calls must be made only after internal state is fully updated — has been taught to every developer since.
How Does a Reentrancy Attack Work?
Consider a simplified withdrawal function in a vulnerable contract. The function reads the caller’s balance, sends that amount to the caller’s address, and then updates the internal record to set the balance to zero. The intent is correct, but the order is wrong: funds leave before the balance is zeroed.
An attacker deploys their own contract and deposits 1 ETH into the vulnerable one. They then call the withdrawal function. The vulnerable contract reads their balance (1 ETH) and sends them 1 ETH. The send invokes a fallback function on the attacker’s contract — a piece of code that runs automatically when the contract receives ETH. Inside that fallback, the attacker has programmed another call to the withdrawal function. The vulnerable contract again reads the attacker’s balance — still 1 ETH, because the original call has not finished updating it — and sends another 1 ETH. The fallback runs again, calls withdrawal again, and the loop continues until reserves are empty or the transaction hits Ethereum’s gas limit.
The fix is straightforward and is taught as the “checks-effects-interactions” pattern: check whether the call is valid, update internal state to reflect the action, and only then interact with external addresses. A contract that zeroes the user’s balance before sending the funds cannot be re-entered, because the second call sees a zero balance and refuses to send. Most modern contracts also use a reentrancy guard — a simple lock that prevents a function from being called while it is already executing — implemented as a one-line modifier from audited libraries like OpenZeppelin.
Reentrancy vs Other Common Smart Contract Exploits
| Reentrancy | Oracle Manipulation | Logic Error | |
|---|---|---|---|
| Root cause | External call before state update | Reliance on a manipulable price source | Incorrect business logic in the contract code |
| Capital required | Small (often refunded via flash loan) | Often large or flash-loan-funded | Varies — sometimes none |
| Detection | Caught by standard audits and static analysis | Requires understanding the protocol’s oracle design | Requires reading and reasoning about all code paths |
| Standard mitigation | Checks-effects-interactions pattern, reentrancy guard | Time-weighted average prices, multiple oracles | Comprehensive test coverage, formal verification |
| Historical significance | The DAO hack (2016); many subsequent variants | Numerous DeFi exploits since 2020 | Common in newer or less-reviewed protocols |
Why Are Reentrancy Attacks Important for Traders?
For users of DeFi protocols, reentrancy is one of the dominant risks of holding funds in smart contracts. Even when a protocol is audited, reentrancy variants continue to appear — including cross-function reentrancy, where the callback enters a different function in the same contract, and read-only reentrancy, where the attack manipulates state that other contracts then read incorrectly. Funds in any single protocol are exposed to the security of the code holding them.
The structural limitation is that smart contract security cannot be proven absolutely. Audits reduce the probability of vulnerabilities but do not eliminate it; formal verification provides stronger guarantees for specific properties but is expensive and not yet universal. Many of the largest exploits in DeFi history have occurred in audited code. The implication is that diversification across protocols is itself a form of risk management, distinct from diversification across assets.
For sophisticated traders, the practical question is not just whether a protocol is safe but what its security history reveals. A protocol that has paid out bug bounties for reentrancy issues and patched them tends to be more robust than one that has never reported any. The absence of disclosed problems is sometimes a signal of immaturity rather than safety, and a credible bug-bounty program with named auditors is a meaningful filter when choosing where to commit capital.
Key Takeaways
- A reentrancy attack exploits a smart contract that sends funds before updating its internal balance, letting a malicious recipient repeatedly call back into the contract and drain it within a single transaction.
- The standard prevention is the checks-effects-interactions pattern: validate inputs, update internal state, then make external calls — never the reverse.
- The DAO hack of June 2016 used a reentrancy bug to drain roughly 3.6 million ETH and led to the Ethereum / Ethereum Classic chain split when the community disagreed on whether to reverse the attack.
- Reentrancy variants beyond the classic single-function case — cross-function and read-only reentrancy — continue to appear in audited code, so the vulnerability class remains current despite being well-known for over a decade.
- Smart contract security cannot be proven absolutely, so diversifying across protocols is itself a form of risk management — distinct from diversifying across assets — that addresses code-execution risk.
How is a reentrancy attack different from a flash loan attack?
A flash loan provides the capital used to amplify an attack, but the vulnerability being exploited can be many different things — reentrancy, oracle manipulation, logic errors. Flash loans and reentrancy often appear together because the flash loan funds the attacker without their own capital, but the two are independent: a reentrancy bug can be exploited without a flash loan if the attacker already holds enough capital, and a flash loan attack can exploit non-reentrancy vulnerabilities.
Can a contract that uses Solidity's safe transfer functions still be vulnerable?
Yes. Solidity's transfer and send functions limit the gas forwarded to the recipient enough to prevent the simplest reentrancy patterns, but not all variants. Cross-function reentrancy, read-only reentrancy, and reentrancy through token contracts following newer standards like ERC-777 can all bypass that mitigation. Modern best practice does not rely on transfer or send — it uses the checks-effects-interactions pattern and explicit reentrancy guards.
Are reentrancy attacks specific to Ethereum?
The vulnerability class arises on any smart contract platform where contracts can call into one another and external calls hand over control. Variants have occurred on every major smart contract chain. The specific patterns and mitigations differ by platform — chains that batch state updates differently, or that limit cross-contract calls, may be exposed to different versions of the same underlying risk.