diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 270386be2bbd3..eab40634ff241 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1438,6 +1438,7 @@ impl pallet_assets::Config for Runtime { type Balance = u128; type AssetId = u32; type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = EnsureRoot; type AssetDeposit = AssetDeposit; type AssetAccountDeposit = ConstU128; diff --git a/frame/assets/src/benchmarking.rs b/frame/assets/src/benchmarking.rs index ca891c2f42e4a..2bde2b0c98945 100644 --- a/frame/assets/src/benchmarking.rs +++ b/frame/assets/src/benchmarking.rs @@ -150,12 +150,14 @@ fn assert_event, I: 'static>(generic_event: >::Runti benchmarks_instance_pallet! { create { - let caller: T::AccountId = whitelisted_caller(); + let asset_id = Default::default(); + let origin = T::CreateOrigin::successful_origin(&asset_id); + let caller = T::CreateOrigin::ensure_origin(origin, &asset_id).unwrap(); let caller_lookup = T::Lookup::unlookup(caller.clone()); T::Currency::make_free_balance_be(&caller, DepositBalanceOf::::max_value()); - }: _(SystemOrigin::Signed(caller.clone()), Default::default(), caller_lookup, 1u32.into()) + }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, 1u32.into()) verify { - assert_last_event::(Event::Created { asset_id: Default::default(), creator: caller.clone(), owner: caller }.into()); + assert_last_event::(Event::Created { asset_id, creator: caller.clone(), owner: caller }.into()); } force_create { diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index 28743f917d323..7e7d68fa6c7dd 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -36,15 +36,15 @@ //! //! ### Terminology //! -//! * **Admin**: An account ID uniquely privileged to be able to unfreeze (thaw) an account and it's +//! * **Admin**: An account ID uniquely privileged to be able to unfreeze (thaw) an account and its //! assets, as well as forcibly transfer a particular class of assets between arbitrary accounts //! and reduce the balance of a particular class of assets of arbitrary accounts. //! * **Asset issuance/minting**: The creation of a new asset, whose total supply will belong to the -//! account that issues the asset. This is a privileged operation. +//! account designated as the beneficiary of the asset. This is a privileged operation. //! * **Asset transfer**: The reduction of the balance of an asset of one account with the //! corresponding increase in the balance of another. -//! * **Asset destruction**: The process of reduce the balance of an asset of one account. This is a -//! privileged operation. +//! * **Asset destruction**: The process of reducing the balance of an asset of one account. This is +//! a privileged operation. //! * **Fungible asset**: An asset whose units are interchangeable. //! * **Issuer**: An account ID uniquely privileged to be able to mint a particular class of assets. //! * **Freezer**: An account ID uniquely privileged to be able to freeze an account from @@ -63,12 +63,12 @@ //! //! The assets system in Substrate is designed to make the following possible: //! -//! * Issue a new assets in a permissioned or permissionless way, if permissionless, then with a +//! * Issue new assets in a permissioned or permissionless way, if permissionless, then with a //! deposit required. //! * Allow accounts to be delegated the ability to transfer assets without otherwise existing //! on-chain (*approvals*). //! * Move assets between accounts. -//! * Update the asset's total supply. +//! * Update an asset class's total supply. //! * Allow administrative activities by specially privileged accounts including freezing account //! balances and minting/burning assets. //! @@ -92,6 +92,7 @@ //! * `force_cancel_approval`: Rescind a previous approval. //! //! ### Privileged Functions +//! //! * `destroy`: Destroys an entire asset class; called by the asset class's Owner. //! * `mint`: Increases the asset balance of an account; called by the asset class's Issuer. //! * `burn`: Decreases the asset balance of an account; called by the asset class's Admin. @@ -156,7 +157,7 @@ use frame_support::{ traits::{ tokens::{fungibles, DepositConsequence, WithdrawConsequence}, BalanceStatus::Reserved, - Currency, ReservableCurrency, StoredMap, + Currency, EnsureOriginWithArg, ReservableCurrency, StoredMap, }, }; use frame_system::Config as SystemConfig; @@ -206,6 +207,14 @@ pub mod pallet { /// The currency mechanism. type Currency: ReservableCurrency; + /// Standard asset class creation is only allowed if the origin attempting it and the + /// asset class are in this set. + type CreateOrigin: EnsureOriginWithArg< + Self::RuntimeOrigin, + Self::AssetId, + Success = Self::AccountId, + >; + /// The origin which may forcibly create or destroy an asset or otherwise alter privileged /// attributes. type ForceOrigin: EnsureOrigin; @@ -485,7 +494,7 @@ pub mod pallet { /// /// This new asset class has no assets initially and its owner is the origin. /// - /// The origin must be Signed and the sender must have sufficient funds free. + /// The origin must conform to the configured `CreateOrigin` and have sufficient funds free. /// /// Funds of sender are reserved by `AssetDeposit`. /// @@ -507,7 +516,7 @@ pub mod pallet { admin: AccountIdLookupOf, min_balance: T::Balance, ) -> DispatchResult { - let owner = ensure_signed(origin)?; + let owner = T::CreateOrigin::ensure_origin(origin, &id)?; let admin = T::Lookup::lookup(admin)?; ensure!(!Asset::::contains_key(id), Error::::InUse); diff --git a/frame/assets/src/mock.rs b/frame/assets/src/mock.rs index 1f105eb6b4fbc..21fb52c9cd931 100644 --- a/frame/assets/src/mock.rs +++ b/frame/assets/src/mock.rs @@ -22,7 +22,7 @@ use crate as pallet_assets; use frame_support::{ construct_runtime, parameter_types, - traits::{ConstU32, ConstU64, GenesisBuild}, + traits::{AsEnsureOriginWithArg, ConstU32, ConstU64, GenesisBuild}, }; use sp_core::H256; use sp_runtime::{ @@ -89,6 +89,7 @@ impl Config for Test { type Balance = u64; type AssetId = u32; type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = frame_system::EnsureRoot; type AssetDeposit = ConstU64<1>; type AssetAccountDeposit = ConstU64<10>; diff --git a/frame/transaction-payment/asset-tx-payment/src/tests.rs b/frame/transaction-payment/asset-tx-payment/src/tests.rs index e775f3aa92990..cfed1c33c9b24 100644 --- a/frame/transaction-payment/asset-tx-payment/src/tests.rs +++ b/frame/transaction-payment/asset-tx-payment/src/tests.rs @@ -21,7 +21,7 @@ use frame_support::{ dispatch::{DispatchClass, DispatchInfo, PostDispatchInfo}, pallet_prelude::*, parameter_types, - traits::{fungibles::Mutate, ConstU32, ConstU64, ConstU8, FindAuthor}, + traits::{fungibles::Mutate, AsEnsureOriginWithArg, ConstU32, ConstU64, ConstU8, FindAuthor}, weights::{Weight, WeightToFee as WeightToFeeT}, ConsensusEngineId, }; @@ -157,6 +157,7 @@ impl pallet_assets::Config for Runtime { type Balance = Balance; type AssetId = u32; type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = EnsureRoot; type AssetDeposit = ConstU64<2>; type AssetAccountDeposit = ConstU64<2>; diff --git a/frame/uniques/src/lib.rs b/frame/uniques/src/lib.rs index d519eedd2787f..185d8fc0c8edd 100644 --- a/frame/uniques/src/lib.rs +++ b/frame/uniques/src/lib.rs @@ -437,7 +437,7 @@ pub mod pallet { /// /// This new collection has no items initially and its owner is the origin. /// - /// The origin must be Signed and the sender must have sufficient funds free. + /// The origin must conform to the configured `CreateOrigin` and have sufficient funds free. /// /// `ItemDeposit` funds of sender are reserved. ///