Rewards are given to validators for voting on finalizing blocks: the fund for these rewards can come from minting (creating new tokens). The amount that is minted depends on how much is staked and our desired yearly inflation. When the total of the tokens staked is very low, the return rate per validator needs to increase, but as the total amount of stake rises, validators will receive less rewards. Once we have acquired the desired stake percentage, the amount minted will just be the desired yearly inflation.
The validator and the delegator must have agreed on a commission rate between themselves. Delegators pay out rewards to validators based on a mutually-determined commission rate that both parties must have agreed upon beforehand. The minted rewards are auto-bonded and only transferred when the funds are unbonded. Once we have calculated the total that needs to be minted at the end of the epoch, we split the minted tokens according to the stake the relevant validators and delegators contributed and distribute them to validators and their delegators. This is similar to what Cosmos does.
We wish to approximate as exactly as possible the following ideal delegator reward distribution system:
At each epoch, for a validator V, iterate over all of the delegations to that validator. Update each delegation D, as follows.
D→D(1+rV(e)/sV(e))
where rV(e) and sV(e) respectively denote the reward and stake of validator V at epoch e.
Similarly, multiply the validator's voting power by the same factor (1+rV(e)/sV(e)), which should now equal the sum of their revised-amount delegations.
In this system, rewards are automatically rebonded to delegations, increasing the delegation amounts and validator voting powers accordingly.
However, we wish to implement this without actually needing to iterate over all delegations each block, since this is too computationally expensive. We can exploit this constant multiplicative factor (1+rV(e)/sV(e)) which does not vary per delegation to perform this calculation lazily, storing only a constant amount of data per validator per epoch, and calculate revised amounts for each individual delegation only when a delegation changes.
We will demonstrate this for a delegation D to a validator V. Let sD(e) denote the stake of D at epoch e.
For two epochs m and n with m<n, define the function p as
p(n,m)=e=m∏n(1+sV(e)rV(e)).
Denote p(n,0) as pn. The function p has a useful property.
p(n,m)=pmpn(1)
One may calculate the accumulated changes upto epoch n as
sD(n)=sD(0)∗pn.
If we know the delegation upto epoch m, the delegation at epoch n is obtained by the following formula,
sD(n)=sD(m)∗p(n,m).
Using property (1),
sD(n)=sD(m)∗pmpn.
Clearly, the quantity pn/pm does not depend on the delegation D. Thus, for a given validator, we need only store this product pe at each epoch e, with which updated amounts for all delegations can be calculated.
The product pe at the end of each epoch e is updated as follows.
Commission is charged by a validator on the rewards coming from delegations. These are set as percentages by the validator, who may charge any commission they wish between 0-100%.
Let c_V(e)bethecommissionrateforadelegationDtoavalidatorVatepoche.Theexpressionfortheproductp_nwehaveintroducedearliercanbemodifiedas<spanclass="katex−display"><spanclass="katex"><spanclass="katex−html"aria−hidden="true"><spanclass="base"><spanclass="strut"style="height:0.625em;vertical−align:−0.1944em;"></span><spanclass="mord"><spanclass="mordmathnormal">p</span><spanclass="msupsub"><spanclass="vlist−tvlist−t2"><spanclass="vlist−r"><spanclass="vlist"style="height:0.1514em;"><spanstyle="top:−2.55em;margin−left:0em;margin−right:0.05em;"><spanclass="pstrut"style="height:2.7em;"></span><spanclass="sizingreset−size6size3mtight"><spanclass="mordmathnormalmtight">n</span></span></span></span><spanclass="vlist−s"></span></span><spanclass="vlist−r"><spanclass="vlist"style="height:0.15em;"><span></span></span></span></span></span></span><spanclass="mspace"style="margin−right:0.2778em;"></span><spanclass="mrel">=</span><spanclass="mspace"style="margin−right:0.2778em;"></span></span><spanclass="base"><spanclass="strut"style="height:2.9185em;vertical−align:−1.2671em;"></span><spanclass="mopop−limits"><spanclass="vlist−tvlist−t2"><spanclass="vlist−r"><spanclass="vlist"style="height:1.6514em;"><spanstyle="top:−1.8829em;margin−left:0em;"><spanclass="pstrut"style="height:3.05em;"></span><spanclass="sizingreset−size6size3mtight"><spanclass="mordmtight"><spanclass="mordmathnormalmtight">e</span><spanclass="mrelmtight">=</span><spanclass="mordmtight">0</span></span></span></span><spanstyle="top:−3.05em;"><spanclass="pstrut"style="height:3.05em;"></span><span><spanclass="mopop−symbollarge−op">∏</span></span></span><spanstyle="top:−4.3em;margin−left:0em;"><spanclass="pstrut"style="height:3.05em;"></span><spanclass="sizingreset−size6size3mtight"><spanclass="mordmtight"><spanclass="mordmathnormalmtight">n</span></span></span></span></span><spanclass="vlist−s"></span></span><spanclass="vlist−r"><spanclass="vlist"style="height:1.2671em;"><span></span></span></span></span></span><spanclass="mspace"style="margin−right:0.1667em;"></span><spanclass="mord"><spanclass="delimsizingsize2">(</span></span><spanclass="mord">1</span><spanclass="mspace"style="margin−right:0.2222em;"></span><spanclass="mbin">+</span><spanclass="mspace"style="margin−right:0.2222em;"></span></span><spanclass="base"><spanclass="strut"style="height:1em;vertical−align:−0.25em;"></span><spanclass="mopen">(</span><spanclass="mord">1</span><spanclass="mspace"style="margin−right:0.2222em;"></span><spanclass="mbin">−</span><spanclass="mspace"style="margin−right:0.2222em;"></span></span><spanclass="base"><spanclass="strut"style="height:2.363em;vertical−align:−0.936em;"></span><spanclass="mord"><spanclass="mordmathnormal">c</span><spanclass="msupsub"><spanclass="vlist−tvlist−t2"><spanclass="vlist−r"><spanclass="vlist"style="height:0.3283em;"><spanstyle="top:−2.55em;margin−left:0em;margin−right:0.05em;"><spanclass="pstrut"style="height:2.7em;"></span><spanclass="sizingreset−size6size3mtight"><spanclass="mordmathnormalmtight"style="margin−right:0.22222em;">V</span></span></span></span><spanclass="vlist−s"></span></span><spanclass="vlist−r"><spanclass="vlist"style="height:0.15em;"><span></span></span></span></span></span></span><spanclass="mopen">(</span><spanclass="mordmathnormal">e</span><spanclass="mclose">))</span><spanclass="mord"><spanclass="mopennulldelimiter"></span><spanclass="mfrac"><spanclass="vlist−tvlist−t2"><spanclass="vlist−r"><spanclass="vlist"style="height:1.427em;"><spanstyle="top:−2.314em;"><spanclass="pstrut"style="height:3em;"></span><spanclass="mord"><spanclass="mord"><spanclass="mordmathnormal">s</span><spanclass="msupsub"><spanclass="vlist−tvlist−t2"><spanclass="vlist−r"><spanclass="vlist"style="height:0.3283em;"><spanstyle="top:−2.55em;margin−left:0em;margin−right:0.05em;"><spanclass="pstrut"style="height:2.7em;"></span><spanclass="sizingreset−size6size3mtight"><spanclass="mordmathnormalmtight"style="margin−right:0.22222em;">V</span></span></span></span><spanclass="vlist−s"></span></span><spanclass="vlist−r"><spanclass="vlist"style="height:0.15em;"><span></span></span></span></span></span></span><spanclass="mopen">(</span><spanclass="mordmathnormal">e</span><spanclass="mclose">)</span></span></span><spanstyle="top:−3.23em;"><spanclass="pstrut"style="height:3em;"></span><spanclass="frac−line"style="border−bottom−width:0.04em;"></span></span><spanstyle="top:−3.677em;"><spanclass="pstrut"style="height:3em;"></span><spanclass="mord"><spanclass="mord"><spanclass="mordmathnormal"style="margin−right:0.02778em;">r</span><spanclass="msupsub"><spanclass="vlist−tvlist−t2"><spanclass="vlist−r"><spanclass="vlist"style="height:0.3283em;"><spanstyle="top:−2.55em;margin−left:−0.0278em;margin−right:0.05em;"><spanclass="pstrut"style="height:2.7em;"></span><spanclass="sizingreset−size6size3mtight"><spanclass="mordmathnormalmtight"style="margin−right:0.22222em;">V</span></span></span></span><spanclass="vlist−s"></span></span><spanclass="vlist−r"><spanclass="vlist"style="height:0.15em;"><span></span></span></span></span></span></span><spanclass="mopen">(</span><spanclass="mordmathnormal">e</span><spanclass="mclose">)</span></span></span></span><spanclass="vlist−s"></span></span><spanclass="vlist−r"><spanclass="vlist"style="height:0.936em;"><span></span></span></span></span></span><spanclass="mclosenulldelimiter"></span></span><spanclass="mord"><spanclass="delimsizingsize2">)</span></span><spanclass="mord">.</span></span></span></span></span>inordertocalculatethenewrewardsgivenouttodelegatorsduringwithdrawal.Thusthecommissionchargedperepochisretainedbythevalidatorandremainsuntoucheduponwithdrawalbythedelegator.Thecommissionratec_V(e)isthesameforalldelegationstoavalidatorVinagivenepoche, including for self-bonds. The validator can change the commission rate at any point, subject to a maximum rate of change per epoch, which is a constant specified when the validator is created and immutable once validator creation has been accepted.
While rewards are given out at the end of every epoch, voting power is only updated after the pipeline offset. According to the proof-of-stake system, at the current epoch e, the validator sets an only be updated for epoch e + pipeline_offset, and it should remain unchanged from epoch e to e + pipeline_offset - 1. Updating voting power in the current epoch would violate this rule.
Slashes should lead to punishment for delegators who were contributing voting power to the validator at the height of the infraction, as if the delegations were iterated over and slashed individually.
This can be implemented as a negative inflation rate for a particular block.
Instant redelegation is not supported. Redelegations must wait the unbonding period.