Closed code423n4 closed 2 years ago
baseRewardPool.earned
returns the amount of CVX tokens earned, which is not what we are looking for in balanceOfJPEG
. Your reasoning would be correct if balanceOfJPEG
cared about rewards in other tokens, but it only cares about JPEG rewards which are claimed from a single extraReward
pool.
Invalid per sponsor's explanation.
Lines of code
https://github.com/code-423n4/2022-04-jpegd/blob/main/contracts/vaults/yVault/strategies/StrategyPUSDConvex.sol#L226
Vulnerability details
Impact
Calculating reward balance within
convexConfig.baseRewardPool
is not an easy task, mostly due to the design ofBaseRewardPool
contracts. In short, theconvexConfig.baseRewardPool
holds some reward itself, then it maintains a list ofextraRewards
, each of which also potentially holds rewards.The implementation of
balanceOfJPEG
ignores rewards held inbaseRewardPool
directly, and directly proceeds to traversebaseRewardPool.extraRewards
. It also does not check allextraRewards
entries exhaustively, but prematurely stops upon reaching the firstextraReward
withJPEG
asrewardToken
. The lack ofbaseRewardPool
is definitely a problem. As forextraRewards
, since there is no guarantee that no twoextraReward
entries can't both map to the samerewardToken
, it is also better to traverse all entries instead of stopping early.The incomplete fetch of rewards leads to an imprecise, underestimated
JPEG
balance, and as the value propagates up toYVaultLPFarming
, it undermines the calculate ofJPEG
yield. This causes users to receive lessJPEG
reward than they should.Proof of Concept
In
StrategyPUSDConvex
, the calculation ofJPEG
balance only considersJPEG
within strategy itself and part of the many reward ofbaseRewardPool
Compared with code used to retrieve rewards in Convex
BaseRewardPool
, it is easy to see Convex implementation is exhaustive, while strategy implementation is not.This imprecision in retrieving
JPEG
balance is reflected inYVaultLPFarming
, whereJPEG
balance is used to updateJPEG
rewards distributed tovaultToken
depositors.Overall, the bug results in
vaultToken
stakers to receive lesserJPEG
token than they should have through rewards.Tools Used
vim, ganache-cli
Recommended Mitigation Steps
Exhaustively traverse
extraReward
array, and also remember to add reward frombaseRewardPool
itself toavailableBalance
.Notice how we passed
address(this)
as the argument ofearned
. This is reported in a separate bug report, but for completeness, the entire fix is shown in both report entries.