Implements a % cap on staking rewards from era inflation (#1660)

This PR implements an (optional) cap of the era inflation that is
allocated to staking rewards. The remaining is minted directly into the
[`RewardRemainder`](https://github.com/paritytech/polkadot-sdk/blob/fb0fd3e62445eb2dee2b2456a0c8574d1ecdcc73/substrate/frame/staking/src/pallet/mod.rs#L160)
account, which is the treasury pot account in Polkadot and Kusama.

The staking pallet now has a percent storage item, `MaxStakersRewards`,
which defines the max percentage of the era inflation that should be
allocated to staking rewards. The remaining era inflation (i.e.
`remaining = max_era_payout - staking_payout.min(staking_payout *
MaxStakersRewards))` is minted directly into the treasury.

The `MaxStakersRewards` can be set by a privileged origin through the
`set_staking_configs` extrinsic.

**To finish**
- [x] run benchmarks for westend-runtime

Replaces https://github.com/paritytech/polkadot-sdk/pull/1483
Closes https://github.com/paritytech/polkadot-sdk/issues/403

---------

Co-authored-by: command-bot <>
This commit is contained in:
Gonçalo Pestana
2024-02-15 20:13:35 +01:00
committed by GitHub
parent 5fc7622cb3
commit fde44474e4
9 changed files with 427 additions and 300 deletions
+10 -1
View File
@@ -36,7 +36,7 @@ use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin};
use pallet_session::historical;
use sp_runtime::{
traits::{Bounded, Convert, One, SaturatedConversion, Saturating, StaticLookup, Zero},
Perbill,
Perbill, Percent,
};
use sp_staking::{
currency_to_vote::CurrencyToVote,
@@ -507,9 +507,18 @@ impl<T: Config> Pallet<T> {
.saturated_into::<u64>();
let staked = Self::eras_total_stake(&active_era.index);
let issuance = T::Currency::total_issuance();
let (validator_payout, remainder) =
T::EraPayout::era_payout(staked, issuance, era_duration);
let total_payout = validator_payout.saturating_add(remainder);
let max_staked_rewards =
MaxStakedRewards::<T>::get().unwrap_or(Percent::from_percent(100));
// apply cap to validators payout and add difference to remainder.
let validator_payout = validator_payout.min(max_staked_rewards * total_payout);
let remainder = total_payout.saturating_sub(validator_payout);
Self::deposit_event(Event::<T>::EraPaid {
era_index: active_era.index,
validator_payout,