The refund() function calls msg.sender before setting players[playerIndex] = address(0), thereby allowing reentrancy.
In PuppyRaffle.sol, the refund() function lacks a reentrancy guard, enabling an attacker to reenter the function due to the callback to msg.sender. As there are state updates after the call, an attacker can delay the deletion of players[playerIndex] by repeatedly calling refund() since the deletion occurs after the callback.
This vulnerability allows an attacker to drain all the ETH in the contract.
Manual Review
To prevent devastating attacks, consider adding reentrancy guard modifiers to functions like refund(), and other critical protocol functions. Alternatively, you can move the external call to the end of the function to adhere to the checks-effects-interactions pattern.
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.