diff --git a/substrate/frame/nfts/src/lib.rs b/substrate/frame/nfts/src/lib.rs index 1a068b95e2..052a017f67 100644 --- a/substrate/frame/nfts/src/lib.rs +++ b/substrate/frame/nfts/src/lib.rs @@ -636,6 +636,8 @@ pub mod pallet { WrongNamespace, /// Can't delete non-empty collections. CollectionNotEmpty, + /// The witness data should be provided. + WitnessRequired, } #[pallet::call] @@ -771,7 +773,8 @@ pub mod pallet { /// - `item`: An identifier of the new item. /// - `mint_to`: Account into which the item will be minted. /// - `witness_data`: When the mint type is `HolderOf(collection_id)`, then the owned - /// item_id from that collection needs to be provided within the witness data object. + /// item_id from that collection needs to be provided within the witness data object. If + /// the mint price is set, then it should be additionally confirmed in the `witness_data`. /// /// Note: the deposit will be taken from the `origin` and not the `owner` of the `item`. /// @@ -785,7 +788,7 @@ pub mod pallet { collection: T::CollectionId, item: T::ItemId, mint_to: AccountIdLookupOf, - witness_data: Option>, + witness_data: Option>>, ) -> DispatchResult { let caller = ensure_signed(origin)?; let mint_to = T::Lookup::lookup(mint_to)?; @@ -817,8 +820,8 @@ pub mod pallet { ); }, MintType::HolderOf(collection_id) => { - let MintWitness { owned_item } = - witness_data.ok_or(Error::::BadWitness)?; + let MintWitness { owned_item, .. } = + witness_data.clone().ok_or(Error::::WitnessRequired)?; let owns_item = Account::::contains_key(( &caller, @@ -858,6 +861,10 @@ pub mod pallet { } if let Some(price) = mint_settings.price { + let MintWitness { mint_price, .. } = + witness_data.clone().ok_or(Error::::WitnessRequired)?; + let mint_price = mint_price.ok_or(Error::::BadWitness)?; + ensure!(mint_price >= price, Error::::BadWitness); T::Currency::transfer( &caller, &collection_details.owner, diff --git a/substrate/frame/nfts/src/tests.rs b/substrate/frame/nfts/src/tests.rs index 55bcf57e8a..4df57cb132 100644 --- a/substrate/frame/nfts/src/tests.rs +++ b/substrate/frame/nfts/src/tests.rs @@ -369,7 +369,37 @@ fn mint_should_work() { MintSettings { mint_type: MintType::Public, price: Some(1), ..Default::default() } )); Balances::make_free_balance_be(&account(2), 100); - assert_ok!(Nfts::mint(RuntimeOrigin::signed(account(2)), 0, 43, account(2), None)); + assert_noop!( + Nfts::mint(RuntimeOrigin::signed(account(2)), 0, 43, account(2), None,), + Error::::WitnessRequired + ); + assert_noop!( + Nfts::mint( + RuntimeOrigin::signed(account(2)), + 0, + 43, + account(2), + Some(MintWitness { ..Default::default() }) + ), + Error::::BadWitness + ); + assert_noop!( + Nfts::mint( + RuntimeOrigin::signed(account(2)), + 0, + 43, + account(2), + Some(MintWitness { mint_price: Some(0), ..Default::default() }) + ), + Error::::BadWitness + ); + assert_ok!(Nfts::mint( + RuntimeOrigin::signed(account(2)), + 0, + 43, + account(2), + Some(MintWitness { mint_price: Some(1), ..Default::default() }) + )); assert_eq!(Balances::total_balance(&account(2)), 99); // validate types @@ -385,11 +415,11 @@ fn mint_should_work() { )); assert_noop!( Nfts::mint(RuntimeOrigin::signed(account(3)), 1, 42, account(3), None), - Error::::BadWitness + Error::::WitnessRequired ); assert_noop!( Nfts::mint(RuntimeOrigin::signed(account(2)), 1, 42, account(2), None), - Error::::BadWitness + Error::::WitnessRequired ); assert_noop!( Nfts::mint( @@ -397,7 +427,7 @@ fn mint_should_work() { 1, 42, account(2), - Some(MintWitness { owned_item: 42 }) + Some(MintWitness { owned_item: 42, ..Default::default() }) ), Error::::BadWitness ); @@ -406,7 +436,7 @@ fn mint_should_work() { 1, 42, account(2), - Some(MintWitness { owned_item: 43 }) + Some(MintWitness { owned_item: 43, ..Default::default() }) )); // can't mint twice @@ -416,7 +446,7 @@ fn mint_should_work() { 1, 46, account(2), - Some(MintWitness { owned_item: 43 }) + Some(MintWitness { owned_item: 43, ..Default::default() }) ), Error::::AlreadyClaimed ); diff --git a/substrate/frame/nfts/src/types.rs b/substrate/frame/nfts/src/types.rs index bea1eca1f4..fe64879223 100644 --- a/substrate/frame/nfts/src/types.rs +++ b/substrate/frame/nfts/src/types.rs @@ -124,10 +124,12 @@ impl CollectionDetails { } /// Witness data for items mint transactions. -#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] -pub struct MintWitness { +#[derive(Clone, Encode, Decode, Default, Eq, PartialEq, RuntimeDebug, TypeInfo)] +pub struct MintWitness { /// Provide the id of the item in a required collection. pub owned_item: ItemId, + /// The price specified in mint settings. + pub mint_price: Option, } /// Information concerning the ownership of a single unique item.