totalFees Leads to Permanent Lockup of Protocol RevenueIn normal operation, the selectWinner() function calculates a 20% protocol fee from the total raffle entry deposits and accumulates this value into totalFees so the contract owner can later withdraw protocol earnings via withdrawFees().
However, totalFees is declared as a 64-bit integer (uint64), while the newly calculated fee is a 256-bit integer (uint256). Because the contract uses Solidity 0.7.6 without explicit overflow protection, casting fee to uint64 silently truncates higher-order bits whenever cumulative or single-raffle fees exceed $2^{64} - 1$ wei ($\approx 18.446 \text{ ETH}$).
Solidity
Likelihood: Medium
Reason 1: Large raffles with total collected funds exceeding $\approx 92.23 \text{ ETH}$ generate a single-instance fee greater than $18.446 \text{ ETH}$, causing immediate bit truncation upon winner selection.
Reason 2: Multiple consecutive medium-sized raffles continuously accumulate fees into totalFees, inevitably pushing the aggregate balance past the type(uint64).max threshold.
Impact: High
Impact 1: Protocol fees above $18.446 \text{ ETH}$ suffer severe truncation, resetting totalFees to a fraction of its true value and permanently trapping the unrecorded ETH balance inside the contract.
Impact 2: The contract owner loses access to legitimate protocol revenues because withdrawFees() restricts withdrawals strictly to the corrupted totalFees state variable.
Ran 1 test for test/PuppyRaffleTest.t.sol:PuppyRaffleTest
[PASS] test_Overflow() (gas: 22379318)
Logs:
sendedFees: 20000000000000000000
totalFees: 1553255926290448384
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 66.42ms (38.15ms CPU time)
Update the type of the totalFees state variable from uint64 to uint256 to ensure it can store fee amounts exceeding $2^{64}-1$ wei without bit truncation. Additionally, remove the explicit uint64 typecast in selectWinner().
For complete safety against arithmetic overflows, consider upgrading the codebase to Solidity 0.8.x (which includes built-in overflow checks) or integrating OpenZeppelin's SafeMath library.
In PuppyRaffle::selectWinner
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.