The current implementation of the penalty logic in the claimReward
function allows users to bypass the intended penalty when claiming small rewards or get a discount from the penalty for bigger rewards when rewards%2!=0. This issue occurs because the division operation in Solidity truncates decimal places, resulting in penalties being rounded down to zero for small reward amounts. This allows users to claim the reward without any penalty or discounted penalty (in case reward%2!=0). The penalty logic is invariant so bypassing it or abusing it should be prevented.
The vulnerability arises from the following code in the claimReward
function:
In Solidity, division between integers results in truncation towards zero, meaning that if the rewardAmount
is 1 token, the penalty becomes 0:
Thus, when claiming a small reward, the user can receive the entire rewardAmount
without paying any penalty. This can lead to abuse if a malicious users claims small rewards, avoiding penalties altogether.
The impact of this vulnerability is that users can avoid paying penalties on small reward claims or not paying the full penalties in case rewards%2!=0. This can lead to the depletion of the reward pool over time, as users can claim rewards without incurring the full intended penalties. This could result in a loss of funds for the contract and unfair distribution of rewards.
The user accumulates a small reward, such as 1 token.
The user claims the reward prematurely, and instead of incurring a 50% penalty, the penalty is rounded down to 0 due to integer division.
The user receives the full reward of 1 token with no penalty.
This process can be repeated to exploit the contract and avoid paying penalties on small reward claims.
Manual review
Make sure that the penalty is rounded up. For example:
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.