* The `selectWinner()` function calculates prize pool and fees using integer division: `prizePool = (totalAmountCollected * 80) / 100` and `fee = (totalAmountCollected * 20) / 100`.
* When `totalAmountCollected` is not divisible by 5, integer division causes rounding errors. The sum of `prizePool + fee` may be less than `totalAmountCollected`, leaving leftover wei permanently stuck in the contract.
```solidity:131:134:src/PuppyRaffle.sol
uint256 totalAmountCollected = players.length * entranceFee;
uint256 prizePool = (totalAmountCollected * 80) / 100;
uint256 fee = (totalAmountCollected * 20) / 100;
totalFees = totalFees + uint64(fee);
```
Likelihood:
* This occurs whenever `totalAmountCollected % 5 != 0` (i.e., when the total is not divisible by 5)
* With common entrance fees, this happens frequently (e.g., 4 players with 1 wei each = 4 wei, not divisible by 5)
* Over many raffles, leftover wei accumulates in the contract
Impact:
* Small amounts of ETH accumulate and become permanently locked
* Funds cannot be recovered or withdrawn
* Accounting discrepancies grow over time
* With many raffles, accumulated leftovers could become significant
## Description `fee` should be 'totalAmountCollected-prizePool' to prevent decimal loss ## Vulnerability Details ``` uint256 totalAmountCollected = players.length * entranceFee; uint256 prizePool = (totalAmountCollected * 80) / 100; uint256 fee = (totalAmountCollected * 20) / 100; ``` This formula calculates `fee` should be 'totalAmountCollected-prizePool' ## Impact By calculates `fee` like the formula above can cause a loss in `totalAmountCollected' if the `prizePool` is rounded. ## Recommendations ```diff - uint256 fee = (totalAmountCollected * 20) / 100; + uint256 fee = totalAmountCollected-prizePool; ```
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.