diff --git a/HIP/hip-406.md b/HIP/hip-406.md index 8aeb8a5ce..7c049c04a 100644 --- a/HIP/hip-406.md +++ b/HIP/hip-406.md @@ -11,7 +11,7 @@ release: v0.27.0 created: 2022-03-27 discussions-to: https://github.com/hashgraph/hedera-improvement-proposal/discussions/408 superseded-by: 782 -updated: 2023-08-09 +updated: 2023-08-10 --- ## Abstract @@ -257,11 +257,13 @@ If rewards are activated (because `0.0.800` reached the threshold at some time i At the end of each staking period, the nodes will be updated. If the staking period is a day, lasting from one midnight UTC to the next, then this update is calculated immediately before handling the first transaction each day whose consensus timestep is after midnight. The calculation is described by the following pseudocode: ``` - // total tinybars of reward earned by all stakers for the staking period now ending - long rate = max(0, min(accountBalance(0.0.800) - pendingRewards, stakingRewardRate)); + // an initial estimate of the total tinybars of reward earned by all stakers for the staking period now ending + long initialTotalReward = stakingRewardRate * totalStakedRewardStart; + // a revised estimate of that reward, given that it can't exceed the unreserved amount in account 0.0.800 + long revisedTotalReward = max(0, min(accountBalance(0.0.800) - pendingRewards, initialTotalReward)); // The tinybars earned per hbar for stakers who are staked to a node whose total // stakedRewarded is in the range [minStake, maxStake] - long perHbarRate = rate / (totalStakedRewardStart / 100_000_000); + long perHbarRate = revisedTotalReward / (totalStakedRewardStart / 100_000_000); for each node { for (i=365; i>0; i--) //push a day onto the history (latest reward is zero, but updated below) @@ -291,20 +293,20 @@ At the end of each staking period, the nodes will be updated. If the staking per //stakedRewardedUsed is the portion of node.stakeRewarded that affects consensus long stakedRewardedUsed = min(node.stakedRewarded, node.stake); node.stakedRewardStart = stakedRewardUsed; - totalStakedRewardedStart += stakedRewardedUsed; + totalStakedRewardStart += stakedRewardedUsed; totalStakedStart += node.stake; } ``` This rewards only active nodes, where "active" is shown as being active for a certain fraction of rounds, though that calculation may be tweaked slightly. -This divides the daily reward equally among all tinybars that were staked and didn't decline the reward. Except there is no reward for staking to a node that is under the minimum stake allowed, and it does not reward the portion of the stake to a node that was over its max limit. The daily reward is `stakingRewardRate`, unless account `0.0.800` has insufficient balance to give the full reward, in which case it simply distributes everything in `0.0.800`. +This divides the daily reward equally among all tinybars that were staked and didn't decline the reward. Except there is no reward for staking to a node that is under the minimum stake allowed, and it does not reward the portion of the stake to a node that was over its max limit. The daily reward is `initialTotalReward`, unless account `0.0.800` has insufficient balance to give the full reward, in which case it simply distributes everything in `0.0.800`. Note that all of the above is done during the time that a single transaction is handled. But it will be very fast, because it is only updating information for each node. It does not actually transfer any rewards. The accounts that stake are rewarded only when they are used, as described above. During transaction handling, fees are computed and divided among the Treasury account (`0.0.98`), staking reward account (`0.0.800`), and node reward account (`0.0.801`). The fraction to each is determined by thge Council. After this feature is first implemented, the balance of `0.0.800` will continue to accumulate until some threshold defined by the council, at which point staked accounts will begin to earn rewards, and the threshold will never again have an effect. -For example, suppose the council set the reward emission rate to (1 billion / 365) hbars per day, and set the threshold to start at one billion hbars. Once account `0.0.800` reaches one billion hbars, reward distributions will begin. All previous staking periods will have 0 rewards, but all subsequent staking periods will have (1 billion / 365) hbars per staking period, until the balance balls below that daily rate. If transfers to the `0.0.800` from both transaction fees and from outside accounts are sufficient, then the rewards can continue at that rate forever. If the transfers to `0.0.800` are insufficient, then eventually the balance will fall below that amount. After that, the rewards will be only the amount obtained from transaction fees each day, until either another transfer from an external account is received, or until the daily transaction fees grow to be able to fund the entire amount each day. +For example, suppose the council set the reward emission rate to (1 billion / 365) hbars per day, and set the threshold to start at one billion hbars. Once account `0.0.800` reaches one billion hbars, reward distributions will begin. All previous staking periods will have 0 rewards, but all subsequent staking periods will have (1 billion / 365) hbars per staking period, until the balance balls below that daily total reward. If transfers to the `0.0.800` from both transaction fees and from outside accounts are sufficient, then the rewards can continue at that rate forever. If the transfers to `0.0.800` are insufficient, then eventually the balance will fall below that amount. After that, the rewards will be only the amount obtained from transaction fees each day, until either another transfer from an external account is received, or until the daily transaction fees grow to be able to fund the entire amount each day. If all nodes are active in a given day, and all have ≥ `minStake` and ≤ `maxStake`, then each `hbar` staked will earn the same amount of reward, regardless of which node it is staked to. If a node has < `minStake`, then no `hbar` staked to that node will earn rewards. If a node has > `maxStake`, then the reward will be as if only `maxStake` had been staked, and is then distributed pro-rata to those accounts staked to that node. For example, if `maxStake` were 1 billion hbars for a given node, but that node actually had 3 billion hbars staked to it, and if Alice's account is staked to that node, then Alice will earn a third of the reward that she would have earned had this node not been staked beyond `maxStake`. @@ -342,7 +344,7 @@ The record immediately after it will be the record for the first transaction in The following new settings will be added to the system, and set by transactions signed by a majority of the Council. - `StakingPeriod` - staking rewards are earned on hbars staked for at least this long (given in minutes, initially defined to be `24 * 60` which is one day) -- `StakingRewardRate` - the total tinybars earned as staking reward during each staking period (example: 100\_000\_000L * 1\_000\_000\_000 / 365 to emit rewards at a total rate of one billion hbars per year) +- `StakingRewardRate` - the staking reward rate to use if it isn't reduced by any other factors (such as 0.0.800 being depleted). In units of tinybars earned per day per hbar staked for reward - `StakingStartThreshold` - Staking rewards are earned starting when `0.0.800` reaches this balance (example: 1 billion) - `MinStake` (per node) - the minimum amount that must be staked to that node, in order for the node to participate in consensus - `MaxStake` (per node) - the maximum amount of the stake to that node that will count (the excess coins are not rewarded and do not affect consensus weight) diff --git a/HIP/hip-782.md b/HIP/hip-782.md index 0509bcfce..051025e35 100644 --- a/HIP/hip-782.md +++ b/HIP/hip-782.md @@ -11,7 +11,7 @@ release: v0.40.0 created: 2023-08-01 discussions-to: https://github.com/hashgraph/hedera-improvement-proposal/pull/782 replaces: 406 -updated: 2023-08-09 +updated: 2023-08-10 --- Note: This hip does not replace all of hip-406 Staking. It replaces only replaces a small part. Otherwise, hip-406 still stands. @@ -38,7 +38,7 @@ Let `unreservedBalance` (in tinybars) be the balance of account `0.0.800` minus //A real number proportional to the unreserved balance, from 0 for empty, up to 1 at the threshold. balanceRatio = min(unreservedBalance, rewardBalanceThreshold) / rewardBalanceThreshold; -stakingRewardRate = maxRewardRate * stakedForReward +stakingRewardRate = maxRewardRate * balanceRatio * (2 – balanceRatio) * min(1, maxStakeRewarded / stakedForReward)