diff --git a/Cargo.lock b/Cargo.lock index 6c04d5679c..e21de2b44c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7032,7 +7032,7 @@ dependencies = [ [[package]] name = "pallet-rmrk-core" version = "0.0.1" -source = "git+https://github.com/Phala-Network/rmrk-substrate?branch=polkadot-v0.9.37#9cc8d217464685a5d090b962f66dbce41d602ad4" +source = "git+https://github.com/Phala-Network/rmrk-substrate?branch=polkadot-v0.9.37#a7e970cd6bd4b7b50f6611ea1023d1570721633c" dependencies = [ "frame-benchmarking", "frame-support", @@ -7047,6 +7047,25 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-rmrk-market" +version = "0.0.1" +source = "git+https://github.com/Phala-Network/rmrk-substrate?branch=polkadot-v0.9.37#a7e970cd6bd4b7b50f6611ea1023d1570721633c" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "pallet-balances", + "pallet-rmrk-core", + "pallet-uniques", + "parity-scale-codec", + "rmrk-traits", + "scale-info", + "serde", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-scheduler" version = "4.0.0-dev" @@ -7886,6 +7905,7 @@ dependencies = [ "pallet-randomness-collective-flip", "pallet-recovery", "pallet-rmrk-core", + "pallet-rmrk-market", "pallet-scheduler", "pallet-session", "pallet-session-benchmarking", @@ -7950,6 +7970,7 @@ dependencies = [ "pallet-preimage", "pallet-randomness-collective-flip", "pallet-rmrk-core", + "pallet-rmrk-market", "pallet-scheduler", "pallet-timestamp", "pallet-uniques", @@ -9353,7 +9374,7 @@ dependencies = [ [[package]] name = "rmrk-traits" version = "0.0.1" -source = "git+https://github.com/Phala-Network/rmrk-substrate?branch=polkadot-v0.9.37#9cc8d217464685a5d090b962f66dbce41d602ad4" +source = "git+https://github.com/Phala-Network/rmrk-substrate?branch=polkadot-v0.9.37#a7e970cd6bd4b7b50f6611ea1023d1570721633c" dependencies = [ "frame-benchmarking", "frame-support", diff --git a/pallets/phala/Cargo.toml b/pallets/phala/Cargo.toml index 62a84bb261..a711d1b085 100644 --- a/pallets/phala/Cargo.toml +++ b/pallets/phala/Cargo.toml @@ -23,6 +23,7 @@ pallet-preimage = { git = "https://github.com/paritytech/substrate", branch = "p # RMRK dependencies pallet-rmrk-core = { git = "https://github.com/Phala-Network/rmrk-substrate", branch = "polkadot-v0.9.37", default-features = false } rmrk-traits = { git = "https://github.com/Phala-Network/rmrk-substrate", branch = "polkadot-v0.9.37", default-features = false } +pallet-rmrk-market = { git = "https://github.com/Phala-Network/rmrk-substrate", branch = "polkadot-v0.9.37", default-features = false } frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", default-features = false } @@ -86,6 +87,7 @@ std = [ "phala-types/enable_serde", "pallet-rmrk-core/std", "rmrk-traits/std", + "pallet-rmrk-market/std", "pallet-collective/std", "pallet-randomness-collective-flip/std", "pallet-preimage/std", diff --git a/pallets/phala/src/compute/base_pool.rs b/pallets/phala/src/compute/base_pool.rs index abfff5e2d0..85aecab331 100644 --- a/pallets/phala/src/compute/base_pool.rs +++ b/pallets/phala/src/compute/base_pool.rs @@ -91,10 +91,7 @@ pub mod pallet { #[pallet::getter(fn next_nft_id)] pub type NextNftId = StorageMap<_, Twox64Concat, CollectionId, NftId, ValueQuery>; - type LockKey = ( - CollectionId, - NftId, - ); + type LockKey = (CollectionId, NftId); #[pallet::storage] pub type LockIterateStartPos = StorageValue<_, Option, ValueQuery>; @@ -511,8 +508,7 @@ pub mod pallet { let last_pos = LockIterateStartPos::::get(); let mut iter = match last_pos { Some(pos) => { - let key: Vec = - pallet_rmrk_core::pallet::Lock::::hashed_key_for(pos); + let key: Vec = pallet_rmrk_core::pallet::Lock::::hashed_key_for(pos); pallet_rmrk_core::pallet::Lock::::iter_from(key) } None => pallet_rmrk_core::pallet::Lock::::iter(), @@ -520,8 +516,10 @@ pub mod pallet { let mut record_vec = vec![]; let mut i = 0; for ((cid, nft_id), _) in iter.by_ref() { - if cid >= RESERVE_CID_START && !pallet_rmrk_core::pallet::Nfts::::contains_key(cid, nft_id) { - record_vec.push((cid, nft_id)); + if cid >= RESERVE_CID_START + && !pallet_rmrk_core::pallet::Nfts::::contains_key(cid, nft_id) + { + record_vec.push((cid, nft_id)); } i += 1; if i > max_iterations { @@ -639,11 +637,7 @@ pub mod pallet { Error::::NotInContributeWhitelist ); } - Self::merge_nft_for_staker( - pool.cid, - account_id.clone(), - pool.pid, - )?; + Self::merge_nft_for_staker(pool.cid, account_id.clone(), pool.pid)?; // The nft instance must be wrote to Nft storage at the end of the function // this nft's property shouldn't be accessed or wrote again from storage before set_nft_attr // is called. Or the property of the nft will be overwrote incorrectly. @@ -909,11 +903,12 @@ pub mod pallet { pid: u64, ) -> Result, DispatchError> { let mut total_shares: BalanceOf = Zero::zero(); - let nfts: Vec<_> = pallet_uniques::Pallet::::owned_in_collection(&cid, &staker).collect(); + let nfts: Vec<_> = + pallet_uniques::Pallet::::owned_in_collection(&cid, &staker).collect(); match nfts.len() { - 0 => return Ok(None), - 1 => return Ok(Some(nfts[0])), - _ => (), + 0 => return Ok(None), + 1 => return Ok(Some(nfts[0])), + _ => (), }; for nftid in nfts { let nft_guard = @@ -952,10 +947,7 @@ pub mod pallet { }) } - fn set_nft_desc_attr( - cid: CollectionId, - nft_id: NftId, - ) -> DispatchResult { + fn set_nft_desc_attr(cid: CollectionId, nft_id: NftId) -> DispatchResult { pallet_rmrk_core::Pallet::::set_lock((cid, nft_id), false); let key: BoundedVec::KeyLimit> = "createtime" .as_bytes() diff --git a/pallets/phala/src/compute/stake_pool_v2.rs b/pallets/phala/src/compute/stake_pool_v2.rs index b80a49f48c..bc1000d5f3 100644 --- a/pallets/phala/src/compute/stake_pool_v2.rs +++ b/pallets/phala/src/compute/stake_pool_v2.rs @@ -83,9 +83,9 @@ pub mod pallet { #[pallet::without_storage_info] pub struct Pallet(_); - #[pallet::storage] - pub type LegacyRewards = StorageMap<_, Twox64Concat, (T::AccountId, u64), BalanceOf>; + pub type LegacyRewards = + StorageMap<_, Twox64Concat, (T::AccountId, u64), BalanceOf>; /// Mapping from workers to the pool they belong to /// /// The map entry lasts from `add_worker()` to `remove_worker()` or force unbinding. @@ -316,6 +316,8 @@ pub mod pallet { LockAccountStakeError, NoLegacyRewardToClaim, + /// The pool's delegation nft is on sell. + UserNftListed, } #[pallet::call] @@ -564,7 +566,8 @@ pub mod pallet { target: T::AccountId, ) -> DispatchResult { let who = ensure_signed(origin)?; - let rewards = LegacyRewards::::take((who, pid)).ok_or(Error::::NoLegacyRewardToClaim)?; + let rewards = + LegacyRewards::::take((who, pid)).ok_or(Error::::NoLegacyRewardToClaim)?; computation::Pallet::::withdraw_subsidy_pool(&target, rewards) .or(Err(Error::::InternalSubsidyPoolCannotWithdraw))?; Ok(()) @@ -698,6 +701,10 @@ pub mod pallet { maybe_vault = Some((vault_pid, vault_info)); } let mut pool_info = ensure_stake_pool::(pid)?; + ensure!( + !wrapped_balances::pallet::Pallet::::have_nft_on_list(&who, &pool_info.basepool.cid), + Error::::UserNftListed + ); let a = amount; // Alias to reduce confusion in the code below // If the pool has a contribution whitelist in storages, check if the origin is authorized to contribute ensure!( @@ -713,11 +720,8 @@ pub mod pallet { }; ensure!(free >= a, Error::::InsufficientBalance); // a lot of weird edge cases when dealing with pending slash. - let shares = base_pool::Pallet::::contribute( - &mut pool_info.basepool, - who.clone(), - amount, - )?; + let shares = + base_pool::Pallet::::contribute(&mut pool_info.basepool, who.clone(), amount)?; if let Some((vault_pid, vault_info)) = &mut maybe_vault { if !vault_info.invest_pools.contains(&pid) { vault_info.invest_pools.push(pid); @@ -796,6 +800,10 @@ pub mod pallet { who = vault_info.basepool.pool_account_id; } let mut pool_info = ensure_stake_pool::(pid)?; + ensure!( + !wrapped_balances::pallet::Pallet::::have_nft_on_list(&who, &pool_info.basepool.cid), + Error::::UserNftListed + ); let maybe_nft_id = base_pool::Pallet::::merge_nft_for_staker( pool_info.basepool.cid, who.clone(), diff --git a/pallets/phala/src/compute/vault.rs b/pallets/phala/src/compute/vault.rs index 0765844f1f..6ec0dcd94b 100644 --- a/pallets/phala/src/compute/vault.rs +++ b/pallets/phala/src/compute/vault.rs @@ -138,6 +138,8 @@ pub mod pallet { VaultBankrupt, /// The caller has no nft to withdraw NoNftToWithdraw, + /// The pool's delegation nft is on sell. + UserNftListed, } #[pallet::call] @@ -246,6 +248,10 @@ pub mod pallet { ) -> DispatchResult { let who = ensure_signed(origin.clone())?; let mut pool_info = ensure_vault::(vault_pid)?; + ensure!( + !wrapped_balances::pallet::Pallet::::have_nft_on_list(&who, &pool_info.basepool.cid), + Error::::UserNftListed + ); ensure!( who == pool_info.basepool.owner, Error::::UnauthorizedPoolOwner @@ -429,6 +435,10 @@ pub mod pallet { pub fn contribute(origin: OriginFor, pid: u64, amount: BalanceOf) -> DispatchResult { let who = ensure_signed(origin)?; let mut pool_info = ensure_vault::(pid)?; + ensure!( + !wrapped_balances::pallet::Pallet::::have_nft_on_list(&who, &pool_info.basepool.cid), + Error::::UserNftListed + ); let a = amount; // Alias to reduce confusion in the code below ensure!( @@ -442,11 +452,8 @@ pub mod pallet { .ok_or(Error::::AssetAccountNotExist)?; ensure!(free >= a, Error::::InsufficientBalance); - let shares = base_pool::Pallet::::contribute( - &mut pool_info.basepool, - who.clone(), - amount, - )?; + let shares = + base_pool::Pallet::::contribute(&mut pool_info.basepool, who.clone(), amount)?; // We have new free stake now, try to handle the waiting withdraw queue @@ -486,6 +493,10 @@ pub mod pallet { pub fn withdraw(origin: OriginFor, pid: u64, shares: BalanceOf) -> DispatchResult { let who = ensure_signed(origin)?; let mut pool_info = ensure_vault::(pid)?; + ensure!( + !wrapped_balances::pallet::Pallet::::have_nft_on_list(&who, &pool_info.basepool.cid), + Error::::UserNftListed + ); let maybe_nft_id = base_pool::Pallet::::merge_nft_for_staker( pool_info.basepool.cid, who.clone(), diff --git a/pallets/phala/src/compute/wrapped_balances.rs b/pallets/phala/src/compute/wrapped_balances.rs index e8f34238b9..bb59b73e55 100644 --- a/pallets/phala/src/compute/wrapped_balances.rs +++ b/pallets/phala/src/compute/wrapped_balances.rs @@ -31,6 +31,7 @@ pub mod pallet { + crate::PhalaConfig + registry::Config + pallet_rmrk_core::Config + + pallet_rmrk_market::Config + computation::Config + pallet_assets::Config + pallet_democracy::Config @@ -143,8 +144,16 @@ pub mod pallet { T: pallet_democracy::Config::Currency>, T: Config + vault::Config, { - fn pre_check(sender: &T::AccountId, collection_id: &CollectionId, nft_id: &NftId) -> bool { + fn pre_check( + sender: &T::AccountId, + recipient: &T::AccountId, + collection_id: &CollectionId, + nft_id: &NftId, + ) -> bool { if let Some(pid) = base_pool::pallet::PoolCollections::::get(collection_id) { + if Self::have_nft_on_list(recipient, collection_id) { + return false; + } if let Ok(net_value) = Pallet::::get_net_value((*sender).clone()) { let property_guard = base_pool::Pallet::::get_nft_attr_guard(*collection_id, *nft_id) @@ -463,6 +472,18 @@ pub mod pallet { } } + /// Check if recipient has Nft listing in a specific collection. + pub fn have_nft_on_list(recipient: &T::AccountId, collection_id: &CollectionId) -> bool { + let iter = pallet_uniques::Pallet::::owned_in_collection(collection_id, recipient) + .take_while(|nftid| { + pallet_rmrk_market::ListedNfts::::contains_key(collection_id, nftid) + }); + if iter.count() > 0 { + return true; + } + false + } + /// Tries to update locked W-PHA amount of the user fn update_user_locked(user: T::AccountId) -> DispatchResult { let mut max_lock: BalanceOf = Zero::zero(); diff --git a/pallets/phala/src/mock.rs b/pallets/phala/src/mock.rs index 43569969d9..5150bd3728 100644 --- a/pallets/phala/src/mock.rs +++ b/pallets/phala/src/mock.rs @@ -21,6 +21,7 @@ use sp_core::H256; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, + Permill, }; use frame_system::EnsureRoot; @@ -42,6 +43,7 @@ frame_support::construct_runtime!( Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, Uniques: pallet_uniques::{Pallet, Storage, Event}, RmrkCore: pallet_rmrk_core::{Pallet, Call, Event}, + RmrkMarket: pallet_rmrk_market::{Pallet, Call, Event}, Democracy: pallet_democracy::{Pallet, Call, Storage, Config, Event}, Assets: pallet_assets::{Pallet, Event}, Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event}, @@ -232,6 +234,21 @@ impl pallet_rmrk_core::Config for Test { type Helper = pallet_rmrk_core::RmrkBenchmark; } +parameter_types! { + pub const MinimumOfferAmount: Balance = DOLLARS / 10_000; + pub const MarketFee: Permill = Permill::from_parts(5_000); +} + +impl pallet_rmrk_market::Config for Test { + type RuntimeEvent = RuntimeEvent; + type ProtocolOrigin = EnsureRoot; + type Currency = Balances; + type MinimumOfferAmount = MinimumOfferAmount; + type WeightInfo = pallet_rmrk_market::weights::SubstrateWeight; + type MarketplaceHooks = (); + type MarketFee = MarketFee; +} + impl computation::Config for Test { type RuntimeEvent = RuntimeEvent; type ExpectedBlockTimeSec = ExpectedBlockTimeSec; diff --git a/pallets/phala/src/utils/balance_convert.rs b/pallets/phala/src/utils/balance_convert.rs index b932c8b6bc..d0855fa829 100644 --- a/pallets/phala/src/utils/balance_convert.rs +++ b/pallets/phala/src/utils/balance_convert.rs @@ -14,7 +14,9 @@ impl FixedPointConvert for u128 { Self::from_fixed(&FixedPoint::from_bits(bits)) } fn from_fixed(v: &FixedPoint) -> Self { - U80F48::unwrapped_from_num(*v).unwrapped_mul_int(PHA).to_num() + U80F48::unwrapped_from_num(*v) + .unwrapped_mul_int(PHA) + .to_num() } fn to_fixed(&self) -> FixedPoint { let v = U80F48::unwrapped_from_num(*self); diff --git a/standalone/prouter/Cargo.lock b/standalone/prouter/Cargo.lock index 566716afef..15d81157fe 100644 --- a/standalone/prouter/Cargo.lock +++ b/standalone/prouter/Cargo.lock @@ -3034,7 +3034,7 @@ dependencies = [ [[package]] name = "pallet-rmrk-core" version = "0.0.1" -source = "git+https://github.com/Phala-Network/rmrk-substrate?branch=polkadot-v0.9.37#9cc8d217464685a5d090b962f66dbce41d602ad4" +source = "git+https://github.com/Phala-Network/rmrk-substrate?branch=polkadot-v0.9.37#a7e970cd6bd4b7b50f6611ea1023d1570721633c" dependencies = [ "frame-benchmarking", "frame-support", @@ -3049,6 +3049,25 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-rmrk-market" +version = "0.0.1" +source = "git+https://github.com/Phala-Network/rmrk-substrate?branch=polkadot-v0.9.37#a7e970cd6bd4b7b50f6611ea1023d1570721633c" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "pallet-balances", + "pallet-rmrk-core", + "pallet-uniques", + "parity-scale-codec", + "rmrk-traits", + "scale-info", + "serde", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-scheduler" version = "4.0.0-dev" @@ -3583,6 +3602,7 @@ dependencies = [ "pallet-randomness-collective-flip", "pallet-recovery", "pallet-rmrk-core", + "pallet-rmrk-market", "pallet-scheduler", "pallet-session", "pallet-session-benchmarking", @@ -3642,6 +3662,7 @@ dependencies = [ "pallet-preimage", "pallet-randomness-collective-flip", "pallet-rmrk-core", + "pallet-rmrk-market", "pallet-uniques", "parity-scale-codec", "phala-types", @@ -3675,6 +3696,7 @@ version = "0.1.0" dependencies = [ "hash-db", "im", + "log", "parity-scale-codec", "scale-info", "serde", @@ -4388,7 +4410,7 @@ dependencies = [ [[package]] name = "rmrk-traits" version = "0.0.1" -source = "git+https://github.com/Phala-Network/rmrk-substrate?branch=polkadot-v0.9.37#9cc8d217464685a5d090b962f66dbce41d602ad4" +source = "git+https://github.com/Phala-Network/rmrk-substrate?branch=polkadot-v0.9.37#a7e970cd6bd4b7b50f6611ea1023d1570721633c" dependencies = [ "frame-benchmarking", "frame-support", @@ -6194,7 +6216,7 @@ checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ "cfg-if", "digest 0.10.3", - "rand 0.8.5", + "rand 0.4.6", "static_assertions", ] diff --git a/standalone/pruntime/Cargo.lock b/standalone/pruntime/Cargo.lock index af14667aa9..4b8e6f7618 100644 --- a/standalone/pruntime/Cargo.lock +++ b/standalone/pruntime/Cargo.lock @@ -4064,7 +4064,7 @@ dependencies = [ [[package]] name = "pallet-rmrk-core" version = "0.0.1" -source = "git+https://github.com/Phala-Network/rmrk-substrate?branch=polkadot-v0.9.37#9cc8d217464685a5d090b962f66dbce41d602ad4" +source = "git+https://github.com/Phala-Network/rmrk-substrate?branch=polkadot-v0.9.37#a7e970cd6bd4b7b50f6611ea1023d1570721633c" dependencies = [ "frame-benchmarking", "frame-support", @@ -4079,6 +4079,25 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-rmrk-market" +version = "0.0.1" +source = "git+https://github.com/Phala-Network/rmrk-substrate?branch=polkadot-v0.9.37#a7e970cd6bd4b7b50f6611ea1023d1570721633c" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "pallet-balances", + "pallet-rmrk-core", + "pallet-uniques", + "parity-scale-codec", + "rmrk-traits", + "scale-info", + "serde", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-scheduler" version = "4.0.0-dev" @@ -4697,6 +4716,7 @@ dependencies = [ "pallet-randomness-collective-flip", "pallet-recovery", "pallet-rmrk-core", + "pallet-rmrk-market", "pallet-scheduler", "pallet-session", "pallet-session-benchmarking", @@ -4756,6 +4776,7 @@ dependencies = [ "pallet-preimage", "pallet-randomness-collective-flip", "pallet-rmrk-core", + "pallet-rmrk-market", "pallet-uniques", "parity-scale-codec", "phala-types", @@ -5751,7 +5772,7 @@ checksum = "fc874b127765f014d792f16763a81245ab80500e2ad921ed4ee9e82481ee08fe" [[package]] name = "rmrk-traits" version = "0.0.1" -source = "git+https://github.com/Phala-Network/rmrk-substrate?branch=polkadot-v0.9.37#9cc8d217464685a5d090b962f66dbce41d602ad4" +source = "git+https://github.com/Phala-Network/rmrk-substrate?branch=polkadot-v0.9.37#a7e970cd6bd4b7b50f6611ea1023d1570721633c" dependencies = [ "frame-benchmarking", "frame-support", @@ -7746,7 +7767,7 @@ checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ "cfg-if", "digest 0.10.3", - "rand 0.8.5", + "rand 0.4.6", "static_assertions", ] diff --git a/standalone/runtime/Cargo.toml b/standalone/runtime/Cargo.toml index 3cc545610e..faf48ae0cc 100644 --- a/standalone/runtime/Cargo.toml +++ b/standalone/runtime/Cargo.toml @@ -98,6 +98,7 @@ phat-offchain-rollup = { path = "../../pallets/offchain-rollup", default-feature # RMRK dependencies pallet-rmrk-core = { git = "https://github.com/Phala-Network/rmrk-substrate", branch = "polkadot-v0.9.37", default-features = false } rmrk-traits = { git = "https://github.com/Phala-Network/rmrk-substrate", branch = "polkadot-v0.9.37", default-features = false } +pallet-rmrk-market = { git = "https://github.com/Phala-Network/rmrk-substrate", branch = "polkadot-v0.9.37", default-features = false } [build-dependencies] substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37", optional = true } @@ -180,6 +181,7 @@ std = [ "pallet-uniques/std", "pallet-rmrk-core/std", "rmrk-traits/std", + "pallet-rmrk-market/std", "phat-offchain-rollup/std", ] runtime-benchmarks = [ diff --git a/standalone/runtime/src/lib.rs b/standalone/runtime/src/lib.rs index f25597887e..0cc3b0dcc4 100644 --- a/standalone/runtime/src/lib.rs +++ b/standalone/runtime/src/lib.rs @@ -1504,6 +1504,22 @@ parameter_types! { pub const QueueCapacity: u32 = 128; } +parameter_types! { + pub const MinimumOfferAmount: Balance = DOLLARS / 10_000; + pub const MarketFee: Permill = Permill::from_parts(5_000); +} + + +impl pallet_rmrk_market::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type ProtocolOrigin = EnsureRoot; + type Currency = Balances; + type MinimumOfferAmount = MinimumOfferAmount; + type WeightInfo = pallet_rmrk_market::weights::SubstrateWeight; + type MarketplaceHooks = (); + type MarketFee = MarketFee; +} + impl pallet_anchor::Config for Runtime { type RuntimeEvent = RuntimeEvent; type OnResponse = PhatOracle; @@ -1586,6 +1602,7 @@ construct_runtime!( // NFT Uniques: pallet_uniques::{Pallet, Storage, Event}, RmrkCore: pallet_rmrk_core::{Pallet, Call, Event}, + RmrkMarket: pallet_rmrk_market::{Pallet, Call, Event}, } );