Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: medium
Valid

Fees Withdraw Fails if Rounding

Summary

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.

Vulnerability Details

Let's break down the numbers:

  1. If there are 9 players and each pays an entrance fee of 1,000,000,000,000,001 wei:

  2. 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.

  3. 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.

  4. Before distributing the prize, our account holds:
    1,000,000,000,000,001 x 9 = 9,000,000,000,000,009 wei.

  5. 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.

Impact

withdrawFee is never permitted, i.e. funds can never be withdrawn.

Tools Used

  • Math

Recommendations

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:

require(players.length == 0, "PuppyRaffle: There are currently players active!");
require(totalFees > 0, "PuppyRaffle: No fees to withdraw");
Updates

Lead Judging Commences

Hamiltonite Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

greifers-send-money-to-contract-to-block-withdrawfees

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.