Skip to content

Commit

Permalink
Merge remote-tracking branch 'namada/brent/update-inflation-spec' (#613)
Browse files Browse the repository at this point in the history
* namada/brent/update-inflation-spec:
  formatting changes
  change `L_{NAM}` -> `L_{PoS}` for clarity and consistency
  change inflation `I` to have units of tokens per epoch
  fix term ordering in error calculation
  Remove other `:=` in favor of `=`
  distinguish new and old inflation rates with a prime
  fix md rendering
  correct the shielded pool error calculation
  change storing of error to storing of token ratios (same procedure)
  fix: `I` is percent per annum
  distinguish between `K` in storage and `K` as intermediate value in inflation calculation
  Use `I` for inflation rates, as `R` reserved for locked ratios
  specify some default values, other small edits
  • Loading branch information
juped committed Oct 20, 2022
2 parents 48b7c7b + cc8f6f7 commit 72feea5
Showing 1 changed file with 36 additions and 36 deletions.
72 changes: 36 additions & 36 deletions documentation/specs/src/economics/inflation-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The Namada protocol controls the Namada token NAM (the native staking token), wh

### Proof-of-stake rewards

The security of the proof-of-stake voting power allocation mechanism used by Namada is depenedent in part upon locking (bonding) tokens to validators, where these tokens can be slashed should the validators misbehave. Funds so locked are only able to be withdrawn after an unbonding period. In order to reward validators and delegators for locking their stake and participating in the consensus mechanism, Namada pays a variable amount of inflation to all delegators and validators. The amount of inflation paid is varied on a PD-controller in order to target a particular bonding ratio (fraction of the NAM token being locked in proof-of-stake). Namada targets a bonding ratio of 2/3, paying up to 10% inflation per annum to proof-of-stake rewards. See [reward distribution mechanism](./proof-of-stake/reward-distribution.md) for details.
The security of the proof-of-stake voting power allocation mechanism used by Namada is dependent in part upon locking (bonding) tokens to validators, where these tokens can be slashed should the validators misbehave. Funds so locked are only able to be withdrawn after an unbonding period. In order to reward validators and delegators for locking their stake and participating in the consensus mechanism, Namada pays a variable amount of inflation to all delegators and validators. The amount of inflation paid is varied on a PD-controller in order to target a particular bonding ratio (fraction of the NAM token being locked in proof-of-stake). Namada targets a bonding ratio of 2/3, paying up to 10% inflation per annum to proof-of-stake rewards. See [reward distribution mechanism](./proof-of-stake/reward-distribution.md) for details.

### Shielded pool rewards

Expand All @@ -20,61 +20,61 @@ Inflation is calculated and paid per-epoch as follows.

First, we start with the following fixed (governance-alterable) parameters:

- $Cap_{PoS}$ is the cap of proof-of-stake reward rate, in units of percent per annum
- $Cap_{SP-A}$ is the cap of shielded pool reward rate for each asset $A$, in units of percent per annum
- $R_{PGF}$ is the public goods funding reward rate, in units of percent per annum
- $R_{PoS-Target}$ is the target staking ratio (genesis default 2/3)
- $R_{SP-A-Target}$ is the target amount of asset $A$ locked in the shielded pool (separate value for each asset $A$)
- $EpochsPerYear$ is the number of epochs per year (genesis default 365)
- ${KP}_{PoS}$ is the proportional gain of the proof-of-stake PD controller, as a fraction of the total input range
- ${KD}_{PoS}$ is the derivative gain of the proof-of-stake PD controller, as a fraction of the total input range
- ${KP}_{SP_A}$ is the proportional gain of the shielded pool reward controller for asset $A$, as a fraction of the total input range (separate value for each asset $A$)
- ${KD}_{SP_A}$ is the derivative gain of the shielded pool reward controller for asset $A$, as a fraction of the total input range (separate value for each asset $A$)
- $Cap_{PoS}$ is the cap of proof-of-stake reward rate, in units of percent per annum (genesis default: 10%)
- $Cap_{SP_A}$ is the cap of shielded pool reward rate for each asset $A$, in units of percent per annum
- $\lambda_{PGF}$ is the public goods funding reward rate, in units of percent per annum
- $R_{PoS-target}$ is the target staking ratio (genesis default: 2/3)
- $R_{SP_A-target}$ is the target amount of asset $A$ locked in the shielded pool (separate value for each asset $A$)
- $EpochsPerYear$ is the number of epochs per year (genesis default: 365)
- ${KP}_{PoS-nom}$ is the nominal proportional gain of the proof-of-stake PD controller, as a fraction of the total input range
- ${KD}_{PoS-nom}$ is the nominal derivative gain of the proof-of-stake PD controller, as a fraction of the total input range
- ${KP}_{SP_A-nom}$ is the nominal proportional gain of the shielded pool reward controller for asset $A$, as a fraction of the total input range (separate value for each asset $A$)
- ${KD}_{SP_A-nom}$ is the nominal derivative gain of the shielded pool reward controller for asset $A$, as a fraction of the total input range (separate value for each asset $A$)

Second, we take as input the following state values:

- $S_{NAM}$ is the current supply of NAM
- $L_{NAM}$ is the current amount of NAM locked in proof-of-stake
- $I_{PoS}$ is the current proof-of-stake reward rate, in units of tokens per epoch
- $E_{PoS-last}$ is the error in proof-of-stake lock ratio (stored from the past epoch)
- $L_{PoS}$ is the current amount of NAM locked in proof-of-stake
- $I_{PoS}$ is the current proof-of-stake inflation amount, in units of tokens per epoch
- $R_{PoS-last}$ is the proof-of-stake locked token ratio from the previous epoch
- $L_{SP_A}$ is the current amount of asset $A$ locked in the shielded pool (separate value for each asset $A$)
- $I_{SP_A}$ is the current shielded pool reward rate for asset $A$, in units of tokens per epoch
- $E_{SP_A-last}$ is the error in shielded pool lock amount for asset $A$ (stored from the past epoch) (separate value for each asset $A$)
- $I_{SP_A}$ is the current shielded pool inflation amount for asset $A$, in units of tokens per epoch
- $R_{SP_A-last}$ is the shielded pool locked token ratio for asset $A$ from the previous epoch (separate value for each asset $A$)

Public goods funding inflation can be calculated and paid immediately:
Public goods funding inflation can be calculated and paid immediately (in terms of total tokens per epoch):

- $I_{PGF} := R_{PGF} * S_{NAM} / EpochsPerYear$
- $I_{PGF} = \lambda_{PGF} * S_{NAM} / EpochsPerYear$

These tokens are distributed to the public goods funding validity predicate.

To run the PD-controllers for proof-of-stake and shielded pool rewards, we first calculate some intermediate values:

- Calculate the staking ratio $R_{PoS}$ as $L_{NAM} / S_{NAM}$
- Calculate the per-epoch cap on proof-of-stake and shielded pool reward rates
- $Cap_{PoS-Epoch} := S_{NAM} * Cap_{PoS} / EpochsPerYear$
- $Cap_{SP_A-Epoch} := S_{NAM} * Cap_{SP_A} / EpochsPerYear$ (separate value for each $A$)
- Calculate PD-controller constants
- ${KP}_{PoS} := {KP}_{PoS} * Cap_{PoS-Epoch}$
- ${KD}_{PoS} := {KD}_{PoS} * Cap_{PoS-Epoch}$
- ${KP}_{SP_A} := {KP}_{SP_A} * Cap_{SP_A-Epoch}$
- ${KD}_{SP_A} := {KD}_{SP_A} * Cap_{SP_A-Epoch}$
- Calculate the latest staking ratio $R_{PoS}$ as $L_{PoS} / S_{NAM}$
- Calculate the per-epoch cap on the proof-of-stake and shielded pool token inflation
- $Cap_{PoS-Epoch} = S_{NAM} * Cap_{PoS} / EpochsPerYear$
- $Cap_{SP_A-Epoch} = S_{NAM} * Cap_{SP_A} / EpochsPerYear$ (separate value for each $A$)
- Calculate PD-controller constants to be used for this epoch
- ${KP}_{PoS} = {KP}_{PoS-nom} * Cap_{PoS-Epoch}$
- ${KD}_{PoS} = {KD}_{PoS-nom} * Cap_{PoS-Epoch}$
- ${KP}_{SP_A} = {KP}_{SP_A-nom} * Cap_{SP_A-Epoch}$
- ${KD}_{SP_A} = {KD}_{SP_A-nom} * Cap_{SP_A-Epoch}$

Then, for proof-of-stake first, run the PD-controller:

- Calculate the error $E_{PoS} := R_{PoS-Target} - R_{PoS}$
- Calculate the error derivative $E'_{PoS} := E_{PoS} - E_{PoS-last}$
- Calculate the control value $C_{PoS} := (KP_{PoS} * E_{PoS}) - (KD_{PoS} * E'_{PoS})$
- Calculate the new $I_{PoS} := max(0, min(I_{PoS} + C_{PoS}, Cap_{PoS}))$
- Calculate the error $E_{PoS} = R_{PoS-target} - R_{PoS}$
- Calculate the error derivative $E'_{PoS} = E_{PoS} - E_{PoS-last} = R_{PoS-last} - R_{PoS}$
- Calculate the control value $C_{PoS} = (KP_{PoS} * E_{PoS}) - (KD_{PoS} * E'_{PoS})$
- Calculate the new $I'_{PoS} = max(0, min(I_{PoS} + C_{PoS}, Cap_{PoS-Epoch}))$

These tokens are distributed to the proof-of-stake reward distribution validity predicate.

Similarly, for each asset $A$ for which shielded pool rewards are being paid:

- Calculate the error $E_{SP_A} := L_{SP_A-Target} - L_{SP_A}$
- Calculate the error derivative $E'_{SP_A} := E_{SP-A} - E_{SP_A-last}$
- Calculate the control value $C_{SP_A} := (KP_{SP_A} * E_{SP_A}) - (KD_{SP_A} * E'{SP_A})$
- Calculate the new $I_{SP_A} := max(0, min(I_{SP_A} + C_{SP_A}, Cap_{SP_A-Epoch}))$
- Calculate the error $E_{SP_A} = R_{SP_A-target} - R_{SP_A}$
- Calculate the error derivative $E'_{SP_A} = E_{SP_A} - E_{SP_A-last} = R_{SP_A-last} - R_{SP_A}$
- Calculate the control value $C_{SP_A} = (KP_{SP_A} * E_{SP_A}) - (KD_{SP_A} * E'_{SP_A})$
- Calculate the new $I'_{SP_A} = max(0, min(I_{SP_A} + C_{SP_A}, Cap_{SP_A-Epoch}))$

These tokens are distributed to the shielded pool reward distribution validity predicate.

Finally, we store the current inflation and error values for the next controller round.
Finally, we store the latest inflation and locked token ratio values for the next epoch's controller round.

0 comments on commit 72feea5

Please sign in to comment.