Open yondonfu opened 2 years ago
From @kautukkundan in https://github.com/livepeer/protocol/issues/463#issuecomment-927939556
possible fix to the problem in my previous comment add a
lastClaimedRound
variable in the delegation struct and check it before callingclaimReward
https://github.com/livepeer/protocol/blob/next/contracts/bonding/Delegations.sol#L28-L31
From a high level the proposal and some iterations I've done myself on this boil down to:
After reviewing the above proposal, going through some design iterations with the same purpose myself and discussing it with @kautukkundan we concluded the following things:
The commission rate makes it hard because some transition needs to happen when the commission rates are changed by an orchestrator. The difference in commission rates across O's also makes it impossible to calculate an inflation rate that is equal for all accounts
The transition that needs to happen when commission rates are changed means that accrued rewards under a previous commission rate need to be processed , which is essentially very similar to a reward call. It's also highly likely that this cost would need to be socialised (e.g. also fall onto delegators if state hasn't progressed yet). In earlier discussions regarding confluence staking and solving the double reward problem me and @yondonfu sort of agreed that this might not be the best UX tradeoff in terms of cost predictability (and effective cost paid), but @kautukkundan mentioned that in a discussion with @adamsoffer that there could also be a benefit; more predictability in rewards.
However the argument above might not be entirely valid anymore as in the current confluence design we already socialize the cost of some state progression based on who takes the first delegation action (or rewards/fees added) in a round. So I think this is definitely an interesting problem area to put some more thought in if we are okay with the cost of some state progressions being socialised.
I thought of another approach for calculating and distributing rewards. This approach has a change in the mechanism of how rewards are called. 2 new variables are introduced in each delegation pool -
prevRoundRewards
,claimedPrevRoundRewards
+orchestratorCutForTheRound
(which can be read from the staking manager).[⛔️ After writing this I realized that I completely missed that there is a need to track if individual delegator has claimed reward, still keeping this comment here for reference]
step 1 - instead of each orchestrator calling reward individually, rewards for all the orchestrators will be called at the same time when
initializeRound
is called [1] end of round [this comment] (https://github.com/livepeer/protocol/issues/463#issuecomment-922581787).step 2 - Now instead of calculating cuts for orchestrator and delegators individually, the total value of reward is simply added to the respective pool and the
prevRoundRewards
is overwritten with the value andclaimedPrevRoundRewards
is set to 0 [2]. However, Before the overwrite the unclaimed rewards from previous round is calculated asprevRoundRewards - claimedPrevRoundRewards
which can be used as per [3]step 3 - Now, each delegator and orchestrator can individually call a
claimReward
function which will use the current shares,prevRoundRewards
andorchestratorCutForTheRound
to calculate respective rewards [4]. delegator rewards =prevRoundRewards * (1-orchestratorCutForTheRound) * delegator's share
orchestrator rewards =prevRoundRewards * orchestratorCutForTheRound * orchestrator's share
then the delegator's and orchestrator's stakes are updated.
step 4 - for each claim, update
claimedPrevRoundRewards
notes -
initializeRound
as it now has a greater gas usage.additional notes -
Originally posted by @kautukkundan in https://github.com/livepeer/protocol/issues/463#issuecomment-927912360