The selectWinner function calculates the prizePool (80%) and fee (20%) using integer division. This causes rounding down, meaning the sum of the distributed amounts can be less than the totalAmountCollected. The remaining "dust" ETH is permanently locked in the contract and never distributed to anyone.
In Solidity, integer division truncates any fractional part. When calculating percentages, if totalAmountCollected is not perfectly divisible by 100 (after multiplying by 80 or 20), the remainder is lost. For example, if the total collected is 101 wei, the prize pool becomes 80 wei and the fee becomes 20 wei. The remaining 1 wei is permanently trapped in the contract. While small per raffle, this accumulates over time.
File: src/PuppyRaffle.sol (lines 132-134)
Severity: Low
Likelihood: High
Impact: Low
❌ Small amounts of ETH (dust) are permanently locked
❌ Users and the protocol lose funds over time
✅ Impact is minimal if entranceFee is a multiple of 100 wei
Scenario: A raffle collects an amount that is not divisible by 100, causing precision loss during the 80/20 split.
Test Output:
What This Proves:
✅ Integer division truncates remainders
✅ Sum of prize and fee is less than total collected
✅ Dust amounts are permanently locked in the contract
Calculate one of the values using division, and calculate the other by subtracting from the total. This ensures 100% of the funds are distributed.
Why This Fixes It:
✅ Ensures prizePool + fee == totalAmountCollected exactly
✅ Prevents any dust amounts from being locked
✅ 100% of user funds are properly distributed
CWE-682: Incorrect Calculation
Solidity Integer Arithmetic Best Practices
## 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.