A simple reentrancy attack demonstration
There are two contracts in this repo:
VulnerableContract
- To deposit and withdraw fundsAttackerContract
- To perform reentrancy attack
The attack can be executed by changing
function withdraw(uint256 amount) external {
require(balances[msg.sender] >= amount, "Insufficient balance");
(bool success, ) = msg.sender.call{value: amount}("");
require(success, "failed call");
balances[msg.sender] -= amount;
}
in VulnerableContract
to:
function withdraw(uint256 amount) external {
require(balances[msg.sender] >= amount, "Insufficient balance");
(bool success, ) = msg.sender.call{value: amount}("");
require(success, "failed call");
unchecked {
balances[msg.sender] -= amount;
}
}
Run
$ forge test -vvv
Verbosity level option is used to get execution traces.