File: RewardsManager.sol
445 if (epoch_ != stakingEpoch_) {
446
447 // if staked in a previous epoch then use the initial exchange rate of epoch
448 bucketRate = bucketExchangeRates[ajnaPool_][bucketIndex][epoch_];
449 } else {
450
451 // if staked during the epoch then use the bucket rate at the time of staking
452 bucketRate = bucketSnapshot.rateAtStakeTime;
453 }
If an epoch is the first epoch for a position, the bucketRate is bucketSnapshot.rateAtStakeTime, otherwise the bucketRate is uniformly bucketExchangeRates[ajnaPool_][bucketIndex][epoch_]. So in a certain epoch, the reward ratio of positions is the same in most cases. But for positions staked in this epoch, the reward rate is different and depends on rateAtStakeTime.
The attacker can choose the most favorable time to stake to get higher bucketRate. This makes his reward potentially much higher than other positions in the epoch, and the excess is stolen from other user rewards.
Proof of Concept
epoch N starts
Alias stake LP, and the ExchangeRate at this time is much less than bucketExchangeRates[ajnaPool_][bucketIndex][epochN]
Alias unstake after epoch N, Alias get a larger reward ratio than other users
Tools Used
Manual review
Recommended Mitigation Steps
It is recommended that the first epoch also use a unified bucketRate and obtain a certain percentage of rewards based on the stake time.
Lines of code
https://github.com/code-423n4/2023-05-ajna/blob/main/ajna-core/src/RewardsManager.sol#L445-L453
Vulnerability details
Impact
If an epoch is the first epoch for a position, the
bucketRate
isbucketSnapshot.rateAtStakeTime
, otherwise thebucketRate
is uniformlybucketExchangeRates[ajnaPool_][bucketIndex][epoch_]
. So in a certain epoch, the reward ratio of positions is the same in most cases. But for positions staked in this epoch, the reward rate is different and depends onrateAtStakeTime
.The attacker can choose the most favorable time to stake to get higher bucketRate. This makes his reward potentially much higher than other positions in the epoch, and the excess is stolen from other user rewards.
Proof of Concept
bucketExchangeRates[ajnaPool_][bucketIndex][epochN]
Tools Used
Manual review
Recommended Mitigation Steps
It is recommended that the first epoch also use a unified bucketRate and obtain a certain percentage of rewards based on the stake time.
Assessed type
Other