Puppy Raffle

AI First Flight #1
Beginner FriendlyFoundrySolidityNFT
EXP
View results
Submission Details
Impact: low
Likelihood: low
Invalid

Slither "divide-before-multiply" at `selectWinner` is a false positive

Description

  • The payout math splits the collected ETH 80/20 between the winner and the fee.

  • Slither flags a divide-before-multiply precision loss, but the dangerous pattern is (a / b) * c (divide first, then amplify). Every expression here multiplies before it divides ((x * 80) / 100), so truncation happens only on the final / 100 and is never amplified. The detector matches on * and / without checking their order.

uint256 totalAmountCollected = players.length * entranceFee;
@> uint256 prizePool = (totalAmountCollected * 80) / 100;
@> uint256 fee = (totalAmountCollected * 20) / 100;

Risk

Likelihood:

  • When entranceFee is set to a contrived sub-100-wei value, so totalAmountCollected is not a multiple of 5.

Impact:

  • At worst, ~2 wei of dust is stranded. For any realistic entranceFee the remainder is exactly zero.

Proof of Concept

function testPayoutSplitLosesNoWei() public view {
uint256 totalAmountCollected = 4 * entranceFee; // entranceFee = 1e18
uint256 prizePool = (totalAmountCollected * 80) / 100;
uint256 fee = (totalAmountCollected * 20) / 100;
assertEq(prizePool + fee, totalAmountCollected); // no dust for realistic fees
}

Only a contrived entranceFee below 100 wei produces a 1–2 wei remainder — economically irrelevant.

Recommended Mitigation

No change required; the operation order is already correct. For defensiveness, derive one share by subtraction so the two always sum exactly:

uint256 fee = (totalAmountCollected * 20) / 100;
- uint256 prizePool = (totalAmountCollected * 80) / 100;
+ uint256 prizePool = totalAmountCollected - fee; // guarantees prizePool + fee == total
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 2 hours ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!