The claimRewards
function in the smart contract contains a logical flaw in reward calculation and tracking. This issue leads to incorrect reward distribution and potential loss of rewards for users. Specifically, resetting userRewards[user]
to totalDistributed
creates a mismatch between actual user entitlements and the global reward state, preventing correct future claims.
The contract calculates pending rewards for users based on their voting power relative to the total voting power:
However, after claiming, the contract resets the user's reward tracker incorrectly:
This issue results in the user’s baseline being incorrectly updated to the global totalDistributed
value rather than their personal entitled share. This discrepancy prevents users from claiming future rewards correctly.
Initial State:
totalDistributed = 1,000
User has 100
voting power (10% of total 1,000
)
userRewards[user] = 0
(never claimed)
Pending Reward Calculation: (1,000 * 100) / 1,000 - 0 = 100
User Claims Rewards:
Receives 100
tokens.
userRewards[user]
is set to totalDistributed = 1,000
(Incorrect!)
New Rewards Distributed:
totalDistributed
increases to 2,000
.
User’s voting power remains 100
(Total Voting Power remains 1,000
).
New Pending Reward Calculation:
share = (2,000 * 100) / 1,000 = 200
pending = 200 - 1,000 (userRewards[user]) = -800 → returns 0
Result: The user should have been entitled to another 100
tokens but sees 0
pending rewards due to the incorrect reset mechanism.
Users may not be able to claim their rightful rewards.
Rewards calculation may be misaligned, leading to unfair distribution.
Over time, this flaw could cause significant loss of funds for users relying on the contract’s fairness.
Manual code review
Solidity static analysis tools
Foundry testing framework (for simulations)
Instead of resetting userRewards[user]
to totalDistributed
, store the user’s last claimed share properly:
Implement thorough unit testing to verify that rewards accumulate correctly across multiple claim cycles.
Ensure that userRewards[user]
reflects the actual rewards distributed rather than a global counter that misaligns future calculations
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.