Noisy Pineapple Wasp
High
When the unclaimed rewards in the deposit are insufficient to pay the feeAmount, this part of rewards will be locked in the contract.
When claiming rewards, users need to pay the claim fee. However, when the rewards are not enough to pay the claim fee, users cannot claim the rewards, and the protocol cannot charge fees. Finally, the rewards will be permanently locked in the contract.
https://github.com/sherlock-audit/2024-11-tally/blob/main/staker/src/GovernanceStaker.sol#L710-L721
When the reward in the deposit is not enough to cover the claim fee (or is exactly equal to it) and the user has withdrawn all the staked tokens, this part of the reward will always be locked in the contract.
Rewards will be locked in contract.
function _claimReward(DepositIdentifier _depositId, Deposit storage deposit, address _claimer)
internal
virtual
returns (uint256)
{
_checkpointGlobalReward();
_checkpointReward(deposit);
uint256 _reward = deposit.scaledUnclaimedRewardCheckpoint / SCALE_FACTOR;
// Intentionally reverts due to overflow if unclaimed rewards are less than fee.
uint256 _payout = _reward - claimFeeParameters.feeAmount;
if (_payout == 0) return 0;
Manual Review
Add a method so that when a user withdraws all staked tokens and the remaining rewards are not enough to pay the claim fee, the contract owner can transfer the rewards to the feeCollector.