diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 54101cc222..18ce64c29f 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -1407,6 +1407,7 @@ impl pallet_uniques::Config for Runtime { #[cfg(feature = "runtime-benchmarks")] type Helper = (); type CreateOrigin = AsEnsureOriginWithArg>; + type Locker = (); } impl pallet_transaction_storage::Config for Runtime { diff --git a/substrate/frame/support/src/traits.rs b/substrate/frame/support/src/traits.rs index 40afc0d337..edeb7fead7 100644 --- a/substrate/frame/support/src/traits.rs +++ b/substrate/frame/support/src/traits.rs @@ -27,7 +27,7 @@ pub use tokens::{ }, fungible, fungibles, imbalance::{Imbalance, OnUnbalanced, SignedImbalance}, - BalanceStatus, ExistenceRequirement, WithdrawReasons, + BalanceStatus, ExistenceRequirement, Locker, WithdrawReasons, }; mod members; diff --git a/substrate/frame/support/src/traits/tokens.rs b/substrate/frame/support/src/traits/tokens.rs index 92f8ce12d9..77eb83adfb 100644 --- a/substrate/frame/support/src/traits/tokens.rs +++ b/substrate/frame/support/src/traits/tokens.rs @@ -27,5 +27,5 @@ pub mod nonfungibles; pub use imbalance::Imbalance; pub use misc::{ AssetId, Balance, BalanceConversion, BalanceStatus, DepositConsequence, ExistenceRequirement, - WithdrawConsequence, WithdrawReasons, + Locker, WithdrawConsequence, WithdrawReasons, }; diff --git a/substrate/frame/support/src/traits/tokens/misc.rs b/substrate/frame/support/src/traits/tokens/misc.rs index f30fd02bfe..86304b14a3 100644 --- a/substrate/frame/support/src/traits/tokens/misc.rs +++ b/substrate/frame/support/src/traits/tokens/misc.rs @@ -179,3 +179,19 @@ pub trait BalanceConversion { type Error; fn to_asset_balance(balance: InBalance, asset_id: AssetId) -> Result; } + +/// Trait to handle asset locking mechanism to ensure interactions with the asset can be implemented +/// downstream to extend logic of Uniques current functionality. +pub trait Locker { + /// Check if the asset should be locked and prevent interactions with the asset from executing. + fn is_locked(class: ClassId, instance: InstanceId) -> bool; +} + +impl Locker for () { + // Default will be false if not implemented downstream. + // Note: The logic check in this function must be constant time and consistent for benchmarks + // to work. + fn is_locked(_class: ClassId, _instance: InstanceId) -> bool { + false + } +} diff --git a/substrate/frame/uniques/src/functions.rs b/substrate/frame/uniques/src/functions.rs index 40c436bd56..8b874997f2 100644 --- a/substrate/frame/uniques/src/functions.rs +++ b/substrate/frame/uniques/src/functions.rs @@ -33,6 +33,7 @@ impl, I: 'static> Pallet { ) -> DispatchResult { let class_details = Class::::get(&class).ok_or(Error::::UnknownClass)?; ensure!(!class_details.is_frozen, Error::::Frozen); + ensure!(!T::Locker::is_locked(class, instance), Error::::Locked); let mut details = Asset::::get(&class, &instance).ok_or(Error::::UnknownClass)?; diff --git a/substrate/frame/uniques/src/lib.rs b/substrate/frame/uniques/src/lib.rs index 1e14825454..d999acc4c9 100644 --- a/substrate/frame/uniques/src/lib.rs +++ b/substrate/frame/uniques/src/lib.rs @@ -43,7 +43,7 @@ pub mod weights; use codec::{Decode, Encode}; use frame_support::traits::{ - BalanceStatus::Reserved, Currency, EnsureOriginWithArg, ReservableCurrency, + tokens::Locker, BalanceStatus::Reserved, Currency, EnsureOriginWithArg, ReservableCurrency, }; use frame_system::Config as SystemConfig; use sp_runtime::{ @@ -108,6 +108,9 @@ pub mod pallet { Self::ClassId, >; + /// Locker trait to enable Locking mechanism downstream. + type Locker: Locker; + /// The basic amount of funds that must be reserved for an asset class. #[pallet::constant] type ClassDeposit: Get>; @@ -352,6 +355,8 @@ pub mod pallet { Unapproved, /// The named owner has not signed ownership of the class is acceptable. Unaccepted, + /// The asset instance is locked. + Locked, } impl, I: 'static> Pallet { diff --git a/substrate/frame/uniques/src/mock.rs b/substrate/frame/uniques/src/mock.rs index 265142443e..f32540f6ef 100644 --- a/substrate/frame/uniques/src/mock.rs +++ b/substrate/frame/uniques/src/mock.rs @@ -91,6 +91,7 @@ impl Config for Test { type Currency = Balances; type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = frame_system::EnsureRoot; + type Locker = (); type ClassDeposit = ConstU64<2>; type InstanceDeposit = ConstU64<1>; type MetadataDepositBase = ConstU64<1>;