Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion frame/balances/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ mod tests_local;
#[cfg(test)]
mod tests_reentrancy;
pub mod weights;
pub mod migration;

pub use self::imbalances::{NegativeImbalance, PositiveImbalance};
use codec::{Codec, Decode, Encode, MaxEncodedLen};
Expand Down Expand Up @@ -497,6 +498,12 @@ pub mod pallet {
#[pallet::whitelist_storage]
pub type TotalIssuance<T: Config<I>, I: 'static = ()> = StorageValue<_, T::Balance, ValueQuery>;

/// The total units of outstanding deactivated balance in the system.
#[pallet::storage]
#[pallet::getter(fn inactive_issuance)]
#[pallet::whitelist_storage]
pub type InactiveIssuance<T: Config<I>, I: 'static = ()> = StorageValue<_, T::Balance, ValueQuery>;

/// The Balances pallet example of storing the balance of an account.
///
/// # Example
Expand Down Expand Up @@ -1067,6 +1074,9 @@ impl<T: Config<I>, I: 'static> fungible::Inspect<T::AccountId> for Pallet<T, I>
fn total_issuance() -> Self::Balance {
TotalIssuance::<T, I>::get()
}
fn active_issuance() -> Self::Balance {
TotalIssuance::<T, I>::get().saturating_sub(InactiveIssuance::<T, I>::get())
}
fn minimum_balance() -> Self::Balance {
T::ExistentialDeposit::get()
}
Expand Down Expand Up @@ -1145,6 +1155,14 @@ impl<T: Config<I>, I: 'static> fungible::Transfer<T::AccountId> for Pallet<T, I>
let er = if keep_alive { KeepAlive } else { AllowDeath };
<Self as Currency<T::AccountId>>::transfer(source, dest, amount, er).map(|_| amount)
}

fn deactivate(amount: Self::Balance) {
InactiveIssuance::<T, I>::mutate(|b| b.saturating_accrue(amount));
}

fn reactivate(amount: Self::Balance) {
InactiveIssuance::<T, I>::mutate(|b| b.saturating_reduce(amount));
}
}

impl<T: Config<I>, I: 'static> fungible::Unbalanced<T::AccountId> for Pallet<T, I> {
Expand Down Expand Up @@ -1418,7 +1436,19 @@ where
}

fn total_issuance() -> Self::Balance {
<TotalIssuance<T, I>>::get()
TotalIssuance::<T, I>::get()
}

fn active_issuance() -> Self::Balance {
<Self as fungibles::Inspect>::active_issuance()
}

fn deactivate(amount: Self::Balance) {
<Self as fungibles::Transfer>::deactivate(amount);
}

fn reactivate(amount: Self::Balance) {
<Self as fungibles::Transfer>::reactivate(amount);
}

