git.delta.rocks / unique-network / refs/commits / f0ad1b02de6f

difftreelog

refac: incapsulate CollectionHandler into CollectionDispatch

Trubnikov Sergey2023-04-24parent: #361b516.patch.diff
in: master

13 files changed

modifiedpallets/balances-adapter/src/lib.rsdiffbeforeafterboth
--- a/pallets/balances-adapter/src/lib.rs
+++ b/pallets/balances-adapter/src/lib.rs
@@ -3,6 +3,7 @@
 #![warn(missing_docs)]
 
 extern crate alloc;
+use frame_support::sp_runtime::DispatchResult;
 pub use pallet::*;
 use pallet_common::CollectionHandle;
 use pallet_evm_coder_substrate::{WithRecorder, SubstrateRecorder};
@@ -10,24 +11,23 @@
 pub mod common;
 pub mod erc;
 
-pub struct NativeFungibleHandle<T: Config>(CollectionHandle<T>);
+pub struct NativeFungibleHandle<T: Config>(SubstrateRecorder<T>);
 impl<T: Config> NativeFungibleHandle<T> {
-	pub fn cast(inner: CollectionHandle<T>) -> Self {
-		Self(inner)
+	pub fn new() -> NativeFungibleHandle<T> {
+		Self(SubstrateRecorder::new(u64::MAX))
 	}
 
-	/// Casts [`NativeFungibleHandle`] into [`CollectionHandle`][`pallet_common::CollectionHandle`].
-	pub fn into_inner(self) -> pallet_common::CollectionHandle<T> {
-		self.0
+	pub fn check_is_internal(&self) -> DispatchResult {
+		Ok(())
 	}
 }
 
 impl<T: Config> WithRecorder<T> for NativeFungibleHandle<T> {
 	fn recorder(&self) -> &pallet_evm_coder_substrate::SubstrateRecorder<T> {
-		&self.0.recorder
+		&self.0
 	}
 	fn into_recorder(self) -> pallet_evm_coder_substrate::SubstrateRecorder<T> {
-		self.0.recorder
+		self.0
 	}
 }
 #[frame_support::pallet]
modifiedpallets/common/src/dispatch.rsdiffbeforeafterboth
--- a/pallets/common/src/dispatch.rs
+++ b/pallets/common/src/dispatch.rs
@@ -34,16 +34,11 @@
 	collection: CollectionId,
 	call: C,
 ) -> DispatchResultWithPostInfo {
-	let handle =
-		CollectionHandle::try_get(collection).map_err(|error| DispatchErrorWithPostInfo {
-			post_info: PostDispatchInfo {
-				actual_weight: Some(dispatch_weight::<T>()),
-				pays_fee: Pays::Yes,
-			},
-			error,
-		})?;
-	handle
-		.check_is_internal()
+	let dispatched = T::CollectionDispatch::dispatch(collection)
+		.and_then(|dispatched| {
+			dispatched.check_is_internal()?;
+			Ok(dispatched)
+		})
 		.map_err(|error| DispatchErrorWithPostInfo {
 			post_info: PostDispatchInfo {
 				actual_weight: Some(dispatch_weight::<T>()),
@@ -51,7 +46,6 @@
 			},
 			error,
 		})?;
-	let dispatched = T::CollectionDispatch::dispatch(handle);
 	let mut result = call(dispatched.as_dyn());
 	match &mut result {
 		Ok(PostDispatchInfo {
@@ -72,6 +66,8 @@
 
 /// Interface for working with different collections through the dispatcher.
 pub trait CollectionDispatch<T: Config> {
+	fn check_is_internal(&self) -> DispatchResult;
+
 	/// Create a collection. The collection will be created according to the value of [`data.mode`](CreateCollectionData::mode).
 	///
 	/// * `sender` - The user who will become the owner of the collection.
@@ -92,7 +88,9 @@
 	/// Get a specialized collection from the handle.
 	///
 	/// * `handle` - Collection handle.
-	fn dispatch(handle: CollectionHandle<T>) -> Self;
+	fn dispatch(collection_id: CollectionId) -> Result<Self, DispatchError>
+	where
+		Self: Sized;
 
 	/// Get the implementation of [`CommonCollectionOperations`].
 	fn as_dyn(&self) -> &dyn CommonCollectionOperations<T>;
modifiedpallets/common/src/erc.rsdiffbeforeafterboth
--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -77,6 +77,14 @@
 	fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult>;
 }
 
+impl CommonEvmHandler for () {
+	const CODE: &'static [u8] = &[];
+
+	fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {
+		None
+	}
+}
+
 /// @title A contract that allows you to work with collections.
 #[solidity_interface(name = Collection, enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T: Config> CollectionHandle<T>
modifiedpallets/structure/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/structure/src/benchmarking.rs
+++ b/pallets/structure/src/benchmarking.rs
@@ -42,7 +42,7 @@
 			},
 			CollectionFlags::default(),
 		)?;
-		let dispatch = T::CollectionDispatch::dispatch(CollectionHandle::try_get(CollectionId(1))?);
+		let dispatch = T::CollectionDispatch::dispatch(CollectionId(1))?;
 		let dispatch = dispatch.as_dyn();
 
 		dispatch.create_item(caller_cross.clone(), caller_cross.clone(), CreateItemData::NFT(CreateNftData::default()), &Unlimited)?;
modifiedpallets/structure/src/lib.rsdiffbeforeafterboth
--- a/pallets/structure/src/lib.rs
+++ b/pallets/structure/src/lib.rs
@@ -155,11 +155,10 @@
 		token: TokenId,
 	) -> Result<Parent<T::CrossAccountId>, DispatchError> {
 		// TODO: Reduce cost by not reading collection config
-		let handle = match CollectionHandle::try_get(collection) {
+		let handle = match T::CollectionDispatch::dispatch(collection) {
 			Ok(v) => v,
 			Err(_) => return Ok(Parent::TokenNotFound),
 		};
-		let handle = T::CollectionDispatch::dispatch(handle);
 		let handle = handle.as_dyn();
 
 		Ok(match handle.token_owner(token) {
@@ -279,8 +278,7 @@
 		self_budget: &dyn Budget,
 		breadth_budget: &dyn Budget,
 	) -> DispatchResultWithPostInfo {
-		let handle = <CollectionHandle<T>>::try_get(collection)?;
-		let dispatch = T::CollectionDispatch::dispatch(handle);
+		let dispatch = T::CollectionDispatch::dispatch(collection)?;
 		let dispatch = dispatch.as_dyn();
 		dispatch.burn_item_recursively(from.clone(), token, self_budget, breadth_budget)
 	}
@@ -404,10 +402,8 @@
 		let Some((collection, token)) = T::CrossTokenAddressMapping::address_to_token(account) else {
 			return Ok(())
 		};
-
-		let handle = <CollectionHandle<T>>::try_get(collection)?;
 
-		let dispatch = T::CollectionDispatch::dispatch(handle);
+		let dispatch = T::CollectionDispatch::dispatch(collection)?;
 		let dispatch = dispatch.as_dyn();
 
 		action(dispatch, token)
modifiedruntime/common/dispatch.rsdiffbeforeafterboth
--- a/runtime/common/dispatch.rs
+++ b/runtime/common/dispatch.rs
@@ -50,6 +50,7 @@
 	Refungible(RefungibleHandle<T>),
 	NativeFungible(NativeFungibleHandle<T>),
 }
+
 impl<T> CollectionDispatch<T> for CollectionDispatchT<T>
 where
 	T: pallet_common::Config
@@ -59,6 +60,15 @@
 		+ pallet_refungible::Config
 		+ pallet_balances_adapter::Config,
 {
+	fn check_is_internal(&self) -> DispatchResult {
+		match self {
+			Self::Fungible(h) => h.check_is_internal(),
+			Self::Nonfungible(h) => h.check_is_internal(),
+			Self::Refungible(h) => h.check_is_internal(),
+			Self::NativeFungible(h) => h.check_is_internal(),
+		}
+	}
+
 	fn create(
 		sender: T::CrossAccountId,
 		payer: T::CrossAccountId,
@@ -104,18 +114,17 @@
 		Ok(())
 	}
 
-	fn dispatch(handle: CollectionHandle<T>) -> Self {
-		match handle.mode {
-			CollectionMode::Fungible(_) => {
-				if handle.id != up_data_structs::CollectionId(0) {
-					Self::Fungible(FungibleHandle::cast(handle))
-				} else {
-					Self::NativeFungible(NativeFungibleHandle::cast(handle))
-				}
-			}
+	fn dispatch(collection_id: CollectionId) -> Result<Self, DispatchError> {
+		if collection_id == CollectionId(0) {
+			return Ok(Self::NativeFungible(NativeFungibleHandle::new()));
+		}
+
+		let handle = <CollectionHandle<T>>::try_get(collection_id)?;
+		Ok(match handle.mode {
+			CollectionMode::Fungible(_) => Self::Fungible(FungibleHandle::cast(handle)),
 			CollectionMode::NFT => Self::Nonfungible(NonfungibleHandle::cast(handle)),
 			CollectionMode::ReFungible => Self::Refungible(RefungibleHandle::cast(handle)),
-		}
+		})
 	}
 
 	fn as_dyn(&self) -> &dyn CommonCollectionOperations<T> {
@@ -172,15 +181,19 @@
 	}
 	fn call(handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {
 		if let Some(collection_id) = map_eth_to_id(&handle.code_address()) {
-			let collection =
-				<CollectionHandle<T>>::new_with_gas_limit(collection_id, handle.remaining_gas())?;
-			let dispatched = Self::dispatch(collection);
+			if collection_id == CollectionId(0) {
+				<NativeFungibleHandle<T>>::new().call(handle)
+			} else {
+				let collection = <CollectionHandle<T>>::new_with_gas_limit(
+					collection_id,
+					handle.remaining_gas(),
+				)?;
 
-			match dispatched {
-				Self::Fungible(h) => h.call(handle),
-				Self::Nonfungible(h) => h.call(handle),
-				Self::Refungible(h) => h.call(handle),
-				Self::NativeFungible(h) => h.call(handle),
+				match collection.mode {
+					CollectionMode::Fungible(_) => FungibleHandle::cast(collection).call(handle),
+					CollectionMode::NFT => NonfungibleHandle::cast(collection).call(handle),
+					CollectionMode::ReFungible => RefungibleHandle::cast(collection).call(handle),
+				}
 			}
 		} else if let Some((collection_id, token_id)) =
 			<T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(
modifiedruntime/common/runtime_apis.rsdiffbeforeafterboth
--- a/runtime/common/runtime_apis.rs
+++ b/runtime/common/runtime_apis.rs
@@ -17,7 +17,7 @@
 #[macro_export]
 macro_rules! dispatch_unique_runtime {
 	($collection:ident.$method:ident($($name:ident),*) $($rest:tt)*) => {{
-		let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);
+		let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch($collection)?;
 		let dispatch = collection.as_dyn();
 
 		Ok::<_, DispatchError>(dispatch.$method($($name),*) $($rest)*)
modifiedtests/src/eth/fungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/fungible.test.ts
+++ b/tests/src/eth/fungible.test.ts
@@ -33,7 +33,7 @@
     'substrate' as const,
     'ethereum' as const,
   ].map(testCase => {
-    itEth.only(`Can perform mintCross() for ${testCase} address`, async ({helper}) => {
+    itEth(`Can perform mintCross() for ${testCase} address`, async ({helper}) => {
       // 1. Create receiver depending on the test case:
       const receiverEth = helper.eth.createAccount();
       const receiverCrossEth = helper.ethCrossAccount.fromAddress(receiverEth);
modifiedtests/src/eth/nativeFungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/nativeFungible.test.ts
+++ b/tests/src/eth/nativeFungible.test.ts
@@ -29,7 +29,7 @@
     });
   });
 
-  itEth.only('Can perform approve()', async ({helper}) => {
+  itEth.skip('Can perform approve()', async ({helper}) => {
     const owner = await helper.eth.createAccountWithBalance(donor);
     const spender = helper.eth.createAccount();
     const collection = await helper.ft.mintCollection(alice);
modifiedtests/src/eth/util/playgrounds/types.tsdiffbeforeafterboth
--- a/tests/src/eth/util/playgrounds/types.ts
+++ b/tests/src/eth/util/playgrounds/types.ts
@@ -48,3 +48,5 @@
   field: CollectionLimitField,
   value: OptionUint,
 }
+
+export const NON_EXISTENT_COLLECTION_ID = 4_294_967_295;
\ No newline at end of file
modifiedtests/src/pallet-presence.test.tsdiffbeforeafterboth
--- a/tests/src/pallet-presence.test.ts
+++ b/tests/src/pallet-presence.test.ts
@@ -19,6 +19,7 @@
 // Pallets that must always be present
 const requiredPallets = [
   'balances',
+  'balancesadapter',
   'common',
   'timestamp',
   'transactionpayment',
modifiedtests/src/transfer.test.tsdiffbeforeafterboth
before · tests/src/transfer.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {IKeyringPair} from '@polkadot/types/types';18import {itEth, usingEthPlaygrounds} from './eth/util';19import {itSub, Pallets, usingPlaygrounds, expect} from './util';2021describe('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {22  let donor: IKeyringPair;23  let alice: IKeyringPair;24  let bob: IKeyringPair;2526  before(async () => {27    await usingPlaygrounds(async (helper, privateKey) => {28      donor = await privateKey({url: import.meta.url});29      [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);30    });31  });3233  itSub('Balance transfers and check balance', async ({helper}) => {34    const alicesBalanceBefore = await helper.balance.getSubstrate(alice.address);35    const bobsBalanceBefore = await helper.balance.getSubstrate(bob.address);3637    expect(await helper.balance.transferToSubstrate(alice, bob.address, 1n)).to.be.true;3839    const alicesBalanceAfter = await helper.balance.getSubstrate(alice.address);40    const bobsBalanceAfter = await helper.balance.getSubstrate(bob.address);4142    expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;43    expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;44  });4546  itSub('Inability to pay fees error message is correct', async ({helper}) => {47    const [zero] = await helper.arrange.createAccounts([0n], donor);4849    // console.error = () => {};50    // The following operation throws an error into the console and the logs. Pay it no heed as long as the test succeeds.51    await expect(helper.balance.transferToSubstrate(zero, donor.address, 1n))52      .to.be.rejectedWith('Inability to pay some fees , e.g. account balance too low');53  });5455  itSub('[nft] User can transfer owned token', async ({helper}) => {56    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-1-NFT', description: '', tokenPrefix: 'T'});57    const nft = await collection.mintToken(alice);5859    await nft.transfer(alice, {Substrate: bob.address});60    expect(await nft.getOwner()).to.be.deep.equal({Substrate: bob.address});61  });6263  itSub('[fungible] User can transfer owned token', async ({helper}) => {64    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-1-FT', description: '', tokenPrefix: 'T'});65    await collection.mint(alice, 10n);6667    await collection.transfer(alice, {Substrate: bob.address}, 9n);68    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(9n);69    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);70  });7172  itSub.ifWithPallets('[refungible] User can transfer owned token', [Pallets.ReFungible], async ({helper}) => {73    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});74    const rft = await collection.mintToken(alice, 10n);7576    await rft.transfer(alice, {Substrate: bob.address}, 9n);77    expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(9n);78    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(1n);79  });8081  itSub('[nft] Collection admin can transfer owned token', async ({helper}) => {82    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-2-NFT', description: '', tokenPrefix: 'T'});83    await collection.addAdmin(alice, {Substrate: bob.address});8485    const nft = await collection.mintToken(bob, {Substrate: bob.address});86    await nft.transfer(bob, {Substrate: alice.address});8788    expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});89  });9091  itSub('[fungible] Collection admin can transfer owned token', async ({helper}) => {92    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-2-FT', description: '', tokenPrefix: 'T'});93    await collection.addAdmin(alice, {Substrate: bob.address});9495    await collection.mint(bob, 10n, {Substrate: bob.address});96    await collection.transfer(bob, {Substrate: alice.address}, 1n);9798    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(9n);99    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);100  });101102  itSub.ifWithPallets('[refungible] Collection admin can transfer owned token', [Pallets.ReFungible], async ({helper}) => {103    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-2-RFT', description: '', tokenPrefix: 'T'});104    await collection.addAdmin(alice, {Substrate: bob.address});105106    const rft = await collection.mintToken(bob, 10n, {Substrate: bob.address});107    await rft.transfer(bob, {Substrate: alice.address}, 1n);108109    expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(9n);110    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(1n);111  });112});113114describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {115  let alice: IKeyringPair;116  let bob: IKeyringPair;117118  before(async () => {119    await usingPlaygrounds(async (helper, privateKey) => {120      const donor = await privateKey({url: import.meta.url});121      [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);122    });123  });124125126  itSub('[nft] Transfer with not existed collection_id', async ({helper}) => {127    const collectionId = (1 << 32) - 1;128    await expect(helper.nft.transferToken(alice, collectionId, 1, {Substrate: bob.address}))129      .to.be.rejectedWith(/common\.CollectionNotFound/);130  });131132  itSub('[fungible] Transfer with not existed collection_id', async ({helper}) => {133    const collectionId = (1 << 32) - 1;134    await expect(helper.ft.transfer(alice, collectionId, {Substrate: bob.address}))135      .to.be.rejectedWith(/common\.CollectionNotFound/);136  });137138  itSub.ifWithPallets('[refungible] Transfer with not existed collection_id', [Pallets.ReFungible], async ({helper}) => {139    const collectionId = (1 << 32) - 1;140    await expect(helper.rft.transferToken(alice, collectionId, 1, {Substrate: bob.address}))141      .to.be.rejectedWith(/common\.CollectionNotFound/);142  });143144  itSub('[nft] Transfer with deleted collection_id', async ({helper}) => {145    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-1-NFT', description: '', tokenPrefix: 'T'});146    const nft = await collection.mintToken(alice);147148    await nft.burn(alice);149    await collection.burn(alice);150151    await expect(nft.transfer(alice, {Substrate: bob.address}))152      .to.be.rejectedWith(/common\.CollectionNotFound/);153  });154155  itSub('[fungible] Transfer with deleted collection_id', async ({helper}) => {156    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-1-FT', description: '', tokenPrefix: 'T'});157    await collection.mint(alice, 10n);158159    await collection.burnTokens(alice, 10n);160    await collection.burn(alice);161162    await expect(collection.transfer(alice, {Substrate: bob.address}))163      .to.be.rejectedWith(/common\.CollectionNotFound/);164  });165166  itSub.ifWithPallets('[refungible] Transfer with deleted collection_id', [Pallets.ReFungible], async ({helper}) => {167    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-1-RFT', description: '', tokenPrefix: 'T'});168    const rft = await collection.mintToken(alice, 10n);169170    await rft.burn(alice, 10n);171    await collection.burn(alice);172173    await expect(rft.transfer(alice, {Substrate: bob.address}))174      .to.be.rejectedWith(/common\.CollectionNotFound/);175  });176177  itSub('[nft] Transfer with not existed item_id', async ({helper}) => {178    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-2-NFT', description: '', tokenPrefix: 'T'});179    await expect(collection.transferToken(alice, 1, {Substrate: bob.address}))180      .to.be.rejectedWith(/common\.TokenNotFound/);181  });182183  itSub('[fungible] Transfer with not existed item_id', async ({helper}) => {184    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-2-FT', description: '', tokenPrefix: 'T'});185    await expect(collection.transfer(alice, {Substrate: bob.address}))186      .to.be.rejectedWith(/common\.TokenValueTooLow/);187  });188189  itSub.ifWithPallets('[refungible] Transfer with not existed item_id', [Pallets.ReFungible], async ({helper}) => {190    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-2-RFT', description: '', tokenPrefix: 'T'});191    await expect(collection.transferToken(alice, 1, {Substrate: bob.address}))192      .to.be.rejectedWith(/common\.TokenValueTooLow/);193  });194195  itSub('Zero transfer NFT', async ({helper}) => {196    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-3-NFT', description: '', tokenPrefix: 'T'});197    const tokenAlice = await collection.mintToken(alice, {Substrate: alice.address});198    const tokenBob = await collection.mintToken(alice, {Substrate: bob.address});199    // 1. Zero transfer of own tokens allowed:200    await helper.executeExtrinsic(alice, 'api.tx.unique.transfer', [{Substrate: bob.address}, collection.collectionId, tokenAlice.tokenId, 0]);201    // 2. Zero transfer of non-owned tokens not allowed:202    await expect(helper.executeExtrinsic(alice, 'api.tx.unique.transfer', [{Substrate: alice.address}, collection.collectionId, tokenBob.tokenId, 0])).to.be.rejectedWith('common.NoPermission');203    // 3. Zero transfer of non-existing tokens not allowed:204    await expect(helper.executeExtrinsic(alice, 'api.tx.unique.transfer', [{Substrate: alice.address}, collection.collectionId, 10, 0])).to.be.rejectedWith('common.TokenNotFound');205    expect(await tokenAlice.getOwner()).to.deep.eq({Substrate: alice.address});206    expect(await tokenBob.getOwner()).to.deep.eq({Substrate: bob.address});207    // 4. Storage is not corrupted:208    await tokenAlice.transfer(alice, {Substrate: bob.address});209    await tokenBob.transfer(bob, {Substrate: alice.address});210    expect(await tokenAlice.getOwner()).to.deep.eq({Substrate: bob.address});211    expect(await tokenBob.getOwner()).to.deep.eq({Substrate: alice.address});212  });213214  itSub('[nft] Transfer with deleted item_id', async ({helper}) => {215    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-3-NFT', description: '', tokenPrefix: 'T'});216    const nft = await collection.mintToken(alice);217218    await nft.burn(alice);219220    await expect(nft.transfer(alice, {Substrate: bob.address}))221      .to.be.rejectedWith(/common\.TokenNotFound/);222  });223224  itSub('[fungible] Transfer with deleted item_id', async ({helper}) => {225    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-3-FT', description: '', tokenPrefix: 'T'});226    await collection.mint(alice, 10n);227228    await collection.burnTokens(alice, 10n);229230    await expect(collection.transfer(alice, {Substrate: bob.address}))231      .to.be.rejectedWith(/common\.TokenValueTooLow/);232  });233234  itSub.ifWithPallets('[refungible] Transfer with deleted item_id', [Pallets.ReFungible], async ({helper}) => {235    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-3-RFT', description: '', tokenPrefix: 'T'});236    const rft = await collection.mintToken(alice, 10n);237238    await rft.burn(alice, 10n);239240    await expect(rft.transfer(alice, {Substrate: bob.address}))241      .to.be.rejectedWith(/common\.TokenValueTooLow/);242  });243244  itSub('[nft] Transfer with recipient that is not owner', async ({helper}) => {245    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-4-NFT', description: '', tokenPrefix: 'T'});246    const nft = await collection.mintToken(alice);247248    await expect(nft.transfer(bob, {Substrate: bob.address}))249      .to.be.rejectedWith(/common\.NoPermission/);250    expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});251  });252253  itSub('[fungible] Transfer with recipient that is not owner', async ({helper}) => {254    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-4-FT', description: '', tokenPrefix: 'T'});255    await collection.mint(alice, 10n);256257    await expect(collection.transfer(bob, {Substrate: bob.address}, 9n))258      .to.be.rejectedWith(/common\.TokenValueTooLow/);259    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(0n);260    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(10n);261  });262263  itSub.ifWithPallets('[refungible] Transfer with recipient that is not owner', [Pallets.ReFungible], async ({helper}) => {264    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});265    const rft = await collection.mintToken(alice, 10n);266267    await expect(rft.transfer(bob, {Substrate: bob.address}, 9n))268      .to.be.rejectedWith(/common\.TokenValueTooLow/);269    expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(0n);270    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(10n);271  });272});273274describe('Transfers to self (potentially over substrate-evm boundary)', () => {275  let donor: IKeyringPair;276277  before(async function() {278    await usingEthPlaygrounds(async (_, privateKey) => {279      donor = await privateKey({url: import.meta.url});280    });281  });282283  itEth('Transfers to self. In case of same frontend', async ({helper}) => {284    const [owner] = await helper.arrange.createAccounts([10n], donor);285    const collection = await helper.ft.mintCollection(owner, {});286    await collection.mint(owner, 100n);287288    const ownerProxy = helper.address.substrateToEth(owner.address);289290    // transfer to own proxy291    await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);292    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);293    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);294295    // transfer-from own proxy to own proxy again296    await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Ethereum: ownerProxy}, 5n);297    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);298    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);299  });300301  itEth('Transfers to self. In case of substrate-evm boundary', async ({helper}) => {302    const [owner] = await helper.arrange.createAccounts([10n], donor);303    const collection = await helper.ft.mintCollection(owner, {});304    await collection.mint(owner, 100n);305306    const ownerProxy = helper.address.substrateToEth(owner.address);307308    // transfer to own proxy309    await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);310    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);311    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);312313    // transfer-from own proxy to self314    await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Substrate: owner.address}, 5n);315    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(95n);316    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(5n);317  });318319  itEth('Transfers to self. In case of inside substrate-evm', async ({helper}) => {320    const [owner] = await helper.arrange.createAccounts([10n], donor);321    const collection = await helper.ft.mintCollection(owner, {});322    await collection.mint(owner, 100n);323324    // transfer to self again325    await collection.transfer(owner, {Substrate: owner.address}, 10n);326    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);327328    // transfer-from self to self again329    await collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 5n);330    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);331  });332333  itEth('Transfers to self. In case of inside substrate-evm when not enought "Fungibles"', async ({helper}) => {334    const [owner] = await helper.arrange.createAccounts([10n], donor);335    const collection = await helper.ft.mintCollection(owner, {});336    await collection.mint(owner, 10n);337338    // transfer to self again339    await expect(collection.transfer(owner, {Substrate: owner.address}, 11n))340      .to.be.rejectedWith(/common\.TokenValueTooLow/);341342    // transfer-from self to self again343    await expect(collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 12n))344      .to.be.rejectedWith(/common\.TokenValueTooLow/);345    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(10n);346  });347});
after · tests/src/transfer.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {IKeyringPair} from '@polkadot/types/types';18import {itEth, usingEthPlaygrounds} from './eth/util';19import {itSub, Pallets, usingPlaygrounds, expect} from './util';20import {NON_EXISTENT_COLLECTION_ID} from './eth/util/playgrounds/types';2122describe('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {23  let donor: IKeyringPair;24  let alice: IKeyringPair;25  let bob: IKeyringPair;2627  before(async () => {28    await usingPlaygrounds(async (helper, privateKey) => {29      donor = await privateKey({url: import.meta.url});30      [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);31    });32  });3334  itSub('Balance transfers and check balance', async ({helper}) => {35    const alicesBalanceBefore = await helper.balance.getSubstrate(alice.address);36    const bobsBalanceBefore = await helper.balance.getSubstrate(bob.address);3738    expect(await helper.balance.transferToSubstrate(alice, bob.address, 1n)).to.be.true;3940    const alicesBalanceAfter = await helper.balance.getSubstrate(alice.address);41    const bobsBalanceAfter = await helper.balance.getSubstrate(bob.address);4243    expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;44    expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;45  });4647  itSub('Inability to pay fees error message is correct', async ({helper}) => {48    const [zero] = await helper.arrange.createAccounts([0n], donor);4950    // console.error = () => {};51    // The following operation throws an error into the console and the logs. Pay it no heed as long as the test succeeds.52    await expect(helper.balance.transferToSubstrate(zero, donor.address, 1n))53      .to.be.rejectedWith('Inability to pay some fees , e.g. account balance too low');54  });5556  itSub('[nft] User can transfer owned token', async ({helper}) => {57    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-1-NFT', description: '', tokenPrefix: 'T'});58    const nft = await collection.mintToken(alice);5960    await nft.transfer(alice, {Substrate: bob.address});61    expect(await nft.getOwner()).to.be.deep.equal({Substrate: bob.address});62  });6364  itSub('[fungible] User can transfer owned token', async ({helper}) => {65    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-1-FT', description: '', tokenPrefix: 'T'});66    await collection.mint(alice, 10n);6768    await collection.transfer(alice, {Substrate: bob.address}, 9n);69    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(9n);70    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);71  });7273  itSub.ifWithPallets('[refungible] User can transfer owned token', [Pallets.ReFungible], async ({helper}) => {74    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});75    const rft = await collection.mintToken(alice, 10n);7677    await rft.transfer(alice, {Substrate: bob.address}, 9n);78    expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(9n);79    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(1n);80  });8182  itSub('[nft] Collection admin can transfer owned token', async ({helper}) => {83    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-2-NFT', description: '', tokenPrefix: 'T'});84    await collection.addAdmin(alice, {Substrate: bob.address});8586    const nft = await collection.mintToken(bob, {Substrate: bob.address});87    await nft.transfer(bob, {Substrate: alice.address});8889    expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});90  });9192  itSub('[fungible] Collection admin can transfer owned token', async ({helper}) => {93    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-2-FT', description: '', tokenPrefix: 'T'});94    await collection.addAdmin(alice, {Substrate: bob.address});9596    await collection.mint(bob, 10n, {Substrate: bob.address});97    await collection.transfer(bob, {Substrate: alice.address}, 1n);9899    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(9n);100    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);101  });102103  itSub.ifWithPallets('[refungible] Collection admin can transfer owned token', [Pallets.ReFungible], async ({helper}) => {104    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-2-RFT', description: '', tokenPrefix: 'T'});105    await collection.addAdmin(alice, {Substrate: bob.address});106107    const rft = await collection.mintToken(bob, 10n, {Substrate: bob.address});108    await rft.transfer(bob, {Substrate: alice.address}, 1n);109110    expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(9n);111    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(1n);112  });113});114115describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {116  let alice: IKeyringPair;117  let bob: IKeyringPair;118119  before(async () => {120    await usingPlaygrounds(async (helper, privateKey) => {121      const donor = await privateKey({url: import.meta.url});122      [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);123    });124  });125126127  itSub('[nft] Transfer with not existed collection_id', async ({helper}) => {128    await expect(helper.nft.transferToken(alice, NON_EXISTENT_COLLECTION_ID, 1, {Substrate: bob.address}))129      .to.be.rejectedWith(/common\.CollectionNotFound/);130  });131132  itSub('[fungible] Transfer with not existed collection_id', async ({helper}) => {133    await expect(helper.ft.transfer(alice, NON_EXISTENT_COLLECTION_ID, {Substrate: bob.address}))134      .to.be.rejectedWith(/common\.CollectionNotFound/);135  });136137  itSub.ifWithPallets('[refungible] Transfer with not existed collection_id', [Pallets.ReFungible], async ({helper}) => {138    await expect(helper.rft.transferToken(alice, NON_EXISTENT_COLLECTION_ID, 1, {Substrate: bob.address}))139      .to.be.rejectedWith(/common\.CollectionNotFound/);140  });141142  itSub('[nft] Transfer with deleted collection_id', async ({helper}) => {143    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-1-NFT', description: '', tokenPrefix: 'T'});144    const nft = await collection.mintToken(alice);145146    await nft.burn(alice);147    await collection.burn(alice);148149    await expect(nft.transfer(alice, {Substrate: bob.address}))150      .to.be.rejectedWith(/common\.CollectionNotFound/);151  });152153  itSub('[fungible] Transfer with deleted collection_id', async ({helper}) => {154    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-1-FT', description: '', tokenPrefix: 'T'});155    await collection.mint(alice, 10n);156157    await collection.burnTokens(alice, 10n);158    await collection.burn(alice);159160    await expect(collection.transfer(alice, {Substrate: bob.address}))161      .to.be.rejectedWith(/common\.CollectionNotFound/);162  });163164  itSub.ifWithPallets('[refungible] Transfer with deleted collection_id', [Pallets.ReFungible], async ({helper}) => {165    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-1-RFT', description: '', tokenPrefix: 'T'});166    const rft = await collection.mintToken(alice, 10n);167168    await rft.burn(alice, 10n);169    await collection.burn(alice);170171    await expect(rft.transfer(alice, {Substrate: bob.address}))172      .to.be.rejectedWith(/common\.CollectionNotFound/);173  });174175  itSub('[nft] Transfer with not existed item_id', async ({helper}) => {176    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-2-NFT', description: '', tokenPrefix: 'T'});177    await expect(collection.transferToken(alice, 1, {Substrate: bob.address}))178      .to.be.rejectedWith(/common\.TokenNotFound/);179  });180181  itSub('[fungible] Transfer with not existed item_id', async ({helper}) => {182    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-2-FT', description: '', tokenPrefix: 'T'});183    await expect(collection.transfer(alice, {Substrate: bob.address}))184      .to.be.rejectedWith(/common\.TokenValueTooLow/);185  });186187  itSub.ifWithPallets('[refungible] Transfer with not existed item_id', [Pallets.ReFungible], async ({helper}) => {188    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-2-RFT', description: '', tokenPrefix: 'T'});189    await expect(collection.transferToken(alice, 1, {Substrate: bob.address}))190      .to.be.rejectedWith(/common\.TokenValueTooLow/);191  });192193  itSub('Zero transfer NFT', async ({helper}) => {194    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-3-NFT', description: '', tokenPrefix: 'T'});195    const tokenAlice = await collection.mintToken(alice, {Substrate: alice.address});196    const tokenBob = await collection.mintToken(alice, {Substrate: bob.address});197    // 1. Zero transfer of own tokens allowed:198    await helper.executeExtrinsic(alice, 'api.tx.unique.transfer', [{Substrate: bob.address}, collection.collectionId, tokenAlice.tokenId, 0]);199    // 2. Zero transfer of non-owned tokens not allowed:200    await expect(helper.executeExtrinsic(alice, 'api.tx.unique.transfer', [{Substrate: alice.address}, collection.collectionId, tokenBob.tokenId, 0])).to.be.rejectedWith('common.NoPermission');201    // 3. Zero transfer of non-existing tokens not allowed:202    await expect(helper.executeExtrinsic(alice, 'api.tx.unique.transfer', [{Substrate: alice.address}, collection.collectionId, 10, 0])).to.be.rejectedWith('common.TokenNotFound');203    expect(await tokenAlice.getOwner()).to.deep.eq({Substrate: alice.address});204    expect(await tokenBob.getOwner()).to.deep.eq({Substrate: bob.address});205    // 4. Storage is not corrupted:206    await tokenAlice.transfer(alice, {Substrate: bob.address});207    await tokenBob.transfer(bob, {Substrate: alice.address});208    expect(await tokenAlice.getOwner()).to.deep.eq({Substrate: bob.address});209    expect(await tokenBob.getOwner()).to.deep.eq({Substrate: alice.address});210  });211212  itSub('[nft] Transfer with deleted item_id', async ({helper}) => {213    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-3-NFT', description: '', tokenPrefix: 'T'});214    const nft = await collection.mintToken(alice);215216    await nft.burn(alice);217218    await expect(nft.transfer(alice, {Substrate: bob.address}))219      .to.be.rejectedWith(/common\.TokenNotFound/);220  });221222  itSub('[fungible] Transfer with deleted item_id', async ({helper}) => {223    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-3-FT', description: '', tokenPrefix: 'T'});224    await collection.mint(alice, 10n);225226    await collection.burnTokens(alice, 10n);227228    await expect(collection.transfer(alice, {Substrate: bob.address}))229      .to.be.rejectedWith(/common\.TokenValueTooLow/);230  });231232  itSub.ifWithPallets('[refungible] Transfer with deleted item_id', [Pallets.ReFungible], async ({helper}) => {233    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-3-RFT', description: '', tokenPrefix: 'T'});234    const rft = await collection.mintToken(alice, 10n);235236    await rft.burn(alice, 10n);237238    await expect(rft.transfer(alice, {Substrate: bob.address}))239      .to.be.rejectedWith(/common\.TokenValueTooLow/);240  });241242  itSub('[nft] Transfer with recipient that is not owner', async ({helper}) => {243    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-4-NFT', description: '', tokenPrefix: 'T'});244    const nft = await collection.mintToken(alice);245246    await expect(nft.transfer(bob, {Substrate: bob.address}))247      .to.be.rejectedWith(/common\.NoPermission/);248    expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});249  });250251  itSub('[fungible] Transfer with recipient that is not owner', async ({helper}) => {252    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-4-FT', description: '', tokenPrefix: 'T'});253    await collection.mint(alice, 10n);254255    await expect(collection.transfer(bob, {Substrate: bob.address}, 9n))256      .to.be.rejectedWith(/common\.TokenValueTooLow/);257    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(0n);258    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(10n);259  });260261  itSub.ifWithPallets('[refungible] Transfer with recipient that is not owner', [Pallets.ReFungible], async ({helper}) => {262    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});263    const rft = await collection.mintToken(alice, 10n);264265    await expect(rft.transfer(bob, {Substrate: bob.address}, 9n))266      .to.be.rejectedWith(/common\.TokenValueTooLow/);267    expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(0n);268    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(10n);269  });270});271272describe('Transfers to self (potentially over substrate-evm boundary)', () => {273  let donor: IKeyringPair;274275  before(async function() {276    await usingEthPlaygrounds(async (_, privateKey) => {277      donor = await privateKey({url: import.meta.url});278    });279  });280281  itEth('Transfers to self. In case of same frontend', async ({helper}) => {282    const [owner] = await helper.arrange.createAccounts([10n], donor);283    const collection = await helper.ft.mintCollection(owner, {});284    await collection.mint(owner, 100n);285286    const ownerProxy = helper.address.substrateToEth(owner.address);287288    // transfer to own proxy289    await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);290    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);291    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);292293    // transfer-from own proxy to own proxy again294    await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Ethereum: ownerProxy}, 5n);295    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);296    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);297  });298299  itEth('Transfers to self. In case of substrate-evm boundary', async ({helper}) => {300    const [owner] = await helper.arrange.createAccounts([10n], donor);301    const collection = await helper.ft.mintCollection(owner, {});302    await collection.mint(owner, 100n);303304    const ownerProxy = helper.address.substrateToEth(owner.address);305306    // transfer to own proxy307    await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);308    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);309    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);310311    // transfer-from own proxy to self312    await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Substrate: owner.address}, 5n);313    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(95n);314    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(5n);315  });316317  itEth('Transfers to self. In case of inside substrate-evm', async ({helper}) => {318    const [owner] = await helper.arrange.createAccounts([10n], donor);319    const collection = await helper.ft.mintCollection(owner, {});320    await collection.mint(owner, 100n);321322    // transfer to self again323    await collection.transfer(owner, {Substrate: owner.address}, 10n);324    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);325326    // transfer-from self to self again327    await collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 5n);328    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);329  });330331  itEth('Transfers to self. In case of inside substrate-evm when not enought "Fungibles"', async ({helper}) => {332    const [owner] = await helper.arrange.createAccounts([10n], donor);333    const collection = await helper.ft.mintCollection(owner, {});334    await collection.mint(owner, 10n);335336    // transfer to self again337    await expect(collection.transfer(owner, {Substrate: owner.address}, 11n))338      .to.be.rejectedWith(/common\.TokenValueTooLow/);339340    // transfer-from self to self again341    await expect(collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 12n))342      .to.be.rejectedWith(/common\.TokenValueTooLow/);343    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(10n);344  });345});
modifiedtests/src/transferFrom.test.tsdiffbeforeafterboth
--- a/tests/src/transferFrom.test.ts
+++ b/tests/src/transferFrom.test.ts
@@ -16,6 +16,7 @@
 
 import {IKeyringPair} from '@polkadot/types/types';
 import {itSub, Pallets, usingPlaygrounds, expect} from './util';
+import {NON_EXISTENT_COLLECTION_ID} from './eth/util/playgrounds/types';
 
 describe('Integration Test transferFrom(from, recipient, collection_id, item_id, value):', () => {
   let alice: IKeyringPair;
@@ -97,10 +98,9 @@
   });
 
   itSub('transferFrom for a collection that does not exist', async ({helper}) => {
-    const collectionId = (1 << 32) - 1;
-    await expect(helper.collection.approveToken(alice, collectionId, 0, {Substrate: bob.address}, 1n))
+    await expect(helper.collection.approveToken(alice, NON_EXISTENT_COLLECTION_ID, 0, {Substrate: bob.address}, 1n))
       .to.be.rejectedWith(/common\.CollectionNotFound/);
-    await expect(helper.collection.transferTokenFrom(bob, collectionId, 0, {Substrate: alice.address}, {Substrate: bob.address}, 1n))
+    await expect(helper.collection.transferTokenFrom(bob, NON_EXISTENT_COLLECTION_ID, 0, {Substrate: alice.address}, {Substrate: bob.address}, 1n))
       .to.be.rejectedWith(/common\.CollectionNotFound/);
   });