264
,
+- `Pool Coefficient = ((Pool Stake(i) << Pool Coefficient Exponent)/Total Stake) + (Validator Stake(i) << Pool Coefficient Exponent) / Total Validator Stake`:
+Since both `Pool Stake(i)` and `Validator Stake(i)` are at most `Token Supply`, to not overflow the calculation, `Pool Coefficient Exponent` must be such that (Token Supply << Pool Coefficient Exponent)< 264
.
+`Pool Coefficient` will then use at most `Pool Coefficient Exponent + 1` bits.
+- `res = (Pool Coefficient * Target Rewards Rate(n))>>PoolCoefficientExponent`: this implies that `Pool Coefficient * Target Rewards Rate(n))` must always be smaller than 264
, which is guaranteed by the condition Initial Target Rewards Rate <263-Pool Coefficient Exponent
.
+- `Pool Reward = ((res * Epoch Performance Factor)/Validation Blocks Per Slot)>>1`: since `res` is at most two times `Initial Target Rewards Rate`, and `Epoch Performance Factor` is at most `Validation Blocks Per Slot <= 32`, this imples that Initial Target Rewards Rate * Validation Blocks Per Slot < 263
.
+
+- `Profit Margin Factor = (Profit Margin(n) * (Pool Rewards(n) - Fixed Cost(n))) >> Profit Margin Exponent`: this implies that `Initial Target Rewards Rate<2^(64-Profit Margin Exponent) `
+
+## Constraints due to parameter compatibility
+
+To avoid locally calculating the parameters, some of them are provided in the snapshot file, even thought they not are defined independently in the Whitepaper.
+To avoid problems in the parameter setting, we define some sanity checks for these parameters below:
+
+## Lookup Table and Annual Decay
+
+Let `Seconds In An Epoch = Slot Duration In Seconds << Slots Per Epoch Exponent` and `Seconds In A Year = 60 * 60 * 24* 365`.
+Then the epoch duration in years is given by `Epoch Duration In Years = Seconds In An Epoch/Seconds In A Year`.
+Additionally, let `Annual Decay Factor = Annual Decay Factor Percentage/100`.
+
+The entry `Lookup Table(epochDiff)` in the Lookup table relative to `epochDiff` should be such that
+
+`0 <= delta < 1`, where
+
+`delta = (Annual Decay Factor)^(epochDiff*Epoch Duration In Years)*(2**decay Factor Exp) - Lookup Table(epochDiff)`
+
+## Initial and Final rewards
+
+Let `Seconds In An Epoch = Slot Duration In Seconds << Slots Per Epoch Exponent` and `Seconds In A Year = 60 * 60 * 24* 365`.
+Then the epoch duration in years is given by `Epoch Duration In Years = Seconds In An Epoch/Seconds In A Year`.
+The bootstrapping duration in years is, then:
+`Bootstrapping Duration In Years = Epoch Duration In Years * Bootstrapping Duration`
+Additionally, let `Annual Decay Factor = Annual Decay Factor Percentage/100`.
+
+Let `Expected Final Target Rewards Rate = (Total Supply * Reward To Generation Ratio * Generation Rate) >> (Generation Rate Exponent - Slots Per Epoch Exponent)` and `Expected Initial Target Rewards Rate = Final Target Rewards Rate / (Annual Decay Factor ^ Bootstrapping Duration In Years)`.
+
+Then, we need
+
+`0 <= Expected Final Target Rewards Rate - Final Target Rewards Rate < 1`
+and
+`0 <= Expected Initial Target Rewards Rate - Initial Target Rewards Rate < 1`
+
+## Bootstrapping Duration and Decay
+
+Let `Seconds In An Epoch = Slot Duration In Seconds << Slots Per Epoch Exponent` and `Seconds In A Year = 60 * 60 * 24 * 365`.
+Then the number of epochs in a years is given by `Epochs In An Year = Seconds In A Year/Seconds In An Epoch`.
+Additionally, let `Annual Decay Factor = Annual Decay Factor Percentage/100`.
+Translating this to an exponential decay (as in the Whitepaper), we have that `Beta Per Year = -log(Annual Decay Factor)`.
+
+The bootstrapping duration should be an integer approximation of `Epochs In An Year/Beta Per Year`
+
+## Decay Factor Epoch Sum and Decay
+
+Decay Factor Epoch Sum should be an integer approximation of
+
+`2^Decay Factor Epoch Sum Exponent* Decay per Epoch/(1-Decay per Epoch)`
diff --git a/tips/TIP-0040/tip-0040.md b/tips/TIP-0040/tip-0040.md
new file mode 100644
index 000000000..372440846
--- /dev/null
+++ b/tips/TIP-0040/tip-0040.md
@@ -0,0 +1,834 @@
+---
+tip: 40
+title: Staking & Delegation
+description: Staking, Delegation and Mana Rewards
+author:
+ Philipp Gackstatter (@PhilippGackstatter) Signals candidacy for committee selection for the epoch after the one in which it is issued.+
+ Name + | ++ Type + | ++ Description + | +
Payload Type | +uint8 | +Set to value 2 to denote a Candidacy Announcement Payload. | +
Describes a Delegation Output, which delegates its contained IOTA coins to a validator.+
+ Name + | ++ Type + | ++ Description + | +|||||||||
Output Type | +uint8 | +Set to value 5 to denote a Delegation Output. | +|||||||||
Amount | +uint64 | +The amount of IOTA coins held by the output. | +|||||||||
Delegated Amount | +uint64 | +The amount of delegated IOTA coins. | +|||||||||
Delegation ID | +ByteArray[32] | +Unique identifier of the Delegation Output, which is the BLAKE2b-256 hash of the Output ID that created it. | +|||||||||
Validator Address oneOf |
+
+
+
+ Account Address+An Address derived from an Account ID which can be unlocked by unlocking the corresponding Account. Defined in TIP-38 (Account Address).+
|
+ ||||||||||
Start Epoch | +uint64 | +The index of the first epoch for which this output delegates. | +|||||||||
End Epoch | +uint64 | +The index of the last epoch for which this output delegates. | +|||||||||
Unlock Conditions Count | +uint8 | +The number of unlock conditions following. | +|||||||||
Unlock Conditions atMostOneOfEach |
+
+
+
+ Address Unlock Condition+Defines the Address that owns this output. It can unlock the output with the proper Unlock in a transaction. Defined in TIP-38 (Address Unlock Condition).+
|
+
Name | +Type | +Description | +
Slot Activity Vector | +uint32 |
+ A bitmap where each bit corresponds to a subslot in the slot for which the performance factor is tracked. + |
Blocks Issued Count | +uint8 |
+ The total number of blocks issued by the validator in the slot. | +
2Profit Margin Exponent
, so `Profit Margin` can
+ be set to use `Profit Margin Exponent` bits.
+- To prevent overflows in the calculation above, (Token Supply << Profit Margin Exponent)< 264
, where `Token Supply` is the current token supply on the network, as defined in [TIP-49](../TIP-0049/tip-0049.md).
+
+The `Profit Margin` must be tracked for each epoch:
+
+Name | +Type | +Description | +
Profit Margin | +uint8 | +
+ An integer representing the epoch profit margin, scaled to 2Profit Margin Exponent .
+ |
+
Name | +Type | +Description | +
Pool Stake | +uint64 |
+ The total amount of IOTA coins staked by the validator and all its delegators. | +
Pool Rewards | +uint64 |
+ The total amount of rewards the validator pool received. | +
Fixed Cost | +uint64 |
+ The fixed cost of the validator in that epoch. | +
(Token Supply << Pool Coefficient Exponent)< 264
. `Pool Coefficient` will then use at most
+ `Pool Coefficient Exponent + 1` bits.
+ - Take the `Epoch Performance Factor` for the whole epoch `n` according to
+ [Epoch Performance Factor](#epoch-performance-factor).
+ - To calculate `Pool Reward`, we first calculate `res = (Pool Coefficient * Target Rewards Rate(n))>>PoolCoefficientExponent`. Then, `Pool Reward = ((res * Epoch Performance Factor)/Validation Blocks Per Slot)>>1`.
+ Note that if this value is smaller than `Fixed Cost`, the validator will not receive rewards from this epoch.
+ This is done to incentivize validators to define reasonable values for their fixed cost.
+
+## Validator Rewards
+
+An account with a _Staking Feature_ can claim rewards in the same transaction where the feature is removed. The
+transaction validation rules for removing the feature are defined in [TIP-42](../TIP-0042/tip-0042.md). Upon removal,
+the amount of Mana Rewards that can be claimed is defined as follows.
+
+### Parameters for Validator Rewards calculation
+
+- Let `Profit Margin Exponent` be as defined in [TIP-49](../TIP-0049/tip-0049.md).
+
+### Input Values for Validator Rewards calculation
+
+- Let `Profit Margin(n)` be the `Profit Margin` for epoch index `n`.
+- Let `Pool Rewards(n)` be the `Pool Rewards` of the entry in `Claimable Rewards` with epoch index `n`.
+- Let `Pool Stake(n)` be the `Pool Stake` of the entry in `Claimable Rewards` with epoch index `n`.
+- Let `Fixed Cost(n)` be the `Fixed Cost` defined in the _Staking Feature_ at epoch `n`.
+
+### Validator Rewards calculation
+
+To calculate the claimable rewards of a validator relative to a past epoch `n`, we must first calculate `Undecayed Validator Rewards(n)`.
+This value corresponds to the claimable reward if the validator claimed them right after the epoch ended.
+If the claiming epoch is larger than `n+1`, this value has to be decayed to account for this epoch difference.
+To calculate the `Undecayed Validator Rewards(n)` for a given epoch `n`, we proceed as follows:
+
+- If `Pool Rewards(n) - Fixed Cost(n) < 0`, then `Undecayed Validator Rewards(n)` is zero.
+- If `Pool Rewards(n) - Fixed Cost(n) >= 0`, then `Undecayed Validator Rewards(n)` is
+ `Fixed Cost(n) + Profit Margin Factor + Residual Validator Factor`, where:
+ - `Profit Margin Factor = (Profit Margin(n) * (Pool Rewards(n) - Fixed Cost(n))) >> Profit Margin Exponent`.
+ - `Residual Validator Factor = ((Profit Margin Complement * (Pool Rewards(n) - Fixed Cost(n))) >> Profit Margin Exponent) * Staked Amount/Pool Stake(n)`
+ where `Profit Margin Complement = (1 << Profit Margin Exponent) - Profit Margin(n)`.
+ - Note that `((Profit Margin Complement * Pool Rewards(n)) >> Profit Margin Exponent) * Staked Amount` can use more than 64 bits. Then, to prevent overflowing, this factor should be either stored as
+ a 128 bits integer or it should be stored as 2 `uint64` variables (and the proper 128 by 64 division algorithm must be used).
+
+Finally, given `Undecayed Validator Rewards(n)`, we can calculate the decayed rewards relative to epoch `n`, by applying `Validator Rewards(Decay End Epoch, n) = Decay(Undecayed Validator Rewards(n), Decay End Epoch - n)`.
+
+Given the values of `Validator Rewards(Decay End Epoch, n)`, we calculate the total claimable reward for a validator as follows:
+
+- Let `Future Bounded Slot Index` be given by `Commitment Index + Min Committable Age` where `Commitment Index` is the
+ slot index of the commitment input. If no _Commitment Input_ is present, the transaction is invalid.
+ - Note that the presence of a _Commitment Input_ is already required for any transaction containing a _Staking
+ Feature_ on the input or output side.
+- Let `Future Bounded Epoch Index` be the epoch index corresponding to the slot index `Future Bounded Slot Index`.
+- Let the `Claimable Rewards(id)` be all reward entries for the validator identified by the Account ID `id` of the
+ account that removes the Staking Feature, where the reward entry's epoch index `Epoch Index` satisfies all of the
+ following conditions:
+ - `Epoch Index >= Start Epoch + 1`.
+ - `Epoch Index < Last Reward Epoch` where `Last Reward Epoch` is the minimum of `Future Bounded Epoch Index` and
+ `End Epoch + 1`.
+- Let `Validator Rewards(Account ID)` be the total claimable decayed rewards for the Account Output identified by
+ `Account ID`. It is the sum of `Validator Rewards(Decay End Epoch, n)` for each epoch `n` in `Claimable Rewards(Account ID)`
+ where `Decay End Epoch` is the maximum of `Future Bounded Epoch Index - 1` (or `0` if that would underflow) and
+ `Last Reward Epoch`.
+ - Note: The `- 1` is applied to allow claiming the full, undecayed reward for an epoch `n - 1` in epoch `n`.
+
+## Delegator Rewards
+
+To claim rewards, a _Delegation Output_ must be destroyed. Depending on the state it is in at that point, different
+conditions for claiming rewards apply. An output destroyed in _Delegating State_ will always forfeit _potential_ rewards
+for the epoch in which it is destroyed, since the rewards for that epoch only become available in the subsequent epoch.
+They are _potential_ since the validator to which the output is delegating may not have been selected into the committee
+for that epoch.
+
+### Parameters for Delegator Rewards calculation
+
+- Let `Profit Margin Exponent` be as defined in [TIP-49](../TIP-0049/tip-0049.md).
+
+### Input Values for Delegator Rewards calculation
+
+- Let `Profit Margin(n)` be the `Profit Margin` for epoch index `n`.
+- Let `Pool Rewards(n)` be the `Pool Rewards` of the entry in `Claimable Rewards(id)` with epoch index `n` for validator
+ `id`.
+- Let `Pool Stake(n)` be the `Pool Stake` of the entry in `Claimable Rewards(id)` with epoch index `n` for validator
+ `id`.
+- Let `Fixed Cost(n)` be the `Fixed Cost` defined in the _Staking Feature_ at epoch `n`.
+
+### Delegator Rewards calculation
+
+Similarly to the validator rewards calculation, the amount of Mana Rewards that can be claimed for a _Delegation Output_ which is destroyed is defined as follows. We begin by calculating the undecayed claimable rewards relative to a past epoch `n`, denoted by `Undecayed Delegator Rewards(n)`.
+This value corresponds to the claimable reward if the delegator claimed them right after the epoch ended.
+If the claiming epoch is larger than `n+1`, this value has to be decayed to account for this epoch difference.
+To calculate the `Undecayed Delegator Rewards(n)` for a given epoch `n`, we proceed as follows:
+
+- If `Pool Rewards(n) - Fixed Cost(n) < 0`, then `Undecayed Delegator Rewards(n)` is
+ `((Profit Margin Complement * Pool Rewards(n)) >> Profit Margin Exponent) * Delegated Amount/Pool Stake(n)`.
+- If `Pool Rewards(n) - Fixed Cost(n) >= 0`, then `Undecayed Delegator Rewards(n)` is
+ `((Profit Margin Complement * (Pool Rewards(n) - Fixed Cost(n))) >> Profit Margin Exponent) * Delegated Amount/Pool Stake(n)`.
+ - Note that `((Profit Margin Complement * Pool Rewards(n)) >> Profit Margin Exponent) * Delegated Amount` can use more than 64 bits. Then, to prevent overflowing, this factor should be either stored as
+ a 128 bits integer or it should be stored as 2 `uint64` variables (and the proper 128 by 64 division algorithm must be used).
+
+Finally, given `Undecayed Delegator Rewards(n)`, we can calculate the decayed rewards relative to epoch `n`, by applying `Delegator Rewards(Decay End Epoch, n) = Decay(Undecayed Delegator Rewards(n), Decay End Epoch - n)`.
+Given the values of `Delegator Rewards(Decay End Epoch, n)`, we calculate the total claimable reward for a delegator as follows:
+
+- Let the `Claimable Rewards(address)` be all reward entries for the validator identified by the Account ID
+ corresponding to the `address`, which is the `Validator Address` field in the Delegation Output, where the entry's
+ epoch index `Epoch Index` satisfies `Epoch Index >= Start Epoch` and `Epoch Index <= Delegation End`, where:
+ - If the output is in _Delegating State_ let `Delegation End` be `Future Bounded Epoch Index - 1`, where:
+ - `Future Bounded Slot Index` is given by `Commitment Index + Min Committable Age` where `Commitment Index` is the
+ slot index of the commitment input. If no _Commitment Input_ is present, the transaction is invalid.
+ - Note that the presence of a _Commitment Input_ is already required for any transaction containing a _Delegation
+ Output_ on the input or output side.
+ - `Future Bounded Epoch Index` is the epoch index corresponding to the slot index `Future Bounded Slot Index`.
+ - Note that no transaction validation rule exists to prevent claiming rewards too early, that is, before the rewards
+ of the previous epoch became available, thus forfeiting the potential rewards of that previous epoch.
+ - If the output is in _Delayed Claiming State_ let `Delegation End` be `End Epoch`.
+- Let `Delegator Rewards(Delegation ID)` be the total claimable decayed rewards for the Delegation Output identified by
+ `Delegation ID` with `address` set to the `Validator Address`. It is the sum of `Delegator Rewards(Decay End Epoch, n)` for each
+ epoch `n` in `Claimable Rewards(address)`, where `Decay End Epoch` is the maximum of `Future Bounded Epoch Index - 1`
+ (or `0` if that would underflow) and `Delegation End`.
+ - Note: The `- 1` is applied to allow claiming the full, undecayed reward for an epoch `n - 1` in epoch `n`.
+
+# Rationale & Design
+
+This section describes the rationale behind some of the design choices and explains how the introduced concepts fit
+together. It is however not part of the formal specification and thus non-normative.
+
+## Delegation Output
+
+Using dedicated Delegation Outputs over a Delegation Feature in an Account has some advantages. First, it makes it
+easily possible to delegate to multiple validators from the same account, by creating multiple outputs. In the Stardust
+Design ([TIP-18](../TIP-0018/tip-0018.md)), Features are assumed to be unique in an output, and thus having multiple
+Delegation Features to allow for multiple delegation targets would require changing that assumption. Second, it
+decouples the delegation logic from the Account. Delegation, in contrast to staking, does not require that an account
+must be the delegator. A Delegation Output can be owned by a plain Ed25519 address or an NFT or Account Address, making
+it more flexible. A Delegation Feature would only allow for Delegation from an account.
+
+### Delayed Claiming
+
+Mana Rewards for some epoch `X` only become available after that epoch ends. At that point, the pool stake for the
+following epoch `X+1` has already been calculated. That means, if one waits until the rewards for `X` are available and
+consumes their Delegation Output to claim rewards, they have already delegated for `X+1` but will lose out on the
+rewards they would get for that delegation.
+
+With delayed claiming, however, a user can delegate for `X` and then transition to delayed claiming. At that point, the
+output only needs to contain the minimum storage deposit. The remaining funds can be put in a new Delegation Output to
+delegate for `X+1`, which can repeat this procedure. In this manner, one can delegate for one epoch at a time and never
+lose out on any rewards. The following figure exemplifies this procedure.
+
+![Example of delayed claiming](./assets/delayed-claiming.png)
+
+Delayed Claiming also allows for a high degree of liquidity while delegating. Even without delayed claiming, this
+delegation mechanism implements _liquid delegation_ as Delegation Outputs are never locked and can be accessed anytime.
+However, one might lose out on rewards. Delayed Claiming fixes this: If one delegated for the current epoch but needs to
+access the funds immediately, one can transition to delayed claiming and access all the funds (minus the small storage
+deposit), and still claim rewards later.
+
+Additionally, Delayed Claiming enables Layer 2 Smart Contract Chains to hold their funds in Delegation Outputs and
+delegate the tokens of their users for them, while they can use those wrapped tokens on Layer 2. Since an Account Output
+belonging to an SC chain is transitioned very frequently, without Delayed Claiming, they would never hold the Delegation
+Output long enough for it to be able to claim rewards. With Delayed Claiming SC chains can implement this kind of
+delegation.
+
+#### Start and End Epoch
+
+This figure showcases how epochs are set when creating and transitioning Delegation Outputs. Note that the length of
+epochs in slots is not accurately depicted here. What matters for epoch setting is 1) what the current epoch is and 2)
+whether the creation or transition happens before or after the registration slot for the following epoch.
+
+![How epochs are set when creating and transitioning Delegation Outputs](./assets/delegation-epochs.png)
+
+- Delegation Output X is created before the end of the Registration Slot. Therefore its `Start Epoch` is set to `21`, as
+ that is the earliest epoch for which it could receive rewards. However, it is also transitioned before the end of the
+ slot, so its `End Epoch` is set to `20`, as that is the last epoch for which it could receive rewards. However, the
+ condition for claiming rewards is not satisfied for any epoch index. There will be no epoch index `A` that satisfies
+ `A >= 21 && A <= 20`. This Delegation Output will consequently not be able to claim any rewards at all, as it was
+ never included in any pool stake calculation.
+- Delegation Output Y is created before the end of the Registration Slot. Therefore its `Start Epoch` is set to `21`, as
+ that is the earliest epoch for which it could receive rewards. It is transitioned after the end of the Registration
+ Slot, so it was included in the pool stake calculation. Therefore the last epoch for which it could get rewards is
+ `21`, which is the value of `End Epoch`. In sum, the delegation output will therefore be able to claim rewards for
+ epoch `21` only.
+- Delegation Output Z is analogous to X, only shifted by one epoch. It is created after the Registration Slot of Epoch
+ 21 but before the Registration Slot of Epoch 22. Therefore its `Start Epoch` is set to `22`, as that is the earliest
+ epoch for which it could receive rewards. It is however transitioned before the Registration Slot of Epoch 22, so it
+ will not be included in the pool stake calculation for said epoch. Its `End Epoch` is thus set to `21`, as that may be
+ the last epoch for which it could get rewards. Similar to Output X, the delegation output will not be able to claim
+ any rewards as it was never included in any pool stake calculation and no epoch index `A` satisfies
+ `A >= 22 && A <= 21`.
+
+These examples show that transitioning a Delegation Output without crossing a Registration Slot boundary does not yield
+any rewards. At least one such boundary must be crossed for any rewards to be claimable.
+
+### Time Boundaries
+
+When designing transaction validation rules, a choice must be made between choosing to bound the past or the future,
+that is, whether to prevent faking the past or faking the future. To maximize rewards, users are incentivized to make
+the range of epochs for which they can claim rewards as large as possible. Thus, there's an incentive to set
+`Start Epoch` as early or low as possible and `End Epoch` as high or late as possible. To prevent malicious behavior,
+like setting `Start Epoch` to the current epoch when the block itself, that contained the transaction in which the
+delegation started, was issued past the registration slot of the next epoch, the boundaries must be set appropriately.
+Thus, `Start Epoch` must be set to or compared against the past-bounded slot index, which prevents faking the past. A
+past-bounded slot index is always at least equal to the slot to which the block belongs, based on its `Issuing Time`,
+since the oldest, valid commitment that can be picked is `Max Committable Age` slots old. Analogously, `End Epoch` must
+be set to or compared against the future-bounded slot index, which prevents faking the future. A future-bounded slot
+index is always at most equal to the slot to which the block belongs, based on its `Issuing Time`, since the newest,
+valid commitment that can be picked is `Min Committable Age` slots old.
+
+# Test Vectors
+
+The protocol parameters used in the following test vectors are the same as in
+[TIP-49 (Protocol Parameters Hash)](../TIP-0049/tip-0049.md#protocol-parameters-hash).
+
+## Storage Score
+
+The following test vector shows the calculation of the storage score according to [TIP-47](../TIP-0047/tip-0047.md).
+
+Delegation Output (json-encoded):
+
+```json
+{
+ "type": 5,
+ "amount": "200000000",
+ "delegatedAmount": "500000000",
+ "delegationId": "0x08b987baffaacb9da156734275ee01a42a35fe06653823be654821a7ddf92380",
+ "validatorAddress": {
+ "type": 8,
+ "accountId": "0x17432c5a7a672503480241125e3952414a7a320441080c624c264b004e09614a"
+ },
+ "startEpoch": 30,
+ "endEpoch": 50,
+ "unlockConditions": [
+ {
+ "type": 0,
+ "address": {
+ "type": 0,
+ "pubKeyHash": "0xed1484f4d1f7d8c037087fed661dd92faccae1eed3c01182d6fdd6828cea144a"
+ }
+ }
+ ]
+}
+```
+
+Delegation Output (hex-encoded binary serialization):
+
+```
+0x0500c2eb0b000000000065cd1d0000000008b987baffaacb9da156734275ee01a42a35fe06653823be654821a7ddf923800817432c5a7a672503480241125e3952414a7a320441080c624c264b004e09614a1e00000032000000010000ed1484f4d1f7d8c037087fed661dd92faccae1eed3c01182d6fdd6828cea144a
+```
+
+Delegation Output Storage Score: `313`.
+
+# Copyright
+
+Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).