Reentrancy is one of the oldest and still most dangerous vulnerabilities in smart contracts.
It looks simple on paper, yet it has drained hundreds of millions of dollars over the years.
In short, a reentrancy attack happens when a contract calls an external address before it finishes updating its own state. The external contract can then call back into the original function and repeat the action while the state is still outdated.
The classic pattern looks like this:
If the recipient is a malicious contract, receiving the ETH triggers its fallback or receive function. That function immediately calls the withdraw function again. Because the balance hasn’t been reduced yet, the contract happily sends the money once more. This repeats until the contract is drained or the transaction runs out of gas.
This is exactly what happens when developers break the Checks-Effects-Interactions pattern.
The most famous case.
The DAO had raised roughly $150 million worth of ETH. An attacker exploited the splitDAO function, which sent ETH before updating the internal balance. Through recursive calls, the attacker drained about 3.6 million ETH (around $60 million at the time).
The incident was so severe that it forced the Ethereum community to hard-fork, creating Ethereum Classic in the process.
Attackers used an ERC-777 token’s callback mechanism to achieve cross-function reentrancy. The protocol lost more than $29 million.
This showed that even after years of awareness, new token standards can reopen the same class of vulnerability.
Between 2023 and 2025 we saw several “read-only reentrancy” attacks (notably affecting Curve pools and protocols that relied on them). In these cases the attacker doesn’t steal funds directly. Instead they manipulate price oracles during the callback window, allowing other protocols to issue under-collateralized loans.
At Panda Security we still regularly find reentrancy issues during audits — not always the classic single-function version, but more subtle cross-function or cross-contract variants that developers thought they had already protected against.
After reviewing hundreds of contracts, we’ve noticed a common pattern: teams treat ReentrancyGuard as a silver bullet.
It’s useful, but it only stops direct reentrancy into the same function. It does not automatically protect against:
The most reliable defense is still discipline: update all relevant state before any external call, then add a reentrancy lock as a second layer.
Follow Checks-Effects-Interactions strictly
Check conditions → update state → only then make external calls.
Use OpenZeppelin’s ReentrancyGuard
Apply the nonReentrant modifier to every function that changes balances or makes external calls.
Be extra careful with callbacks
ERC-777, ERC-721, ERC-1155, and custom hooks are frequent attack vectors.
Test the reentrancy paths
Write explicit tests that try to re-enter your functions. Fuzzing helps a lot here.
Reentrancy has been around for a decade, yet it keeps appearing in new forms. Understanding the root cause — and respecting the order of operations — is still the best protection.
If you’re preparing a protocol for mainnet and want a second pair of eyes on reentrancy and related issues, the Panda Security team is happy to help.
UNCX's token vesting contract lost roughly $87.7K when an attacker exploited a share-accounting flaw in release(), topUpVesting(), and cancel(). We break down the root cause, the exact attack sequence, and what builders should take away from it — without the jargon.
Autheo’s THEO token lost 92% after attackers used a Hyperlane TrustedRelayerIsm misconfiguration to mint 19 million unbacked tokens on Base and extract roughly $1.76 million. Here’s how the attack worked and why single-key security models remain dangerous for cross-chain assets.
Uniswap v4 hooks explained: the PoolManager singleton, flash accounting, and what the Cork and Bunni exploits teach us about hook security. A PandaSecurity deep dive.
An attacker forced a Uniswap V4 vault into a zero-liquidity state, redeemed one minimal share unit, and withdrew roughly 14,838.47 DAI. Panda Security breaks down the transaction, vulnerable code, root cause, and practical fixes.