Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Batch reward calls on round initialization #482

Open
yondonfu opened this issue Oct 7, 2021 · 2 comments
Open

Batch reward calls on round initialization #482

yondonfu opened this issue Oct 7, 2021 · 2 comments

Comments

@yondonfu
Copy link
Member

yondonfu commented Oct 7, 2021

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] (#463 (comment)).

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 and claimedPrevRoundRewards is set to 0 [2]. However, Before the overwrite the unclaimed rewards from previous round is calculated as prevRoundRewards - 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 and orchestratorCutForTheRound 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 -

  1. Since there are a fixed number of orchestrators that is 100, calling reward for all the orchestrators will be a constant time function
  2. due to overwrite there won't be an unbonded growth for the storage
  3. The unclaimed rewards can be used for a variety of purposed. eg - can be given to orchestrator, can be used for governance etc. A part of this can even be used to reward the account which calls initializeRound as it now has a greater gas usage.
  4. This also solves the problem where delegators are dependant upon orchestrators for calling reward, now they don't lose reward even if the orchestrator doesn't call reward. Also, if the user does not call reward, they lose the reward, which is similar to the current approach.

additional notes -

  1. The first step does increase gas usage as the rewards are calculated for each orchestrator but for individual users the gas will be much lower
  2. This solves the problem of instant eligibility, dilution before reward call and also dilution after reward call

Originally posted by @kautukkundan in #463 (comment)

@yondonfu
Copy link
Member Author

yondonfu commented Oct 7, 2021

From @kautukkundan in #463 (comment)

possible fix to the problem in my previous comment
add a lastClaimedRound variable in the delegation struct and check it before calling claimReward
https://github.com/livepeer/protocol/blob/next/contracts/bonding/Delegations.sol#L28-L31

@kyriediculous
Copy link
Contributor

From a high level the proposal and some iterations I've done myself on this boil down to:

  1. Keep track of a reward pool across orchestrators accruing each round based on each Os equity share of stake
  2. Keep track of a delegation pool per orchestrators
  3. When commission rates are changed move accrued rewards from pool in [1] to the delegation pool minus orchestrator commissions

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants