The core problem of a reentrancy attack can be summed up in one sentence: the contract hands control to an external address before it finishes updating its own ledger, and that external address calls back into the same function before the contract "records the transaction." As a result, the contract repeatedly approves withdrawals based on an outdated balance that has not yet been deducted. The official Ethereum glossary defines it directly: a contract calls another contract, which calls back into the first contract before it completes its state update, allowing the attacker to act on stale values.

A leading global cryptocurrency platform,suitable for both beginners and experienced traders.
New user benefit: 20% off trading fees upon registration!!
A Concrete Example of Fund Drainage
Imagine a simplified contract that lets users withdraw ETH they have deposited. The code logic might look like this: first check if the caller's balance is greater than zero, then use call to send ETH to them, and finally set the caller's balance to zero.
The problem lies in the window between "sending funds" and "setting the balance to zero." When the contract executes call to send ETH to an attacker's contract, the attacker's fallback or receive function is triggered. In that code, the attacker calls the original contract's withdrawal function again. At this point, the original contract's balance record has not yet been set to zero, because the first transfer has not finished executing. So the second call still sees "you have 1 ETH available to withdraw" and approves another transfer. The attacker can loop this callback repeatedly until the contract's funds are drained or gas runs out.
The phrase "hasn't recorded the transaction yet" in the title refers to this exact state: the contract has already paid out assets, but its internal ledger still shows the balance from before the payment. The attacker exploits precisely this time gap.
Why This Vulnerability Keeps Appearing
The most famous reentrancy attack on Ethereum was the 2016 DAO incident, where roughly $60 million worth of ETH was drained. The DAO's contract updated internal balances only after sending ETH to the attacker. The attacker repeatedly re-entered the withdrawal logic through callbacks, completing multiple withdrawals before the balance was deducted. If the contract had followed the "update state first, then make external calls" order, this attack would not have been possible.
Reentrancy attacks are not limited to ancient code. In July 2025, GMX V1 lost approximately $42 million on Arbitrum due to cross-contract reentrancy. In early 2026, Futureswap was also exploited due to a similar ledger update timing issue. The common thread in these cases: when the contract interacts with an external address, the internal control flow is interrupted, and the ledger update is not completed before the interaction. The attack surface can span multiple contracts, but the trigger condition remains the same timing gap.
The Key to Defense Is Not "Checking for Reentrancy" but Eliminating the Timing Gap
The most common approach is to reorder the code so that state changes happen before external calls. This is known as the "Checks-Effects-Interactions" pattern: first check that conditions are met, then update the contract's internal state (such as deducting the user's balance), and finally execute the transfer or call the external contract. With this order, even if the external contract calls back after receiving the transfer, it sees the already-deducted balance and cannot withdraw again.
Another complementary measure is a reentrancy guard. OpenZeppelin's ReentrancyGuard uses a state variable to mark whether "the current function is currently executing." If it is called again during execution, the call is rejected outright. This approach does not rely on developers manually adjusting the order of every piece of code and is suitable for adding a layer of general protection to critical functions.
It is important to note that a reentrancy guard cannot replace correct code ordering; it is only an additional interception layer. In complex cross-contract interactions, attackers may find paths not covered by the lock, or exploit state desynchronization between multiple contracts to bypass the protection. The GMX case demonstrates that a guard deployed four years earlier can fail in cross-contract scenarios.
What Does This Knowledge Mean for Regular Users?
You don't need to audit contract code, but you can remember one principle: when a DeFi contract allows you to withdraw funds and its withdrawal logic depends on external calls (such as sending ETH or tokens to your address), whether the contract's code order is secure determines whether your deposits are at risk of being drained. You cannot directly see the code order from the interface, but you can check whether the project has undergone a public security audit, whether it uses mature reentrancy protection libraries, and whether it has been running long enough in the industry without experiencing similar incidents. This information does not guarantee safety, but it can help you filter out projects that lack even basic protections.

A leading global cryptocurrency platform,suitable for both beginners and experienced traders.
New user benefit: 20% off trading fees upon registration!!
References
- ETHGlossary·reentrancy definition, 2026-11-03
- IEEE Xplore·Reentrancy Vulnerability in the Blockchain Ecosystem: Historical Attacks, Detection Approaches, and Mitigation Strategies, 2026-11-03
- Dagstuhl·Using Coq to Enforce the Checks-Effects-Interactions Pattern in DeepSEA Smart Contracts, 2026-11-03
- BlockSec·GMX Security Incident #4: Cross-Contract Reentrancy Attack Bypasses a Four-Year-Old Defense, 2026-11-03
- Foresight News·BlockSec: FutureSwap Protocol on Arbitrum Attacked Again, Reentrancy Vulnerability Causes $74,000 Loss, 2026-11-03
- arXiv·Temporarily Restricting Solidity Smart Contract Interactions, 2026-11-03


