Lines of code
<https://github.com/code-423n4/2023-08-livepeer/blob/main/contracts/bonding/libraries/EarningsPoolLIP36.sol#L47-L59>
When user unbonds before transcoder calls reward, then cumulativeRewardFactor for the round is less than it should be. As result other delegators loose rewards.
Each round transcoder can call reward function in order to claim reward tokens for himself and his delegators. This function can be called at any time in the round. In order to pay correct amount of rewards, protocol stores EarningsPool.Data for each round. One of itβs variables is cumulativeRewardFactor, which is used to calculate rewards for user. When reward function is called, then cumulativeRewardFactor for current round is updated.
function updateCumulativeRewardFactor(
EarningsPool.Data storage earningsPool,
EarningsPool.Data memory _prevEarningsPool,
uint256 _rewards
) internal {
uint256 prevCumulativeRewardFactor = _prevEarningsPool.cumulativeRewardFactor != 0
? _prevEarningsPool.cumulativeRewardFactor
: PreciseMathUtils.percPoints(1, 1);
earningsPool.cumulativeRewardFactor = prevCumulativeRewardFactor.add(
PreciseMathUtils.percOf(prevCumulativeRewardFactor, _rewards, earningsPool.totalStake)
);
}
As you can see, this function uses earningsPool.totalStake as total amount of staked funds in the epoch.
Now, letβs see what happens if user unbonds. In this case decreaseTotalStake function is called, which should decrease staked amount. It will do so only for next round, which means that earningsPoolPerRound for current round will be same.
That means that if user unbonds before reward is called, then this unbonded amount is still in the earningsPoolPerRound[currentPeriod].totalStaked, which means that it dilutes cumulativeRewardFactor for all other users.
Example.
1.There is transcoder with delegatedAmount 100 tokens.
2.In round 10 delegator that has 50 tokens unbonds them all.
3.In same round 10 transcoder calls reward and receives 10 more tokens that should be distributed to delegators.
4.cumulativeRewardFactor calculation will use 100 tokens as earningsPool.totalStake.
5.Rest of delegators received and claimed only 5 reward tokens.
6.Unbonded delegator also never received rest 5 tokens. They just stuck in the contract.
VsCode
In case if user unbonds some amount, before reward call, then update earningsPoolPerRound[currentPeriod].totalStaked for the current round.
Error
The text was updated successfully, but these errors were encountered:
All reactions