From 1155834af15d066c8d304a6b647938241a32468c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Y=C3=A1=C3=B1ez?= Date: Mon, 24 Apr 2023 22:59:34 -0600 Subject: [PATCH 1/2] Import mapped assets to gated marketplace --- Cargo.lock | 2 + pallets/gated-marketplace/Cargo.toml | 1 + pallets/gated-marketplace/src/functions.rs | 47 ++++++++++++++-------- pallets/gated-marketplace/src/lib.rs | 5 ++- parachain-runtime/Cargo.toml | 1 + parachain-runtime/src/lib.rs | 30 ++++++++++++++ runtime/src/lib.rs | 2 +- 7 files changed, 69 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c4f0e0e7..222ee8f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3328,6 +3328,7 @@ dependencies = [ "pallet-im-online", "pallet-indices", "pallet-lottery", + "pallet-mapped-assets", "pallet-membership", "pallet-multisig", "pallet-preimage", @@ -5975,6 +5976,7 @@ dependencies = [ "log", "pallet-balances", "pallet-fruniques", + "pallet-mapped-assets", "pallet-rbac", "pallet-timestamp", "pallet-uniques", diff --git a/pallets/gated-marketplace/Cargo.toml b/pallets/gated-marketplace/Cargo.toml index f68ac2b1..268de887 100644 --- a/pallets/gated-marketplace/Cargo.toml +++ b/pallets/gated-marketplace/Cargo.toml @@ -30,6 +30,7 @@ pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "p pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } pallet-fruniques = { path = "../fruniques", default-features = false, version = "0.1.0-dev" } pallet-rbac = { path = "../rbac/", default-features = false, version = "4.0.0-dev" } +pallet-mapped-assets = { path = "../mapped-assets",default-features = false, version = "4.0.0-dev"} [dev-dependencies] sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } diff --git a/pallets/gated-marketplace/src/functions.rs b/pallets/gated-marketplace/src/functions.rs index 9bc0cd19..79397453 100644 --- a/pallets/gated-marketplace/src/functions.rs +++ b/pallets/gated-marketplace/src/functions.rs @@ -6,6 +6,7 @@ use pallet_rbac::types::*; use scale_info::prelude::vec; // vec![] macro use sp_runtime::sp_std::vec::Vec; // vec primitive +use frame_support::traits::fungibles::Transfer; use frame_support::traits::Currency; use frame_support::traits::ExistenceRequirement::KeepAlive; use frame_support::traits::Time; @@ -226,15 +227,9 @@ impl Pallet { Ok(()) } - - pub fn self_enroll( - account: T::AccountId, - marketplace_id: [u8; 32], - ) -> DispatchResult { - - //since users can self-enroll, the caller of this function must validate + pub fn self_enroll(account: T::AccountId, marketplace_id: [u8; 32]) -> DispatchResult { + //since users can self-enroll, the caller of this function must validate //that the user is indeed the owner of the address by using ensure_signed - //ensure the account is not already in the marketplace ensure!( @@ -248,10 +243,13 @@ impl Pallet { // ensure the marketplace exist ensure!(>::contains_key(marketplace_id), Error::::MarketplaceNotFound); - - Self::insert_in_auth_market_lists(account.clone(), MarketplaceRole::Participant, marketplace_id)?; + Self::insert_in_auth_market_lists( + account.clone(), + MarketplaceRole::Participant, + marketplace_id, + )?; Self::deposit_event(Event::AuthorityAdded(account, MarketplaceRole::Participant)); - + Ok(()) } @@ -362,6 +360,7 @@ impl Pallet { collection_id, item_id, creator: authority.clone(), + // might require a storage migration price, fee: price * Permill::deconstruct(marketplace.sell_fee).into() / 1_000_000u32.into(), percentage: Permill::from_percent(percentage), @@ -405,8 +404,6 @@ impl Pallet { price: BalanceOf, percentage: u32, ) -> DispatchResult { - - //ensure the marketplace exists ensure!(>::contains_key(marketplace_id), Error::::MarketplaceNotFound); @@ -424,10 +421,11 @@ impl Pallet { &marketplace_id, authority.clone(), &collection_id, - &item_id + &item_id, )?; //ensure user has enough balance to create the offer + // TODO: find a way to get users total asset balance let total_user_balance = T::Currency::total_balance(&authority); ensure!(total_user_balance >= price, Error::::NotEnoughBalance); @@ -450,6 +448,7 @@ impl Pallet { collection_id, item_id, creator: authority.clone(), + // TODO: evaluate if the change will require a storage migration price, fee: price * Permill::deconstruct(marketplace.buy_fee).into() / 1_000_000u32.into(), percentage: Permill::from_percent(percentage), @@ -509,6 +508,7 @@ impl Pallet { //ensure the offer is open and available ensure!(offer_data.status == OfferStatus::Open, Error::::OfferIsNotAvailable); //TODO: Use free_balance instead of total_balance + // TODO: find a way to get buyer's total balance //Get the buyer's balance let total_amount_buyer = T::Currency::total_balance(&buyer); //ensure the buyer has enough balance to buy the item @@ -518,6 +518,7 @@ impl Pallet { >::get(offer_data.marketplace_id).ok_or(Error::::OfferNotFound)?; let owners_cut: BalanceOf = offer_data.price - offer_data.fee; //Transfer the balance + // TODO: replace transfer for T::MappedAssets::transfer(...); T::Currency::transfer(&buyer, &owner_item, owners_cut, KeepAlive)?; T::Currency::transfer(&buyer, &marketplace.creator, offer_data.fee, KeepAlive)?; @@ -602,6 +603,7 @@ impl Pallet { ensure!(offer_data.status == OfferStatus::Open, Error::::OfferIsNotAvailable); //TODO: Use free_balance instead of total_balance + // TODO: find a way to get users's total balance //Get the buyer's balance let total_amount_buyer = T::Currency::total_balance(&offer_data.creator); //ensure the buy_offer_creator has enough balance to buy the item @@ -611,6 +613,7 @@ impl Pallet { >::get(offer_data.marketplace_id).ok_or(Error::::OfferNotFound)?; let owners_cut: BalanceOf = offer_data.price - offer_data.fee; //Transfer the balance to the owner of the item + // TODO: replace transfer for T::MappedAssets::transfer(...); T::Currency::transfer(&offer_data.creator, &owner_item, owners_cut, KeepAlive)?; T::Currency::transfer( &offer_data.creator, @@ -885,7 +888,10 @@ impl Pallet { // ensure the origin is authorized to block users Self::is_authorized(authority.clone(), &marketplace_id, Permission::BlockUser)?; // ensure the user is not already a participant of the marketplace - ensure!(!Self::has_any_role(user.clone(), &marketplace_id), Error::::UserAlreadyParticipant); + ensure!( + !Self::has_any_role(user.clone(), &marketplace_id), + Error::::UserAlreadyParticipant + ); // ensure the user is not already blocked ensure!( !Self::is_user_blocked(user.clone(), marketplace_id), @@ -912,7 +918,10 @@ impl Pallet { // ensure the origin is authorized to block users Self::is_authorized(authority.clone(), &marketplace_id, Permission::BlockUser)?; // ensure the user is not already a participant of the marketplace - ensure!(!Self::has_any_role(user.clone(), &marketplace_id), Error::::UserAlreadyParticipant); + ensure!( + !Self::has_any_role(user.clone(), &marketplace_id), + Error::::UserAlreadyParticipant + ); // ensure the user is blocked ensure!(Self::is_user_blocked(user.clone(), marketplace_id), Error::::UserIsNotBlocked); @@ -952,7 +961,11 @@ impl Pallet { /// Let us know if the selected account has at least one role in the marketplace. fn has_any_role(account: T::AccountId, marketplace_id: &[u8; 32]) -> bool { let pallet_id = Self::pallet_id(); - ::Rbac::does_user_have_any_role_in_scope(account, pallet_id, marketplace_id) + ::Rbac::does_user_have_any_role_in_scope( + account, + pallet_id, + marketplace_id, + ) } ///Lets us know if the selected user is an admin. diff --git a/pallets/gated-marketplace/src/lib.rs b/pallets/gated-marketplace/src/lib.rs index 040e45be..63c2b6b9 100644 --- a/pallets/gated-marketplace/src/lib.rs +++ b/pallets/gated-marketplace/src/lib.rs @@ -14,7 +14,7 @@ pub mod types; #[frame_support::pallet] pub mod pallet { use frame_support::pallet_prelude::*; - use frame_support::traits::{Currency, Time}; + use frame_support::traits::{tokens::fungibles::Transfer, Currency, Time}; use frame_system::pallet_prelude::*; use sp_runtime::traits::Scale; use sp_runtime::Permill; @@ -27,6 +27,8 @@ pub mod pallet { pub type BalanceOf = <::Currency as Currency< ::AccountId, >>::Balance; + // TODO: replace BalanceOf with the mapped assets one + pub type BalanceOf2 = >::Balance; #[pallet::config] pub trait Config: frame_system::Config + pallet_fruniques::Config { @@ -69,6 +71,7 @@ pub mod pallet { type MaxBlockedUsersPerMarket: Get; type Rbac: RoleBasedAccessControl; + type MappedAssets: Transfer; } #[pallet::pallet] diff --git a/parachain-runtime/Cargo.toml b/parachain-runtime/Cargo.toml index e27c8f33..5a04707a 100644 --- a/parachain-runtime/Cargo.toml +++ b/parachain-runtime/Cargo.toml @@ -50,6 +50,7 @@ pallet-fruniques = { path = "../pallets/fruniques", default-features = false } pallet-gated-marketplace = { path = "../pallets/gated-marketplace", default-features = false } pallet-rbac = { path = "../pallets/rbac", default-features = false } pallet-confidential-docs = { path = "../pallets/confidential-docs", default-features = false } +pallet-mapped-assets = { path = "../pallets/mapped-assets",default-features = false } # Prebuilt Pallets pallet-alliance = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } pallet-assets = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } diff --git a/parachain-runtime/src/lib.rs b/parachain-runtime/src/lib.rs index 30b23937..90e13052 100644 --- a/parachain-runtime/src/lib.rs +++ b/parachain-runtime/src/lib.rs @@ -22,6 +22,7 @@ use sp_runtime::{ ApplyExtrinsicResult, MultiSignature, }; +use pallet_mapped_assets::DefaultCallback; use sp_std::prelude::*; #[cfg(feature = "std")] use sp_version::NativeVersion; @@ -804,6 +805,33 @@ impl pallet_confidential_docs::Config for Runtime { type MaxMemberGroups = MaxMemberGroups; } +parameter_types! { + pub const MappedMaxReserves: u32 = 200; +} + +impl pallet_mapped_assets::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Balance = u128; + type AssetId = u32; + type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; + type ForceOrigin = EnsureRoot; + type AssetDeposit = AssetDeposit; + type AssetAccountDeposit = ConstU128; + type MetadataDepositBase = MetadataDepositBase; + type MetadataDepositPerByte = MetadataDepositPerByte; + type ApprovalDeposit = ApprovalDeposit; + type StringLimit = StringLimit; + type Freezer = (); + type Extra = (); + type WeightInfo = (); + type MaxReserves = MappedMaxReserves; + type ReserveIdentifier = u32; + type RemoveItemsLimit = RemoveItemsLimit; + type AssetIdParameter = u32; + type CallbackHandle = DefaultCallback; +} + impl pallet_remark::Config for Runtime { type WeightInfo = pallet_remark::weights::SubstrateWeight; type RuntimeEvent = RuntimeEvent; @@ -1027,6 +1055,7 @@ impl pallet_gated_marketplace::Config for Runtime { type Timestamp = Timestamp; type Moment = Moment; type Rbac = RBAC; + type MappedAssets = MappedAssets; } parameter_types! { @@ -1114,6 +1143,7 @@ construct_runtime!( GatedMarketplace: pallet_gated_marketplace::{Pallet, Call, Storage, Event} = 154, RBAC: pallet_rbac::{Pallet, Call, Storage, Event} = 155, ConfidentialDocs: pallet_confidential_docs::{Pallet, Call, Storage, Event} = 156, + MappedAssets: pallet_mapped_assets::{Pallet, Call, Storage, Event} = 157, } ); diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 30f050d5..a1925a92 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -676,6 +676,7 @@ impl pallet_gated_marketplace::Config for Runtime { type Timestamp = Timestamp; type Moment = Moment; type Rbac = RBAC; + type MappedAssets = MappedAssets; } parameter_types! { @@ -762,7 +763,6 @@ impl pallet_mapped_assets::Config for Runtime { type CallbackHandle = DefaultCallback; } - parameter_types! { pub const MaxScopesPerPallet: u32 = 1000; pub const MaxRolesPerPallet: u32 = 50; From a09b4cf38d40c51f98205b6f18c3e71f88ba3da4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Y=C3=A1=C3=B1ez?= Date: Tue, 25 Apr 2023 19:56:05 -0600 Subject: [PATCH 2/2] GM: replaces currency usage with MappedAssets --- pallets/gated-marketplace/src/functions.rs | 31 +++++++++++++++------- pallets/gated-marketplace/src/lib.rs | 18 ++++++++----- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/pallets/gated-marketplace/src/functions.rs b/pallets/gated-marketplace/src/functions.rs index 79397453..d62e8afd 100644 --- a/pallets/gated-marketplace/src/functions.rs +++ b/pallets/gated-marketplace/src/functions.rs @@ -2,6 +2,7 @@ use super::*; use crate::types::*; use frame_support::pallet_prelude::*; use frame_support::sp_io::hashing::blake2_256; +use frame_support::traits::tokens::AssetId; use pallet_rbac::types::*; use scale_info::prelude::vec; // vec![] macro use sp_runtime::sp_std::vec::Vec; // vec primitive @@ -426,8 +427,8 @@ impl Pallet { //ensure user has enough balance to create the offer // TODO: find a way to get users total asset balance - let total_user_balance = T::Currency::total_balance(&authority); - ensure!(total_user_balance >= price, Error::::NotEnoughBalance); + //let total_user_balance = T::Currency::total_balance(&authority); + //ensure!(total_user_balance >= price, Error::::NotEnoughBalance); //ensure the price is valid Self::is_the_offer_valid(price, Permill::from_percent(percentage))?; @@ -510,17 +511,19 @@ impl Pallet { //TODO: Use free_balance instead of total_balance // TODO: find a way to get buyer's total balance //Get the buyer's balance - let total_amount_buyer = T::Currency::total_balance(&buyer); + //let total_amount_buyer = T::Currency::total_balance(&buyer); //ensure the buyer has enough balance to buy the item - ensure!(total_amount_buyer > offer_data.price, Error::::NotEnoughBalance); + //ensure!(total_amount_buyer > offer_data.price, Error::::NotEnoughBalance); let marketplace = >::get(offer_data.marketplace_id).ok_or(Error::::OfferNotFound)?; let owners_cut: BalanceOf = offer_data.price - offer_data.fee; //Transfer the balance // TODO: replace transfer for T::MappedAssets::transfer(...); - T::Currency::transfer(&buyer, &owner_item, owners_cut, KeepAlive)?; - T::Currency::transfer(&buyer, &marketplace.creator, offer_data.fee, KeepAlive)?; + T::MappedAssets::transfer(1.into(), &buyer, &owner_item, owners_cut, true)?; + //T::Currency::transfer(&buyer, &owner_item, owners_cut, KeepAlive)?; + T::MappedAssets::transfer(1.into(), &buyer, &marketplace.creator, offer_data.fee, true)?; + //T::Currency::transfer(&buyer, &marketplace.creator, offer_data.fee, KeepAlive)?; pallet_fruniques::Pallet::::do_thaw(&offer_data.collection_id, offer_data.item_id)?; if offer_data.percentage == Permill::from_percent(100) { @@ -605,22 +608,32 @@ impl Pallet { //TODO: Use free_balance instead of total_balance // TODO: find a way to get users's total balance //Get the buyer's balance - let total_amount_buyer = T::Currency::total_balance(&offer_data.creator); + //let total_amount_buyer = T::Currency::total_balance(&offer_data.creator); //ensure the buy_offer_creator has enough balance to buy the item - ensure!(total_amount_buyer > offer_data.price, Error::::NotEnoughBalance); + //ensure!(total_amount_buyer > offer_data.price, Error::::NotEnoughBalance); let marketplace = >::get(offer_data.marketplace_id).ok_or(Error::::OfferNotFound)?; let owners_cut: BalanceOf = offer_data.price - offer_data.fee; //Transfer the balance to the owner of the item // TODO: replace transfer for T::MappedAssets::transfer(...); - T::Currency::transfer(&offer_data.creator, &owner_item, owners_cut, KeepAlive)?; + T::MappedAssets::transfer(1.into(), &offer_data.creator, &owner_item, owners_cut, true)?; + //T::Currency::transfer(&offer_data.creator, &owner_item, owners_cut, KeepAlive)?; + T::MappedAssets::transfer( + 1.into(), + &offer_data.creator, + &marketplace.creator, + offer_data.fee, + true, + )?; + /* T::Currency::transfer( &offer_data.creator, &marketplace.creator, offer_data.fee, KeepAlive, )?; + */ pallet_fruniques::Pallet::::do_thaw(&offer_data.collection_id, offer_data.item_id)?; if offer_data.percentage == Permill::from_percent(100) { diff --git a/pallets/gated-marketplace/src/lib.rs b/pallets/gated-marketplace/src/lib.rs index 63c2b6b9..d888b2f2 100644 --- a/pallets/gated-marketplace/src/lib.rs +++ b/pallets/gated-marketplace/src/lib.rs @@ -14,7 +14,10 @@ pub mod types; #[frame_support::pallet] pub mod pallet { use frame_support::pallet_prelude::*; - use frame_support::traits::{tokens::fungibles::Transfer, Currency, Time}; + use frame_support::traits::{ + tokens::fungibles::{Inspect, Transfer}, + Currency, Time, + }; use frame_system::pallet_prelude::*; use sp_runtime::traits::Scale; use sp_runtime::Permill; @@ -23,12 +26,12 @@ pub mod pallet { use crate::types::*; use pallet_rbac::types::RoleBasedAccessControl; - - pub type BalanceOf = <::Currency as Currency< - ::AccountId, - >>::Balance; + //pub type BalanceOf = <::Currency as Currency< + // ::AccountId, + //>>::Balance; // TODO: replace BalanceOf with the mapped assets one - pub type BalanceOf2 = >::Balance; + pub type BalanceOf = + <::MappedAssets as Inspect<::AccountId>>::Balance; #[pallet::config] pub trait Config: frame_system::Config + pallet_fruniques::Config { @@ -71,7 +74,8 @@ pub mod pallet { type MaxBlockedUsersPerMarket: Get; type Rbac: RoleBasedAccessControl; - type MappedAssets: Transfer; + + type MappedAssets: Transfer + Inspect; } #[pallet::pallet]