Skip to content

Commit

Permalink
feat!(runtime): Add ability to align total supply (#3418)
Browse files Browse the repository at this point in the history
  • Loading branch information
breathx authored Oct 19, 2023
1 parent ff7f6d4 commit 928e7ec
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 3 deletions.
7 changes: 7 additions & 0 deletions gsdk/src/metadata/generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3250,6 +3250,8 @@ pub mod runtime_types {
to: ::subxt::utils::MultiAddress<::subxt::utils::AccountId32, ()>,
value: ::core::primitive::u128,
},
#[codec(index = 3)]
align_supply { target: ::core::primitive::u128 },
}
#[derive(Debug, crate::gp::Decode, crate::gp::DecodeAsType, crate::gp::Encode)]
#[doc = "Error for the staking rewards pallet."]
Expand All @@ -3273,6 +3275,9 @@ pub mod runtime_types {
#[codec(index = 2)]
#[doc = "Burned from the pool."]
Burned { amount: ::core::primitive::u128 },
#[codec(index = 3)]
#[doc = "Minted to the pool."]
Minted { amount: ::core::primitive::u128 },
}
}
}
Expand Down Expand Up @@ -9792,6 +9797,7 @@ pub mod calls {
Refill,
ForceRefill,
Withdraw,
AlignSupply,
}
impl CallInfo for StakingRewardsCall {
const PALLET: &'static str = "StakingRewards";
Expand All @@ -9800,6 +9806,7 @@ pub mod calls {
Self::Refill => "refill",
Self::ForceRefill => "force_refill",
Self::Withdraw => "withdraw",
Self::AlignSupply => "align_supply",
}
}
}
Expand Down
25 changes: 24 additions & 1 deletion pallets/staking-rewards/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ pub struct InflationInfo {
#[frame_support::pallet]
pub mod pallet {
use super::*;
use core::cmp::Ordering;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;

Expand Down Expand Up @@ -237,6 +238,8 @@ pub mod pallet {
Withdrawn { amount: BalanceOf<T> },
/// Burned from the pool.
Burned { amount: BalanceOf<T> },
/// Minted to the pool.
Minted { amount: BalanceOf<T> },
}

/// Error for the staking rewards pallet.
Expand Down Expand Up @@ -326,6 +329,26 @@ pub mod pallet {

Ok(())
}

#[pallet::call_index(3)]
#[pallet::weight(<T as Config>::WeightInfo::align_supply())]
pub fn align_supply(origin: OriginFor<T>, target: BalanceOf<T>) -> DispatchResult {
ensure_root(origin)?;

let issuance = T::Currency::total_issuance();

match target.cmp(&issuance) {
Ordering::Greater => {
OffsetPool::<T>::on_nonzero_unbalanced(T::Currency::issue(target - issuance));
}
Ordering::Less => {
Self::on_nonzero_unbalanced(T::Currency::burn(issuance - target));
}
_ => {}
};

Ok(())
}
}

impl<T: Config> Pallet<T> {
Expand Down Expand Up @@ -438,7 +461,7 @@ impl<T: Config> OnUnbalanced<NegativeImbalanceOf<T>> for OffsetPool<T> {
// Should resolve into existing but resolving with creation is a safer bet anyway
T::Currency::resolve_creating(&Pallet::<T>::account_id(), amount);

Pallet::deposit_event(Event::<T>::Deposited {
Pallet::deposit_event(Event::<T>::Minted {
amount: numeric_amount,
});
}
Expand Down
103 changes: 101 additions & 2 deletions pallets/staking-rewards/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
#![cfg(test)]

use crate::{mock::*, *};
use frame_support::{assert_noop, assert_ok};
use sp_runtime::{PerThing, Perbill};
use frame_support::{assert_noop, assert_ok, assert_storage_noop};
use sp_runtime::{DispatchError, PerThing, Perbill};

macro_rules! assert_approx_eq {
($left:expr, $right:expr, $tol:expr) => {{
Expand All @@ -43,6 +43,105 @@ pub(crate) fn init_logger() {
.try_init();
}

#[test]
fn supply_alignment_works() {
init_logger();

ExtBuilder::default()
.initial_authorities(vec![
(VAL_1_STASH, VAL_1_CONTROLLER, VAL_1_AUTH_ID),
(VAL_2_STASH, VAL_2_CONTROLLER, VAL_2_AUTH_ID),
(VAL_3_STASH, VAL_3_CONTROLLER, VAL_3_AUTH_ID),
])
.stash(VALIDATOR_STAKE)
.endowment(ENDOWMENT)
.endowed_accounts(vec![SIGNER])
.total_supply(INITIAL_TOTAL_TOKEN_SUPPLY)
.non_stakeable(Perquintill::from_rational(4108_u64, 10_000_u64))
.pool_balance(Perquintill::from_percent(11) * INITIAL_TOTAL_TOKEN_SUPPLY)
.ideal_stake(Perquintill::from_percent(85))
.target_inflation(Perquintill::from_rational(578_u64, 10_000_u64))
.build()
.execute_with(|| {
let assert_issuance =
|balance: BalanceOf<Test>| assert_eq!(Balances::total_issuance(), balance);

let assert_pool = |balance: BalanceOf<Test>| {
assert_eq!(
Balances::total_balance(&StakingRewards::account_id()),
balance + Balances::minimum_balance()
)
};

// Asserting initial parameters.
assert_issuance(INITIAL_TOTAL_TOKEN_SUPPLY);

let initial_pool_balance = Perquintill::from_percent(11) * INITIAL_TOTAL_TOKEN_SUPPLY;
assert_pool(initial_pool_balance);

// Asserting bad origin.
assert_noop!(
StakingRewards::align_supply(
RuntimeOrigin::signed(SIGNER),
INITIAL_TOTAL_TOKEN_SUPPLY
),
DispatchError::BadOrigin
);

// Asserting no-op in case of equity.
assert_storage_noop!(assert_ok!(StakingRewards::align_supply(
RuntimeOrigin::root(),
INITIAL_TOTAL_TOKEN_SUPPLY
)));

// Burning N tokens.
let n = Balances::minimum_balance() * 5;

assert_ok!(Balances::set_balance(
RuntimeOrigin::root(),
SIGNER,
Balances::free_balance(SIGNER) - n,
Balances::reserved_balance(SIGNER),
));

assert_issuance(INITIAL_TOTAL_TOKEN_SUPPLY - n);
assert_pool(initial_pool_balance);

// Aligning supply.
assert_ok!(StakingRewards::align_supply(
RuntimeOrigin::root(),
INITIAL_TOTAL_TOKEN_SUPPLY
));

System::assert_has_event(Event::Minted { amount: n }.into());
assert_issuance(INITIAL_TOTAL_TOKEN_SUPPLY);
assert_pool(initial_pool_balance + n);

// Minting M tokens.
let m = Balances::minimum_balance() * 12;

assert_ok!(Balances::set_balance(
RuntimeOrigin::root(),
SIGNER,
Balances::free_balance(SIGNER) + m,
Balances::reserved_balance(SIGNER),
));

assert_issuance(INITIAL_TOTAL_TOKEN_SUPPLY + m);
assert_pool(initial_pool_balance + n);

// Aligning supply.
assert_ok!(StakingRewards::align_supply(
RuntimeOrigin::root(),
INITIAL_TOTAL_TOKEN_SUPPLY
));

System::assert_has_event(Event::Burned { amount: m }.into());
assert_issuance(INITIAL_TOTAL_TOKEN_SUPPLY);
assert_pool(initial_pool_balance + n - m);
});
}

#[test]
fn genesis_config_works() {
init_logger();
Expand Down
13 changes: 13 additions & 0 deletions pallets/staking-rewards/src/weights.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 928e7ec

Please sign in to comment.