`StaticATokenLM::_claimRewardsOnBehalf`: wrong update of `_unclaimedRewards[onBehalfOf]` if `reward > totBal` lead to user lose of pending rewards. #36
If for some reason the current contract reward token balance is lower than the rewards meant to be paid to onBehalf address, then this rewards can never be claimed.
function _claimRewardsOnBehalf(
address onBehalfOf,
address receiver,
bool forceUpdate
) internal {
if (forceUpdate) {
_collectAndUpdateRewards();
}
uint256 balance = balanceOf(onBehalfOf);
uint256 reward = _getClaimableRewards(onBehalfOf, balance, false); // @audit unclaimed + pending rewards
uint256 totBal = REWARD_TOKEN.balanceOf(address(this));
if (reward > totBal) {
reward = totBal; // @audit the idea here is to end up paying current rewards balance if the rewards to pay are greater. However, this also mean that there is still some unclaimed rewards pending to pay in a future. Current code does not take into account this.
}
if (reward > 0) {
_unclaimedRewards[onBehalfOf] = 0; // @audit This lines assumes that reward <= totBal always, something that is not true given previous conditional block
_updateUserSnapshotRewardsPerToken(onBehalfOf);
REWARD_TOKEN.safeTransfer(receiver, reward);
}
}
Impact
Lost of expected rewards
POC
Alice try to claim her unclaimed rewards through StaticATokenLM::claimRewardsToSelf, which are supposed to be 100 aReward tokens
For some reason REWARD_TOKEN.balanceOf(address(this)); returns 80 inside StaticATokenLM::_claimRewardsOnBehalf
Alice en up getting 80, and there is no way for her to claim her others 20 aReward tokens
Lines of code
https://github.com/reserve-protocol/protocol/blob/9ee60f142f9f5c1fe8bc50eef915cf33124a534f/contracts/plugins/assets/aave/StaticATokenLM.sol#L461-L482
Vulnerability details
Description
If for some reason the current contract reward token balance is lower than the rewards meant to be paid to
onBehalf
address, then this rewards can never be claimed.Impact
Lost of expected rewards
POC
StaticATokenLM::claimRewardsToSelf
, which are supposed to be 100 aReward tokensREWARD_TOKEN.balanceOf(address(this));
returns 80 insideStaticATokenLM::_claimRewardsOnBehalf
Mitigation steps
Assessed type
Other