The closePot() function distributes remaining rewards to all claimants without tracking who has already claimed during the normal period. This causes users who claimed early to receive duplicate payments, while users who waited receive less than their fair share.
The function calculates claimantCut by dividing remaining rewards among all players, then pays this amount to every claimant—including those who already claimed. Additionally, it fails to update remainingRewards after transferring the manager cut, violating the solvency invariant.
Severity: Critical
Users who claim early receive their original share plus an additional payment from closePot(), while users who wait receive only the reduced closePot() amount. In a scenario with 1,000 tokens and 4 players where 2 claim early (250 each), closePot() calculates 112.5 per claimant from the remaining 450. Early claimers receive 362.5 total (45% extra), while late claimers receive only 112.5 (55% less).
The failure to update remainingRewards creates an accounting discrepancy where pot.balance < remainingRewards, breaking protocol invariants and potentially causing other operations to fail.
The following trace demonstrates the solvency invariant violation:
Track which users have claimed and only distribute to unclaimed addresses:
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.