withdrawFees
can fail, because the equation address(this).balance == uint256(totalFees)
is too strict.
If the account hasn't exactly the same ether as totalFees
, withdraw is impossible, This situation is very likely, if rounding will happen during calculation of the totalFees
and prizePool
.
Let's break down the numbers:
If there are 9 players and each pays an entrance fee of 1,000,000,000,000,001 wei:
The total fees collected will be 20% of the entrance fees:
1,000,000,000,000,001 (entrance fee) x 9 (players) x 0.2 = 1,800,000,000,000,001.8.
Solidity rounds this down to 1,800,000,000,000,001.
The prize pool will be 80% of the entrance fees:
1,000,000,000,000,001 (entrance fee) x 9 (players) x 0.8 = 7,200,000,000,000,007.2.
This gets rounded down to 7,200,000,000,000,007.
Before distributing the prize, our account holds:
1,000,000,000,000,001 x 9 = 9,000,000,000,000,009 wei.
After giving out the prize, our account will have:
9,000,000,000,000,009 - 7,200,000,000,000,007 = 1,800,000,000,000,002 wei left.
However, notice that the calculated total fees are 1,800,000,000,000,001, which is 1 wei less than the difference above.
withdrawFee
is never permitted, i.e. funds can never be withdrawn.
Math
require(address(this).balance == uint256(totalFees), "PuppyRaffle: There are currently players active!");
is used only to validate that the game is finished and selectWinner
has been called.
After each successful selectWinner
the players
array is reset with delete
, which will reset the array length to zero.
It would be ok, to replace the above validation with this:
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.