diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index a0b966c63c33b..2727be5c54079 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1046,6 +1046,7 @@ impl pallet_assets::Config for Runtime { } parameter_types! { + pub IgnoredIssuance: Balance = Treasury::pot(); pub const QueueCount: u32 = 300; pub const MaxQueueLen: u32 = 1000; pub const FifoQueueLen: u32 = 500; @@ -1061,6 +1062,7 @@ impl pallet_gilt::Config for Runtime { type AdminOrigin = frame_system::EnsureRoot; type Deficit = (); type Surplus = (); + type IgnoredIssuance = IgnoredIssuance; type QueueCount = QueueCount; type MaxQueueLen = MaxQueueLen; type FifoQueueLen = FifoQueueLen; diff --git a/frame/gilt/src/lib.rs b/frame/gilt/src/lib.rs index 94d341f47f44e..ab35ce76742bc 100644 --- a/frame/gilt/src/lib.rs +++ b/frame/gilt/src/lib.rs @@ -109,6 +109,10 @@ pub mod pallet { /// over freezing period). type Surplus: OnUnbalanced>; + /// The issuance to ignore. This is subtracted from the `Currency`'s `total_issuance` to get + /// the issuance by which we inflate or deflate the gilt. + type IgnoredIssuance: Get>; + /// Number of duration queues in total. This sets the maximum duration supported, which is /// this value multiplied by `Period`. #[pallet::constant] @@ -191,7 +195,9 @@ pub mod pallet { /// The way of determining the net issuance (i.e. after factoring in all maturing frozen funds) /// is: /// - /// `total_issuance - frozen + proportion * total_issuance` + /// `issuance - frozen + proportion * issuance` + /// + /// where `issuance = total_issuance - IgnoredIssuance` #[derive(Clone, Eq, PartialEq, Default, Encode, Decode, RuntimeDebug)] pub struct ActiveGiltsTotal { /// The total amount of funds held in reserve for all active gilts. @@ -440,7 +446,7 @@ pub mod pallet { Active::::remove(index); // Multiply the proportion it is by the total issued. - let total_issuance = T::Currency::total_issuance(); + let total_issuance = T::Currency::total_issuance().saturating_sub(T::IgnoredIssuance::get()); ActiveTotal::::mutate(|totals| { let nongilt_issuance: u128 = total_issuance.saturating_sub(totals.frozen) .saturated_into(); @@ -490,7 +496,7 @@ pub mod pallet { if totals.proportion < totals.target { let missing = totals.target.saturating_sub(totals.proportion); - let total_issuance = T::Currency::total_issuance(); + let total_issuance = T::Currency::total_issuance().saturating_sub(T::IgnoredIssuance::get()); let nongilt_issuance: u128 = total_issuance.saturating_sub(totals.frozen) .saturated_into(); let effective_issuance = totals.proportion.left_from_one() @@ -515,7 +521,7 @@ pub mod pallet { amount: BalanceOf, max_bids: u32, ) -> (u32, u32) { - let total_issuance = T::Currency::total_issuance(); + let total_issuance = T::Currency::total_issuance().saturating_sub(T::IgnoredIssuance::get()); let mut remaining = amount; let mut bids_taken = 0; let mut queues_hit = 0; diff --git a/frame/gilt/src/mock.rs b/frame/gilt/src/mock.rs index 701c5c2f6d73b..7c6c547e65cc2 100644 --- a/frame/gilt/src/mock.rs +++ b/frame/gilt/src/mock.rs @@ -20,7 +20,8 @@ use crate as pallet_gilt; use frame_support::{ - parameter_types, ord_parameter_types, traits::{OnInitialize, OnFinalize, GenesisBuild}, + parameter_types, ord_parameter_types, + traits::{OnInitialize, OnFinalize, GenesisBuild, Currency}, }; use sp_core::H256; use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; @@ -86,6 +87,7 @@ impl pallet_balances::Config for Test { } parameter_types! { + pub IgnoredIssuance: u64 = Balances::total_balance(&0); // Account zero is ignored. pub const QueueCount: u32 = 3; pub const MaxQueueLen: u32 = 3; pub const FifoQueueLen: u32 = 1; @@ -104,6 +106,7 @@ impl pallet_gilt::Config for Test { type AdminOrigin = frame_system::EnsureSignedBy; type Deficit = (); type Surplus = (); + type IgnoredIssuance = IgnoredIssuance; type QueueCount = QueueCount; type MaxQueueLen = MaxQueueLen; type FifoQueueLen = FifoQueueLen; diff --git a/frame/gilt/src/tests.rs b/frame/gilt/src/tests.rs index 637a6a8705979..2f328ba904bbe 100644 --- a/frame/gilt/src/tests.rs +++ b/frame/gilt/src/tests.rs @@ -322,6 +322,30 @@ fn thaw_when_issuance_higher_works() { }); } +#[test] +fn thaw_with_ignored_issuance_works() { + new_test_ext().execute_with(|| { + run_to_block(1); + // Give account zero some balance. + Balances::make_free_balance_be(&0, 200); + + assert_ok!(Gilt::place_bid(Origin::signed(1), 100, 1)); + Gilt::enlarge(100, 1); + + // Account zero transfers 50 into everyone else's accounts. + assert_ok!(Balances::transfer(Origin::signed(0), 2, 50)); + assert_ok!(Balances::transfer(Origin::signed(0), 3, 50)); + assert_ok!(Balances::transfer(Origin::signed(0), 4, 50)); + + run_to_block(4); + assert_ok!(Gilt::thaw(Origin::signed(1), 0)); + + // Account zero changes have been ignored. + assert_eq!(Balances::free_balance(1), 150); + assert_eq!(Balances::reserved_balance(1), 0); + }); +} + #[test] fn thaw_when_issuance_lower_works() { new_test_ext().execute_with(|| {