Reentrancy Attacks
Reentrancy is the most notorious smart contract vulnerability — it enabled the DAO hack ($60M, 2016) and continues to appear in new protocols. Understanding how it works and how to prevent it is non-negotiable for every Solidity developer.
Reentrancy: Attack & Defense
The attack pattern:
1. Victim contract calls attacker contract to send ETH
2. Attacker's receive() function immediately calls back into victim
3. Victim's state is not yet updated — balance check still passes
4. Loop continues until victim is drained
Classic conditions for reentrancy:
1. External call (call, transfer, send) BEFORE state update
2. Enough gas forwarded to re-execute (>2300 gas)
3. Attacker contract with a fallback/receive that re-enters
Three forms of reentrancy:
- Single-function: re-enters the SAME function
- Cross-function: re-enters a DIFFERENT function in the same contract
- Read-only reentrancy: reads stale state during another function's executionCommon Mistakes
- Thinking .transfer() is always safe — transfer() forwards only 2300 gas, preventing most reentrancy, but EIP-2929 gas cost changes can break transfer() in some scenarios. Use CEI + nonReentrant instead.
- Only protecting the obvious withdraw() function — cross-function reentrancy attacks a different function. Apply nonReentrant to ALL state-changing functions that make external calls.
- Forgetting read-only reentrancy — an attacker can re-enter a view function during another call to read stale state and use it in an arbitrage. The Curve Finance read-only reentrancy bug exploited this.
Tip
Tip
Practice Reentrancy Attacks in small, isolated examples before integrating into larger projects. Breaking concepts into small experiments builds genuine understanding faster than reading alone.
Once deployed, smart contracts are immutable — code is law
Practice Task
Note
Practice Task — (1) Write a working example of Reentrancy Attacks from scratch without looking at notes. (2) Modify it to handle an edge case (empty input, null value, or error state). (3) Share your solution in the Priygop community for feedback.
Quick Quiz
Common Mistake
Warning
A common mistake with Reentrancy Attacks is skipping edge case testing — empty inputs, null values, and unexpected data types. Always validate boundary conditions to write robust, production-ready web3 code.
Key Takeaways
- Reentrancy is the most notorious smart contract vulnerability — it enabled the DAO hack ($60M, 2016) and continues to appear in new protocols.
- Thinking .transfer() is always safe — transfer() forwards only 2300 gas, preventing most reentrancy, but EIP-2929 gas cost changes can break transfer() in some scenarios. Use CEI + nonReentrant instead.
- Only protecting the obvious withdraw() function — cross-function reentrancy attacks a different function. Apply nonReentrant to ALL state-changing functions that make external calls.
- Forgetting read-only reentrancy — an attacker can re-enter a view function during another call to read stale state and use it in an arbitrage. The Curve Finance read-only reentrancy bug exploited this.