From 8ab70244ae32292eafbce5c1e444d27cc173ee3d Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 27 Jun 2024 16:50:34 +0330 Subject: [PATCH] Blueprint of how to fix inflation --- Cargo.lock | 14 +------- relay/kusama/Cargo.toml | 2 ++ relay/kusama/src/lib.rs | 72 +++++++++++++++++++++++++++++++++++---- relay/polkadot/Cargo.toml | 1 - 4 files changed, 69 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5ae9b093f0..037b458915 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9120,18 +9120,6 @@ dependencies = [ "sp-std", ] -[[package]] -name = "pallet-staking-reward-curve" -version = "11.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efca5a4a423427d2c83af5fe07ab648c16b91e3782c3cc23316fe0bd96b4c794" -dependencies = [ - "proc-macro-crate 3.1.0", - "proc-macro2", - "quote", - "syn 2.0.52", -] - [[package]] name = "pallet-staking-reward-fn" version = "20.0.0" @@ -11014,7 +11002,6 @@ dependencies = [ "pallet-session", "pallet-session-benchmarking", "pallet-staking", - "pallet-staking-reward-curve", "pallet-staking-reward-fn", "pallet-staking-runtime-api", "pallet-state-trie-migration", @@ -16106,6 +16093,7 @@ dependencies = [ "pallet-session-benchmarking", "pallet-society", "pallet-staking", + "pallet-staking-reward-fn", "pallet-staking-runtime-api", "pallet-timestamp", "pallet-transaction-payment", diff --git a/relay/kusama/Cargo.toml b/relay/kusama/Cargo.toml index b2df38038f..77f0e46aae 100644 --- a/relay/kusama/Cargo.toml +++ b/relay/kusama/Cargo.toml @@ -72,6 +72,7 @@ pallet-session = { workspace = true } pallet-society = { workspace = true } frame-support = { features = ["tuples-96"], workspace = true } pallet-staking = { workspace = true } +pallet-staking-reward-fn = { workspace = true } pallet-staking-runtime-api = { workspace = true } frame-system = { workspace = true } frame-system-rpc-runtime-api = { workspace = true } @@ -171,6 +172,7 @@ std = [ "pallet-session/std", "pallet-society/std", "pallet-staking-runtime-api/std", + "pallet-staking-reward-fn/std", "pallet-staking/std", "pallet-timestamp/std", "pallet-transaction-payment-rpc-runtime-api/std", diff --git a/relay/kusama/src/lib.rs b/relay/kusama/src/lib.rs index ded3ff7838..033e59c381 100644 --- a/relay/kusama/src/lib.rs +++ b/relay/kusama/src/lib.rs @@ -22,6 +22,7 @@ use codec::{Decode, Encode, MaxEncodedLen}; use pallet_nis::WithMaximumOf; +use pallet_staking_reward_fn::compute_inflation; use polkadot_primitives::{ slashing, vstaging::{ApprovalVotingParams, NodeFeatures}, @@ -43,6 +44,7 @@ use polkadot_runtime_common::{ U256ToBalance, }; use scale_info::TypeInfo; +use sp_runtime::traits::Saturating; use sp_std::{cmp::Ordering, collections::btree_map::BTreeMap, prelude::*}; use runtime_parachains::{ @@ -682,14 +684,72 @@ impl pallet_staking::EraPayout for EraPayout { const MAX_ANNUAL_INFLATION: Perquintill = Perquintill::from_percent(10); const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100; - polkadot_runtime_common::impls::era_payout( + let use_auctioned_slots = todo!("should come from pallet parameters as well"); + let params = EraPayoutParams { total_staked, - Nis::issuance().other, - MAX_ANNUAL_INFLATION, - Perquintill::from_rational(era_duration_millis, MILLISECONDS_PER_YEAR), - auctioned_slots, - ) + total_stakable: Nis::issuance().other, + ideal_stake: todo!("must come from pallet parameters, and default set to 75%"), + max_annual_inflation: todo!("must come from pallet parameters, and default set to 10%"), + min_annual_inflation: todo!( + "must come from pallet parameters, and default set to 2.5%" + ), + falloff: todo!("must come from pallet parameters, and default set to 5%"), + period_fraction: Perquintill::from_rational(era_duration_millis, MILLISECONDS_PER_YEAR), + legacy_auction_proportion: if use_auctioned_slots { + Some(Perquintill::from_rational(auctioned_slots.min(60), 200)) + } else { + None + }, + }; + relay_era_payout(params) + // TODO: remove pub fn era_payout from polkadot-sdk. + } +} + +pub(crate) struct EraPayoutParams { + total_staked: Balance, + total_stakable: Balance, + ideal_stake: Perquintill, + max_annual_inflation: Perquintill, + min_annual_inflation: Perquintill, + falloff: Perquintill, + period_fraction: Perquintill, + legacy_auction_proportion: Option, +} + +// TODO: move this to a shared create between both relays. +pub fn relay_era_payout(params: EraPayoutParams) -> (Balance, Balance) { + let EraPayoutParams { + total_staked, + total_stakable, + ideal_stake, + max_annual_inflation, + min_annual_inflation, + falloff, + period_fraction, + legacy_auction_proportion, + } = params; + + let delta_annual_inflation = max_annual_inflation.saturating_sub(min_annual_inflation); + + let ideal_stake = ideal_stake.saturating_sub(legacy_auction_proportion.unwrap_or_default()); + + let stake = Perquintill::from_rational(total_staked, total_stakable); + let adjustment = compute_inflation(stake, ideal_stake, falloff); + let staking_inflation = + min_annual_inflation.saturating_add(delta_annual_inflation * adjustment); + + let max_payout = period_fraction * max_annual_inflation * total_stakable; + let staking_payout = (period_fraction * staking_inflation) * total_stakable; + let rest = max_payout.saturating_sub(staking_payout); + + let other_issuance = total_stakable.saturating_sub(total_staked); + if total_staked > other_issuance { + let _cap_rest = Perquintill::from_rational(other_issuance, total_staked) * staking_payout; + // We don't do anything with this, but if we wanted to, we could introduce a cap on the + // treasury amount with: `rest = rest.min(cap_rest);` } + (staking_payout, rest) } parameter_types! { diff --git a/relay/polkadot/Cargo.toml b/relay/polkadot/Cargo.toml index c7f8c92b6b..c95f205696 100644 --- a/relay/polkadot/Cargo.toml +++ b/relay/polkadot/Cargo.toml @@ -68,7 +68,6 @@ pallet-session = { workspace = true } frame-support = { workspace = true } pallet-staking = { workspace = true } pallet-staking-reward-fn = { workspace = true } -pallet-staking-reward-curve = { workspace = true } pallet-staking-runtime-api = { workspace = true } pallet-state-trie-migration = { workspace = true } frame-system = { workspace = true }