☠️ Re-entrancy Attack

Branch Info

Source code: https://github.com/scaffold-eth/scaffold-eth-examples/tree/simple-nft-example Intended audience: Beginners/Intermediate Topics: Scaffold-eth basics, Security

Re-entrancy Example

Tutorial Explanation

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
📱 Open http://localhost:3000 to see the app
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: