After a player uses refund
to exit the raffle, the players
array still account for the same number of players, this will break the prize distribution and fee allocation during the selection of the winner.
Let's assume five players enter the raffle and after some time a player decides to use refund
to exit. The function will send the ether back to the player but in line 103 the function does not reduce the array, it only replaces the address with the zero address:
This means the raffle still has five players but the balance of the contract was reduced from 5 to 4 ether.
After the raffle ends, someone calls selectWinner
and here is where the impact of the bug can be seen. The amount of prize and fees are calculated as such:
Because the players
array still accounts for five player the values of these variables are:
totalAmountCollected
is equal to 5 ether
prizePool
will be 4 ether
fee
will be 1 ether
The actual balance in the contract is 4 ether, everything will be sent to the winner and the totalFees
will be set as 1 ether despite having no remaining balance.
The will make withdrawFees
to revert because the check in this function will never pass.
Even after new rounds the balance of the contract will never equal the value of totalFees
because after new rounds the new fees are added to it.
Paste and run the following code snippet in PuppyRaffleTest.t.sol
to see the effect of the bug.
Fees stuck in the contract.
VS Code and Foundry.
Instead of only replacing the address of the player, switch its position to the last and use the pop
array method to remove it from the game, this change will result in correct math for the prize and fee allocation.
Funds are locked to no one. If someone gets the refund issue, they also got this issue. IMPACT: High Likelihood: High
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.