Lucene search

K
code423n4Code4renaCODE423N4:2023-08-LIVEPEER-FINDINGS-ISSUES-184
HistorySep 06, 2023 - 12:00 a.m.

Calculating the previous pool's 'cumulativeRewardFactor' from the current pool incorrectly calculates the reward.

2023-09-0600:00:00
Code4rena
github.com
1
reward calculation
transcoder update
cumulative reward factor
token minting
mitigation update

Lines of code

Vulnerability details

Impact

When we updated a transcoder with rewards and then try to update a transcoder with fees, it incorrectly calculates the reward generated in the current round for that transcoder, which also incorrectly calculates the previous pool’s cumulativeRewardFactor, then the current pool’s incorrect cumulativeRewardFactor.

Proof of Concept

If the transcoder has already been updated with a reward, lastRewardRound is equivalent to currentRound.
And let’s assume the previous pool’s cumulativeRewardFactor is zero.
In this case, we calculate the previous pool’s cumulativeRewardFactor value from the current pool’s cumulativeRewardFactor.
That is, it falls to the below part.

if (prevEarningsPool.cumulativeRewardFactor == 0 && lastRewardRound == currentRound) {
    IMinter mtr = minter();
    uint256 rewards = PreciseMathUtils.percOf(
       mtr.currentMintableTokens().add(mtr.currentMintedTokens()),
       totalStake,
       currentRoundTotalActiveStake
    );

    ...
}

The logic behind this is below.

rewards = mtr.currentMintableTokens() * totalStake / currentRoundTotalActiveStake;
delegatorsRewards = rewards - treasuryRewards - transcoderCommissionRewards;
prevEarningsPool.cumulativeRewardFactor * (1 + delegatorsRewards / totalStake) = earningsPool.cumulativeRewardFactor;

But in Minter, we calculate the rewards for the transcoder like below.

uint256 mintAmount = MathUtils.percOf(currentMintableTokens, _fracNum, _fracDenom);

As you can see, it doesn’t involve currentMintedTokens because currentMintableTokens is constant during the round.

And also in Minter, we used MathUtils but PreciseMathUtils in BondingManager.
This is also bug I think.

Tools Used

Manual audit

Recommended Mitigation Steps

Update like below.

uint256 rewards = MathUtils.percOf(
    mtr.currentMintableTokens(),
    totalStake,
    currentRoundTotalActiveStake
);

Assessed type

Error


The text was updated successfully, but these errors were encountered:

All reactions