git.delta.rocks / unique-network / refs/commits / 07649f272b8b

difftreelog

Merge pull request #125 from usetech-llc/fix/NFTPAR-367_createMultipleItems_overflow_checks

usetech-llc2021-03-14parents: #447a9ec #a5cb42a.patch.diff
in: master
Fix bulk mint exceeds collection token limit

2 files changed

modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
967967
968 let target_collection = <Collection<T>>::get(collection_id);968 let target_collection = <Collection<T>>::get(collection_id);
969969
970 Self::can_create_items_in_collection(collection_id, &target_collection, &sender, &owner)?;970 Self::can_create_items_in_collection(collection_id, &target_collection, &sender, &owner, 1)?;
971 Self::validate_create_item_args(&target_collection, &data)?;971 Self::validate_create_item_args(&target_collection, &data)?;
972 Self::create_item_no_validation(collection_id, owner, data)?;972 Self::create_item_no_validation(collection_id, owner, data)?;
973973
1003 Self::collection_exists(collection_id)?;1003 Self::collection_exists(collection_id)?;
1004 let target_collection = <Collection<T>>::get(collection_id);1004 let target_collection = <Collection<T>>::get(collection_id);
10051005
1006 Self::can_create_items_in_collection(collection_id, &target_collection, &sender, &owner)?;1006 Self::can_create_items_in_collection(collection_id, &target_collection, &sender, &owner, items_data.len() as u32)?;
10071007
1008 for data in &items_data {1008 for data in &items_data {
1009 Self::validate_create_item_args(&target_collection, data)?;1009 Self::validate_create_item_args(&target_collection, data)?;
1638 Ok(())1638 Ok(())
1639 }1639 }
16401640
1641 fn can_create_items_in_collection(collection_id: CollectionId, collection: &CollectionType<T::AccountId>, sender: &T::AccountId, owner: &T::AccountId) -> DispatchResult {1641 fn can_create_items_in_collection(collection_id: CollectionId, collection: &CollectionType<T::AccountId>, sender: &T::AccountId, owner: &T::AccountId, amount: u32) -> DispatchResult {
16421642
1643 // check token limit and account token limit1643 // check token limit and account token limit
1644 let total_items: u32 = ItemListIndex::get(collection_id);1644 let total_items: u32 = ItemListIndex::get(collection_id)
1645 .checked_add(amount)
1646 .ok_or(Error::<T>::CollectionTokenLimitExceeded)?;
1645 let account_items: u32 = <AddressTokens<T>>::get(collection_id, owner).len() as u32;1647 let account_items: u32 = (<AddressTokens<T>>::get(collection_id, owner).len() as u32)
1648 .checked_add(amount)
1649 .ok_or(Error::<T>::AccountTokenLimitExceeded)?;
1646 ensure!(collection.limits.token_limit > total_items, Error::<T>::CollectionTokenLimitExceeded);1650 ensure!(collection.limits.token_limit >= total_items, Error::<T>::CollectionTokenLimitExceeded);
1647 ensure!(collection.limits.account_token_ownership_limit > account_items, Error::<T>::AccountTokenLimitExceeded);1651 ensure!(collection.limits.account_token_ownership_limit >= account_items, Error::<T>::AccountTokenLimitExceeded);
16481652
1649 if !Self::is_owner_or_admin_permissions(collection_id, sender.clone()) {1653 if !Self::is_owner_or_admin_permissions(collection_id, sender.clone()) {
1650 ensure!(collection.mint_mode == true, Error::<T>::PublicMintingNotAllowed);1654 ensure!(collection.mint_mode == true, Error::<T>::PublicMintingNotAllowed);
modifiedtests/src/createMultipleItems.test.tsdiffbeforeafterboth
--- a/tests/src/createMultipleItems.test.ts
+++ b/tests/src/createMultipleItems.test.ts
@@ -11,7 +11,9 @@
 import {
   createCollectionExpectSuccess,
   destroyCollectionExpectSuccess,
+  getGenericResult,
   IReFungibleTokenDataType,
+  setCollectionLimitsExpectSuccess,
 } from './util/helpers';
 
 chai.use(chaiAsPromised);
@@ -92,6 +94,25 @@
       expect(token3Data.VariableData.toString()).to.be.equal('0x33');
     });
   });
+
+  it('Can mint amount of items equals to collection limits', async () => {
+    await usingApi(async (api) => {
+      const alice = privateKey('//Alice');
+
+      const collectionId = await createCollectionExpectSuccess();
+      await setCollectionLimitsExpectSuccess(alice, collectionId, {
+        TokenLimit: 2,
+      });
+      const args = [
+        { nft: ['A', 'A'] },
+        { nft: ['B', 'B'] },
+      ];
+      const createMultipleItemsTx = api.tx.nft.createMultipleItems(collectionId, alice.address, args);
+      const events = await submitTransactionAsync(alice, createMultipleItemsTx);
+      const result = getGenericResult(events);
+      expect(result.success).to.be.true;
+    });
+  });
 });
 
 describe('Negative Integration Test createMultipleItems(collection_id, owner, items_data):', () => {
@@ -175,4 +196,21 @@
       await expect(submitTransactionExpectFailAsync(Alice, createMultipleItemsTx)).to.be.rejected;
     });
   });
+
+  it('Fails when minting tokens exceeds collectionLimits amount', async () => {
+    await usingApi(async (api) => {
+      const alice = privateKey('//Alice');
+
+      const collectionId = await createCollectionExpectSuccess();
+      await setCollectionLimitsExpectSuccess(alice, collectionId, {
+        TokenLimit: 1,
+      });
+      const args = [
+        { nft: ['A', 'A'] },
+        { nft: ['B', 'B'] },
+      ];
+      const createMultipleItemsTx = api.tx.nft.createMultipleItems(collectionId, alice.address, args);
+      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
+    });
+  });
 });