From 04a43780693e46c9fe1cda95787ea1f719bf80f2 Mon Sep 17 00:00:00 2001 From: Dmitry Lavrenov <lawrenowdima@gmail.com> Date: Fri, 29 Dec 2023 12:56:23 +0300 Subject: [PATCH] Draft addition of fungible related traits for currency type at pallet-pot --- crates/pallet-pot/src/lib.rs | 55 ++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/crates/pallet-pot/src/lib.rs b/crates/pallet-pot/src/lib.rs index a822c1fc1..ac09983ba 100644 --- a/crates/pallet-pot/src/lib.rs +++ b/crates/pallet-pot/src/lib.rs @@ -5,7 +5,10 @@ #![cfg_attr(not(feature = "std"), no_std)] -use frame_support::traits::{Imbalance, OnUnbalanced, StorageVersion}; +use frame_support::traits::{ + fungible::{Balanced, Credit, Inspect, Mutate, Unbalanced}, + Imbalance, OnUnbalanced, StorageVersion, +}; use frame_support::{pallet_prelude::*, traits::Currency, PalletId}; use frame_system::pallet_prelude::*; use sp_runtime::traits::{AccountIdConversion, CheckedSub, MaybeDisplay, Saturating}; @@ -17,11 +20,14 @@ const STORAGE_VERSION: StorageVersion = StorageVersion::new(0); /// The balance of accessor for the currency. pub type BalanceOf<T, I = ()> = - <<T as Config<I>>::Currency as Currency<<T as Config<I>>::AccountId>>::Balance; + <<T as Config<I>>::FungibleAsset as Currency<<T as Config<I>>::AccountId>>::Balance; /// The negative implanace accessor. pub type NegativeImbalanceOf<T, I = ()> = - <<T as Config<I>>::Currency as Currency<<T as Config<I>>::AccountId>>::NegativeImbalance; + <<T as Config<I>>::FungibleAsset as Currency<<T as Config<I>>::AccountId>>::NegativeImbalance; + +/// The credit accessor. +pub type CreditOf<T, I = ()> = Credit<<T as Config<I>>::AccountId, <T as Config<I>>::FungibleAsset>; /// The initial state of the pot, for use in genesis. #[cfg(feature = "std")] @@ -63,8 +69,12 @@ pub mod pallet { + Ord + MaxEncodedLen; - /// The currency to operate with. - type Currency: Currency<<Self as Config<I>>::AccountId>; + /// The fungible asset to operate with. + type FungibleAsset: Currency<<Self as Config<I>>::AccountId> + + Inspect<<Self as Config<I>>::AccountId, Balance = BalanceOf<Self, I>> + + Balanced<<Self as Config<I>>::AccountId, Balance = BalanceOf<Self, I>> + + Unbalanced<<Self as Config<I>>::AccountId, Balance = BalanceOf<Self, I>> + + Mutate<<Self as Config<I>>::AccountId, Balance = BalanceOf<Self, I>>; /// The pot's pallet id, used for deriving its sovereign account ID. #[pallet::constant] @@ -127,20 +137,20 @@ pub mod pallet { // Just pass though. } InitialState::Initialized => { - let current = T::Currency::free_balance(&account_id); - let min = T::Currency::minimum_balance(); + let current = T::FungibleAsset::balance(&account_id); + let min = <T::FungibleAsset as Inspect<_>>::minimum_balance(); assert!( current >= min, "the initial pot balance must be greater or equal than the existential balance" ); } InitialState::Balance { balance } => { - let min = T::Currency::minimum_balance(); + let min = <T::FungibleAsset as Inspect<_>>::minimum_balance(); assert!( balance >= min, "the configured initial pot balance must be greater or equal than the existential balance" ); - let _ = T::Currency::make_free_balance_be(&account_id, balance); + let _ = T::FungibleAsset::set_balance(&account_id, balance); } } } @@ -159,9 +169,9 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> { // The existential deposit (`minimum_balance`) is not part of // the pot so the pot account never gets killed. pub fn balance() -> BalanceOf<T, I> { - T::Currency::free_balance(&Self::account_id()) + T::FungibleAsset::balance(&Self::account_id()) // Must never be less than 0 but better be safe. - .saturating_sub(T::Currency::minimum_balance()) + .saturating_sub(<T::FungibleAsset as Inspect<_>>::minimum_balance()) } /// Update the inactive supply for this pot. @@ -169,17 +179,17 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> { /// This function uses the whole balance of the account, unlike [`Self::balance`], /// which subtracts the existential balance. fn update_inactive() -> Weight { - let balance = T::Currency::free_balance(&Self::account_id()); + let balance = T::FungibleAsset::balance(&Self::account_id()); let current = Inactive::<T, I>::get(); let mut weight = T::DbWeight::get().reads(2); if balance != current { if let Some(delta) = balance.checked_sub(¤t) { - T::Currency::deactivate(delta) + <T::FungibleAsset as Unbalanced<_>>::deactivate(delta) } if let Some(delta) = current.checked_sub(&balance) { - T::Currency::reactivate(delta) + <T::FungibleAsset as Unbalanced<_>>::reactivate(delta) } Inactive::<T, I>::put(balance); @@ -195,10 +205,25 @@ impl<T: Config<I>, I: 'static> OnUnbalanced<NegativeImbalanceOf<T, I>> for Palle let numeric_amount = amount.peek(); // Must resolve into existing but better to be safe. - T::Currency::resolve_creating(&Self::account_id(), amount); + T::FungibleAsset::resolve_creating(&Self::account_id(), amount); Self::deposit_event(Event::Deposit { value: numeric_amount, }); } } + +pub struct OnUnbalancedOverCredit<T, I>(Pallet<T, I>); + +impl<T: Config<I>, I: 'static> OnUnbalanced<CreditOf<T, I>> for OnUnbalancedOverCredit<T, I> { + fn on_nonzero_unbalanced(amount: CreditOf<T, I>) { + let numeric_amount = amount.peek(); + + T::FungibleAsset::resolve(&Pallet::<T, I>::account_id(), amount); + T::FungibleAsset::done_deposit(&Pallet::<T, I>::account_id(), numeric_amount); + + Pallet::<T, I>::deposit_event(Event::Deposit { + value: numeric_amount, + }); + } +}