fn minimum_balance() -> Self::Balance {
Expand Down
19 changes: 19 additions & 0 deletions frame/support/src/traits/tokens/currency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ pub trait Currency<AccountId> {
/// The total amount of issuance in the system.
fn total_issuance() -> Self::Balance;

/// The total amount of issuance in the system excluding those which are controlled by the
/// system.
fn active_issuance() -> Self::Balance { Self::total_issuance() }

/// Reduce the active issuance by some amount.
fn deactivate(_: Self::Balance) {}

/// Increase the active issuance by some amount, up to the outstanding amount reduced.
fn reactivate(_: Self::Balance) {}

/// The minimum balance any single account may have. This is equivalent to the `Balances`
/// module's `ExistentialDeposit`.
fn minimum_balance() -> Self::Balance;
Expand Down Expand Up @@ -212,6 +222,15 @@ impl<C: Currency<A>, A> Get<C::Balance> for TotalIssuanceOf<C, A> {
}
}

/// A non-const `Get` implementation parameterised by a `Currency` impl which provides the result
/// of `active_issuance`.
pub struct ActiveIssuanceOf<C: Currency<A>, A>(sp_std::marker::PhantomData<(C, A)>);
impl<C: Currency<A>, A> Get<C::Balance> for ActiveIssuanceOf<C, A> {
fn get() -> C::Balance {
C::active_issuance()
}
}

#[cfg(feature = "std")]
impl<AccountId> Currency<AccountId> for () {
type Balance = u32;
Expand Down
19 changes: 19 additions & 0 deletions frame/support/src/traits/tokens/fungible.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ pub trait Inspect<AccountId> {
/// The total amount of issuance in the system.
fn total_issuance() -> Self::Balance;

/// The total amount of issuance in the system excluding those which are controlled by the
/// system.
fn active_issuance() -> Self::Balance { Self::total_issuance() }

/// The minimum balance any single account may have.
fn minimum_balance() -> Self::Balance;

Expand Down Expand Up @@ -120,6 +124,12 @@ pub trait Transfer<AccountId>: Inspect<AccountId> {
amount: Self::Balance,
keep_alive: bool,
) -> Result<Self::Balance, DispatchError>;

/// Reduce the active issuance by some amount.
fn deactivate(_: Self::Balance) {}

/// Increase the active issuance by some amount, up to the outstanding amount reduced.
fn reactivate(_: Self::Balance) {}
}

/// Trait for inspecting a fungible asset which can be reserved.
Expand Down Expand Up @@ -213,6 +223,9 @@ impl<
fn total_issuance() -> Self::Balance {
<F as fungibles::Inspect<AccountId>>::total_issuance(A::get())
}
fn active_issuance() -> Self::Balance {
<F as fungibles::Inspect<AccountId>>::active_issuance(A::get())
}
fn minimum_balance() -> Self::Balance {
<F as fungibles::Inspect<AccountId>>::minimum_balance(A::get())
}
Expand Down Expand Up @@ -258,6 +271,12 @@ impl<
) -> Result<Self::Balance, DispatchError> {
<F as fungibles::Transfer<AccountId>>::transfer(A::get(), source, dest, amount, keep_alive)
}
fn deactivate(amount: Self::Balance) {
<F as fungibles::Transfer<AccountId>>::deactivate(A::get(), amount)
}
fn reactivate(amount: Self::Balance) {
<F as fungibles::Transfer<AccountId>>::reactivate(A::get(), amount)
}
}

impl<
Expand Down
10 changes: 10 additions & 0 deletions frame/support/src/traits/tokens/fungibles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ pub trait Inspect<AccountId> {
/// The total amount of issuance in the system.
fn total_issuance(asset: Self::AssetId) -> Self::Balance;

/// The total amount of issuance in the system excluding those which are controlled by the
/// system.
fn active_issuance(asset: Self::AssetId) -> Self::Balance { Self::total_issuance(asset) }

/// The minimum balance any single account may have.
fn minimum_balance(asset: Self::AssetId) -> Self::Balance;

Expand Down Expand Up @@ -177,6 +181,12 @@ pub trait Transfer<AccountId>: Inspect<AccountId> {
amount: Self::Balance,
keep_alive: bool,
) -> Result<Self::Balance, DispatchError>;

/// Reduce the active issuance by some amount.
fn deactivate(_: Self::AssetId, _: Self::Balance) {}

/// Increase the active issuance by some amount, up to the outstanding amount reduced.
fn reactivate(_: Self::AssetId, _: Self::Balance) {}
}

/// Trait for inspecting a set of named fungible assets which can be placed on hold.
Expand Down
15 changes: 15 additions & 0 deletions frame/treasury/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ mod benchmarking;
#[cfg(test)]
mod tests;
pub mod weights;
pub mod migration;

use codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
Expand Down Expand Up @@ -138,6 +139,7 @@ pub mod pallet {
use super::*;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
use sp_runtime::traits::CheckedSub;

#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
Expand Down Expand Up @@ -229,6 +231,11 @@ pub mod pallet {
pub type Approvals<T: Config<I>, I: 'static = ()> =
StorageValue<_, BoundedVec<ProposalIndex, T::MaxApprovals>, ValueQuery>;

/// The amount which has been reported as inactive to Currency.
#[pallet::storage]
pub type Deactivated<T: Config<I>, I: 'static = ()> =
StorageValue<_, BalanceOf<T>, ValueQuery>;

#[pallet::genesis_config]
pub struct GenesisConfig;

Expand Down Expand Up @@ -322,6 +329,14 @@ pub mod pallet {
} else {
Weight::zero()
}
let pot = Self::pot();
let deactivated = Deactivated::<T>::get();
if let Some(v) = pot.checked_sub(&deactivated) {
T::Currency::deactivate(v)
}
else if let Some(v) = deactivated.checked_sub(&pot) {
T::Currency::reactivate(v)
}
}
}

Expand Down