The refund function in the PuppyRaffle contract is vulnerable to a reentrancy attack due to not checking the return values after sendValue and the improper use of the Checks-Effects-Interactions pattern. This could allow an attacker to drain funds from the contract.
The refund function sends ether to msg.sender before setting the player's address to zero. and sending value with an unchecked call return values. This allows a malicious contract to call the refund function again before the player's address is set to zero, leading to a reentrancy attack.
A malicious contract could look like this:
Here is a detailed attack path
Deploy set up the attack contract
Simulate the attack using foundry for test to trigger Attack contract deployment and call it in a raffle
this will trigger a recursive calls to the refund function until all the funds in PuppyRaffle are depleted shown in the logs
An attacker who is a malicious player/participant in the raffle could drain all the funds from the PuppyRaffle contract, leading to a loss of funds for all players.
Foundry
To mitigate this vulnerability, the Checks-Effects-Interactions pattern should be properly implemented. The state of the contract should be updated before calling external contracts. In this case, players[playerIndex] = address(0); should be moved before payable(msg.sender).sendValue(entranceFee);.
To prevent further attack, you must use the transfer function instead of sendValue. The transfer function also sends Ether, but it only forwards a limited amount of gas, preventing the called contract from performing complex operations like calling back into the calling contract.
if there are unknown risks which may be introduced through permissionless operation of the raffle, a reentrancyGuard may be used as a way to ensure there is no way to call the function more than once within the same call frame
-The nonReentrant modifier ensures that the function cannot be re-entered while it's being executed, which protects against reentrancy attacks.
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.