[M] Calling claimRewards() or unstake() when ajnaToken is insufficient will permanently lose part or all of the rewards
Summary
This issue concerns the balance of AjnaToken and its impact on contract execution. If the balance of AjnaToken is insufficient, it may cause issues with transferring rewards to the user.
Vulnerability Detail
In the contract code, the _claimRewards function is used to transfer rewards to the user. The rewards are transferred using the safeTransfer function of the IERC20 interface, which transfers rewards from the contract's address to the user's address. The rewards are calculated based on various factors and stored in the rewardsEarned variable. Before the transfer, there is a check to ensure that rewardsEarned is not greater than the balance of AjnaToken at the contract's address. If it is, rewardsEarned is set to the balance of AjnaToken.
However, when the contract's ajnaToken is insufficient, _claimRewards_claimRewards continue to run, modify and store according to the rewards that have been withdrawn, but the rewards are not issued in full.
Impact
If the balance of AjnaToken is 0, the rewardsEarned check will always be true and rewardsEarned will always be set to 0. This means that the user will not receive any rewards, even if they have earned them.
oxcm
medium
[M] Calling
claimRewards()
orunstake()
whenajnaToken
is insufficient will permanently lose part or all of the rewardsSummary
This issue concerns the balance of AjnaToken and its impact on contract execution. If the balance of AjnaToken is insufficient, it may cause issues with transferring rewards to the user.
Vulnerability Detail
In the contract code, the
_claimRewards
function is used to transfer rewards to the user. The rewards are transferred using the safeTransfer function of the IERC20 interface, which transfers rewards from the contract's address to the user's address. The rewards are calculated based on various factors and stored in the rewardsEarned variable. Before the transfer, there is a check to ensure that rewardsEarned is not greater than the balance of AjnaToken at the contract's address. If it is, rewardsEarned is set to the balance of AjnaToken.However, when the contract's
ajnaToken
is insufficient,_claimRewards
_claimRewards
continue to run, modify and store according to the rewards that have been withdrawn, but the rewards are not issued in full.Impact
If the balance of AjnaToken is 0, the rewardsEarned check will always be true and rewardsEarned will always be set to 0. This means that the user will not receive any rewards, even if they have earned them.
Code Snippet
https://github.com/sherlock-audit/2023-01-ajna/blob/main/contracts/src/RewardsManager.sol#L446-L484
Tool used
Manual Review
Recommendation
A possible solution to this issue is to add a check for balance before the transfer of rewards.
If the balance is insufficient, the transfer should be prevented, This will ensure that the user can receive their earned rewards.
And consider adding a "force" parameter to allow users to bypass restrictions
Duplicate of #120