An attacker can deploy a contract that is capable of draining all funds from the raffle.
The refund function violates the checks-effects-interactions pattern whereby ETH is transferred to the msg.sender before the player is removed from the raffle.
A PoC is demonstrated below.
The attack works as follows:
Enter the raffle with the attack contract.
Store the attack contracts playerIndex in it's own storage as entryIndex.
Immediately call refund.
Fallback function will be triggered, where another refund is requested. This continues while the balance of the target PuppyRaffle contract is greater than, or equal to, the entranceFee.
All funds lost.
Foundry.
Switch the following lines in the refund function: payable(msg.sender).sendValue(entranceFee); and players[playerIndex] = address(0);.
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.