☠️ Re-entrancy Attack
Source code: https://github.com/scaffold-eth/scaffold-eth-examples/tree/simple-nft-example
Intended audience: Beginners/Intermediate
Topics: Scaffold-eth basics, Security
The re-enterancy contract is vulnerable through its poorly written withdraw() function. Withdraw_safe() is not. To test the attack do this:
Player 1 (usually an incognito tab):
In the re-enterancy contract, Deposit 0.001 ETH (converted into GWEI by clicking *)
Verify the amount in the contract is $0.001 (or whatever the price of ETH is)
Player 2 (attacker):
In the attacker contract, deposit 0.001 ETH as well.
Verify the contract now has $0.002
From the attacker contract, withdraw
Notice the balance of the attacker contract now has 2x the funds it should, and re-enterancy has 0. Also, the Player 1's balance in the contract seems to still be 0.001.
The takeaway? Follow the checks-effects-interaction pattern in all your functions :)
git clone https://github.com/scaffold-eth/scaffold-eth-examples.git reentrancy
cd reentrancy
git checkout reentrancy-example
yarn install
yarn start
in a second terminal window:
yarn chain
in a third terminal window:
yarn deploy
🔏 Edit your smart contract
Attacker.sol
and Reenterancy.sol
in packages/hardhat/contracts
📝 Edit your frontend
App.jsx
in packages/react-app/src
First try interacting with
Reenterancy.sol
directly. You can deposit, check your balance, and withdraw:
For the attack to work, you need to deposit some extra funds so they can be stolen:

Make sure the
Reenterancy.sol
contract has extra funds in it:
Then, deposit a the same amount through the
Attacker.sol
:
Finally, when you withdraw from the
Attacker.sol
it will withdraw once and then re-enter and withdraw again:
The
Reenterancy.sol
contract is now empty but the original account that deposited the extra funds thinks they still have a balance:
Last modified 1yr ago