PLP transfer or balance updates do not update reward index
The reward calculation in _getPendingRewards depends on two key factors: the user's PLP token balance and their reward index (usrRwdIndexQ128).
Severity
Impact: High
Likelihood: High
Description
The reward calculation in _getPendingRewards depends on two key factors: the user's PLP token balance and their reward index (usrRwdIndexQ128).
function _getPendingRewards(address token, address user) internal view returns (uint256) {RewardInfo storage rewards = PoolStorage.layout().ledger.state.rewardsByToken[token];ILPToken plp_ = ILPToken(PoolStorage.layout().setUp.base.plp);uint256 lpBalance = plp_.balanceOf(user);uint8 plpDecimals = IERC20Metadata(PoolStorage.layout().setUp.base.plp).decimals();uint8 tokenDecimals = IERC20Metadata(token).decimals();uint256 rewardIndexQ128 = PoolStorage.layout().ledger.state.usrRwdIndexQ128[token][user];rewardIndexQ128 = rewards.rewardsPerLPQ128 - rewardIndexQ128;return lpBalance.mulDiv(rewardIndexQ128, Q128).toDecimals(plpDecimals, tokenDecimals);}
While the PLP balance can change through various operations (addLiquidity, withdrawLiquidity, or direct token transfers), the reward index is only updated in specific scenarios. This could lead to incorrect accounting for the rewards during PLP Token Transfers Or Other Balance Updates(like partial liquidity withdraw).
// Current update points for usrRwdIndexQ128:// 1. First deposit (_initRewardIndex)// 2. Full exit (_initRewardIndex)// 3. Manual claim (_claimRewards)function _updateLpRewardIndex(address token, address user) internal {PoolStorage.layout().ledger.state.usrRwdIndexQ128[token][user] =PoolStorage.layout().ledger.state.rewardsByToken[token].rewardsPerLPQ128;}
In such cases, users can manipulate their rewards by transferring PLP tokens without updating their usrRwdIndexQ128:
- A malicious user could transfer a large amount of PLP tokens to themselves before claiming rewards.
- The calculation
lpBalance.mulDiv(rewardIndexQ128, Q128)would use the inflated balance.
Recommendations
Implement a hook/accounting system to update the reward index whenever PLP token balances change.
Report provenance
Published by Pashov Audit Group, with Carlos (Bloqarl) participating as a contractor. The source report states that its fixes review was not fully completed; no final remediation disposition is recorded for this finding. Read the full report.