code-423n4 / 2023-05-ajna-findings

2 stars 0 forks source link

`RewardsManager.sol` contract the reward of the staked epoch is different from other epochs, which may be exploited to steal rewards #345

Closed code423n4 closed 1 year ago

code423n4 commented 1 year ago

Lines of code

https://github.com/code-423n4/2023-05-ajna/blob/main/ajna-core/src/RewardsManager.sol#L445-L453

Vulnerability details

Impact

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

  1. epoch N starts
  2. Alias stake LP, and the ExchangeRate at this time is much less than bucketExchangeRates[ajnaPool_][bucketIndex][epochN]
  3. 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.

Assessed type

Other

c4-judge commented 1 year ago

Picodes marked the issue as unsatisfactory: Insufficient quality