The refund
function can be exploited by the .sendValue
external call to continue withdrawing the entranceFee
until the PuppyRaffle
contract's balance is drained in a reentrancy attack.
When I call the refund
function, I supply my valid playerIndex
number the function uses to find my address in the players
array of addresses then proceeds to send me the public global entranceFee
.
However, I can just deploy a smart contract to run a drain attack logic in the receive or fallback function that enables me to keep calling the PuppyRaffle::refund
function as long as the balance is greater than a certain amount, e.g the entrance fee.
Manual review
The fix for this is to either implement a nonReentrant lock or opt for the CEI pattern by clearing my address from the players
array before making the transfer like so:
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.