The current implementation of the reward distribution function contains a critical inconsistency that can lead to excess tokens being trapped in the contract.
The bug arises from an inconsistency between how the claimantCut
is calculated and how it's distributed:
claimantCut
is calculated using i_players.length
, which represents all players.
The distribution loop uses claimants.length
, which represents only the players who claimed in time.
This inconsistency can lead to excess tokens being left in the contract when i_players.length
> claimants.length
.
Excess Tokens: When there are fewer claimants than total players, a portion of the rewards will remain undistributed in the contract.
Trapped Funds: The excess rewards become trapped in the contract as there is no independent function to transfer these tokens out.
Manager Unable to Retrieve: The contract manager cannot access or redistribute these excess tokens.
The root cause is the mismatch between the calculation of claimantCut
and its distribution. The calculation should use claimants.length
instead of i_players.length
to accurately distribute the remaining pool to those who claimed in time.
Set up a scenario where i_players.length
> claimants.length
.
Execute the reward distribution function.
Observe that some tokens remain in the contract after distribution.
Update the claimantCut
calculation to use claimants.length
:
Additionally, consider implementing a function that allows the contract manager to withdraw any excess tokens that might accumulate due to rounding errors or edge cases.
Add checks to ensure claimants.length
is not zero before performing the division.
Implement a mechanism to handle any remaining dust (small amounts left due to division rounding).
Consider using a pull pattern for reward distribution to mitigate potential issues with failed transfers.
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.