git.delta.rocks / unique-network / refs/commits / 1c0b76dadcbc

difftreelog

Merge branch 'develop' into chore/fix-warnings

Fahrrader2022-12-23parents: #8371463 #cf483e2.patch.diff
in: master

76 files changed

modified.docker/Dockerfile-try-runtimediffbeforeafterboth
--- a/.docker/Dockerfile-try-runtime
+++ b/.docker/Dockerfile-try-runtime
@@ -46,4 +46,4 @@
     echo "Fork from: $REPLICA_FROM\n" && \
     cargo build --features=try-runtime,${NETWORK}-runtime --release
 
-CMD cargo run --features=try-runtime,${NETWORK}-runtime --release -- try-runtime -ltry-runtime::cli=debug --no-spec-check-panic on-runtime-upgrade live --uri $REPLICA_FROM
+CMD cargo run --release --features ${NETWORK}-runtime,try-runtime -- try-runtime --runtime target/release/wbuild/${NETWORK}-runtime/${NETWORK}_runtime.compact.compressed.wasm -lruntime=debug -ltry-runtime::cli=debug on-runtime-upgrade --checks live --uri $REPLICA_FROM
modified.envdiffbeforeafterboth
--- a/.env
+++ b/.env
@@ -5,19 +5,19 @@
 STATEMINT_BUILD_BRANCH=release-parachains-v9320
 ACALA_BUILD_BRANCH=2.11.0
 MOONBEAM_BUILD_BRANCH=runtime-1901
-UNIQUE_MAINNET_BRANCH=release-v930033
+UNIQUE_MAINNET_BRANCH=release-v930033-fix-gas-price
 UNIQUE_REPLICA_FROM=wss://eu-ws.unique.network:443
 
 KUSAMA_MAINNET_BRANCH=release-v0.9.35
 STATEMINE_BUILD_BRANCH=release-parachains-v9330
 KARURA_BUILD_BRANCH=release-karura-2.11.0
 MOONRIVER_BUILD_BRANCH=runtime-2000
-QUARTZ_MAINNET_BRANCH=release-v930034
+QUARTZ_MAINNET_BRANCH=release-v930034-fix-gas-price
 QUARTZ_REPLICA_FROM=wss://eu-ws-quartz.unique.network:443
 
 UNQWND_MAINNET_BRANCH=release-v0.9.30
 WESTMINT_BUILD_BRANCH=parachains-v9330
-OPAL_MAINNET_BRANCH=release-v930034
+OPAL_MAINNET_BRANCH=release-v930034-fix-gas-price
 OPAL_REPLICA_FROM=wss://eu-ws-opal.unique.network:443
 
 POLKADOT_LAUNCH_BRANCH=unique-network
modified.github/workflows/ci-master.ymldiffbeforeafterboth
--- a/.github/workflows/ci-master.yml
+++ b/.github/workflows/ci-master.yml
@@ -42,3 +42,6 @@
 
   codestyle:
     uses: ./.github/workflows/codestyle.yml
+
+  polkadot-types:
+    uses: ./.github/workflows/polkadot-types.yml
\ No newline at end of file
added.github/workflows/polkadot-types.ymldiffbeforeafterboth
--- /dev/null
+++ b/.github/workflows/polkadot-types.yml
@@ -0,0 +1,96 @@
+# Integration test in --dev mode
+# https://cryptousetech.atlassian.net/wiki/spaces/CI/pages/2586411104/Integration+tests
+name: Polkadot types
+
+# Triger: only call from main workflow(re-usable workflows)
+on:
+  workflow_call:
+  # Allows you to run this workflow manually from the Actions tab
+  workflow_dispatch:
+
+# on:
+#   pull_request:
+#     branches: [ 'develop' ]
+#     types: [ opened, reopened, synchronize, ready_for_review, converted_to_draft ]
+
+
+# A workflow run is made up of one or more jobs that can run sequentially or in parallel
+jobs:
+  
+  polkadot_generate_types:
+    # The type of runner that the job will run on
+    runs-on: [self-hosted-ci,medium]
+    timeout-minutes: 1380
+
+    name: ${{ matrix.network }}
+
+    continue-on-error: true         #Do not stop testing of matrix runs failed.  As it decided during PR review - it required 50/50& Let's check it with false.
+
+    strategy:
+      matrix:
+        include:
+          - network: sapphire
+            usage: "--sapphire"
+          - network: "opal"
+            usage: ""
+          - network: "quartz"
+            usage: ""
+          - network: "unique"
+            usage: ""
+
+    steps:
+
+      - name: Clean Workspace
+        uses: AutoModality/action-clean@v1.1.0
+
+      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
+      - uses: actions/checkout@v3
+        with:
+          ref: ${{ github.head_ref }}  #Checking out head commit
+
+      - name: Read .env file
+        uses: xom9ikk/dotenv@v2
+
+      - name: Generate ENV related extend file for docker-compose
+        uses: cuchi/jinja2-action@v1.2.0
+        with:
+          template: .docker/docker-compose.tmp-dev.j2
+          output_file: .docker/docker-compose.${{ matrix.network }}.yml
+          variables: |
+            RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}
+            NETWORK=${{ matrix.network }}
+   
+      - name: Show build configuration
+        run: cat .docker/docker-compose.${{ matrix.network }}.yml
+
+      - name: Build the stack
+        run: docker-compose -f ".docker/docker-compose.${{ matrix.network }}.yml" up -d --build --remove-orphans
+
+      - uses: actions/setup-node@v3
+        with:
+          node-version: 16
+
+      - name: Install jq
+        run: sudo apt install jq -y
+
+      - name: Run generate_types_package script
+        working-directory: tests
+        run: |
+          yarn install
+          /bin/bash ./scripts/wait_for_first_block.sh
+          git config --global user.name "Unique"
+          git config --global user.email github-actions@usetech.com          
+          /bin/bash ./scripts/generate_types_package.sh --release ${{ matrix.usage }} --push
+        env:
+          RPC_URL: http://127.0.0.1:9933/
+
+      - name: Stop running containers
+        if: always()                   # run this step always
+        run: docker-compose -f ".docker/docker-compose.${{ matrix.network }}.yml" down
+
+      - name: Remove builder cache
+        if: always()                   # run this step always
+        run: |
+          docker builder prune -f -a
+          docker system prune -f
+          docker image prune -f -a
modified.github/workflows/schedule-trigger-for-develop-build.ymldiffbeforeafterboth
--- a/.github/workflows/schedule-trigger-for-develop-build.yml
+++ b/.github/workflows/schedule-trigger-for-develop-build.yml
@@ -1,8 +1,8 @@
 name: schedule-trigger-for-develop-build
 on:
   # update the branch ci/develop-scheduler every night
-  schedule:
-    - cron: '0 1 * * *'
+  # schedule:
+  #   - cron: '0 1 * * *'
   # or update the branch manually
   workflow_dispatch:
   # pull_request:
modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2467,7 +2467,7 @@
 [[package]]
 name = "fc-consensus"
 version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"
 dependencies = [
  "async-trait",
  "fc-db",
@@ -2486,7 +2486,7 @@
 [[package]]
 name = "fc-db"
 version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"
 dependencies = [
  "fp-storage",
  "kvdb-rocksdb",
@@ -2505,7 +2505,7 @@
 [[package]]
 name = "fc-mapping-sync"
 version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"
 dependencies = [
  "fc-db",
  "fp-consensus",
@@ -2522,7 +2522,7 @@
 [[package]]
 name = "fc-rpc"
 version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"
 dependencies = [
  "ethereum 0.14.0",
  "ethereum-types 0.14.1",
@@ -2565,7 +2565,7 @@
 [[package]]
 name = "fc-rpc-core"
 version = "1.1.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"
 dependencies = [
  "ethereum 0.14.0",
  "ethereum-types 0.14.1",
@@ -2730,7 +2730,7 @@
 [[package]]
 name = "fp-consensus"
 version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"
 dependencies = [
  "ethereum 0.14.0",
  "parity-scale-codec 3.2.1",
@@ -2742,7 +2742,7 @@
 [[package]]
 name = "fp-ethereum"
 version = "1.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"
 dependencies = [
  "ethereum 0.14.0",
  "ethereum-types 0.14.1",
@@ -2757,7 +2757,7 @@
 [[package]]
 name = "fp-evm"
 version = "3.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"
 dependencies = [
  "evm",
  "frame-support",
@@ -2771,7 +2771,7 @@
 [[package]]
 name = "fp-evm-mapping"
 version = "0.1.0"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"
 dependencies = [
  "frame-support",
  "sp-core",
@@ -2780,7 +2780,7 @@
 [[package]]
 name = "fp-rpc"
 version = "3.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"
 dependencies = [
  "ethereum 0.14.0",
  "ethereum-types 0.14.1",
@@ -2797,7 +2797,7 @@
 [[package]]
 name = "fp-self-contained"
 version = "1.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"
 dependencies = [
  "ethereum 0.14.0",
  "frame-support",
@@ -2810,7 +2810,7 @@
 [[package]]
 name = "fp-storage"
 version = "2.0.0"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"
 dependencies = [
  "parity-scale-codec 3.2.1",
  "serde",
@@ -5682,7 +5682,7 @@
 [[package]]
 name = "pallet-base-fee"
 version = "1.0.0"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"
 dependencies = [
  "fp-evm",
  "frame-support",
@@ -5918,7 +5918,7 @@
 [[package]]
 name = "pallet-ethereum"
 version = "4.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"
 dependencies = [
  "ethereum 0.14.0",
  "ethereum-types 0.14.1",
@@ -5946,7 +5946,7 @@
 [[package]]
 name = "pallet-evm"
 version = "6.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"
 dependencies = [
  "environmental",
  "evm",
@@ -6032,7 +6032,7 @@
 [[package]]
 name = "pallet-evm-precompile-simple"
 version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#db60b911813df1d82e60e0de7f3dfa290e60d2f0"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.36#cf1894629c7df1c4dafe58aa773627a3d940da14"
 dependencies = [
  "fp-evm",
  "ripemd",
@@ -12965,6 +12965,7 @@
  "sp-core",
  "sp-finality-grandpa",
  "sp-inherents",
+ "sp-io",
  "sp-keystore",
  "sp-offchain",
  "sp-runtime",
modifiedcrates/evm-coder/procedural/src/abi_derive/derive_enum.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/abi_derive/derive_enum.rs
+++ b/crates/evm-coder/procedural/src/abi_derive/derive_enum.rs
@@ -143,8 +143,7 @@
 	)
 }
 
-pub fn check_and_count_options(de: &syn::DataEnum) -> syn::Result<usize> {
-	let mut count = 0;
+pub fn check_enum_fields(de: &syn::DataEnum) -> syn::Result<()> {
 	for v in de.variants.iter() {
 		if !v.fields.is_empty() {
 			return Err(syn::Error::new(
@@ -156,12 +155,10 @@
 				v.ident.span(),
 				"Enumeration options should not have an explicit specified value",
 			));
-		} else {
-			count += 1;
 		}
 	}
 
-	Ok(count)
+	Ok(())
 }
 
 pub fn check_repr_u8(name: &syn::Ident, attrs: &[syn::Attribute]) -> syn::Result<()> {
modifiedcrates/evm-coder/procedural/src/abi_derive/mod.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/abi_derive/mod.rs
+++ b/crates/evm-coder/procedural/src/abi_derive/mod.rs
@@ -70,6 +70,7 @@
 ) -> syn::Result<proc_macro2::TokenStream> {
 	let name = &ast.ident;
 	check_repr_u8(name, &ast.attrs)?;
+	check_enum_fields(de)?;
 	let docs = extract_docs(&ast.attrs)?;
 	let enum_options = de.variants.iter();
 
modifiednode/cli/Cargo.tomldiffbeforeafterboth
--- a/node/cli/Cargo.toml
+++ b/node/cli/Cargo.toml
@@ -122,6 +122,10 @@
 git = "https://github.com/paritytech/substrate"
 branch = "polkadot-v0.9.36"
 
+[dependencies.sp-io]
+git = "https://github.com/paritytech/substrate"
+branch = "polkadot-v0.9.36"
+
 [dependencies.sp-finality-grandpa]
 git = "https://github.com/paritytech/substrate"
 branch = "polkadot-v0.9.36"
modifiednode/cli/src/command.rsdiffbeforeafterboth
--- a/node/cli/src/command.rs
+++ b/node/cli/src/command.rs
@@ -412,6 +412,7 @@
 		#[cfg(feature = "try-runtime")]
 		Some(Subcommand::TryRuntime(cmd)) => {
 			use std::{future::Future, pin::Pin};
+			use sc_executor::{sp_wasm_interface::ExtendedHostFunctions, NativeExecutionDispatch};
 
 			let runner = cli.create_runner(cmd)?;
 
@@ -429,12 +430,21 @@
 				Ok((
 					match config.chain_spec.runtime_id() {
 						#[cfg(feature = "unique-runtime")]
-						RuntimeId::Unique => Box::pin(cmd.run::<Block, UniqueRuntimeExecutor>(config)),
+						RuntimeId::Unique => Box::pin(cmd.run::<Block, ExtendedHostFunctions<
+							sp_io::SubstrateHostFunctions,
+							<UniqueRuntimeExecutor as NativeExecutionDispatch>::ExtendHostFunctions,
+						>>()),
 
 						#[cfg(feature = "quartz-runtime")]
-						RuntimeId::Quartz => Box::pin(cmd.run::<Block, QuartzRuntimeExecutor>(config)),
+						RuntimeId::Quartz => Box::pin(cmd.run::<Block, ExtendedHostFunctions<
+							sp_io::SubstrateHostFunctions,
+							<QuartzRuntimeExecutor as NativeExecutionDispatch>::ExtendHostFunctions,
+						>>()),
 
-						RuntimeId::Opal => Box::pin(cmd.run::<Block, OpalRuntimeExecutor>(config)),
+						RuntimeId::Opal => Box::pin(cmd.run::<Block, ExtendedHostFunctions<
+							sp_io::SubstrateHostFunctions,
+							<OpalRuntimeExecutor as NativeExecutionDispatch>::ExtendHostFunctions,
+						>>()),
 						RuntimeId::Unknown(chain) => return Err(no_runtime_err!(chain).into()),
 					},
 					task_manager,
modifiednode/cli/src/service.rsdiffbeforeafterboth
--- a/node/cli/src/service.rs
+++ b/node/cli/src/service.rs
@@ -106,7 +106,12 @@
 
 #[cfg(feature = "unique-runtime")]
 impl NativeExecutionDispatch for UniqueRuntimeExecutor {
+	/// Only enable the benchmarking host functions when we actually want to benchmark.
+	#[cfg(feature = "runtime-benchmarks")]
 	type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;
+	/// Otherwise we only use the default Substrate host functions.
+	#[cfg(not(feature = "runtime-benchmarks"))]
+	type ExtendHostFunctions = ();
 
 	fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {
 		unique_runtime::api::dispatch(method, data)
@@ -119,7 +124,12 @@
 
 #[cfg(feature = "quartz-runtime")]
 impl NativeExecutionDispatch for QuartzRuntimeExecutor {
+	/// Only enable the benchmarking host functions when we actually want to benchmark.
+	#[cfg(feature = "runtime-benchmarks")]
 	type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;
+	/// Otherwise we only use the default Substrate host functions.
+	#[cfg(not(feature = "runtime-benchmarks"))]
+	type ExtendHostFunctions = ();
 
 	fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {
 		quartz_runtime::api::dispatch(method, data)
@@ -131,7 +141,12 @@
 }
 
 impl NativeExecutionDispatch for OpalRuntimeExecutor {
+	/// Only enable the benchmarking host functions when we actually want to benchmark.
+	#[cfg(feature = "runtime-benchmarks")]
 	type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;
+	/// Otherwise we only use the default Substrate host functions.
+	#[cfg(not(feature = "runtime-benchmarks"))]
+	type ExtendHostFunctions = ();
 
 	fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {
 		opal_runtime::api::dispatch(method, data)
modifiedpallets/common/src/eth.rsdiffbeforeafterboth
--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -127,7 +127,7 @@
 pub struct OptionCrossAddress {
 	/// Whether or not this CrossAdress is valid and has meaning.
 	pub status: bool,
-	/// The underlying CrossAddress. If the status is false, can be set to whatever.
+	/// The underlying CrossAddress value. If the status is false, can be set to whatever.
 	pub value: CrossAddress,
 }
 
modifiedpallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/evm-contract-helpers/src/stubs/ContractHelpers.soldiffbeforeafterboth
--- a/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol
+++ b/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol
@@ -283,6 +283,8 @@
 
 /// Ethereum representation of Optional value with CrossAddress.
 struct OptionCrossAddress {
+	/// TODO: field description
 	bool status;
+	/// TODO: field description
 	CrossAddress value;
 }
modifiedpallets/nonfungible/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/benchmarking.rs
+++ b/pallets/nonfungible/src/benchmarking.rs
@@ -228,7 +228,7 @@
 			owner: sub; collection: collection(owner); owner: cross_from_sub;
 			operator: cross_sub;
 		};
-	}: {<Pallet<T>>::set_allowance_for_all(&collection, &owner, &operator, true)}
+	}: {<Pallet<T>>::set_allowance_for_all(&collection, &owner, &operator, true)?}
 
 	allowance_for_all {
 		bench_init!{
modifiedpallets/refungible/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/refungible/src/benchmarking.rs
+++ b/pallets/refungible/src/benchmarking.rs
@@ -22,21 +22,17 @@
 use frame_benchmarking::{benchmarks, account};
 use pallet_common::{
 	bench_init,
-	benchmarking::{create_collection_raw, property_key, property_value, create_data},
+	benchmarking::{create_collection_raw, property_key, property_value},
 };
-use sp_core::H160;
 use sp_std::prelude::*;
-use up_data_structs::{
-	CollectionMode, MAX_ITEMS_PER_BATCH, MAX_PROPERTIES_PER_ITEM, CUSTOM_DATA_LIMIT,
-	budget::Unlimited,
-};
+use up_data_structs::{CollectionMode, MAX_ITEMS_PER_BATCH, MAX_PROPERTIES_PER_ITEM, budget::Unlimited};
 
 const SEED: u32 = 1;
 
-fn create_max_item_data<CrossAccountId: Ord>(
-	users: impl IntoIterator<Item = (CrossAccountId, u128)>,
-) -> CreateItemData<CrossAccountId> {
-	CreateItemData {
+fn create_max_item_data<T: Config>(
+	users: impl IntoIterator<Item = (T::CrossAccountId, u128)>,
+) -> CreateItemData<T> {
+	CreateItemData::<T> {
 		users: users
 			.into_iter()
 			.collect::<BTreeMap<_, _>>()
@@ -51,7 +47,7 @@
 	sender: &T::CrossAccountId,
 	users: impl IntoIterator<Item = (T::CrossAccountId, u128)>,
 ) -> Result<TokenId, DispatchError> {
-	let data: CreateItemData<T::CrossAccountId> = create_max_item_data(users);
+	let data: CreateItemData<T> = create_max_item_data::<T>(users);
 	<Pallet<T>>::create_item(&collection, sender, data, &Unlimited)?;
 	Ok(TokenId(<TokensMinted<T>>::get(&collection.id)))
 }
@@ -83,7 +79,7 @@
 			owner: sub; collection: collection(owner);
 			sender: cross_from_sub(owner); to: cross_sub;
 		};
-		let data = (0..b).map(|_| create_max_item_data([(to.clone(), 200)])).collect();
+		let data = (0..b).map(|_| create_max_item_data::<T>([(to.clone(), 200)])).collect();
 	}: {<Pallet<T>>::create_multiple_items(&collection, &sender, data, &Unlimited)?}
 
 	create_multiple_items_ex_multiple_items {
@@ -94,7 +90,7 @@
 		};
 		let data = (0..b).map(|t| {
 			bench_init!(to: cross_sub(t););
-			create_max_item_data([(to, 200)])
+			create_max_item_data::<T>([(to, 200)])
 		}).collect();
 	}: {<Pallet<T>>::create_multiple_items(&collection, &sender, data, &Unlimited)?}
 
@@ -104,7 +100,7 @@
 			owner: sub; collection: collection(owner);
 			sender: cross_from_sub(owner);
 		};
-		let data = vec![create_max_item_data((0..b).map(|u| {
+		let data = vec![create_max_item_data::<T>((0..b).map(|u| {
 			bench_init!(to: cross_sub(u););
 			(to, 200)
 		}))].try_into().unwrap();
@@ -296,7 +292,7 @@
 			owner: sub; collection: collection(owner); owner: cross_from_sub;
 			operator: cross_sub;
 		};
-	}: {<Pallet<T>>::set_allowance_for_all(&collection, &owner, &operator, true)}
+	}: {<Pallet<T>>::set_allowance_for_all(&collection, &owner, &operator, true)?}
 
 	allowance_for_all {
 		bench_init!{
modifiedpallets/refungible/src/erc_token.rsdiffbeforeafterboth
--- a/pallets/refungible/src/erc_token.rs
+++ b/pallets/refungible/src/erc_token.rs
@@ -43,6 +43,9 @@
 	TotalSupply, weights::WeightInfo,
 };
 
+/// Refungible token handle contains information about token's collection and id
+///
+/// RefungibleTokenHandle doesn't check token's existance upon creation
 pub struct RefungibleTokenHandle<T: Config>(pub RefungibleHandle<T>, pub TokenId);
 
 #[solidity_interface(name = ERC1633)]
modifiedruntime/common/ethereum/sponsoring.rsdiffbeforeafterboth
--- a/runtime/common/ethereum/sponsoring.rs
+++ b/runtime/common/ethereum/sponsoring.rs
@@ -32,14 +32,22 @@
 	Config as FungibleConfig,
 	erc::{UniqueFungibleCall, ERC20Call},
 };
-use pallet_refungible::Config as RefungibleConfig;
+use pallet_refungible::{
+	Config as RefungibleConfig,
+	erc::UniqueRefungibleCall,
+	erc_token::{RefungibleTokenHandle, UniqueRefungibleTokenCall},
+	RefungibleHandle,
+};
 use pallet_unique::Config as UniqueConfig;
 use sp_std::prelude::*;
-use up_data_structs::{CollectionMode, CreateItemData, CreateNftData, TokenId};
+use up_data_structs::{
+	CollectionMode, CreateItemData, CreateNftData, mapping::TokenAddressMapping, TokenId,
+};
 use up_sponsorship::SponsorshipHandler;
-
 use crate::{Runtime, runtime_common::sponsoring::*};
 
+mod refungible;
+
 pub type EvmSponsorshipHandler = (
 	UniqueEthSponsorshipHandler<Runtime>,
 	pallet_evm_contract_helpers::HelpersContractSponsoring<Runtime>,
@@ -53,80 +61,163 @@
 		who: &T::CrossAccountId,
 		call_context: &CallContext,
 	) -> Option<T::CrossAccountId> {
-		let collection_id = map_eth_to_id(&call_context.contract_address)?;
-		let collection = <CollectionHandle<T>>::new(collection_id)?;
-		let sponsor = collection.sponsorship.sponsor()?.clone();
-		let (method_id, mut reader) = AbiReader::new_call(&call_context.input).ok()?;
-		Some(T::CrossAccountId::from_sub(match &collection.mode {
-			CollectionMode::NFT => {
-				let call = <UniqueNFTCall<T>>::parse(method_id, &mut reader).ok()??;
-				match call {
-					UniqueNFTCall::TokenProperties(TokenPropertiesCall::SetProperty {
-						token_id,
-						key,
-						value,
-						..
-					}) => {
-						let token_id: TokenId = token_id.try_into().ok()?;
-						withdraw_set_token_property::<T>(
+		if let Some(collection_id) = map_eth_to_id(&call_context.contract_address) {
+			let collection = <CollectionHandle<T>>::new(collection_id)?;
+			let sponsor = collection.sponsorship.sponsor()?.clone();
+			let (method_id, mut reader) = AbiReader::new_call(&call_context.input).ok()?;
+			Some(T::CrossAccountId::from_sub(match &collection.mode {
+				CollectionMode::NFT => {
+					let call = <UniqueNFTCall<T>>::parse(method_id, &mut reader).ok()??;
+					match call {
+						UniqueNFTCall::TokenProperties(TokenPropertiesCall::SetProperty {
+							token_id,
+							key,
+							value,
+							..
+						}) => {
+							let token_id: TokenId = token_id.try_into().ok()?;
+							withdraw_set_token_property::<T>(
+								&collection,
+								&who,
+								&token_id,
+								key.len() + value.len(),
+							)
+							.map(|()| sponsor)
+						}
+						UniqueNFTCall::ERC721UniqueExtensions(
+							ERC721UniqueExtensionsCall::Transfer { token_id, .. },
+						) => {
+							let token_id: TokenId = token_id.try_into().ok()?;
+							withdraw_transfer::<T>(&collection, &who, &token_id).map(|()| sponsor)
+						}
+						UniqueNFTCall::ERC721UniqueMintable(
+							ERC721UniqueMintableCall::Mint { .. }
+							| ERC721UniqueMintableCall::MintCheckId { .. }
+							| ERC721UniqueMintableCall::MintWithTokenUri { .. }
+							| ERC721UniqueMintableCall::MintWithTokenUriCheckId { .. },
+						) => withdraw_create_item::<T>(
 							&collection,
 							&who,
-							&token_id,
-							key.len() + value.len(),
+							&CreateItemData::NFT(CreateNftData::default()),
 						)
-						.map(|()| sponsor)
-					}
-					UniqueNFTCall::ERC721UniqueExtensions(
-						ERC721UniqueExtensionsCall::Transfer { token_id, .. },
-					) => {
-						let token_id: TokenId = token_id.try_into().ok()?;
-						withdraw_transfer::<T>(&collection, &who, &token_id).map(|()| sponsor)
+						.map(|()| sponsor),
+						UniqueNFTCall::ERC721(ERC721Call::TransferFrom {
+							token_id, from, ..
+						}) => {
+							let token_id: TokenId = token_id.try_into().ok()?;
+							let from = T::CrossAccountId::from_eth(from);
+							withdraw_transfer::<T>(&collection, &from, &token_id).map(|()| sponsor)
+						}
+						UniqueNFTCall::ERC721(ERC721Call::Approve { token_id, .. }) => {
+							let token_id: TokenId = token_id.try_into().ok()?;
+							withdraw_approve::<T>(&collection, who.as_sub(), &token_id)
+								.map(|()| sponsor)
+						}
+						_ => None,
 					}
-					UniqueNFTCall::ERC721UniqueMintable(
-						ERC721UniqueMintableCall::Mint { .. }
-						| ERC721UniqueMintableCall::MintCheckId { .. }
-						| ERC721UniqueMintableCall::MintWithTokenUri { .. }
-						| ERC721UniqueMintableCall::MintWithTokenUriCheckId { .. },
-					) => withdraw_create_item::<T>(
-						&collection,
-						&who,
-						&CreateItemData::NFT(CreateNftData::default()),
-					)
-					.map(|()| sponsor),
-					UniqueNFTCall::ERC721(ERC721Call::TransferFrom { token_id, from, .. }) => {
-						let token_id: TokenId = token_id.try_into().ok()?;
-						let from = T::CrossAccountId::from_eth(from);
-						withdraw_transfer::<T>(&collection, &from, &token_id).map(|()| sponsor)
-					}
-					UniqueNFTCall::ERC721(ERC721Call::Approve { token_id, .. }) => {
-						let token_id: TokenId = token_id.try_into().ok()?;
-						withdraw_approve::<T>(&collection, who.as_sub(), &token_id)
-							.map(|()| sponsor)
-					}
-					_ => None,
 				}
-			}
-			CollectionMode::Fungible(_) => {
-				let call = <UniqueFungibleCall<T>>::parse(method_id, &mut reader).ok()??;
-				#[allow(clippy::single_match)]
-				match call {
-					UniqueFungibleCall::ERC20(ERC20Call::Transfer { .. }) => {
-						withdraw_transfer::<T>(&collection, who, &TokenId::default())
-							.map(|()| sponsor)
-					}
-					UniqueFungibleCall::ERC20(ERC20Call::TransferFrom { from, .. }) => {
-						let from = T::CrossAccountId::from_eth(from);
-						withdraw_transfer::<T>(&collection, &from, &TokenId::default())
-							.map(|()| sponsor)
+				CollectionMode::ReFungible => {
+					let call = <UniqueRefungibleCall<T>>::parse(method_id, &mut reader).ok()??;
+					refungible::call_sponsor(call, collection, who).map(|()| sponsor)
+				}
+				CollectionMode::Fungible(_) => {
+					let call = <UniqueFungibleCall<T>>::parse(method_id, &mut reader).ok()??;
+					match call {
+						UniqueFungibleCall::ERC20(ERC20Call::Transfer { .. }) => {
+							withdraw_transfer::<T>(&collection, who, &TokenId::default())
+								.map(|()| sponsor)
+						}
+						UniqueFungibleCall::ERC20(ERC20Call::TransferFrom { from, .. }) => {
+							let from = T::CrossAccountId::from_eth(from);
+							withdraw_transfer::<T>(&collection, &from, &TokenId::default())
+								.map(|()| sponsor)
+						}
+						UniqueFungibleCall::ERC20(ERC20Call::Approve { .. }) => {
+							withdraw_approve::<T>(&collection, who.as_sub(), &TokenId::default())
+								.map(|()| sponsor)
+						}
+						_ => None,
 					}
-					UniqueFungibleCall::ERC20(ERC20Call::Approve { .. }) => {
-						withdraw_approve::<T>(&collection, who.as_sub(), &TokenId::default())
-							.map(|()| sponsor)
-					}
-					_ => None,
 				}
+			}?))
+		} else {
+			let (collection_id, token_id) =
+				T::EvmTokenAddressMapping::address_to_token(&call_context.contract_address)?;
+			let collection = <CollectionHandle<T>>::new(collection_id)?;
+			if collection.mode != CollectionMode::ReFungible {
+				return None;
 			}
-			_ => None,
-		}?))
+			let sponsor = collection.sponsorship.sponsor()?.clone();
+			let rft_collection = RefungibleHandle::cast(collection);
+			// Token existance isn't checked at this point and should be checked in `withdraw` method.
+			let token = RefungibleTokenHandle(rft_collection, token_id);
+
+			let (method_id, mut reader) = AbiReader::new_call(&call_context.input).ok()?;
+			let call = <UniqueRefungibleTokenCall<T>>::parse(method_id, &mut reader).ok()??;
+			Some(T::CrossAccountId::from_sub(
+				refungible::token_call_sponsor(call, token, who).map(|()| sponsor)?,
+			))
+		}
+	}
+}
+
+mod common {
+	use super::*;
+
+	use pallet_common::erc::{CollectionCall};
+
+	pub fn collection_call_sponsor<T>(
+		call: CollectionCall<T>,
+		_collection: CollectionHandle<T>,
+		_who: &T::CrossAccountId,
+	) -> Option<()>
+	where
+		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,
+	{
+		use CollectionCall::*;
+
+		match call {
+			// Readonly
+			ERC165Call(_, _)
+			| CollectionProperty { .. }
+			| CollectionProperties { .. }
+			| HasCollectionPendingSponsor
+			| CollectionSponsor
+			| ContractAddress
+			| AllowlistedCross { .. }
+			| IsOwnerOrAdminEth { .. }
+			| IsOwnerOrAdminCross { .. }
+			| CollectionOwner
+			| CollectionAdmins
+			| CollectionLimits
+			| CollectionNestingRestrictedIds
+			| CollectionNestingPermissions
+			| UniqueCollectionType => None,
+
+			// Not sponsored
+			AddToCollectionAllowList { .. }
+			| AddToCollectionAllowListCross { .. }
+			| RemoveFromCollectionAllowList { .. }
+			| RemoveFromCollectionAllowListCross { .. }
+			| AddCollectionAdminCross { .. }
+			| RemoveCollectionAdminCross { .. }
+			| AddCollectionAdmin { .. }
+			| RemoveCollectionAdmin { .. }
+			| SetNestingBool { .. }
+			| SetNesting { .. }
+			| SetCollectionAccess { .. }
+			| SetCollectionMintMode { .. }
+			| SetOwner { .. }
+			| ChangeCollectionOwnerCross { .. }
+			| SetCollectionProperty { .. }
+			| SetCollectionProperties { .. }
+			| DeleteCollectionProperty { .. }
+			| DeleteCollectionProperties { .. }
+			| SetCollectionSponsor { .. }
+			| SetCollectionSponsorCross { .. }
+			| SetCollectionLimit { .. }
+			| ConfirmCollectionSponsorship
+			| RemoveCollectionSponsor => None,
+		}
 	}
 }
addedruntime/common/ethereum/sponsoring/refungible.rsdiffbeforeafterboth
--- /dev/null
+++ b/runtime/common/ethereum/sponsoring/refungible.rs
@@ -0,0 +1,381 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+//! Implements EVM sponsoring logic via TransactionValidityHack
+
+use core::convert::TryInto;
+use pallet_common::CollectionHandle;
+use pallet_evm::account::CrossAccountId;
+use pallet_fungible::Config as FungibleConfig;
+use pallet_refungible::Config as RefungibleConfig;
+use pallet_nonfungible::Config as NonfungibleConfig;
+use pallet_unique::Config as UniqueConfig;
+use up_data_structs::{CreateItemData, CreateNftData, TokenId};
+
+use super::common;
+use crate::runtime_common::sponsoring::*;
+
+use pallet_refungible::{
+	erc::{
+		ERC721BurnableCall, ERC721Call, ERC721EnumerableCall, ERC721MetadataCall,
+		ERC721UniqueExtensionsCall, ERC721UniqueMintableCall, TokenPropertiesCall,
+		UniqueRefungibleCall,
+	},
+	erc_token::{
+		ERC1633Call, ERC20Call, ERC20UniqueExtensionsCall, RefungibleTokenHandle,
+		UniqueRefungibleTokenCall,
+	},
+};
+
+pub fn call_sponsor<T>(
+	call: UniqueRefungibleCall<T>,
+	collection: CollectionHandle<T>,
+	who: &T::CrossAccountId,
+) -> Option<()>
+where
+	T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,
+{
+	use UniqueRefungibleCall::*;
+
+	match call {
+		// Readonly
+		ERC165Call(_, _) => None,
+
+		ERC721Enumerable(call) => erc721::enumerable_call_sponsor(call, collection, who),
+		ERC721Burnable(call) => erc721::burnable_call_sponsor(call, collection, who),
+		ERC721Metadata(call) => erc721::metadata_call_sponsor(call, collection, who),
+		Collection(call) => common::collection_call_sponsor(call, collection, who),
+		ERC721(call) => erc721::call_sponsor(call, collection, who),
+		ERC721UniqueExtensions(call) => {
+			erc721::unique_extensions_call_sponsor(call, collection, who)
+		}
+		ERC721UniqueMintable(call) => erc721::unique_mintable_call_sponsor(call, collection, who),
+		TokenProperties(call) => token_properties_call_sponsor(call, collection, who),
+	}
+}
+
+pub fn token_properties_call_sponsor<T>(
+	call: TokenPropertiesCall<T>,
+	collection: CollectionHandle<T>,
+	who: &T::CrossAccountId,
+) -> Option<()>
+where
+	T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,
+{
+	use TokenPropertiesCall::*;
+
+	match call {
+		// Readonly
+		ERC165Call(_, _) | Property { .. } | TokenPropertyPermissions => None,
+
+		// Not sponsored
+		SetTokenPropertyPermission { .. }
+		| SetTokenPropertyPermissions { .. }
+		| SetProperties { .. }
+		| DeleteProperty { .. }
+		| DeleteProperties { .. } => None,
+
+		SetProperty {
+			token_id,
+			key,
+			value,
+			..
+		} => {
+			let token_id = TokenId::try_from(token_id).ok()?;
+			withdraw_set_token_property::<T>(&collection, &who, &token_id, key.len() + value.len())
+		}
+	}
+}
+
+pub fn token_call_sponsor<T>(
+	call: UniqueRefungibleTokenCall<T>,
+	token: RefungibleTokenHandle<T>,
+	who: &T::CrossAccountId,
+) -> Option<()>
+where
+	T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,
+{
+	use UniqueRefungibleTokenCall::*;
+
+	match call {
+		// Readonly
+		ERC165Call(_, _) => None,
+
+		ERC20(call) => erc20::call_sponsor(call, token, who),
+		ERC20UniqueExtensions(call) => erc20::unique_extensions_call_sponsor(call, token, who),
+		ERC1633(call) => erc1633::call_sponsor(call, token, who),
+	}
+}
+
+mod erc721 {
+	use super::*;
+
+	pub fn call_sponsor<T>(
+		call: ERC721Call<T>,
+		collection: CollectionHandle<T>,
+		_who: &T::CrossAccountId,
+	) -> Option<()>
+	where
+		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,
+	{
+		use ERC721Call::*;
+
+		match call {
+			// Readonly
+			ERC165Call(_, _)
+			| BalanceOf { .. }
+			| OwnerOf { .. }
+			| GetApproved { .. }
+			| IsApprovedForAll { .. }
+			| CollectionHelperAddress => None,
+
+			// Not sponsored
+			SafeTransferFromWithData { .. }
+			| SafeTransferFrom { .. }
+			| SetApprovalForAll { .. } => None,
+
+			TransferFrom { token_id, from, .. } => {
+				let token_id = TokenId::try_from(token_id).ok()?;
+				let from = T::CrossAccountId::from_eth(from);
+				withdraw_transfer::<T>(&collection, &from, &token_id)
+			}
+
+			// Not supported
+			Approve { .. } => None,
+		}
+	}
+
+	pub fn enumerable_call_sponsor<T>(
+		call: ERC721EnumerableCall<T>,
+		_collection: CollectionHandle<T>,
+		_who: &T::CrossAccountId,
+	) -> Option<()>
+	where
+		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,
+	{
+		use ERC721EnumerableCall::*;
+
+		match call {
+			// Readonly
+			ERC165Call(_, _) | TokenByIndex { .. } | TokenOfOwnerByIndex { .. } | TotalSupply => {
+				None
+			}
+		}
+	}
+
+	pub fn burnable_call_sponsor<T>(
+		call: ERC721BurnableCall<T>,
+		_collection: CollectionHandle<T>,
+		_who: &T::CrossAccountId,
+	) -> Option<()>
+	where
+		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,
+	{
+		use ERC721BurnableCall::*;
+
+		match call {
+			// Readonly
+			ERC165Call(_, _) => None,
+
+			// Not sponsored
+			Burn { .. } => None,
+		}
+	}
+
+	pub fn metadata_call_sponsor<T>(
+		call: ERC721MetadataCall<T>,
+		_collection: CollectionHandle<T>,
+		_who: &T::CrossAccountId,
+	) -> Option<()>
+	where
+		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,
+	{
+		use ERC721MetadataCall::*;
+
+		match call {
+			// Readonly
+			ERC165Call(_, _) | NameProxy | SymbolProxy | TokenUri { .. } => None,
+		}
+	}
+
+	pub fn unique_extensions_call_sponsor<T>(
+		call: ERC721UniqueExtensionsCall<T>,
+		collection: CollectionHandle<T>,
+		who: &T::CrossAccountId,
+	) -> Option<()>
+	where
+		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,
+	{
+		use ERC721UniqueExtensionsCall::*;
+
+		match call {
+			// Readonly
+			ERC165Call(_, _)
+			| Name
+			| Symbol
+			| Description
+			| CrossOwnerOf { .. }
+			| Properties { .. }
+			| NextTokenId
+			| TokenContractAddress { .. } => None,
+
+			// Not sponsored
+			BurnFrom { .. }
+			| BurnFromCross { .. }
+			| MintBulk { .. }
+			| MintBulkWithTokenUri { .. } => None,
+
+			MintCross { .. } => withdraw_create_item::<T>(
+				&collection,
+				&who,
+				&CreateItemData::NFT(CreateNftData::default()),
+			),
+
+			TransferCross { token_id, .. }
+			| TransferFromCross { token_id, .. }
+			| Transfer { token_id, .. } => {
+				let token_id = TokenId::try_from(token_id).ok()?;
+				withdraw_transfer::<T>(&collection, &who, &token_id)
+			}
+		}
+	}
+
+	pub fn unique_mintable_call_sponsor<T>(
+		call: ERC721UniqueMintableCall<T>,
+		collection: CollectionHandle<T>,
+		who: &T::CrossAccountId,
+	) -> Option<()>
+	where
+		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,
+	{
+		use ERC721UniqueMintableCall::*;
+
+		match call {
+			// Readonly
+			ERC165Call(_, _) | MintingFinished => None,
+
+			// Not sponsored
+			FinishMinting => None,
+
+			Mint { .. }
+			| MintCheckId { .. }
+			| MintWithTokenUri { .. }
+			| MintWithTokenUriCheckId { .. } => withdraw_create_item::<T>(
+				&collection,
+				&who,
+				&CreateItemData::NFT(CreateNftData::default()),
+			),
+		}
+	}
+}
+
+/// Module for methods of refungible token
+///
+/// Existance of token should be checked before searching for sponsor
+/// because RefungibleTokenHandle doesn't check token's existence upon creation
+mod erc20 {
+	use super::*;
+
+	pub fn call_sponsor<T>(
+		call: ERC20Call<T>,
+		token: RefungibleTokenHandle<T>,
+		who: &T::CrossAccountId,
+	) -> Option<()>
+	where
+		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,
+	{
+		use ERC20Call::*;
+
+		match call {
+			// Readonly
+			ERC165Call(_, _)
+			| Name
+			| Symbol
+			| TotalSupply
+			| Decimals
+			| BalanceOf { .. }
+			| Allowance { .. } => None,
+
+			Transfer { .. } => {
+				let RefungibleTokenHandle(handle, token_id) = token;
+				let token_id = token_id.try_into().ok()?;
+				withdraw_transfer::<T>(&handle, &who, &token_id)
+			}
+			TransferFrom { from, .. } => {
+				let RefungibleTokenHandle(handle, token_id) = token;
+				let token_id = token_id.try_into().ok()?;
+				let from = T::CrossAccountId::from_eth(from);
+				withdraw_transfer::<T>(&handle, &from, &token_id)
+			}
+			Approve { .. } => {
+				let RefungibleTokenHandle(handle, token_id) = token;
+				let token_id = token_id.try_into().ok()?;
+				withdraw_approve::<T>(&handle, who.as_sub(), &token_id)
+			}
+		}
+	}
+
+	pub fn unique_extensions_call_sponsor<T>(
+		call: ERC20UniqueExtensionsCall<T>,
+		token: RefungibleTokenHandle<T>,
+		who: &T::CrossAccountId,
+	) -> Option<()>
+	where
+		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,
+	{
+		use ERC20UniqueExtensionsCall::*;
+
+		match call {
+			// Readonly
+			ERC165Call(_, _) => None,
+
+			// Not sponsored
+			BurnFrom { .. } | BurnFromCross { .. } | Repartition { .. } => None,
+
+			TransferCross { .. } | TransferFromCross { .. } => {
+				let RefungibleTokenHandle(handle, token_id) = token;
+				let token_id = token_id.try_into().ok()?;
+				withdraw_transfer::<T>(&handle, &who, &token_id)
+			}
+
+			ApproveCross { .. } => {
+				let RefungibleTokenHandle(handle, token_id) = token;
+				let token_id = token_id.try_into().ok()?;
+				withdraw_approve::<T>(&handle, who.as_sub(), &token_id)
+			}
+		}
+	}
+}
+
+mod erc1633 {
+	use super::*;
+
+	pub fn call_sponsor<T>(
+		call: ERC1633Call<T>,
+		_token: RefungibleTokenHandle<T>,
+		_who: &T::CrossAccountId,
+	) -> Option<()>
+	where
+		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,
+	{
+		use ERC1633Call::*;
+
+		match call {
+			// Readonly
+			ERC165Call(_, _) | ParentToken | ParentTokenId => None,
+		}
+	}
+}
modifiedruntime/common/runtime_apis.rsdiffbeforeafterboth
--- a/runtime/common/runtime_apis.rs
+++ b/runtime/common/runtime_apis.rs
@@ -780,15 +780,16 @@
 
             #[cfg(feature = "try-runtime")]
             impl frame_try_runtime::TryRuntime<Block> for Runtime {
-                fn on_runtime_upgrade() -> (frame_support::pallet_prelude::Weight, frame_support::pallet_prelude::Weight) {
+                fn on_runtime_upgrade(checks: bool) -> (frame_support::pallet_prelude::Weight, frame_support::pallet_prelude::Weight) {
                     log::info!("try-runtime::on_runtime_upgrade unique-chain.");
-                    let weight = Executive::try_runtime_upgrade().unwrap();
+                    let weight = Executive::try_runtime_upgrade(checks).unwrap();
                     (weight, crate::config::substrate::RuntimeBlockWeights::get().max_block)
                 }
 
                 fn execute_block(
                     block: Block,
                     state_root_check: bool,
+                    signature_check: bool,
                     select: frame_try_runtime::TryStateSelect
                 ) -> frame_support::pallet_prelude::Weight {
                     log::info!(
@@ -799,7 +800,7 @@
                         select,
                     );
 
-                    Executive::try_execute_block(block, state_root_check, select).unwrap()
+                    Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap()
                 }
             }
         }
modifiedruntime/opal/Cargo.tomldiffbeforeafterboth
--- a/runtime/opal/Cargo.toml
+++ b/runtime/opal/Cargo.toml
@@ -91,6 +91,7 @@
     'pallet-unique-scheduler-v2/try-runtime',
     'pallet-maintenance/try-runtime',
     'pallet-test-utils?/try-runtime',
+    'fp-self-contained/try-runtime',
 ]
 std = [
     'codec/std',
modifiedruntime/quartz/Cargo.tomldiffbeforeafterboth
--- a/runtime/quartz/Cargo.toml
+++ b/runtime/quartz/Cargo.toml
@@ -86,6 +86,7 @@
     'pallet-evm-transaction-payment/try-runtime',
     'pallet-evm-migration/try-runtime',
     'pallet-maintenance/try-runtime',
+    'fp-self-contained/try-runtime',
 ]
 std = [
     'codec/std',
modifiedruntime/unique/Cargo.tomldiffbeforeafterboth
--- a/runtime/unique/Cargo.toml
+++ b/runtime/unique/Cargo.toml
@@ -87,6 +87,7 @@
     'pallet-evm-transaction-payment/try-runtime',
     'pallet-evm-migration/try-runtime',
     'pallet-maintenance/try-runtime',
+    'fp-self-contained/try-runtime',
 ]
 std = [
     'codec/std',
modifiedtests/.eslintrc.jsondiffbeforeafterboth
--- a/tests/.eslintrc.json
+++ b/tests/.eslintrc.json
@@ -18,6 +18,9 @@
         "mocha"
     ],
     "rules": {
+        "@typescript-eslint/no-floating-promises": [
+            "error"
+        ],
         "indent": [
             "error",
             2,
modifiedtests/package.jsondiffbeforeafterboth
--- a/tests/package.json
+++ b/tests/package.json
@@ -11,8 +11,8 @@
     "@types/chai-subset": "^1.3.3",
     "@types/mocha": "^10.0.0",
     "@types/node": "^18.11.2",
-    "@typescript-eslint/eslint-plugin": "^5.40.1",
-    "@typescript-eslint/parser": "^5.40.1",
+    "@typescript-eslint/eslint-plugin": "^5.47.0",
+    "@typescript-eslint/parser": "^5.47.0",
     "chai": "^4.3.6",
     "chai-subset": "^1.6.0",
     "eslint": "^8.25.0",
modifiedtests/src/apiConsts.test.tsdiffbeforeafterboth
--- a/tests/src/apiConsts.test.ts
+++ b/tests/src/apiConsts.test.ts
@@ -46,33 +46,33 @@
 
 describe('integration test: API UNIQUE consts', () => {
   let api: ApiPromise;
-  
+
   before(async () => {
     await usingPlaygrounds(async (helper) => {
       api = await helper.getApi();
     });
   });
-  
+
   itSub('DEFAULT_NFT_COLLECTION_LIMITS', () => {
     expect(api.consts.unique.nftDefaultCollectionLimits.toHuman()).to.deep.equal(DEFAULT_COLLETCTION_LIMIT);
   });
-  
+
   itSub('DEFAULT_RFT_COLLECTION_LIMITS', () => {
     expect(api.consts.unique.rftDefaultCollectionLimits.toHuman()).to.deep.equal(DEFAULT_COLLETCTION_LIMIT);
   });
-  
+
   itSub('DEFAULT_FT_COLLECTION_LIMITS', () => {
     expect(api.consts.unique.ftDefaultCollectionLimits.toHuman()).to.deep.equal(DEFAULT_COLLETCTION_LIMIT);
   });
-  
+
   itSub('MAX_COLLECTION_NAME_LENGTH', () => {
     checkConst(api.consts.unique.maxCollectionNameLength, MAX_COLLECTION_NAME_LENGTH);
   });
-  
+
   itSub('MAX_COLLECTION_DESCRIPTION_LENGTH', () => {
     checkConst(api.consts.unique.maxCollectionDescriptionLength, MAX_COLLECTION_DESCRIPTION_LENGTH);
   });
-  
+
   itSub('MAX_COLLECTION_PROPERTIES_SIZE', () => {
     checkConst(api.consts.unique.maxCollectionPropertiesSize, MAX_COLLECTION_PROPERTIES_SIZE);
   });
@@ -84,31 +84,31 @@
   itSub('MAX_PROPERTY_KEY_LENGTH', () => {
     checkConst(api.consts.unique.maxPropertyKeyLength, MAX_PROPERTY_KEY_LENGTH);
   });
-  
+
   itSub('MAX_PROPERTY_VALUE_LENGTH', () => {
     checkConst(api.consts.unique.maxPropertyValueLength, MAX_PROPERTY_VALUE_LENGTH);
   });
-  
+
   itSub('MAX_PROPERTIES_PER_ITEM', () => {
     checkConst(api.consts.unique.maxPropertiesPerItem, MAX_PROPERTIES_PER_ITEM);
   });
-  
+
   itSub('NESTING_BUDGET', () => {
     checkConst(api.consts.unique.nestingBudget, NESTING_BUDGET);
   });
-  
+
   itSub('MAX_TOKEN_PROPERTIES_SIZE', () => {
     checkConst(api.consts.unique.maxTokenPropertiesSize, MAX_TOKEN_PROPERTIES_SIZE);
   });
-  
+
   itSub('COLLECTION_ADMINS_LIMIT', () => {
     checkConst(api.consts.unique.collectionAdminsLimit, COLLECTION_ADMINS_LIMIT);
   });
-  
+
   itSub('HELPERS_CONTRACT_ADDRESS', () => {
     expect(api.consts.evmContractHelpers.contractAddress.toString().toLowerCase()).to.be.equal(HELPERS_CONTRACT_ADDRESS.toLowerCase());
   });
-  
+
   itSub('EVM_COLLECTION_HELPERS_ADDRESS', () => {
     expect(api.consts.common.contractAddress.toString().toLowerCase()).to.be.equal(EVM_COLLECTION_HELPERS_ADDRESS.toLowerCase());
   });
modifiedtests/src/app-promotion.seqtest.tsdiffbeforeafterboth
--- a/tests/src/app-promotion.seqtest.ts
+++ b/tests/src/app-promotion.seqtest.ts
@@ -50,31 +50,31 @@
       await expect(helper.signTransaction(nonAdmin, api.tx.appPromotion.setAdminAddress({Substrate: nonAdmin.address}))).to.be.rejected;
       await expect(helper.signTransaction(nonAdmin, api.tx.sudo.sudo(api.tx.appPromotion.setAdminAddress({Substrate: nonAdmin.address})))).to.be.rejected;
     });
-    
+
     itSub('can be any valid CrossAccountId', async ({helper}) => {
       // We are not going to set an eth address as a sponsor,
       // but we do want to check, it doesn't break anything;
       const api = helper.getApi();
       const [account] = await helper.arrange.createAccounts([10n], donor);
-      const ethAccount = helper.address.substrateToEth(account.address); 
+      const ethAccount = helper.address.substrateToEth(account.address);
       // Alice sets Ethereum address as a sudo. Then Substrate address back...
       await expect(helper.signTransaction(superuser, api.tx.sudo.sudo(api.tx.appPromotion.setAdminAddress({Ethereum: ethAccount})))).to.be.fulfilled;
       await expect(helper.signTransaction(superuser, api.tx.sudo.sudo(api.tx.appPromotion.setAdminAddress({Substrate: palletAdmin.address})))).to.be.fulfilled;
-        
+
       // ...It doesn't break anything;
       const collection = await helper.nft.mintCollection(account, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});
       await expect(helper.signTransaction(account, api.tx.appPromotion.sponsorCollection(collection.collectionId))).to.be.rejected;
     });
-  
+
     itSub('can be reassigned', async ({helper}) => {
       const api = helper.getApi();
       const [oldAdmin, newAdmin, collectionOwner] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
       const collection  = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});
-        
+
       await expect(helper.signTransaction(superuser, api.tx.sudo.sudo(api.tx.appPromotion.setAdminAddress({Substrate: oldAdmin.address})))).to.be.fulfilled;
       await expect(helper.signTransaction(superuser, api.tx.sudo.sudo(api.tx.appPromotion.setAdminAddress({Substrate: newAdmin.address})))).to.be.fulfilled;
       await expect(helper.signTransaction(oldAdmin, api.tx.appPromotion.sponsorCollection(collection.collectionId))).to.be.rejected;
-        
+
       await expect(helper.signTransaction(newAdmin, api.tx.appPromotion.sponsorCollection(collection.collectionId))).to.be.fulfilled;
     });
   });
modifiedtests/src/approve.test.tsdiffbeforeafterboth
--- a/tests/src/approve.test.ts
+++ b/tests/src/approve.test.ts
@@ -538,7 +538,7 @@
     const approveTx = () => helper.rft.approveToken(alice, collectionId, 1, {Substrate: bob.address});
     await expect(approveTx()).to.be.rejected;
   });
-  
+
   itSub('[nft] Approve transfer of a token that does not exist', async ({helper}) => {
     const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
     const approveTx = () => helper.nft.approveToken(alice, collectionId, 2, {Substrate: bob.address});
@@ -639,7 +639,7 @@
     await helper.rft.setAllowanceForAll(alice, collectionId, {Substrate: bob.address}, true);
     const checkAfterApproval = await helper.rft.allowanceForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});
     expect(checkAfterApproval).to.be.true;
-    
+
     await helper.rft.setAllowanceForAll(alice, collectionId, {Substrate: bob.address}, false);
     const checkAfterDisapproval = await helper.rft.allowanceForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});
     expect(checkAfterDisapproval).to.be.false;
modifiedtests/src/burnItem.test.tsdiffbeforeafterboth
--- a/tests/src/burnItem.test.ts
+++ b/tests/src/burnItem.test.ts
@@ -185,7 +185,7 @@
     const collection = await helper.nft.mintCollection(alice, {name: 'Coll', description: 'Desc', tokenPrefix: 'T'});
     const tokenAlice = await collection.mintToken(alice, {Substrate: alice.address});
     const tokenBob = await collection.mintToken(alice, {Substrate: bob.address});
-    
+
     // 1. Zero burn of own tokens allowed:
     await helper.executeExtrinsic(alice, 'api.tx.unique.burnItem', [collection.collectionId, tokenAlice.tokenId, 0]);
     // 2. Zero burn of non-owned tokens not allowed:
modifiedtests/src/calibrate.tsdiffbeforeafterboth
--- a/tests/src/calibrate.ts
+++ b/tests/src/calibrate.ts
@@ -295,6 +295,7 @@
   }
 }
 
+// eslint-disable-next-line @typescript-eslint/no-floating-promises
 (async () => {
   await usingEthPlaygrounds(async (helper: EthUniqueHelper, privateKey) => {
     // Subsequent runs reduce error, as price line is not actually straight, this is a curve
modifiedtests/src/createCollection.test.tsdiffbeforeafterboth
--- a/tests/src/createCollection.test.ts
+++ b/tests/src/createCollection.test.ts
@@ -127,7 +127,7 @@
     const mintCollectionTx = () => helper.nft.mintCollection(alice, {name: 'name', description: 'descr', tokenPrefix: 'A'.repeat(17)});
     await expect(mintCollectionTx()).to.be.rejectedWith('Verification Error');
   });
-  
+
   itSub('(!negative test!) fails when bad limits are set', async ({helper}) => {
     const mintCollectionTx = () => helper.nft.mintCollection(alice, {name: 'name', description: 'descr', tokenPrefix: 'COL', limits: {tokenLimit: 0}});
     await expect(mintCollectionTx()).to.be.rejectedWith(/common\.CollectionTokenLimitExceeded/);
modifiedtests/src/createMultipleItems.test.tsdiffbeforeafterboth
--- a/tests/src/createMultipleItems.test.ts
+++ b/tests/src/createMultipleItems.test.ts
@@ -272,8 +272,8 @@
 
     const types = ['NFT', 'Fungible', 'ReFungible'];
     await expect(helper.executeExtrinsic(
-      alice, 
-      'api.tx.unique.createMultipleItems', 
+      alice,
+      'api.tx.unique.createMultipleItems',
       [collectionId, {Substrate: alice.address}, types],
     )).to.be.rejectedWith(/nonfungible\.NotNonfungibleDataUsedToMintFungibleCollectionToken/);
   });
modifiedtests/src/eth/abi/reFungibleDeprecated.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/reFungibleDeprecated.json
+++ b/tests/src/eth/abi/reFungibleDeprecated.json
@@ -98,5 +98,33 @@
     "outputs": [],
     "stateMutability": "nonpayable",
     "type": "function"
+  },
+  {
+    "inputs": [
+      { "internalType": "address", "name": "to", "type": "address" },
+      { "internalType": "uint256[]", "name": "tokenIds", "type": "uint256[]" }
+    ],
+    "name": "mintBulk",
+    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+    "stateMutability": "nonpayable",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      { "internalType": "address", "name": "to", "type": "address" },
+      {
+        "components": [
+          { "internalType": "uint256", "name": "field_0", "type": "uint256" },
+          { "internalType": "string", "name": "field_1", "type": "string" }
+        ],
+        "internalType": "struct Tuple0[]",
+        "name": "tokens",
+        "type": "tuple[]"
+      }
+    ],
+    "name": "mintBulkWithTokenURI",
+    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+    "stateMutability": "nonpayable",
+    "type": "function"
   }
 ]
modifiedtests/src/eth/api/ContractHelpers.soldiffbeforeafterboth
--- a/tests/src/eth/api/ContractHelpers.sol
+++ b/tests/src/eth/api/ContractHelpers.sol
@@ -183,7 +183,9 @@
 
 /// Ethereum representation of Optional value with CrossAddress.
 struct OptionCrossAddress {
+	/// TODO: field description
 	bool status;
+	/// TODO: field description
 	CrossAddress value;
 }
 
modifiedtests/src/eth/collectionSponsoring.test.tsdiffbeforeafterboth
--- a/tests/src/eth/collectionSponsoring.test.ts
+++ b/tests/src/eth/collectionSponsoring.test.ts
@@ -15,10 +15,10 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 import {IKeyringPair} from '@polkadot/types/types';
-import {usingPlaygrounds} from '../util/index';
+import {Pallets, requirePalletsOrSkip, usingPlaygrounds} from '../util/index';
 import {itEth, expect} from './util';
 
-describe('evm collection sponsoring', () => {
+describe('evm nft collection sponsoring', () => {
   let donor: IKeyringPair;
   let alice: IKeyringPair;
   let nominal: bigint;
@@ -101,12 +101,14 @@
       expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.true;
 
       await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
+      let sponsorStruct = await collectionEvm.methods.collectionSponsor().call({from: owner});
+      expect(helper.address.restoreCrossAccountFromBigInt(BigInt(sponsorStruct.sub))).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
       expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;
 
       await collectionEvm.methods.removeCollectionSponsor().send({from: owner});
 
-      const sponsorTuple = await collectionEvm.methods.collectionSponsor().call({from: owner});
-      expect(sponsorTuple.eth).to.be.eq('0x0000000000000000000000000000000000000000');
+      sponsorStruct = await collectionEvm.methods.collectionSponsor().call({from: owner});
+      expect(sponsorStruct.eth).to.be.eq('0x0000000000000000000000000000000000000000');
     }));
 
   [
@@ -142,7 +144,7 @@
       expect(nextTokenId).to.be.equal('1');
 
       // Set collection permissions:
-      const oldPermissions = (await collectionSub.getData())!.raw.permissions; // (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman();
+      const oldPermissions = (await collectionSub.getData())!.raw.permissions;
       expect(oldPermissions.mintMode).to.be.false;
       expect(oldPermissions.access).to.be.equal('Normal');
 
@@ -150,12 +152,13 @@
       await collectionEvm.methods.addToCollectionAllowListCross(userCross).send({from: owner});
       await collectionEvm.methods.setCollectionMintMode(true).send({from: owner});
 
-      const newPermissions = (await collectionSub.getData())!.raw.permissions; // (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman();
+      const newPermissions = (await collectionSub.getData())!.raw.permissions;
       expect(newPermissions.mintMode).to.be.true;
       expect(newPermissions.access).to.be.equal('AllowList');
 
       const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
       const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));
+      const userBalanceBefore =  await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
 
       // User can mint token without balance:
       {
@@ -179,7 +182,7 @@
 
         expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
         expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);
-        expect(userBalanceAfter).to.be.eq(0n);
+        expect(userBalanceAfter).to.be.eq(userBalanceBefore);
         expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;
       }
     }));
@@ -315,3 +318,531 @@
     expect(collectionSponsor).to.deep.eq({Unconfirmed: sponsorSub.address});
   });
 });
+
+describe('evm RFT collection sponsoring', () => {
+  let donor: IKeyringPair;
+  let alice: IKeyringPair;
+  let nominal: bigint;
+
+  before(async function() {
+    await usingPlaygrounds(async (helper, privateKey) => {
+      requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);
+      donor = await privateKey({filename: __filename});
+      [alice] = await helper.arrange.createAccounts([100n], donor);
+      nominal = helper.balance.getOneTokenNominal();
+    });
+  });
+
+  [
+    'mintCross',
+    'mintWithTokenURI',
+  ].map(testCase =>
+    itEth(`[${testCase}] sponsors mint transactions`, async ({helper}) => {
+      const collection = await helper.rft.mintCollection(alice, {tokenPrefix: 'spnr', permissions: {mintMode: true}, tokenPropertyPermissions: [
+        {key: 'URI', permission: {tokenOwner: true, mutable: true, collectionAdmin: true}},
+      ]});
+
+      const owner = await helper.eth.createAccountWithBalance(donor);
+      await collection.setSponsor(alice, alice.address);
+      await collection.confirmSponsorship(alice);
+
+      const minter = helper.eth.createAccount();
+      const minterCross = helper.ethCrossAccount.fromAddress(minter);
+      expect(await helper.balance.getEthereum(minter)).to.equal(0n);
+
+      const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+      const contract = await helper.ethNativeContract.collection(collectionAddress, 'rft', minter, true);
+
+      await collection.addToAllowList(alice, {Ethereum: minter});
+      await collection.addAdmin(alice, {Ethereum: owner});
+      const collectionHelpers = await helper.ethNativeContract.collectionHelpers(owner);
+      await collectionHelpers.methods.makeCollectionERC721MetadataCompatible(collectionAddress, 'base/')
+        .send();
+
+      let mintingResult;
+      let tokenId;
+      switch (testCase) {
+        case 'mintCross':
+          mintingResult = await contract.methods.mintCross(minterCross, []).send();
+          break;
+        case 'mintWithTokenURI':
+          mintingResult = await contract.methods.mintWithTokenURI(minter, 'Test URI').send();
+          tokenId = mintingResult.events.Transfer.returnValues.tokenId;
+          expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
+          break;
+      }
+
+      const events = helper.eth.normalizeEvents(mintingResult.events);
+      expect(events).to.deep.include({
+        address: collectionAddress,
+        event: 'Transfer',
+        args: {
+          from: '0x0000000000000000000000000000000000000000',
+          to: minter,
+          tokenId: '1',
+        },
+      });
+    }));
+
+  [
+    'setCollectionSponsorCross',
+    'setCollectionSponsor', // Soft-deprecated
+  ].map(testCase =>
+    itEth(`[${testCase}] can remove collection sponsor`, async ({helper}) => {
+      const owner = await helper.eth.createAccountWithBalance(donor);
+      const collectionHelpers = await helper.ethNativeContract.collectionHelpers(owner);
+
+      let result = await collectionHelpers.methods.createRFTCollection('Sponsor collection', '1', '1').send({value: Number(2n * nominal)});
+      const collectionIdAddress = helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);
+      const sponsor = await helper.eth.createAccountWithBalance(donor);
+      const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);
+      const collectionEvm = await helper.ethNativeContract.collection(collectionIdAddress, 'rft', owner, testCase === 'setCollectionSponsor');
+
+      expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;
+      result = await collectionEvm.methods[testCase](testCase === 'setCollectionSponsor' ? sponsor : sponsorCross).send({from: owner});
+      expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.true;
+
+      await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
+      expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;
+
+      await collectionEvm.methods.removeCollectionSponsor().send({from: owner});
+
+      const sponsorStruct = await collectionEvm.methods.collectionSponsor().call({from: owner});
+      expect(sponsorStruct.eth).to.be.eq('0x0000000000000000000000000000000000000000');
+    }));
+
+  [
+    'setCollectionSponsorCross',
+    'setCollectionSponsor', // Soft-deprecated
+  ].map(testCase =>
+    itEth(`[${testCase}] Can sponsor from evm address via access list`, async ({helper}) => {
+      const owner = await helper.eth.createAccountWithBalance(donor);
+      const sponsorEth = await helper.eth.createAccountWithBalance(donor);
+      const sponsorCrossEth = helper.ethCrossAccount.fromAddress(sponsorEth);
+
+      const {collectionId, collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, 'Sponsor collection', '1', '1', '');
+
+      const collectionSub = helper.rft.getCollectionObject(collectionId);
+      const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner, testCase === 'setCollectionSponsor');
+
+      // Set collection sponsor:
+      await collectionEvm.methods[testCase](testCase === 'setCollectionSponsor' ? sponsorEth : sponsorCrossEth).send({from: owner});
+      let sponsorship = (await collectionSub.getData())!.raw.sponsorship;
+      expect(sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsorEth, true));
+      // Account cannot confirm sponsorship if it is not set as a sponsor
+      await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');
+
+      // Sponsor can confirm sponsorship:
+      await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsorEth});
+      sponsorship = (await collectionSub.getData())!.raw.sponsorship;
+      expect(sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsorEth, true));
+
+      // Create user with no balance:
+      const user = helper.eth.createAccount();
+      const userCross = helper.ethCrossAccount.fromAddress(user);
+      const nextTokenId = await collectionEvm.methods.nextTokenId().call();
+      expect(nextTokenId).to.be.equal('1');
+
+      // Set collection permissions:
+      const oldPermissions = (await collectionSub.getData())!.raw.permissions;
+      expect(oldPermissions.mintMode).to.be.false;
+      expect(oldPermissions.access).to.be.equal('Normal');
+
+      await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner});
+      await collectionEvm.methods.addToCollectionAllowListCross(userCross).send({from: owner});
+      await collectionEvm.methods.setCollectionMintMode(true).send({from: owner});
+
+      const newPermissions = (await collectionSub.getData())!.raw.permissions;
+      expect(newPermissions.mintMode).to.be.true;
+      expect(newPermissions.access).to.be.equal('AllowList');
+
+      const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
+      const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));
+      const userBalanceBefore =  await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
+
+      // User can mint token without balance:
+      {
+        const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});
+        const events = helper.eth.normalizeEvents(result.events);
+
+        expect(events).to.deep.include({
+          address: collectionAddress,
+          event: 'Transfer',
+          args: {
+            from: '0x0000000000000000000000000000000000000000',
+            to: user,
+            tokenId: '1',
+          },
+        });
+
+        const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
+        const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));
+        const userBalanceAfter =  await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
+
+        expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
+        expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);
+        expect(userBalanceAfter).to.be.eq(userBalanceBefore);
+        expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;
+      }
+    }));
+
+  [
+    'setCollectionSponsorCross',
+    'setCollectionSponsor', // Soft-deprecated
+  ].map(testCase =>
+    itEth(`[${testCase}] Check that collection admin EVM transaction spend money from sponsor eth address`, async ({helper}) => {
+      const owner = await helper.eth.createAccountWithBalance(donor);
+      const sponsor = await helper.eth.createAccountWithBalance(donor);
+      const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);
+
+      const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');
+
+      const collectionSub = helper.rft.getCollectionObject(collectionId);
+      const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner, testCase === 'setCollectionSponsor');
+      // Set collection sponsor:
+      expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.false;
+      await collectionEvm.methods[testCase](testCase === 'setCollectionSponsor' ? sponsor : sponsorCross).send();
+      expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.true;
+      let collectionData = (await collectionSub.getData())!;
+      expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
+      await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');
+      expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.true;
+
+      await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
+      collectionData = (await collectionSub.getData())!;
+      expect(collectionData.raw.sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
+      expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.false;
+      const sponsorStruct = await collectionEvm.methods.collectionSponsor().call({from: owner});
+      const sponsorSubAddress = helper.address.normalizeSubstrateToChainFormat(helper.address.ethToSubstrate(sponsor));
+      const actualSubAddress = helper.address.normalizeSubstrateToChainFormat(helper.address.restoreCrossAccountFromBigInt(BigInt(sponsorStruct.sub)));
+      expect(actualSubAddress).to.be.equal(sponsorSubAddress);
+
+      const user = helper.eth.createAccount();
+      const userCross = helper.ethCrossAccount.fromAddress(user);
+      await collectionEvm.methods.addCollectionAdminCross(userCross).send();
+
+      const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
+      const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
+
+      const mintingResult = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});
+      const tokenId = mintingResult.events.Transfer.returnValues.tokenId;
+
+      const events = helper.eth.normalizeEvents(mintingResult.events);
+      const address = helper.ethAddress.fromCollectionId(collectionId);
+
+      expect(events).to.deep.include({
+        address,
+        event: 'Transfer',
+        args: {
+          from: '0x0000000000000000000000000000000000000000',
+          to: user,
+          tokenId: '1',
+        },
+      });
+      expect(await collectionEvm.methods.tokenURI(tokenId).call({from: user})).to.be.equal('Test URI');
+
+      const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
+      expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);
+      const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
+      expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
+    }));
+
+  itEth('Check that collection admin EVM transaction spend money from sponsor sub address', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor);
+    const sponsor = alice;
+    const sponsorCross = helper.ethCrossAccount.fromKeyringPair(sponsor);
+
+    const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');
+
+    const collectionSub = helper.rft.getCollectionObject(collectionId);
+    const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner, false);
+    // Set collection sponsor:
+    expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.false;
+    await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();
+    expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.true;
+    let collectionData = (await collectionSub.getData())!;
+    expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(sponsor.address);
+    await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');
+
+    await collectionSub.confirmSponsorship(sponsor);
+    collectionData = (await collectionSub.getData())!;
+    expect(collectionData.raw.sponsorship.Confirmed).to.be.eq(sponsor.address);
+    expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.false;
+    const sponsorStruct = await collectionEvm.methods.collectionSponsor().call({from: owner});
+    expect(BigInt(sponsorStruct.sub)).to.be.equal(BigInt('0x' + Buffer.from(sponsor.addressRaw).toString('hex')));
+
+    const user = helper.eth.createAccount();
+    const userCross = helper.ethCrossAccount.fromAddress(user);
+    await collectionEvm.methods.addCollectionAdminCross(userCross).send();
+
+    const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
+    const sponsorBalanceBefore = await helper.balance.getSubstrate(sponsor.address);
+
+    const mintingResult = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});
+    const tokenId = mintingResult.events.Transfer.returnValues.tokenId;
+
+    const events = helper.eth.normalizeEvents(mintingResult.events);
+
+    expect(events).to.deep.include({
+      address: collectionAddress,
+      event: 'Transfer',
+      args: {
+        from: '0x0000000000000000000000000000000000000000',
+        to: user,
+        tokenId: '1',
+      },
+    });
+    expect(await collectionEvm.methods.tokenURI(tokenId).call({from: user})).to.be.equal('Test URI');
+
+    const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
+    expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);
+    const sponsorBalanceAfter = await helper.balance.getSubstrate(sponsor.address);
+    expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
+  });
+
+  itEth('Sponsoring collection from substrate address via access list', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor);
+    const user = helper.eth.createAccount();
+    const userCross =  helper.ethCrossAccount.fromAddress(user);
+    const sponsor = alice;
+    const sponsorCross = helper.ethCrossAccount.fromKeyringPair(sponsor);
+
+    const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');
+    const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner, false);
+
+    await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send({from: owner});
+
+    const collectionSub = helper.rft.getCollectionObject(collectionId);
+    await collectionSub.confirmSponsorship(sponsor);
+
+    const nextTokenId = await collectionEvm.methods.nextTokenId().call();
+    expect(nextTokenId).to.be.equal('1');
+
+    await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner});
+
+    await collectionEvm.methods.addToCollectionAllowListCross(userCross).send({from: owner});
+    await collectionEvm.methods.setCollectionMintMode(true).send({from: owner});
+
+    const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
+    const sponsorBalanceBefore = await helper.balance.getSubstrate(sponsor.address);
+    const userBalanceBefore =  await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
+
+    {
+      const nextTokenId = await collectionEvm.methods.nextTokenId().call();
+      expect(nextTokenId).to.be.equal('1');
+      const mintingResult = await collectionEvm.methods.mintWithTokenURI(
+        user,
+        'Test URI',
+      ).send({from: user});
+
+      const events = helper.eth.normalizeEvents(mintingResult.events);
+
+
+      expect(events).to.deep.include({
+        address: collectionAddress,
+        event: 'Transfer',
+        args: {
+          from: '0x0000000000000000000000000000000000000000',
+          to: user,
+          tokenId: nextTokenId,
+        },
+      });
+
+      const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
+      const sponsorBalanceAfter = await helper.balance.getSubstrate(sponsor.address);
+      const userBalanceAfter =  await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
+
+      expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
+      expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);
+      expect(userBalanceAfter).to.be.eq(userBalanceBefore);
+      expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;
+    }
+  });
+
+  itEth('Can reassign collection sponsor', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor);
+    const sponsorEth = await helper.eth.createAccountWithBalance(donor);
+    const sponsorCrossEth = helper.ethCrossAccount.fromAddress(sponsorEth);
+    const [sponsorSub] = await helper.arrange.createAccounts([100n], donor);
+    const sponsorCrossSub = helper.ethCrossAccount.fromKeyringPair(sponsorSub);
+
+    const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');
+    const collectionSub = helper.rft.getCollectionObject(collectionId);
+    const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
+
+    // Set and confirm sponsor:
+    await collectionEvm.methods.setCollectionSponsorCross(sponsorCrossEth).send({from: owner});
+    await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsorEth});
+
+    // Can reassign sponsor:
+    await collectionEvm.methods.setCollectionSponsorCross(sponsorCrossSub).send({from: owner});
+    const collectionSponsor = (await collectionSub.getData())?.raw.sponsorship;
+    expect(collectionSponsor).to.deep.eq({Unconfirmed: sponsorSub.address});
+  });
+
+  [
+    'transfer',
+    'transferCross',
+    'transferFrom',
+    'transferFromCross',
+  ].map(testCase =>
+    itEth(`[${testCase}] Check that transfer via EVM spend money from sponsor address`, async ({helper}) => {
+      const owner = await helper.eth.createAccountWithBalance(donor);
+
+      const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');
+      const sponsor = await helper.eth.createAccountWithBalance(donor);
+      const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);
+      const receiver = await helper.eth.createAccountWithBalance(donor);
+      const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
+
+      await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();
+      await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
+
+      const user = await helper.eth.createAccountWithBalance(donor);
+      const userCross = helper.ethCrossAccount.fromAddress(user);
+      await collectionEvm.methods.addCollectionAdminCross(userCross).send();
+
+      const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});
+      const tokenId = result.events.Transfer.returnValues.tokenId;
+
+      const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
+      const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
+      const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
+
+      switch (testCase) {
+        case 'transfer':
+          await collectionEvm.methods.transfer(receiver, tokenId).send({from: user});
+          break;
+        case 'transferCross':
+          await collectionEvm.methods.transferCross(helper.ethCrossAccount.fromAddress(receiver), tokenId).send({from: user});
+          break;
+        case 'transferFrom':
+          await collectionEvm.methods.transferFrom(user, receiver, tokenId).send({from: user});
+          break;
+        case 'transferFromCross':
+          await collectionEvm.methods.transferFromCross(helper.ethCrossAccount.fromAddress(user), helper.ethCrossAccount.fromAddress(receiver), tokenId).send({from: user});
+          break;
+      }
+
+      const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
+      expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);
+      const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
+      expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
+      const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
+      expect(userBalanceAfter).to.be.eq(userBalanceBefore);
+    }));
+});
+
+describe('evm RFT token sponsoring', () => {
+  let donor: IKeyringPair;
+
+  before(async function() {
+    await usingPlaygrounds(async (helper, privateKey) => {
+      requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);
+      donor = await privateKey({filename: __filename});
+    });
+  });
+
+  [
+    'transfer',
+    'transferCross',
+    'transferFrom',
+    'transferFromCross',
+  ].map(testCase =>
+    itEth(`[${testCase}] Check that token piece transfer via EVM spend money from sponsor address`, async ({helper}) => {
+      const owner = await helper.eth.createAccountWithBalance(donor);
+
+      const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');
+      const sponsor = await helper.eth.createAccountWithBalance(donor);
+      const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);
+      const receiver = await helper.eth.createAccountWithBalance(donor);
+      const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
+
+      await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();
+      await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
+
+      const user = await helper.eth.createAccountWithBalance(donor);
+      const userCross = helper.ethCrossAccount.fromAddress(user);
+      await collectionEvm.methods.addCollectionAdminCross(userCross).send();
+
+      const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});
+      const tokenId = result.events.Transfer.returnValues.tokenId;
+
+      const tokenContract = await helper.ethNativeContract.rftTokenById(collectionId, tokenId, user);
+      await tokenContract.methods.repartition(2).send();
+
+      const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
+      const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
+      const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
+
+      switch (testCase) {
+        case 'transfer':
+          await tokenContract.methods.transfer(receiver, 1).send();
+          break;
+        case 'transferCross':
+          await tokenContract.methods.transferCross(helper.ethCrossAccount.fromAddress(receiver), 1).send();
+          break;
+        case 'transferFrom':
+          await tokenContract.methods.transferFrom(user, receiver, 1).send();
+          break;
+        case 'transferFromCross':
+          await tokenContract.methods.transferFromCross(helper.ethCrossAccount.fromAddress(user), helper.ethCrossAccount.fromAddress(receiver), 1).send();
+          break;
+      }
+
+      const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
+      expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);
+      const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
+      expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
+      const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
+      expect(userBalanceAfter).to.be.eq(userBalanceBefore);
+    }));
+
+  [
+    'approve',
+    'approveCross',
+  ].map(testCase =>
+    itEth(`[${testCase}] Check that approve via EVM spend money from sponsor address`, async ({helper}) => {
+      const owner = await helper.eth.createAccountWithBalance(donor);
+
+      const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');
+      const sponsor = await helper.eth.createAccountWithBalance(donor);
+      const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);
+      const receiver = await helper.eth.createAccountWithBalance(donor);
+      const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
+
+      await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();
+      await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
+
+      const user = await helper.eth.createAccountWithBalance(donor);
+      const userCross = helper.ethCrossAccount.fromAddress(user);
+      await collectionEvm.methods.addCollectionAdminCross(userCross).send();
+
+      const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});
+      const tokenId = result.events.Transfer.returnValues.tokenId;
+
+      const tokenContract = await helper.ethNativeContract.rftTokenById(collectionId, tokenId, user);
+      await tokenContract.methods.repartition(2).send();
+
+      const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
+      const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
+      const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
+
+      switch (testCase) {
+        case 'approve':
+          await tokenContract.methods.approve(receiver, 1).send();
+          break;
+        case 'approveCross':
+          await tokenContract.methods.approveCross(helper.ethCrossAccount.fromAddress(receiver), 1).send();
+          break;
+      }
+
+      const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
+      expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);
+      const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
+      expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
+      const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
+      expect(userBalanceAfter).to.be.eq(userBalanceBefore);
+    }));
+});
+
modifiedtests/src/eth/createFTCollection.test.tsdiffbeforeafterboth
--- a/tests/src/eth/createFTCollection.test.ts
+++ b/tests/src/eth/createFTCollection.test.ts
@@ -32,6 +32,7 @@
     });
   });
 
+  // TODO move sponsorship tests to another file:
   // Soft-deprecated
   itEth('[eth] Set sponsorship', async ({helper}) => {
     const owner = await helper.eth.createAccountWithBalance(donor);
@@ -93,6 +94,11 @@
     expect(await collectionHelpers
       .methods.isCollectionExist(collectionAddress).call())
       .to.be.true;
+
+    // check collectionOwner:
+    const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner, true);
+    const collectionOwner = await collectionEvm.methods.collectionOwner().call();
+    expect(helper.address.restoreCrossAccountFromBigInt(BigInt(collectionOwner.sub))).to.eq(helper.address.ethToSubstrate(owner, true));
   });
 
   itEth('destroyCollection', async ({helper}) => {
modifiedtests/src/eth/createNFTCollection.test.tsdiffbeforeafterboth
--- a/tests/src/eth/createNFTCollection.test.ts
+++ b/tests/src/eth/createNFTCollection.test.ts
@@ -134,6 +134,11 @@
     expect(await collectionHelpers
       .methods.isCollectionExist(collectionAddress).call())
       .to.be.true;
+
+    // check collectionOwner:
+    const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner, true);
+    const collectionOwner = await collectionEvm.methods.collectionOwner().call();
+    expect(helper.address.restoreCrossAccountFromBigInt(BigInt(collectionOwner.sub))).to.eq(helper.address.ethToSubstrate(owner, true));
   });
 });
 
modifiedtests/src/eth/createRFTCollection.test.tsdiffbeforeafterboth
--- a/tests/src/eth/createRFTCollection.test.ts
+++ b/tests/src/eth/createRFTCollection.test.ts
@@ -88,27 +88,6 @@
     ]);
   });
 
-  // this test will occasionally fail when in async environment.
-  itEth.skip('Check collection address exist', async ({helper}) => {
-    const owner = await helper.eth.createAccountWithBalance(donor);
-
-    const expectedCollectionId = +(await helper.callRpc('api.rpc.unique.collectionStats')).created + 1;
-    const expectedCollectionAddress = helper.ethAddress.fromCollectionId(expectedCollectionId);
-    const collectionHelpers = await helper.ethNativeContract.collectionHelpers(owner);
-
-    expect(await collectionHelpers.methods
-      .isCollectionExist(expectedCollectionAddress)
-      .call()).to.be.false;
-
-    await collectionHelpers.methods
-      .createRFTCollection('A', 'A', 'A')
-      .send({value: Number(2n * helper.balance.getOneTokenNominal())});
-
-    expect(await collectionHelpers.methods
-      .isCollectionExist(expectedCollectionAddress)
-      .call()).to.be.true;
-  });
-
   // Soft-deprecated
   itEth('[eth] Set sponsorship', async ({helper}) => {
     const owner = await helper.eth.createAccountWithBalance(donor);
@@ -166,6 +145,11 @@
     expect(await collectionHelpers
       .methods.isCollectionExist(collectionAddress).call())
       .to.be.true;
+
+    // check collectionOwner:
+    const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner, true);
+    const collectionOwner = await collectionEvm.methods.collectionOwner().call();
+    expect(helper.address.restoreCrossAccountFromBigInt(BigInt(collectionOwner.sub))).to.eq(helper.address.ethToSubstrate(owner, true));
   });
 });
 
modifiedtests/src/eth/evmCoder.test.tsdiffbeforeafterboth
--- a/tests/src/eth/evmCoder.test.ts
+++ b/tests/src/eth/evmCoder.test.ts
@@ -62,7 +62,7 @@
       donor = await privateKey({filename: __filename});
     });
   });
-  
+
   itEth('Call non-existing function', async ({helper}) => {
     const owner = await helper.eth.createAccountWithBalance(donor);
     const collection = await helper.eth.createNFTCollection(owner, 'EVMCODER', '', 'TEST');
modifiedtests/src/eth/nonFungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/nonFungible.test.ts
+++ b/tests/src/eth/nonFungible.test.ts
@@ -167,7 +167,6 @@
     expect(event.returnValues.to).to.be.equal(receiver);
 
     expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
-    console.log(await contract.methods.crossOwnerOf(tokenId).call());
     expect(await contract.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']);
     // TODO: this wont work right now, need release 919000 first
     // await helper.methods.setOffchainSchema(collectionIdAddress, 'https://offchain-service.local/token-info/{id}').send();
@@ -200,7 +199,6 @@
             },
           };
         });
-
 
       const collection = await helper.nft.mintCollection(minter, {
         tokenPrefix: 'ethp',
modifiedtests/src/eth/proxyContract.test.tsdiffbeforeafterboth
--- a/tests/src/eth/proxyContract.test.ts
+++ b/tests/src/eth/proxyContract.test.ts
@@ -31,11 +31,11 @@
     const deployer = await helper.eth.createAccountWithBalance(donor);
     const caller = await helper.eth.createAccountWithBalance(donor);
     const proxyContract = await deployProxyContract(helper, deployer);
-    
+
     const realContractV1 = await deployRealContractV1(helper, deployer);
     const realContractV1proxy = new helper.web3!.eth.Contract(realContractV1.options.jsonInterface, proxyContract.options.address, {from: caller, gas: helper.eth.DEFAULT_GAS});
     await proxyContract.methods.updateVersion(realContractV1.options.address).send();
-    
+
     await realContractV1proxy.methods.flip().send();
     await realContractV1proxy.methods.flip().send();
     await realContractV1proxy.methods.flip().send();
modifiedtests/src/eth/scheduling.test.tsdiffbeforeafterboth
--- a/tests/src/eth/scheduling.test.ts
+++ b/tests/src/eth/scheduling.test.ts
@@ -53,7 +53,7 @@
       );
 
     expect(await flipper.methods.getValue().call()).to.be.equal(initialValue);
-    
+
     await helper.wait.newBlocks(waitForBlocks + 1);
     expect(await flipper.methods.getValue().call()).to.be.not.equal(initialValue);
 
modifiedtests/src/eth/util/index.tsdiffbeforeafterboth
--- a/tests/src/eth/util/index.ts
+++ b/tests/src/eth/util/index.ts
@@ -58,9 +58,9 @@
     silentConsole.disable();
   }
 };
-  
+
 export function itEth(name: string, cb: (apis: { helper: EthUniqueHelper, privateKey: (seed: string | {filename: string}) => Promise<IKeyringPair> }) => any, opts: { only?: boolean, skip?: boolean, requiredPallets?: string[] } = {}) {
-  (opts.only ? it.only : 
+  (opts.only ? it.only :
     opts.skip ? it.skip : it)(name, async function() {
     await usingEthPlaygrounds(async (helper, privateKey) => {
       if (opts.requiredPallets) {
modifiedtests/src/fungible.test.tsdiffbeforeafterboth
--- a/tests/src/fungible.test.ts
+++ b/tests/src/fungible.test.ts
@@ -43,7 +43,7 @@
     expect(itemCountAfter).to.be.equal(defaultTokenId);
     expect(aliceBalance).to.be.equal(U128_MAX);
   });
-  
+
   itSub('RPC method tokenOnewrs for fungible collection and token', async ({helper}) => {
     const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
     const facelessCrowd = (await helper.arrange.createAccounts(Array(7).fill(0n), donor)).map(keyring => {return {Substrate: keyring.address};});
@@ -54,22 +54,22 @@
 
     await collection.transfer(alice, {Substrate: bob.address}, 1000n);
     await collection.transfer(alice, ethAcc, 900n);
-    
+
     for (let i = 0; i < 7; i++) {
       await collection.transfer(alice, facelessCrowd[i], 1n);
-    } 
+    }
 
     const owners = await collection.getTop10Owners();
 
     // What to expect
     expect(owners).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
     expect(owners.length).to.be.equal(10);
-    
+
     const [eleven] = await helper.arrange.createAccounts([0n], donor);
     expect(await collection.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
     expect((await collection.getTop10Owners()).length).to.be.equal(10);
   });
-  
+
   itSub('Transfer token', async ({helper}) => {
     const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
     const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
@@ -108,7 +108,7 @@
     expect(await collection.doesTokenExist(0)).to.be.true;
     expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);
   });
-  
+
   itSub('Burn all tokens ', async ({helper}) => {
     const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
     await collection.mint(alice, 500n);
@@ -127,7 +127,7 @@
     await collection.mint(alice, 100n);
 
     expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(100n);
-    
+
     expect(await collection.approveTokens(alice, {Substrate: bob.address}, 60n)).to.be.true;
     expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(60n);
     expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(0n);
@@ -169,11 +169,11 @@
     // 1. Alice cannot transfer more than 0 tokens if balance low:
     await expect(collection.transfer(alice, {Substrate: charlie.address}, 1n)).to.be.rejectedWith('common.TokenValueTooLow');
     await expect(collection.transfer(alice, {Substrate: charlie.address}, 100n)).to.be.rejectedWith('common.TokenValueTooLow');
-    
+
     // 2. Alice cannot transfer non-existing token:
     await expect(nonExistingCollection.transfer(alice, {Substrate: charlie.address}, 0n)).to.be.rejectedWith('common.CollectionNotFound');
     await expect(nonExistingCollection.transfer(alice, {Substrate: charlie.address}, 1n)).to.be.rejectedWith('common.CollectionNotFound');
-    
+
     // 3. Zero transfer allowed (EIP-20):
     await collection.transfer(bob, {Substrate: charlie.address}, 0n);
     // 3.1 even if the balance = 0
modifiedtests/src/inflation.seqtest.tsdiffbeforeafterboth
--- a/tests/src/inflation.seqtest.ts
+++ b/tests/src/inflation.seqtest.ts
@@ -26,7 +26,7 @@
       superuser = await privateKey('//Alice');
     });
   });
-  
+
   itSub('First year inflation is 10%', async ({helper}) => {
     // Make sure non-sudo can't start inflation
     const [bob] = await helper.arrange.createAccounts([10n], superuser);
modifiedtests/src/interfaces/unique/definitions.tsdiffbeforeafterboth
--- a/tests/src/interfaces/unique/definitions.ts
+++ b/tests/src/interfaces/unique/definitions.ts
@@ -38,39 +38,39 @@
   types: {},
   rpc: {
     accountTokens: fun(
-      'Get tokens owned by an account in a collection', 
-      [collectionParam, crossAccountParam()], 
+      'Get tokens owned by an account in a collection',
+      [collectionParam, crossAccountParam()],
       'Vec<u32>',
     ),
     collectionTokens: fun(
-      'Get tokens contained within a collection', 
-      [collectionParam], 
+      'Get tokens contained within a collection',
+      [collectionParam],
       'Vec<u32>',
     ),
     tokenExists: fun(
-      'Check if the token exists', 
-      [collectionParam, tokenParam], 
+      'Check if the token exists',
+      [collectionParam, tokenParam],
       'bool',
     ),
 
     tokenOwner: fun(
-      'Get the token owner', 
-      [collectionParam, tokenParam], 
+      'Get the token owner',
+      [collectionParam, tokenParam],
       `Option<${CROSS_ACCOUNT_ID_TYPE}>`,
     ),
     topmostTokenOwner: fun(
-      'Get the topmost token owner in the hierarchy of a possibly nested token', 
-      [collectionParam, tokenParam], 
+      'Get the topmost token owner in the hierarchy of a possibly nested token',
+      [collectionParam, tokenParam],
       `Option<${CROSS_ACCOUNT_ID_TYPE}>`,
     ),
     tokenOwners: fun(
-      'Returns 10 tokens owners in no particular order', 
-      [collectionParam, tokenParam], 
+      'Returns 10 tokens owners in no particular order',
+      [collectionParam, tokenParam],
       `Vec<${CROSS_ACCOUNT_ID_TYPE}>`,
     ),
     tokenChildren: fun(
-      'Get tokens nested directly into the token', 
-      [collectionParam, tokenParam], 
+      'Get tokens nested directly into the token',
+      [collectionParam, tokenParam],
       'Vec<UpDataStructsTokenChild>',
     ),
 
@@ -91,13 +91,13 @@
     ),
 
     constMetadata: fun(
-      'Get token constant metadata', 
-      [collectionParam, tokenParam], 
+      'Get token constant metadata',
+      [collectionParam, tokenParam],
       'Vec<u8>',
     ),
     variableMetadata: fun(
-      'Get token variable metadata', 
-      [collectionParam, tokenParam], 
+      'Get token variable metadata',
+      [collectionParam, tokenParam],
       'Vec<u8>',
     ),
 
@@ -107,77 +107,77 @@
       'UpDataStructsTokenData',
     ),
     totalSupply: fun(
-      'Get the amount of distinctive tokens present in a collection', 
-      [collectionParam], 
+      'Get the amount of distinctive tokens present in a collection',
+      [collectionParam],
       'u32',
     ),
 
     accountBalance: fun(
-      'Get the amount of any user tokens owned by an account', 
-      [collectionParam, crossAccountParam()], 
+      'Get the amount of any user tokens owned by an account',
+      [collectionParam, crossAccountParam()],
       'u32',
     ),
     balance: fun(
-      'Get the amount of a specific token owned by an account', 
-      [collectionParam, crossAccountParam(), tokenParam], 
+      'Get the amount of a specific token owned by an account',
+      [collectionParam, crossAccountParam(), tokenParam],
       'u128',
     ),
     allowance: fun(
-      'Get the amount of currently possible sponsored transactions on a token for the fee to be taken off a sponsor', 
-      [collectionParam, crossAccountParam('sender'), crossAccountParam('spender'), tokenParam], 
+      'Get the amount of currently possible sponsored transactions on a token for the fee to be taken off a sponsor',
+      [collectionParam, crossAccountParam('sender'), crossAccountParam('spender'), tokenParam],
       'u128',
     ),
 
     adminlist: fun(
-      'Get the list of admin accounts of a collection', 
-      [collectionParam], 
+      'Get the list of admin accounts of a collection',
+      [collectionParam],
       'Vec<PalletEvmAccountBasicCrossAccountIdRepr>',
     ),
     allowlist: fun(
-      'Get the list of accounts allowed to operate within a collection', 
-      [collectionParam], 
+      'Get the list of accounts allowed to operate within a collection',
+      [collectionParam],
       'Vec<PalletEvmAccountBasicCrossAccountIdRepr>',
     ),
     allowed: fun(
-      'Check if a user is allowed to operate within a collection', 
-      [collectionParam, crossAccountParam()], 
+      'Check if a user is allowed to operate within a collection',
+      [collectionParam, crossAccountParam()],
       'bool',
     ),
 
     lastTokenId: fun(
-      'Get the last token ID created in a collection', 
-      [collectionParam], 
+      'Get the last token ID created in a collection',
+      [collectionParam],
       'u32',
     ),
     collectionById: fun(
-      'Get a collection by the specified ID', 
-      [collectionParam], 
+      'Get a collection by the specified ID',
+      [collectionParam],
       'Option<UpDataStructsRpcCollection>',
     ),
     collectionStats: fun(
-      'Get chain stats about collections', 
-      [], 
+      'Get chain stats about collections',
+      [],
       'UpDataStructsCollectionStats',
     ),
 
     nextSponsored: fun(
-      'Get the number of blocks until sponsoring a transaction is available', 
-      [collectionParam, crossAccountParam(), tokenParam], 
+      'Get the number of blocks until sponsoring a transaction is available',
+      [collectionParam, crossAccountParam(), tokenParam],
       'Option<u64>',
     ),
     effectiveCollectionLimits: fun(
-      'Get effective collection limits', 
-      [collectionParam], 
+      'Get effective collection limits',
+      [collectionParam],
       'Option<UpDataStructsCollectionLimits>',
     ),
     totalPieces: fun(
-      'Get the total amount of pieces of an RFT', 
-      [collectionParam, tokenParam], 
+      'Get the total amount of pieces of an RFT',
+      [collectionParam, tokenParam],
       'Option<u128>',
     ),
     allowanceForAll: fun(
-      'Tells whether the given `owner` approves the `operator`.', 
-      [collectionParam, crossAccountParam('owner'), crossAccountParam('operator')], 
+      'Tells whether the given `owner` approves the `operator`.',
+      [collectionParam, crossAccountParam('owner'), crossAccountParam('operator')],
       'Option<bool>',
     ),
   },
modifiedtests/src/limits.test.tsdiffbeforeafterboth
--- a/tests/src/limits.test.ts
+++ b/tests/src/limits.test.ts
@@ -30,7 +30,7 @@
   itSub.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async ({helper}) => {
     const collection = await helper.nft.mintCollection(alice, {});
     await collection.setLimits(alice, {accountTokenOwnershipLimit: 20});
-    
+
     for(let i = 0; i < 10; i++){
       await expect(collection.mintToken(alice)).to.be.not.rejected;
     }
@@ -40,14 +40,14 @@
     }
     await collection.burn(alice);
   });
-  
+
   itSub('Collection limits allow lower number than chain limits, collection limits are enforced', async ({helper}) => {
     const collection = await helper.nft.mintCollection(alice, {});
     await collection.setLimits(alice, {accountTokenOwnershipLimit: 1});
 
     await collection.mintToken(alice);
     await expect(collection.mintToken(alice)).to.be.rejectedWith(/common\.AccountTokenLimitExceeded/);
-    
+
     await collection.burnToken(alice, 1);
     await expect(collection.burn(alice)).to.be.not.rejected;
   });
@@ -68,7 +68,7 @@
   itSub.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async ({helper}) => {
     const collection = await helper.rft.mintCollection(alice, {});
     await collection.setLimits(alice, {accountTokenOwnershipLimit: 20});
-    
+
     for(let i = 0; i < 10; i++){
       await expect(collection.mintToken(alice, 10n)).to.be.not.rejected;
     }
@@ -85,7 +85,7 @@
 
     await collection.mintToken(alice);
     await expect(collection.mintToken(alice)).to.be.rejectedWith(/common\.AccountTokenLimitExceeded/);
-    
+
     await collection.burnToken(alice, 1);
     await expect(collection.burn(alice)).to.be.not.rejected;
   });
@@ -314,7 +314,7 @@
 
     await collection.setSponsor(alice, alice.address);
     await collection.confirmSponsorship(alice);
-    
+
     await token.transfer(alice, {Substrate: bob.address});
     const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);
 
@@ -345,7 +345,7 @@
 
     await collection.setSponsor(alice, alice.address);
     await collection.confirmSponsorship(alice);
-    
+
     await collection.transfer(alice, {Substrate: bob.address}, 2n);
     const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);
 
@@ -387,7 +387,7 @@
 
     await collection.setSponsor(alice, alice.address);
     await collection.confirmSponsorship(alice);
-    
+
     await token.transfer(alice, {Substrate: bob.address}, 2n);
     const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);
 
@@ -408,17 +408,17 @@
       [alice] = await helper.arrange.createAccounts([10n], donor);
     });
   });
-  
+
   itSub('Effective collection limits', async ({helper}) => {
     const collection = await helper.nft.mintCollection(alice, {});
-    await collection.setLimits(alice, {ownerCanTransfer: true});    
-    
-    { 
+    await collection.setLimits(alice, {ownerCanTransfer: true});
+
+    {
       // Check that limits are undefined
       const collectionInfo = await collection.getData();
       const limits = collectionInfo?.raw.limits;
       expect(limits).to.be.any;
-      
+
       expect(limits.accountTokenOwnershipLimit).to.be.null;
       expect(limits.sponsoredDataSize).to.be.null;
       expect(limits.sponsoredDataRateLimit).to.be.null;
@@ -449,7 +449,7 @@
       expect(limits.transfersEnabled).to.be.true;
     }
 
-    { 
+    {
       // Check the values for collection limits
       await collection.setLimits(alice, {
         accountTokenOwnershipLimit: 99_999,
modifiedtests/src/nesting/collectionProperties.seqtest.tsdiffbeforeafterboth
--- a/tests/src/nesting/collectionProperties.seqtest.ts
+++ b/tests/src/nesting/collectionProperties.seqtest.ts
@@ -20,7 +20,7 @@
 describe('Integration Test: Collection Properties with sudo', () => {
   let superuser: IKeyringPair;
   let alice: IKeyringPair;
-  
+
   before(async () => {
     await usingPlaygrounds(async (helper, privateKey) => {
       superuser = await privateKey('//Alice');
@@ -32,7 +32,7 @@
   [
     {mode: 'nft' as const, requiredPallets: []},
     {mode: 'ft' as const, requiredPallets: []},
-    {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]}, 
+    {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
   ].map(testSuite => describe(`${testSuite.mode.toUpperCase()}`, () => {
     before(async function() {
       // eslint-disable-next-line require-await
modifiedtests/src/nesting/collectionProperties.test.tsdiffbeforeafterboth
--- a/tests/src/nesting/collectionProperties.test.ts
+++ b/tests/src/nesting/collectionProperties.test.ts
@@ -20,14 +20,14 @@
 describe('Integration Test: Collection Properties', () => {
   let alice: IKeyringPair;
   let bob: IKeyringPair;
-  
+
   before(async () => {
     await usingPlaygrounds(async (helper, privateKey) => {
       const donor = await privateKey({filename: __filename});
       [alice, bob] = await helper.arrange.createAccounts([200n, 10n], donor);
     });
   });
-  
+
   itSub('Properties are initially empty', async ({helper}) => {
     const collection = await helper.nft.mintCollection(alice);
     expect(await collection.getProperties()).to.be.empty;
@@ -36,7 +36,7 @@
   [
     {mode: 'nft' as const, requiredPallets: []},
     {mode: 'ft' as const, requiredPallets: []},
-    {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]}, 
+    {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
   ].map(testSuite => describe(`${testSuite.mode.toUpperCase()}`, () => {
     before(async function() {
       // eslint-disable-next-line require-await
@@ -50,37 +50,37 @@
 
       // As owner
       await expect(collection.setProperties(alice, [{key: 'electron', value: 'come bond'}])).to.be.fulfilled;
-    
+
       await collection.addAdmin(alice, {Substrate: bob.address});
-    
+
       // As administrator
       await expect(collection.setProperties(bob, [{key: 'black_hole'}])).to.be.fulfilled;
-    
+
       const properties = await collection.getProperties();
       expect(properties).to.include.deep.members([
         {key: 'electron', value: 'come bond'},
         {key: 'black_hole', value: ''},
       ]);
     });
-    
+
     itSub('Check valid names for collection properties keys', async ({helper}) =>  {
       const collection = await helper[testSuite.mode].mintCollection(alice);
 
       // alpha symbols
       await expect(collection.setProperties(alice, [{key: 'answer'}])).to.be.fulfilled;
-    
+
       // numeric symbols
       await expect(collection.setProperties(alice, [{key: '451'}])).to.be.fulfilled;
-    
+
       // underscore symbol
       await expect(collection.setProperties(alice, [{key: 'black_hole'}])).to.be.fulfilled;
-    
+
       // dash symbol
       await expect(collection.setProperties(alice, [{key: '-'}])).to.be.fulfilled;
-    
+
       // dot symbol
       await expect(collection.setProperties(alice, [{key: 'once.in.a.long.long.while...', value: 'you get a little lost'}])).to.be.fulfilled;
-    
+
       const properties = await collection.getProperties();
       expect(properties).to.include.deep.members([
         {key: 'answer', value: ''},
@@ -90,29 +90,29 @@
         {key: 'once.in.a.long.long.while...', value: 'you get a little lost'},
       ]);
     });
-  
+
     itSub('Changes properties of a collection', async ({helper}) =>  {
       const collection = await helper[testSuite.mode].mintCollection(alice);
 
       await expect(collection.setProperties(alice, [{key: 'electron', value: 'come bond'}, {key: 'black_hole', value: ''}])).to.be.fulfilled;
-    
+
       // Mutate the properties
       await expect(collection.setProperties(alice, [{key: 'black_hole', value: 'LIGO'}])).to.be.fulfilled;
-    
+
       const properties = await collection.getProperties();
       expect(properties).to.include.deep.members([
         {key: 'electron', value: 'come bond'},
         {key: 'black_hole', value: 'LIGO'},
       ]);
     });
-  
+
     itSub('Deletes properties of a collection', async ({helper}) =>  {
       const collection = await helper[testSuite.mode].mintCollection(alice);
 
       await expect(collection.setProperties(alice, [{key: 'electron', value: 'come bond'}, {key: 'black_hole', value: 'LIGO'}])).to.be.fulfilled;
-    
+
       await expect(collection.deleteProperties(alice, ['electron'])).to.be.fulfilled;
-    
+
       const properties = await collection.getProperties(['black_hole', 'electron']);
       expect(properties).to.be.deep.equal([
         {key: 'black_hole', value: 'LIGO'},
@@ -201,11 +201,11 @@
     });
   }));
 });
-  
+
 describe('Negative Integration Test: Collection Properties', () => {
   let alice: IKeyringPair;
   let bob: IKeyringPair;
-  
+
   before(async () => {
     await usingPlaygrounds(async (helper, privateKey) => {
       const donor = await privateKey({filename: __filename});
@@ -216,7 +216,7 @@
   [
     {mode: 'nft' as const, requiredPallets: []},
     {mode: 'ft' as const, requiredPallets: []},
-    {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]}, 
+    {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
   ].map(testSuite => describe(`${testSuite.mode.toUpperCase()}`, () => {
     before(async function() {
       // eslint-disable-next-line require-await
@@ -224,21 +224,21 @@
         requirePalletsOrSkip(this, helper, testSuite.requiredPallets);
       });
     });
-    
+
     itSub('Fails to set properties in a collection if not its onwer/administrator', async ({helper}) =>  {
       const collection = await helper[testSuite.mode].mintCollection(alice);
 
       await expect(collection.setProperties(bob, [{key: 'electron', value: 'come bond'}, {key: 'black_hole', value: 'LIGO'}]))
         .to.be.rejectedWith(/common\.NoPermission/);
-    
+
       expect(await collection.getProperties()).to.be.empty;
     });
-    
+
     itSub('Fails to set properties that exceed the limits', async ({helper}) =>  {
       const collection = await helper[testSuite.mode].mintCollection(alice);
 
       const spaceLimit = (await (collection.helper!.api! as any).query.common.collectionProperties(collection.collectionId)).spaceLimit.toNumber();
-      
+
       // Mute the general tx parsing error, too many bytes to process
       {
         console.error = () => {};
@@ -246,17 +246,17 @@
           {key: 'electron', value: 'low high '.repeat(Math.ceil(spaceLimit! / 9))},
         ])).to.be.rejected;
       }
-    
+
       expect(await collection.getProperties(['electron'])).to.be.empty;
-    
+
       await expect(collection.setProperties(alice, [
-        {key: 'electron', value: 'low high '.repeat(Math.ceil(spaceLimit! / 18))}, 
-        {key: 'black_hole', value: '0'.repeat(Math.ceil(spaceLimit! / 2))}, 
+        {key: 'electron', value: 'low high '.repeat(Math.ceil(spaceLimit! / 18))},
+        {key: 'black_hole', value: '0'.repeat(Math.ceil(spaceLimit! / 2))},
       ])).to.be.rejectedWith(/common\.NoSpaceForProperty/);
-    
+
       expect(await collection.getProperties(['electron', 'black_hole'])).to.be.empty;
     });
-    
+
     itSub('Fails to set more properties than it is allowed', async ({helper}) =>  {
       const collection = await helper[testSuite.mode].mintCollection(alice);
 
@@ -267,10 +267,10 @@
           value: Math.random() > 0.5 ? 'high' : 'low',
         });
       }
-    
+
       await expect(collection.setProperties(alice, propertiesToBeSet)).
         to.be.rejectedWith(/common\.PropertyLimitReached/);
-    
+
       expect(await collection.getProperties()).to.be.empty;
     });
 
@@ -282,34 +282,34 @@
         [{key: 'Mr/Sandman', value: 'Bring me a gene'}],
         [{key: 'déjà vu', value: 'hmm...'}],
       ];
-    
+
       for (let i = 0; i < invalidProperties.length; i++) {
         await expect(
-          collection.setProperties(alice, invalidProperties[i]), 
+          collection.setProperties(alice, invalidProperties[i]),
           `on rejecting the new badly-named property #${i}`,
         ).to.be.rejectedWith(/common\.InvalidCharacterInPropertyKey/);
       }
-    
+
       await expect(
-        collection.setProperties(alice, [{key: '', value: 'nothing must not exist'}]), 
+        collection.setProperties(alice, [{key: '', value: 'nothing must not exist'}]),
         'on rejecting an unnamed property',
       ).to.be.rejectedWith(/common\.EmptyPropertyKey/);
-    
+
       await expect(
-        collection.setProperties(alice, [{key: 'CRISPR-Cas9', value: 'rewriting nature!'}]), 
+        collection.setProperties(alice, [{key: 'CRISPR-Cas9', value: 'rewriting nature!'}]),
         'on setting the correctly-but-still-badly-named property',
       ).to.be.fulfilled;
-    
+
       const keys = invalidProperties.flatMap(propertySet => propertySet.map(property => property.key)).concat('CRISPR-Cas9').concat('');
-    
+
       const properties = await collection.getProperties(keys);
       expect(properties).to.be.deep.equal([
         {key: 'CRISPR-Cas9', value: 'rewriting nature!'},
       ]);
-    
+
       for (let i = 0; i < invalidProperties.length; i++) {
         await expect(
-          collection.deleteProperties(alice, invalidProperties[i].map(propertySet => propertySet.key)), 
+          collection.deleteProperties(alice, invalidProperties[i].map(propertySet => propertySet.key)),
           `on trying to delete the non-existent badly-named property #${i}`,
         ).to.be.rejectedWith(/common\.InvalidCharacterInPropertyKey/);
       }
@@ -326,4 +326,3 @@
     });
   }));
 });
-  
\ No newline at end of file
modifiedtests/src/nesting/graphs.test.tsdiffbeforeafterboth
--- a/tests/src/nesting/graphs.test.ts
+++ b/tests/src/nesting/graphs.test.ts
@@ -56,7 +56,7 @@
     // to self
     await expect(
       tokens[0].nest(alice, tokens[0]),
-      'first transaction',  
+      'first transaction',
     ).to.be.rejectedWith(/structure\.OuroborosDetected/);
     // to nested part of graph
     await expect(
modifiedtests/src/nesting/nest.test.tsdiffbeforeafterboth
--- a/tests/src/nesting/nest.test.ts
+++ b/tests/src/nesting/nest.test.ts
@@ -36,7 +36,7 @@
     const nestedToken = await collection.mintToken(alice, targetToken.nestingAccount());
     expect(await nestedToken.getTopmostOwner()).to.be.deep.equal({Substrate: alice.address});
     expect(await nestedToken.getOwner()).to.be.deep.equal(targetToken.nestingAccount().toLowerCase());
-    
+
     // Create a token to be nested
     const newToken = await collection.mintToken(alice);
 
@@ -66,7 +66,7 @@
     // Create a nested token
     const tokenC = await collection.mintToken(alice, tokenA.nestingAccount());
     expect(await tokenC.getOwner()).to.be.deep.equal(tokenA.nestingAccount().toLowerCase());
-    
+
     // Transfer the nested token to another token
     await expect(tokenC.transferFrom(alice, tokenA.nestingAccount(), tokenB.nestingAccount())).to.be.fulfilled;
     expect(await tokenC.getTopmostOwner()).to.be.deep.equal({Substrate: alice.address});
@@ -76,7 +76,7 @@
   itSub('Checks token children', async ({helper}) => {
     const collectionA = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}});
     const collectionB = await helper.ft.mintCollection(alice);
-    
+
     const targetToken = await collectionA.mintToken(alice);
     expect((await targetToken.getChildren()).length).to.be.equal(0, 'Children length check at creation');
 
@@ -108,7 +108,7 @@
       {tokenId: 0, collectionId: collectionB.collectionId},
     ], 'Children contents check at nesting #4 (from another collection)')
       .and.be.length(2, 'Children length check at nesting #4 (from another collection)');
-    
+
     // Move part of the fungible token inside token A deeper in the nesting tree
     await collectionB.transferFrom(alice, targetToken.nestingAccount(), tokenA.nestingAccount(), 1n);
     expect(await targetToken.getChildren()).to.be.have.deep.members([
modifiedtests/src/nesting/propertyPermissions.test.tsdiffbeforeafterboth
--- a/tests/src/nesting/propertyPermissions.test.ts
+++ b/tests/src/nesting/propertyPermissions.test.ts
@@ -21,94 +21,94 @@
 describe('Integration Test: Access Rights to Token Properties', () => {
   let alice: IKeyringPair;
   let bob: IKeyringPair;
-  
+
   before(async () => {
     await usingPlaygrounds(async (helper, privateKey) => {
       const donor = await privateKey({filename: __filename});
       [alice, bob] = await helper.arrange.createAccounts([100n, 10n], donor);
     });
   });
-    
+
   itSub('Reads access rights to properties of a collection', async ({helper}) =>  {
     const collection = await helper.nft.mintCollection(alice);
     const propertyRights = (await helper.callRpc('api.query.common.collectionPropertyPermissions', [collection.collectionId])).toJSON();
     expect(propertyRights).to.be.empty;
   });
-    
-  async function testSetsAccessRightsToProperties(collection: UniqueNFTCollection | UniqueRFTCollection) {  
+
+  async function testSetsAccessRightsToProperties(collection: UniqueNFTCollection | UniqueRFTCollection) {
     await expect(collection.setTokenPropertyPermissions(alice, [{key: 'skullduggery', permission: {mutable: true}}]))
       .to.be.fulfilled;
-  
+
     await collection.addAdmin(alice, {Substrate: bob.address});
-  
+
     await expect(collection.setTokenPropertyPermissions(bob, [{key: 'mindgame', permission: {collectionAdmin: true, tokenOwner: false}}]))
       .to.be.fulfilled;
-  
+
     const propertyRights = await collection.getPropertyPermissions(['skullduggery', 'mindgame']);
     expect(propertyRights).to.include.deep.members([
       {key: 'skullduggery', permission: {mutable: true, collectionAdmin: false, tokenOwner: false}},
       {key: 'mindgame', permission: {mutable: false, collectionAdmin: true, tokenOwner: false}},
     ]);
   }
-  
+
   itSub('Sets access rights to properties of a collection (NFT)', async ({helper}) =>  {
     await testSetsAccessRightsToProperties(await helper.nft.mintCollection(alice));
   });
-  
+
   itSub.ifWithPallets('Sets access rights to properties of a collection (ReFungible)', [Pallets.ReFungible], async ({helper}) => {
     await testSetsAccessRightsToProperties(await helper.rft.mintCollection(alice));
   });
-    
+
   async function testChangesAccessRightsToProperty(collection: UniqueNFTCollection | UniqueRFTCollection) {
     await expect(collection.setTokenPropertyPermissions(alice, [{key: 'skullduggery', permission: {mutable: true, collectionAdmin: true}}]))
       .to.be.fulfilled;
-  
+
     await expect(collection.setTokenPropertyPermissions(alice, [{key: 'skullduggery', permission: {mutable: false, tokenOwner: true}}]))
       .to.be.fulfilled;
-  
+
     const propertyRights = await collection.getPropertyPermissions();
     expect(propertyRights).to.be.deep.equal([
       {key: 'skullduggery', permission: {'mutable': false, 'collectionAdmin': false, 'tokenOwner': true}},
     ]);
   }
-  
+
   itSub('Changes access rights to properties of a NFT collection', async ({helper}) =>  {
     await testChangesAccessRightsToProperty(await helper.nft.mintCollection(alice));
   });
-  
+
   itSub.ifWithPallets('Changes access rights to properties of a ReFungible collection', [Pallets.ReFungible], async ({helper}) => {
     await testChangesAccessRightsToProperty(await helper.rft.mintCollection(alice));
   });
 });
-  
+
 describe('Negative Integration Test: Access Rights to Token Properties', () => {
   let alice: IKeyringPair;
   let bob: IKeyringPair;
-  
+
   before(async () => {
     await usingPlaygrounds(async (helper, privateKey) => {
       const donor = await privateKey({filename: __filename});
       [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);
     });
   });
-  
+
   async function testPreventsFromSettingAccessRightsNotAdminOrOwner(collection: UniqueNFTCollection | UniqueRFTCollection) {
     await expect(collection.setTokenPropertyPermissions(bob, [{key: 'skullduggery', permission: {mutable: true, tokenOwner: true}}]))
       .to.be.rejectedWith(/common\.NoPermission/);
-  
+
     const propertyRights = await collection.getPropertyPermissions(['skullduggery']);
     expect(propertyRights).to.be.empty;
   }
-  
+
   itSub('Prevents from setting access rights to properties of a NFT collection if not an onwer/admin', async ({helper}) =>  {
     await testPreventsFromSettingAccessRightsNotAdminOrOwner(await helper.nft.mintCollection(alice));
   });
-  
+
   itSub.ifWithPallets('Prevents from setting access rights to properties of a ReFungible collection if not an onwer/admin', [Pallets.ReFungible], async ({helper}) => {
     await testPreventsFromSettingAccessRightsNotAdminOrOwner(await helper.rft.mintCollection(alice));
   });
-  
-  async function testPreventFromAddingTooManyPossibleProperties(collection: UniqueNFTCollection | UniqueRFTCollection) {  
+
+  async function testPreventFromAddingTooManyPossibleProperties(collection: UniqueNFTCollection | UniqueRFTCollection) {
     const constitution = [];
     for (let i = 0; i < 65; i++) {
       constitution.push({
@@ -116,82 +116,82 @@
         permission: Math.random() > 0.5 ? {mutable: true, collectionAdmin: true, tokenOwner: true} : {},
       });
     }
-  
+
     await expect(collection.setTokenPropertyPermissions(alice, constitution))
       .to.be.rejectedWith(/common\.PropertyLimitReached/);
-  
+
     const propertyRights = await collection.getPropertyPermissions();
     expect(propertyRights).to.be.empty;
   }
-  
+
   itSub('Prevents from adding too many possible properties (NFT)', async ({helper}) =>  {
     await testPreventFromAddingTooManyPossibleProperties(await helper.nft.mintCollection(alice));
   });
-  
+
   itSub.ifWithPallets('Prevents from adding too many possible properties (ReFungible)', [Pallets.ReFungible], async ({helper}) => {
     await testPreventFromAddingTooManyPossibleProperties(await helper.rft.mintCollection(alice));
   });
-  
+
   async function testPreventAccessRightsModifiedIfConstant(collection: UniqueNFTCollection | UniqueRFTCollection) {
     await expect(collection.setTokenPropertyPermissions(alice, [{key: 'skullduggery', permission: {mutable: false, tokenOwner: true}}]))
       .to.be.fulfilled;
-  
+
     await expect(collection.setTokenPropertyPermissions(alice, [{key: 'skullduggery', permission: {collectionAdmin: true}}]))
       .to.be.rejectedWith(/common\.NoPermission/);
-  
+
     const propertyRights = await collection.getPropertyPermissions(['skullduggery']);
     expect(propertyRights).to.deep.equal([
       {key: 'skullduggery', permission: {'mutable': false, 'collectionAdmin': false, 'tokenOwner': true}},
     ]);
   }
-  
+
   itSub('Prevents access rights to be modified if constant (NFT)', async ({helper}) =>  {
     await testPreventAccessRightsModifiedIfConstant(await helper.nft.mintCollection(alice));
   });
-  
+
   itSub.ifWithPallets('Prevents access rights to be modified if constant (ReFungible)', [Pallets.ReFungible], async ({helper}) => {
     await testPreventAccessRightsModifiedIfConstant(await helper.rft.mintCollection(alice));
   });
-  
+
   async function testPreventsAddingPropertiesWithInvalidNames(collection: UniqueNFTCollection | UniqueRFTCollection) {
     const invalidProperties = [
       [{key: 'skullduggery', permission: {tokenOwner: true}}, {key: 'im possible', permission: {collectionAdmin: true}}],
       [{key: 'G#4', permission: {tokenOwner: true}}],
       [{key: 'HÆMILTON', permission: {mutable: false, collectionAdmin: true, tokenOwner: true}}],
     ];
-  
+
     for (let i = 0; i < invalidProperties.length; i++) {
       await expect(
-        collection.setTokenPropertyPermissions(alice, invalidProperties[i]), 
+        collection.setTokenPropertyPermissions(alice, invalidProperties[i]),
         `on setting the new badly-named property #${i}`,
       ).to.be.rejectedWith(/common\.InvalidCharacterInPropertyKey/);
     }
-  
+
     await expect(
-      collection.setTokenPropertyPermissions(alice, [{key: '', permission: {}}]), 
+      collection.setTokenPropertyPermissions(alice, [{key: '', permission: {}}]),
       'on rejecting an unnamed property',
     ).to.be.rejectedWith(/common\.EmptyPropertyKey/);
-  
+
     const correctKey = '--0x03116e387820CA05'; // PolkadotJS would parse this as an already encoded hex-string
     await expect(
       collection.setTokenPropertyPermissions(alice, [
         {key: correctKey, permission: {collectionAdmin: true}},
-      ]), 
+      ]),
       'on setting the correctly-but-still-badly-named property',
     ).to.be.fulfilled;
-  
+
     const keys = invalidProperties.flatMap(propertySet => propertySet.map(property => property.key)).concat(correctKey).concat('');
-  
+
     const propertyRights = await collection.getPropertyPermissions(keys);
     expect(propertyRights).to.be.deep.equal([
       {key: correctKey, permission: {mutable: false, collectionAdmin: true, tokenOwner: false}},
     ]);
   }
-  
+
   itSub('Prevents adding properties with invalid names (NFT)', async ({helper}) =>  {
     await testPreventsAddingPropertiesWithInvalidNames(await helper.nft.mintCollection(alice));
   });
-  
+
   itSub.ifWithPallets('Prevents adding properties with invalid names (ReFungible)', [Pallets.ReFungible], async ({helper}) => {
     await testPreventsAddingPropertiesWithInvalidNames(await helper.rft.mintCollection(alice));
   });
modifiedtests/src/nesting/tokenProperties.seqtest.tsdiffbeforeafterboth
--- a/tests/src/nesting/tokenProperties.seqtest.ts
+++ b/tests/src/nesting/tokenProperties.seqtest.ts
@@ -31,7 +31,7 @@
 
   [
     {mode: 'nft' as const, pieces: undefined, requiredPallets: []},
-    {mode: 'rft' as const, pieces: 100n, requiredPallets: [Pallets.ReFungible]}, 
+    {mode: 'rft' as const, pieces: 100n, requiredPallets: [Pallets.ReFungible]},
   ].map(testSuite => describe(`${testSuite.mode.toUpperCase()}`, () => {
     before(async function() {
       // eslint-disable-next-line require-await
@@ -39,7 +39,7 @@
         requirePalletsOrSkip(this, helper, testSuite.requiredPallets);
       });
     });
-    
+
     itSub('force_repair_item preserves valid consumed space', async({helper}) => {
       const propKey = 'tok-prop';
 
modifiedtests/src/nesting/tokenProperties.test.tsdiffbeforeafterboth
--- a/tests/src/nesting/tokenProperties.test.ts
+++ b/tests/src/nesting/tokenProperties.test.ts
@@ -43,12 +43,12 @@
 
   async function mintCollectionWithAllPermissionsAndToken(helper: UniqueHelper, mode: 'NFT' | 'RFT'): Promise<[UniqueNFToken | UniqueRFToken, bigint]> {
     const collection = await (mode == 'NFT' ? helper.nft : helper.rft).mintCollection(alice, {
-      tokenPropertyPermissions: permissions.flatMap(({permission, signers}, i) => 
+      tokenPropertyPermissions: permissions.flatMap(({permission, signers}, i) =>
         signers.map(signer => {return {key: `${i+1}_${signer.address}`, permission};})),
     });
     return mode == 'NFT' ? [await collection.mintToken(alice), 1n] : [await collection.mintToken(alice, 100n), 100n];
   }
-  
+
   async function testReadsYetEmptyProperties(token: UniqueNFToken | UniqueRFToken) {
     const properties = await token.getProperties();
     expect(properties).to.be.empty;
@@ -84,7 +84,7 @@
         propertyKeys.push(key);
 
         await expect(
-          token.setProperties(signer, [{key: key, value: 'Serotonin increase'}]), 
+          token.setProperties(signer, [{key: key, value: 'Serotonin increase'}]),
           `on adding property #${i} by signer #${j}`,
         ).to.be.fulfilled;
       }
@@ -117,7 +117,7 @@
     for (const permission of permissions) {
       i++;
       if (!permission.permission.mutable) continue;
-      
+
       let j = 0;
       for (const signer of permission.signers) {
         j++;
@@ -125,12 +125,12 @@
         propertyKeys.push(key);
 
         await expect(
-          token.setProperties(signer, [{key, value: 'Serotonin increase'}]), 
+          token.setProperties(signer, [{key, value: 'Serotonin increase'}]),
           `on adding property #${i} by signer #${j}`,
         ).to.be.fulfilled;
 
         await expect(
-          token.setProperties(signer, [{key, value: 'Serotonin stable'}]), 
+          token.setProperties(signer, [{key, value: 'Serotonin stable'}]),
           `on changing property #${i} by signer #${j}`,
         ).to.be.fulfilled;
       }
@@ -164,7 +164,7 @@
     for (const permission of permissions) {
       i++;
       if (!permission.permission.mutable) continue;
-      
+
       let j = 0;
       for (const signer of permission.signers) {
         j++;
@@ -172,12 +172,12 @@
         propertyKeys.push(key);
 
         await expect(
-          token.setProperties(signer, [{key, value: 'Serotonin increase'}]), 
+          token.setProperties(signer, [{key, value: 'Serotonin increase'}]),
           `on adding property #${i} by signer #${j}`,
         ).to.be.fulfilled;
 
         await expect(
-          token.deleteProperties(signer, [key]), 
+          token.deleteProperties(signer, [key]),
           `on deleting property #${i} by signer #${j}`,
         ).to.be.fulfilled;
       }
@@ -186,7 +186,7 @@
     expect(await token.getProperties(propertyKeys)).to.be.empty;
     expect((await token.getData())!.properties).to.be.empty;
   }
-  
+
   itSub('Deletes properties of a token according to permissions (NFT)', async ({helper}) =>  {
     const [token, amount] = await mintCollectionWithAllPermissionsAndToken(helper, 'NFT');
     await testDeletePropertiesAccordingPermission(token, amount);
@@ -200,7 +200,7 @@
   itSub('Assigns properties to a nested token according to permissions', async ({helper}) =>  {
     const collectionA = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}});
     const collectionB = await helper.nft.mintCollection(alice, {
-      tokenPropertyPermissions: permissions.flatMap(({permission, signers}, i) => 
+      tokenPropertyPermissions: permissions.flatMap(({permission, signers}, i) =>
         signers.map(signer => {return {key: `${i+1}_${signer.address}`, permission};})),
     });
     const targetToken = await collectionA.mintToken(alice);
@@ -220,7 +220,7 @@
         propertyKeys.push(key);
 
         await expect(
-          nestedToken.setProperties(signer, [{key, value: 'Serotonin increase'}]), 
+          nestedToken.setProperties(signer, [{key, value: 'Serotonin increase'}]),
           `on adding property #${i} by signer #${j}`,
         ).to.be.fulfilled;
       }
@@ -238,7 +238,7 @@
   itSub('Changes properties of a nested token according to permissions', async ({helper}) =>  {
     const collectionA = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}});
     const collectionB = await helper.nft.mintCollection(alice, {
-      tokenPropertyPermissions: permissions.flatMap(({permission, signers}, i) => 
+      tokenPropertyPermissions: permissions.flatMap(({permission, signers}, i) =>
         signers.map(signer => {return {key: `${i+1}_${signer.address}`, permission};})),
     });
     const targetToken = await collectionA.mintToken(alice);
@@ -252,7 +252,7 @@
     for (const permission of permissions) {
       i++;
       if (!permission.permission.mutable) continue;
-      
+
       let j = 0;
       for (const signer of permission.signers) {
         j++;
@@ -260,12 +260,12 @@
         propertyKeys.push(key);
 
         await expect(
-          nestedToken.setProperties(signer, [{key, value: 'Serotonin increase'}]), 
+          nestedToken.setProperties(signer, [{key, value: 'Serotonin increase'}]),
           `on adding property #${i} by signer #${j}`,
         ).to.be.fulfilled;
 
         await expect(
-          nestedToken.setProperties(signer, [{key, value: 'Serotonin stable'}]), 
+          nestedToken.setProperties(signer, [{key, value: 'Serotonin stable'}]),
           `on changing property #${i} by signer #${j}`,
         ).to.be.fulfilled;
       }
@@ -283,7 +283,7 @@
   itSub('Deletes properties of a nested token according to permissions', async ({helper}) =>  {
     const collectionA = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}});
     const collectionB = await helper.nft.mintCollection(alice, {
-      tokenPropertyPermissions: permissions.flatMap(({permission, signers}, i) => 
+      tokenPropertyPermissions: permissions.flatMap(({permission, signers}, i) =>
         signers.map(signer => {return {key: `${i+1}_${signer.address}`, permission};})),
     });
     const targetToken = await collectionA.mintToken(alice);
@@ -297,7 +297,7 @@
     for (const permission of permissions) {
       i++;
       if (!permission.permission.mutable) continue;
-      
+
       let j = 0;
       for (const signer of permission.signers) {
         j++;
@@ -305,12 +305,12 @@
         propertyKeys.push(key);
 
         await expect(
-          nestedToken.setProperties(signer, [{key, value: 'Serotonin increase'}]), 
+          nestedToken.setProperties(signer, [{key, value: 'Serotonin increase'}]),
           `on adding property #${i} by signer #${j}`,
         ).to.be.fulfilled;
 
         await expect(
-          nestedToken.deleteProperties(signer, [key]), 
+          nestedToken.deleteProperties(signer, [key]),
           `on deleting property #${i} by signer #${j}`,
         ).to.be.fulfilled;
       }
@@ -323,7 +323,7 @@
 
   [
     {mode: 'nft' as const, storage: 'nonfungible' as const, pieces: undefined, requiredPallets: []},
-    {mode: 'rft' as const, storage: 'refungible' as const, pieces: 100n, requiredPallets: [Pallets.ReFungible]}, 
+    {mode: 'rft' as const, storage: 'refungible' as const, pieces: 100n, requiredPallets: [Pallets.ReFungible]},
   ].map(testCase =>
     itSub.ifWithPallets(`Allows modifying a token property multiple times with the same size (${testCase.mode})`, testCase.requiredPallets, async({helper}) => {
       const propKey = 'tok-prop';
@@ -370,7 +370,7 @@
 
   [
     {mode: 'nft' as const, pieces: undefined, requiredPallets: []},
-    {mode: 'rft' as const, pieces: 100n, requiredPallets: [Pallets.ReFungible]}, 
+    {mode: 'rft' as const, pieces: 100n, requiredPallets: [Pallets.ReFungible]},
   ].map(testCase =>
     itSub.ifWithPallets(`Adding then removing a token property doesn't change the consumed space (${testCase.mode})`, testCase.requiredPallets, async({helper}) => {
       const propKey = 'tok-prop';
@@ -404,7 +404,7 @@
 
   [
     {mode: 'nft' as const, pieces: undefined, requiredPallets: []},
-    {mode: 'rft' as const, pieces: 100n, requiredPallets: [Pallets.ReFungible]}, 
+    {mode: 'rft' as const, pieces: 100n, requiredPallets: [Pallets.ReFungible]},
   ].map(testCase =>
     itSub.ifWithPallets(`Modifying a token property with different sizes correctly changes the consumed space (${testCase.mode})`, testCase.requiredPallets, async({helper}) => {
       const propKey = 'tok-prop';
@@ -497,12 +497,12 @@
       i++;
       const signer = passage.signers[0];
       await expect(
-        token.setProperties(signer, [{key: `${i}`, value: 'Serotonin increase'}]), 
+        token.setProperties(signer, [{key: `${i}`, value: 'Serotonin increase'}]),
         `on adding property ${i} by ${signer.address}`,
       ).to.be.fulfilled;
     }
 
-    const originalSpace = await getConsumedSpace(token.collection.helper.getApi(), token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT'); 
+    const originalSpace = await getConsumedSpace(token.collection.helper.getApi(), token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT');
     return originalSpace;
   }
 
@@ -515,17 +515,17 @@
       if (!forbiddance.permission.mutable) continue;
 
       await expect(
-        token.setProperties(forbiddance.sinner, [{key: `${i}`, value: 'Serotonin down'}]), 
+        token.setProperties(forbiddance.sinner, [{key: `${i}`, value: 'Serotonin down'}]),
         `on failing to change property ${i} by the malefactor`,
       ).to.be.rejectedWith(/common\.NoPermission/);
 
       await expect(
-        token.deleteProperties(forbiddance.sinner, [`${i}`]), 
+        token.deleteProperties(forbiddance.sinner, [`${i}`]),
         `on failing to delete property ${i} by the malefactor`,
       ).to.be.rejectedWith(/common\.NoPermission/);
     }
 
-    const consumedSpace = await getConsumedSpace(token.collection.helper.getApi(), token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT'); 
+    const consumedSpace = await getConsumedSpace(token.collection.helper.getApi(), token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT');
     expect(consumedSpace).to.be.equal(originalSpace);
   }
 
@@ -548,17 +548,17 @@
       if (permission.permission.mutable) continue;
 
       await expect(
-        token.setProperties(permission.signers[0], [{key: `${i}`, value: 'Serotonin down'}]), 
+        token.setProperties(permission.signers[0], [{key: `${i}`, value: 'Serotonin down'}]),
         `on failing to change property ${i} by signer #0`,
       ).to.be.rejectedWith(/common\.NoPermission/);
 
       await expect(
-        token.deleteProperties(permission.signers[0], [i.toString()]), 
+        token.deleteProperties(permission.signers[0], [i.toString()]),
         `on failing to delete property ${i} by signer #0`,
       ).to.be.rejectedWith(/common\.NoPermission/);
     }
-  
-    const consumedSpace = await getConsumedSpace(token.collection.helper.getApi(), token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT'); 
+
+    const consumedSpace = await getConsumedSpace(token.collection.helper.getApi(), token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT');
     expect(consumedSpace).to.be.equal(originalSpace);
   }
 
@@ -576,23 +576,23 @@
     const originalSpace = await prepare(token, pieces);
 
     await expect(
-      token.setProperties(alice, [{key: 'non-existent', value: 'I exist!'}]), 
+      token.setProperties(alice, [{key: 'non-existent', value: 'I exist!'}]),
       'on failing to add a previously non-existent property',
     ).to.be.rejectedWith(/common\.NoPermission/);
-      
+
     await expect(
-      token.collection.setTokenPropertyPermissions(alice, [{key: 'now-existent', permission: {}}]), 
+      token.collection.setTokenPropertyPermissions(alice, [{key: 'now-existent', permission: {}}]),
       'on setting a new non-permitted property',
     ).to.be.fulfilled;
 
     await expect(
-      token.setProperties(alice, [{key: 'now-existent', value: 'I exist!'}]), 
+      token.setProperties(alice, [{key: 'now-existent', value: 'I exist!'}]),
       'on failing to add a property forbidden by the \'None\' permission',
     ).to.be.rejectedWith(/common\.NoPermission/);
 
     expect(await token.getProperties(['non-existent', 'now-existent'])).to.be.empty;
-      
-    const consumedSpace = await getConsumedSpace(token.collection.helper.getApi(), token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT'); 
+
+    const consumedSpace = await getConsumedSpace(token.collection.helper.getApi(), token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT');
     expect(consumedSpace).to.be.equal(originalSpace);
   }
 
@@ -611,9 +611,9 @@
 
     await expect(
       token.collection.setTokenPropertyPermissions(alice, [
-        {key: 'a_holy_book', permission: {collectionAdmin: true, tokenOwner: true}}, 
+        {key: 'a_holy_book', permission: {collectionAdmin: true, tokenOwner: true}},
         {key: 'young_years', permission: {collectionAdmin: true, tokenOwner: true}},
-      ]), 
+      ]),
       'on setting new permissions for properties',
     ).to.be.fulfilled;
 
@@ -625,12 +625,12 @@
     }
 
     await expect(token.setProperties(alice, [
-      {key: 'a_holy_book', value: 'word '.repeat(3277)}, 
+      {key: 'a_holy_book', value: 'word '.repeat(3277)},
       {key: 'young_years', value: 'neverending'.repeat(1490)},
     ])).to.be.rejectedWith(/common\.NoSpaceForProperty/);
-  
+
     expect(await token.getProperties(['a_holy_book', 'young_years'])).to.be.empty;
-    const consumedSpace = await getConsumedSpace(token.collection.helper.getApi(), token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT'); 
+    const consumedSpace = await getConsumedSpace(token.collection.helper.getApi(), token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT');
     expect(consumedSpace).to.be.equal(originalSpace);
   }
 
@@ -646,7 +646,7 @@
 
   [
     {mode: 'nft' as const, requiredPallets: []},
-    {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]}, 
+    {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
   ].map(testCase =>
     itSub.ifWithPallets(`Forbids adding too many propeties to a token (${testCase.mode})`, testCase.requiredPallets, async({helper}) => {
       const collection = await helper[testCase.mode].mintCollection(alice);
@@ -667,7 +667,7 @@
 
   [
     {mode: 'nft' as const, pieces: undefined, requiredPallets: []},
-    {mode: 'rft' as const, pieces: 100n, requiredPallets: [Pallets.ReFungible]}, 
+    {mode: 'rft' as const, pieces: 100n, requiredPallets: [Pallets.ReFungible]},
   ].map(testCase =>
     itSub.ifWithPallets(`Forbids force_repair_item from non-sudo (${testCase.mode})`, testCase.requiredPallets, async({helper}) => {
       const propKey = 'tok-prop';
@@ -712,10 +712,10 @@
   async function prepare(helper: UniqueHelper): Promise<UniqueRFToken> {
     const collection = await helper.rft.mintCollection(alice);
     const token = await collection.mintToken(alice, 100n);
-    
+
     await collection.addAdmin(alice, {Substrate: bob.address});
     await collection.setTokenPropertyPermissions(alice, [{key: 'fractals', permission: {mutable: true, tokenOwner: true}}]);
-    
+
     return token;
   }
 
@@ -725,7 +725,7 @@
     await token.transfer(alice, {Substrate: charlie.address}, 33n);
 
     await expect(token.setProperties(alice, [
-      {key: 'fractals', value: 'multiverse'}, 
+      {key: 'fractals', value: 'multiverse'},
     ])).to.be.rejectedWith(/common\.NoPermission/);
   });
 
@@ -736,13 +736,13 @@
       .to.be.fulfilled;
 
     await expect(token.setProperties(alice, [
-      {key: 'fractals', value: 'multiverse'}, 
+      {key: 'fractals', value: 'multiverse'},
     ])).to.be.fulfilled;
 
     await token.transfer(alice, {Substrate: charlie.address}, 33n);
 
     await expect(token.setProperties(alice, [
-      {key: 'fractals', value: 'want to rule the world'}, 
+      {key: 'fractals', value: 'want to rule the world'},
     ])).to.be.rejectedWith(/common\.NoPermission/);
   });
 
@@ -750,7 +750,7 @@
     const token = await prepare(helper);
 
     await expect(token.setProperties(alice, [
-      {key: 'fractals', value: 'one headline - why believe it'}, 
+      {key: 'fractals', value: 'one headline - why believe it'},
     ])).to.be.fulfilled;
 
     await token.transfer(alice, {Substrate: charlie.address}, 33n);
@@ -768,7 +768,7 @@
       .to.be.fulfilled;
 
     await expect(token.setProperties(alice, [
-      {key: 'fractals', value: 'multiverse'}, 
+      {key: 'fractals', value: 'multiverse'},
     ])).to.be.fulfilled;
   });
 });
modifiedtests/src/nesting/unnest.test.tsdiffbeforeafterboth
--- a/tests/src/nesting/unnest.test.ts
+++ b/tests/src/nesting/unnest.test.ts
@@ -30,7 +30,7 @@
   itSub('NFT: allows the owner to successfully unnest a token', async ({helper}) => {
     const collection = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}});
     const targetToken = await collection.mintToken(alice);
-    
+
     // Create a nested token
     const nestedToken = await collection.mintToken(alice, targetToken.nestingAccount());
 
@@ -49,7 +49,7 @@
     const targetToken = await collection.mintToken(alice);
 
     const collectionFT = await helper.ft.mintCollection(alice);
-    
+
     // Nest and unnest
     await collectionFT.mint(alice, 10n, targetToken.nestingAccount());
     await expect(collectionFT.transferFrom(alice, targetToken.nestingAccount(), {Substrate: alice.address}, 9n), 'while unnesting').to.be.fulfilled;
@@ -69,7 +69,7 @@
     const targetToken = await collection.mintToken(alice);
 
     const collectionRFT = await helper.rft.mintCollection(alice);
-    
+
     // Nest and unnest
     const token = await collectionRFT.mintToken(alice, 10n, targetToken.nestingAccount());
     await expect(token.transferFrom(alice, targetToken.nestingAccount(), {Substrate: alice.address}, 9n), 'while unnesting').to.be.fulfilled;
modifiedtests/src/nextSponsoring.test.tsdiffbeforeafterboth
--- a/tests/src/nextSponsoring.test.ts
+++ b/tests/src/nextSponsoring.test.ts
@@ -39,7 +39,7 @@
 
     // Check with Disabled sponsoring state
     expect(await token.getNextSponsored({Substrate: alice.address})).to.be.null;
-    
+
     // Check with Unconfirmed sponsoring state
     await collection.setSponsor(alice, bob.address);
     expect(await token.getNextSponsored({Substrate: alice.address})).to.be.null;
@@ -52,7 +52,7 @@
     await token.transfer(alice, {Substrate: bob.address});
     expect(await token.getNextSponsored({Substrate: alice.address})).to.be.lessThanOrEqual(SPONSORING_TIMEOUT);
 
-    // Non-existing token 
+    // Non-existing token
     expect(await collection.getTokenNextSponsored(0, {Substrate: alice.address})).to.be.null;
   });
 
@@ -65,7 +65,7 @@
 
     await collection.setSponsor(alice, bob.address);
     await collection.confirmSponsorship(bob);
-    
+
     // Check with Confirmed sponsoring state
     expect(await collection.getTokenNextSponsored(0, {Substrate: alice.address})).to.be.equal(0);
 
@@ -91,7 +91,7 @@
     await token.transfer(alice, {Substrate: bob.address});
     expect(await token.getNextSponsored({Substrate: alice.address})).to.be.lessThanOrEqual(SPONSORING_TIMEOUT);
 
-    // Non-existing token 
+    // Non-existing token
     expect(await collection.getTokenNextSponsored(0, {Substrate: alice.address})).to.be.null;
   });
 });
modifiedtests/src/refungible.test.tsdiffbeforeafterboth
--- a/tests/src/refungible.test.ts
+++ b/tests/src/refungible.test.ts
@@ -32,36 +32,36 @@
       [alice, bob] = await helper.arrange.createAccounts([100n, 10n], donor);
     });
   });
-  
+
   itSub('Create refungible collection and token', async ({helper}) => {
     const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
 
     const itemCountBefore = await collection.getLastTokenId();
     const token = await collection.mintToken(alice, 100n);
-    
+
     const itemCountAfter = await collection.getLastTokenId();
-    
+
     // What to expect
     expect(token?.tokenId).to.be.gte(itemCountBefore);
     expect(itemCountAfter).to.be.equal(itemCountBefore + 1);
     expect(itemCountAfter.toString()).to.be.equal(token?.tokenId.toString());
   });
-  
+
   itSub('Checking RPC methods when interacting with maximum allowed values (MAX_REFUNGIBLE_PIECES)', async ({helper}) => {
     const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-    
+
     const token = await collection.mintToken(alice, MAX_REFUNGIBLE_PIECES);
-    
+
     expect(await collection.getTokenBalance(token.tokenId, {Substrate: alice.address})).to.be.equal(MAX_REFUNGIBLE_PIECES);
-    
+
     await collection.transferToken(alice, token.tokenId, {Substrate: bob.address}, MAX_REFUNGIBLE_PIECES);
     expect(await collection.getTokenBalance(token.tokenId, {Substrate: bob.address})).to.be.equal(MAX_REFUNGIBLE_PIECES);
     expect(await token.getTotalPieces()).to.be.equal(MAX_REFUNGIBLE_PIECES);
-    
+
     await expect(collection.mintToken(alice, MAX_REFUNGIBLE_PIECES + 1n))
       .to.eventually.be.rejectedWith(/refungible\.WrongRefungiblePieces/);
   });
-  
+
   itSub('RPC method tokenOwners for refungible collection and token', async ({helper}) => {
     const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
     const facelessCrowd = (await helper.arrange.createAccounts(Array(7).fill(0n), donor)).map(keyring => {return {Substrate: keyring.address};});
@@ -72,32 +72,32 @@
 
     await token.transfer(alice, {Substrate: bob.address}, 1000n);
     await token.transfer(alice, ethAcc, 900n);
-    
+
     for (let i = 0; i < 7; i++) {
       await token.transfer(alice, facelessCrowd[i], 50n * BigInt(i + 1));
-    } 
+    }
 
     const owners = await token.getTop10Owners();
 
     // What to expect
     expect(owners).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
     expect(owners.length).to.be.equal(10);
-    
+
     const [eleven] = await helper.arrange.createAccounts([0n], donor);
     expect(await token.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
     expect((await token.getTop10Owners()).length).to.be.equal(10);
   });
-  
+
   itSub('Transfer token pieces', async ({helper}) => {
     const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
     const token = await collection.mintToken(alice, 100n);
 
     expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
     expect(await token.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
-    
+
     expect(await token.getBalance({Substrate: alice.address})).to.be.equal(40n);
     expect(await token.getBalance({Substrate: bob.address})).to.be.equal(60n);
-    
+
     await expect(token.transfer(alice, {Substrate: bob.address}, 41n))
       .to.eventually.be.rejectedWith(/common\.TokenValueTooLow/);
   });
@@ -111,8 +111,8 @@
     //   {owner: {Substrate: alice.address}, pieces: 100n},
     // ]);
     await helper.rft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, [
-      {pieces: 1n}, 
-      {pieces: 2n}, 
+      {pieces: 1n},
+      {pieces: 2n},
       {pieces: 100n},
     ]);
     const lastTokenId = await collection.getLastTokenId();
@@ -133,7 +133,7 @@
   itSub('Burn all pieces', async ({helper}) => {
     const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
     const token = await collection.mintToken(alice, 100n);
-    
+
     expect(await collection.doesTokenExist(token.tokenId)).to.be.true;
     expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
 
@@ -146,7 +146,7 @@
     const token = await collection.mintToken(alice, 100n);
 
     expect(await collection.doesTokenExist(token.tokenId)).to.be.true;
-    
+
     expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
     expect(await token.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
 
@@ -171,7 +171,7 @@
   itSub('Set allowance for token', async ({helper}) => {
     const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
     const token = await collection.mintToken(alice, 100n);
-    
+
     expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
 
     expect(await token.approve(alice, {Substrate: bob.address}, 60n)).to.be.true;
@@ -190,14 +190,14 @@
     expect(await token.repartition(alice, 200n)).to.be.true;
     expect(await token.getBalance({Substrate: alice.address})).to.be.equal(200n);
     expect(await token.getTotalPieces()).to.be.equal(200n);
-    
+
     expect(await token.transfer(alice, {Substrate: bob.address}, 110n)).to.be.true;
     expect(await token.getBalance({Substrate: alice.address})).to.be.equal(90n);
     expect(await token.getBalance({Substrate: bob.address})).to.be.equal(110n);
-    
+
     await expect(token.repartition(alice, 80n))
       .to.eventually.be.rejectedWith(/refungible\.RepartitionWhileNotOwningAllPieces/);
-    
+
     expect(await token.transfer(alice, {Substrate: bob.address}, 90n)).to.be.true;
     expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);
     expect(await token.getBalance({Substrate: bob.address})).to.be.equal(200n);
@@ -220,7 +220,7 @@
       data: [
         collection.collectionId,
         token.tokenId,
-        {substrate: alice.address}, 
+        {substrate: alice.address},
         100n,
       ],
     });
@@ -239,12 +239,12 @@
       data: [
         collection.collectionId,
         token.tokenId,
-        {substrate: alice.address}, 
+        {substrate: alice.address},
         50n,
       ],
     });
   });
-  
+
   itSub('Create new collection with properties', async ({helper}) => {
     const properties = [{key: 'key1', value: 'val1'}];
     const tokenPropertyPermissions = [{key: 'key1', permission: {tokenOwner: true, mutable: false, collectionAdmin: true}}];
@@ -280,7 +280,7 @@
     await expect(tokenBob.transfer(alice, {Substrate: charlie.address}, 1n)).to.be.rejectedWith('common.TokenValueTooLow');
     await expect(tokenBob.transfer(alice, {Substrate: charlie.address}, 10n)).to.be.rejectedWith('common.TokenValueTooLow');
     await expect(tokenBob.transfer(alice, {Substrate: charlie.address}, 100n)).to.be.rejectedWith('common.TokenValueTooLow');
-    
+
     // 2. Alice cannot transfer non-existing token:
     await expect(collection.transferToken(alice, 100, {Substrate: charlie.address}, 0n)).to.be.rejectedWith('common.TokenValueTooLow');
     await expect(collection.transferToken(alice, 100, {Substrate: charlie.address}, 1n)).to.be.rejectedWith('common.TokenValueTooLow');
modifiedtests/src/removeCollectionAdmin.test.tsdiffbeforeafterboth
--- a/tests/src/removeCollectionAdmin.test.ts
+++ b/tests/src/removeCollectionAdmin.test.ts
@@ -94,7 +94,7 @@
 
   itSub('Admin can\'t remove collection admin.', async ({helper}) => {
     const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-Neg-4', tokenPrefix: 'RCA'});
-    
+
     await collection.addAdmin(alice, {Substrate: bob.address});
     await collection.addAdmin(alice, {Substrate: charlie.address});
 
modifiedtests/src/rpc.test.tsdiffbeforeafterboth
--- a/tests/src/rpc.test.ts
+++ b/tests/src/rpc.test.ts
@@ -35,20 +35,20 @@
     const owner = (await helper.callRpc('api.rpc.unique.tokenOwner', [collection.collectionId, 0])).toJSON() as any;
     expect(owner).to.be.null;
   });
-  
+
   itSub('RPC method tokenOwners for fungible collection and token', async ({helper}) => {
     // Set-up a few token owners of all stripes
     const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
     const facelessCrowd = (await helper.arrange.createAccounts([0n, 0n, 0n, 0n, 0n, 0n, 0n], donor))
       .map(i => {return {Substrate: i.address};});
-    
+
     const collection = await helper.ft.mintCollection(alice, {name: 'RPC-2', tokenPrefix: 'RPC'});
     // mint some maximum (u128) amounts of tokens possible
     await collection.mint(alice, (1n << 128n) - 1n);
-    
+
     await collection.transfer(alice, {Substrate: bob.address}, 1000n);
     await collection.transfer(alice, ethAcc, 900n);
-          
+
     for (let i = 0; i < facelessCrowd.length; i++) {
       await collection.transfer(alice, facelessCrowd[i], 1n);
     }
@@ -59,7 +59,7 @@
 
     expect(ids).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
     expect(owners.length == 10).to.be.true;
-    
+
     // Make sure only 10 results are returned with this RPC
     const [eleven] = await helper.arrange.createAccounts([0n], donor);
     expect(await collection.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
modifiedtests/src/scheduler.seqtest.tsdiffbeforeafterboth
--- a/tests/src/scheduler.seqtest.ts
+++ b/tests/src/scheduler.seqtest.ts
@@ -47,7 +47,7 @@
     const token = await collection.mintToken(alice);
     const scheduledId = scheduleKind == 'named' ? helper.arrange.makeScheduledId() : undefined;
     const blocksBeforeExecution = 4;
-    
+
     await token.scheduleAfter(blocksBeforeExecution, {scheduledId})
       .transfer(alice, {Substrate: bob.address});
     const executionBlock = await helper.chain.getLatestBlockNumber() + blocksBeforeExecution + 1;
@@ -156,7 +156,7 @@
     const maxScheduledPerBlock = 50;
     let fillScheduledIds = new Array(maxScheduledPerBlock);
     let extraScheduledId = undefined;
-    
+
     if (scheduleKind == 'named') {
       const scheduledIds = helper.arrange.makeScheduledIds(maxScheduledPerBlock + 1);
       fillScheduledIds = scheduledIds.slice(0, maxScheduledPerBlock);
@@ -641,7 +641,7 @@
     const balanceBefore = await helper.balance.getSubstrate(bob.address);
 
     const scheduled = helper.scheduler.scheduleAfter(waitForBlocks, {scheduledId, priority: 42});
-    
+
     await expect(scheduled.balance.transferToSubstrate(alice, bob.address, amount))
       .to.be.rejectedWith(/BadOrigin/);
 
modifiedtests/src/setCollectionLimits.test.tsdiffbeforeafterboth
--- a/tests/src/setCollectionLimits.test.ts
+++ b/tests/src/setCollectionLimits.test.ts
@@ -75,7 +75,7 @@
     await collection.setLimits(alice, collectionLimits);
 
     const collectionInfo1 = await collection.getEffectiveLimits();
-      
+
     expect(collectionInfo1.tokenLimit).to.be.equal(tokenLimit);
 
     await collection.setLimits(alice, collectionLimits);
@@ -108,7 +108,7 @@
       [alice, bob] = await helper.arrange.createAccounts([20n, 10n], donor);
     });
   });
-  
+
   itSub('execute setCollectionLimits for not exists collection', async ({helper}) => {
     const nonExistentCollectionId = (1 << 32) - 1;
     await expect(helper.collection.setLimits(
@@ -180,7 +180,7 @@
 
   itSub('Setting the higher token limit fails', async ({helper}) => {
     const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-Neg-4', tokenPrefix: 'SCL'});
-      
+
     const collectionLimits = {
       accountTokenOwnershipLimit: accountTokenOwnershipLimit,
       sponsoredMintSize: sponsoredDataSize,
modifiedtests/src/setCollectionSponsor.test.tsdiffbeforeafterboth
--- a/tests/src/setCollectionSponsor.test.ts
+++ b/tests/src/setCollectionSponsor.test.ts
@@ -37,7 +37,7 @@
       Unconfirmed: bob.address,
     });
   });
-  
+
   itSub('Set Fungible collection sponsor', async ({helper}) => {
     const collection = await helper.ft.mintCollection(alice, {name: 'SetCollectionSponsor-1-FT', tokenPrefix: 'SCS'});
     await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
@@ -75,7 +75,7 @@
       Unconfirmed: charlie.address,
     });
   });
-  
+
   itSub('Collection admin add sponsor', async ({helper}) => {
     const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-4', tokenPrefix: 'SCS'});
     await collection.addAdmin(alice, {Substrate: bob.address});
modifiedtests/src/setPermissions.test.tsdiffbeforeafterboth
--- a/tests/src/setPermissions.test.ts
+++ b/tests/src/setPermissions.test.ts
@@ -34,11 +34,11 @@
 
     await collection.setPermissions(alice, {access: 'AllowList', mintMode: true, nesting: {collectionAdmin: true, tokenOwner: true, restricted: [1, 2]}});
     await collection.setPermissions(alice, {access: 'AllowList', mintMode: true, nesting: {collectionAdmin: true, tokenOwner: true, restricted: [1, 2]}});
-    
+
     const permissions = (await collection.getData())?.raw.permissions;
     expect(permissions).to.be.deep.equal({
-      access: 'AllowList', 
-      mintMode: true, 
+      access: 'AllowList',
+      mintMode: true,
       nesting: {collectionAdmin: true, tokenOwner: true, restricted: [1, 2]},
     });
   });
@@ -49,16 +49,16 @@
 
     await collection.setPermissions(alice, {access: 'AllowList', nesting: {collectionAdmin: false, tokenOwner: true, restricted: [1, 2]}});
     expect((await collection.getData())?.raw.permissions).to.be.deep.equal({
-      access: 'AllowList', 
-      mintMode: false, 
+      access: 'AllowList',
+      mintMode: false,
       nesting: {collectionAdmin: false, tokenOwner: true, restricted: [1, 2]},
     });
 
     await collection.setPermissions(alice, {access: 'Normal', mintMode: false, nesting: {}});
     await collection.setPermissions(alice, {access: 'Normal', mintMode: false, nesting: {}});
     expect((await collection.getData())?.raw.permissions).to.be.deep.equal({
-      access: 'Normal', 
-      mintMode: false, 
+      access: 'Normal',
+      mintMode: false,
       nesting: {collectionAdmin: false, tokenOwner: false, restricted: null},
     });
   });
@@ -67,7 +67,7 @@
     const collection = await helper.nft.mintCollection(alice, {name: 'SetPermissions-2', tokenPrefix: 'SP'});
     await collection.addAdmin(alice, {Substrate: bob.address});
     await collection.setPermissions(bob, {access: 'AllowList', mintMode: true});
-    
+
     expect((await collection.getData())?.raw.permissions.access).to.equal('AllowList');
     expect((await collection.getData())?.raw.permissions.mintMode).to.equal(true);
   });
modifiedtests/src/transfer.nload.tsdiffbeforeafterboth
--- a/tests/src/transfer.nload.ts
+++ b/tests/src/transfer.nload.ts
@@ -14,6 +14,7 @@
 // You should have received a copy of the GNU General Public License
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
+/* eslint-disable @typescript-eslint/no-floating-promises */
 import os from 'os';
 import {IKeyringPair} from '@polkadot/types/types';
 import {usingPlaygrounds} from './util';
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({filename: __filename});29      [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);30    });31  });32  33  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({filename: __filename});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  });165  166  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({filename: __filename});280    });281  });282  283  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';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({filename: __filename});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({filename: __filename});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({filename: __filename});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});
modifiedtests/src/transferFrom.test.tsdiffbeforeafterboth
--- a/tests/src/transferFrom.test.ts
+++ b/tests/src/transferFrom.test.ts
@@ -44,7 +44,7 @@
     await collection.mint(alice, 10n);
     await collection.approveTokens(alice, {Substrate: bob.address}, 7n);
     expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(7n);
-    
+
     await collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 6n);
     expect(await collection.getBalance({Substrate: charlie.address})).to.be.equal(6n);
     expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(4n);
@@ -56,7 +56,7 @@
     const rft = await collection.mintToken(alice, 10n);
     await rft.approve(alice, {Substrate: bob.address}, 7n);
     expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(7n);
-    
+
     await rft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 6n);
     expect(await rft.getBalance({Substrate: charlie.address})).to.be.equal(6n);
     expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(4n);
@@ -155,11 +155,11 @@
     expect(await nft.isApproved({Substrate: bob.address})).to.be.true;
 
     await expect(helper.collection.transferTokenFrom(
-      bob, 
-      collection.collectionId, 
-      nft.tokenId, 
-      {Substrate: alice.address}, 
-      {Substrate: charlie.address}, 
+      bob,
+      collection.collectionId,
+      nft.tokenId,
+      {Substrate: alice.address},
+      {Substrate: charlie.address},
       2n,
     )).to.be.rejectedWith(/nonfungible\.NonfungibleItemsHaveNoAmount/);
     expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
@@ -202,7 +202,7 @@
 
     await expect(nft.transferFrom(
       charlie,
-      {Substrate: alice.address}, 
+      {Substrate: alice.address},
       {Substrate: charlie.address},
     )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
     expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
@@ -218,7 +218,7 @@
 
     await expect(collection.transferFrom(
       charlie,
-      {Substrate: alice.address}, 
+      {Substrate: alice.address},
       {Substrate: charlie.address},
     )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
     expect(await collection.getBalance({Substrate: alice.address})).to.be.deep.equal(10000n);
@@ -236,7 +236,7 @@
 
     await expect(rft.transferFrom(
       charlie,
-      {Substrate: alice.address}, 
+      {Substrate: alice.address},
       {Substrate: charlie.address},
     )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
     expect(await rft.getBalance({Substrate: alice.address})).to.be.deep.equal(10000n);
@@ -254,7 +254,7 @@
 
     await expect(nft.transferFrom(
       bob,
-      {Substrate: alice.address}, 
+      {Substrate: alice.address},
       {Substrate: charlie.address},
     )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
   });
@@ -269,7 +269,7 @@
 
     await expect(collection.transferFrom(
       alice,
-      {Substrate: alice.address}, 
+      {Substrate: alice.address},
       {Substrate: charlie.address},
     )).to.be.rejectedWith(/common\.TokenValueTooLow/);
   });
@@ -284,7 +284,7 @@
 
     await expect(rft.transferFrom(
       alice,
-      {Substrate: alice.address}, 
+      {Substrate: alice.address},
       {Substrate: charlie.address},
     )).to.be.rejectedWith(/common\.TokenValueTooLow/);
   });
@@ -300,7 +300,7 @@
 
     await expect(nft.transferFrom(
       bob,
-      {Substrate: alice.address}, 
+      {Substrate: alice.address},
       {Substrate: charlie.address},
     )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
   });
@@ -316,7 +316,7 @@
 
     await expect(collection.transferFrom(
       bob,
-      {Substrate: alice.address}, 
+      {Substrate: alice.address},
       {Substrate: charlie.address},
     )).to.be.rejectedWith(/common\.TokenValueTooLow/);
   });
@@ -332,7 +332,7 @@
 
     await expect(rft.transferFrom(
       bob,
-      {Substrate: alice.address}, 
+      {Substrate: alice.address},
       {Substrate: charlie.address},
     )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
   });
@@ -345,7 +345,7 @@
 
     await expect(nft.transferFrom(
       alice,
-      {Substrate: bob.address}, 
+      {Substrate: bob.address},
       {Substrate: charlie.address},
     )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
   });
modifiedtests/src/util/globalSetup.tsdiffbeforeafterboth
--- a/tests/src/util/globalSetup.ts
+++ b/tests/src/util/globalSetup.ts
@@ -17,10 +17,10 @@
       // 2. Create donors for test files
       await fundFilenamesWithRetries(3)
         .then((result) => {
-          if (!result) Promise.reject();
+          if (!result) throw Error('Some problems with fundFilenamesWithRetries');
         });
 
-      // 3. Configure App Promotion 
+      // 3. Configure App Promotion
       const missingPallets = helper.fetchMissingPalletNames([Pallets.AppPromotion]);
       if (missingPallets.length === 0) {
         const superuser = await privateKey('//Alice');
@@ -38,7 +38,7 @@
       }
     } catch (error) {
       console.error(error);
-      Promise.reject();
+      throw Error('Error during globalSetup');
     }
   });
 };
@@ -78,7 +78,7 @@
 
         if (aliceBalance < MINIMUM_DONOR_FUND * oneToken) {
           tx.push(helper.executeExtrinsic(
-            alice, 
+            alice,
             'api.tx.balances.transfer',
             [account.address, DONOR_FUNDING * oneToken],
             true,
modifiedtests/src/util/index.tsdiffbeforeafterboth
--- a/tests/src/util/index.ts
+++ b/tests/src/util/index.ts
@@ -41,7 +41,7 @@
       else {
         const actualSeed = getTestSeed(seed.filename);
         let account = helper.util.fromSeed(actualSeed, ss58Format);
-        // here's to hoping that no 
+        // here's to hoping that no
         if (!seed.ignoreFundsPresence && ((helper as any)['balance'] == undefined || await (helper as any).balance.getSubstrate(account.address) < MINIMUM_DONOR_FUND)) {
           console.warn(`${path.basename(seed.filename)}: Not enough funds present on the filename account. Using the default one as the donor instead.`);
           account = helper.util.fromSeed('//Alice', ss58Format);
@@ -115,7 +115,7 @@
 
 export function requirePalletsOrSkip(test: Context, helper: DevUniqueHelper, requiredPallets: string[]) {
   const missingPallets = helper.fetchMissingPalletNames(requiredPallets);
-    
+
   if (missingPallets.length > 0) {
     const skipMsg = `\tSkipping test '${test.test?.title}'.\n\tThe following pallets are missing:\n\t- ${missingPallets.join('\n\t- ')}`;
     console.warn('\x1b[38:5:208m%s\x1b[0m', skipMsg);
@@ -124,13 +124,13 @@
 }
 
 export function itSub(name: string, cb: (apis: { helper: DevUniqueHelper, privateKey: (seed: string) => Promise<IKeyringPair> }) => any, opts: { only?: boolean, skip?: boolean, requiredPallets?: string[] } = {}) {
-  (opts.only ? it.only : 
+  (opts.only ? it.only :
     opts.skip ? it.skip : it)(name, async function () {
     await usingPlaygrounds(async (helper, privateKey) => {
       if (opts.requiredPallets) {
         requirePalletsOrSkip(this, helper, opts.requiredPallets);
       }
-      
+
       await cb({helper, privateKey});
     });
   });
modifiedtests/src/util/playgrounds/types.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/types.ts
+++ b/tests/src/util/playgrounds/types.ts
@@ -26,7 +26,7 @@
 export interface ISubscribeBlockEventsData {
   number: number;
   hash: string;
-  timestamp: number; 
+  timestamp: number;
   events: IEvent[];
 }
 
@@ -56,7 +56,7 @@
   connected?: (...args: any[]) => any;
   disconnected?: (...args: any[]) => any;
   error?: (...args: any[]) => any;
-  ready?: (...args: any[]) => any; 
+  ready?: (...args: any[]) => any;
   decorated?: (...args: any[]) => any;
 }
 
modifiedtests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/unique.dev.ts
+++ b/tests/src/util/playgrounds/unique.dev.ts
@@ -35,7 +35,7 @@
     this.consoleWarn = console.warn;
   }
 
-  enable() {  
+  enable() {
     const outFn = (printer: any) => (...args: any[]) => {
       for (const arg of args) {
         if (typeof arg !== 'string')
@@ -45,7 +45,7 @@
       }
       printer(...args);
     };
-  
+
     console.error = outFn(this.consoleErr.bind(console));
     console.log = outFn(this.consoleLog.bind(console));
     console.warn = outFn(this.consoleWarn.bind(console));
@@ -188,11 +188,11 @@
   }
 
   /**
-   * Generates accounts with the specified UNQ token balance 
+   * Generates accounts with the specified UNQ token balance
    * @param balances balances for generated accounts. Each balance will be multiplied by the token nominal.
    * @param donor donor account for balances
    * @returns array of newly created accounts
-   * @example const [acc1, acc2, acc3] = await createAccounts([0n, 10n, 20n], donor); 
+   * @example const [acc1, acc2, acc3] = await createAccounts([0n, 10n, 20n], donor);
    */
   createAccounts = async (balances: bigint[], donor: IKeyringPair): Promise<IKeyringPair[]> => {
     let nonce = await this.helper.chain.getNonce(donor.address);
@@ -212,7 +212,7 @@
     }
 
     await Promise.all(transactions).catch(_e => {});
-    
+
     //#region TODO remove this region, when nonce problem will be solved
     const checkBalances = async () => {
       let isSuccess = true;
@@ -242,7 +242,7 @@
   };
 
   // TODO combine this method and createAccounts into one
-  createCrowd = async (accountsToCreate: number, withBalance: bigint, donor: IKeyringPair): Promise<IKeyringPair[]> => {  
+  createCrowd = async (accountsToCreate: number, withBalance: bigint, donor: IKeyringPair): Promise<IKeyringPair[]> => {
     const createAsManyAsCan = async () => {
       let transactions: any = [];
       const accounts: IKeyringPair[] = [];
@@ -250,9 +250,9 @@
       const tokenNominal = this.helper.balance.getOneTokenNominal();
       for (let i = 0; i < accountsToCreate; i++) {
         if (i === 500) { // if there are too many accounts to create
-          await Promise.allSettled(transactions); // wait while first 500 (should be 100 for devnode) tx will be settled 
+          await Promise.allSettled(transactions); // wait while first 500 (should be 100 for devnode) tx will be settled
           transactions = []; //
-          nonce = await this.helper.chain.getNonce(donor.address); // update nonce 
+          nonce = await this.helper.chain.getNonce(donor.address); // update nonce
         }
         const recepient = this.helper.util.fromSeed(mnemonicGenerate());
         accounts.push(recepient);
@@ -262,7 +262,7 @@
           nonce++;
         }
       }
-      
+
       const fullfilledAccounts = [];
       await Promise.allSettled(transactions);
       for (const account of accounts) {
@@ -274,7 +274,7 @@
       return fullfilledAccounts;
     };
 
-    
+
     const crowd: IKeyringPair[] = [];
     // do up to 5 retries
     for (let index = 0; index < 5 && accountsToCreate !== 0; index++) {
@@ -291,7 +291,7 @@
   isDevNode = async () => {
     let blockNumber = (await this.helper.callRpc('api.query.system.number')).toJSON();
     if (blockNumber == 0) {
-      await this.helper.wait.newBlocks(1); 
+      await this.helper.wait.newBlocks(1);
       blockNumber = (await this.helper.callRpc('api.query.system.number')).toJSON();
     }
     const block2 = await this.helper.callRpc('api.rpc.chain.getBlock', [await this.helper.callRpc('api.rpc.chain.getBlockHash', [blockNumber])]);
@@ -310,15 +310,15 @@
     const block2date = await findCreationDate(block2);
     if(block2date! - block1date! < 9000) return true;
   };
-  
+
   async calculcateFee(payer: ICrossAccountId, promise: () => Promise<any>): Promise<bigint> {
     const address = payer.Substrate ? payer.Substrate : await this.helper.address.ethToSubstrate(payer.Ethereum!);
-    let balance = await this.helper.balance.getSubstrate(address); 
-    
+    let balance = await this.helper.balance.getSubstrate(address);
+
     await promise();
-    
+
     balance -= await this.helper.balance.getSubstrate(address);
-    
+
     return balance;
   }
 
@@ -335,7 +335,7 @@
 
       const scheduledId = '0x' + '0'.repeat(prefixSize) + hexId;
 
-      return scheduledId;  
+      return scheduledId;
     }
 
     const ids = [];
@@ -424,7 +424,7 @@
   /**
    * Wait for specified number of blocks
    * @param blocksCount number of blocks to wait
-   * @returns 
+   * @returns
    */
   async newBlocks(blocksCount = 1, timeout?: number): Promise<void> {
     timeout = timeout ?? blocksCount * 60_000;
@@ -457,7 +457,7 @@
     await this.waitWithTimeout(promise, timeout);
     return promise;
   }
-  
+
   async forRelayBlockNumber(blockNumber: bigint | number, timeout?: number) {
     timeout = timeout ?? 30 * 60 * 1000;
     // eslint-disable-next-line no-async-promise-executor
@@ -476,7 +476,7 @@
 
   noScheduledTasks() {
     const api = this.helper.getApi();
-    
+
     // eslint-disable-next-line no-async-promise-executor
     const promise = new Promise<void>(async resolve => {
       const unsubscribe = await api.rpc.chain.subscribeNewHeads(async () => {
@@ -486,7 +486,7 @@
           unsubscribe();
           resolve();
         }
-      }); 
+      });
     });
 
     return promise;
@@ -500,16 +500,16 @@
         const blockHash = header.hash;
         const eventIdStr = `${eventSection}.${eventMethod}`;
         const waitLimitStr = `wait blocks remaining: ${maxBlocksToWait}`;
-  
+
         this.helper.logger.log(`[Block #${blockNumber}] Waiting for event \`${eventIdStr}\` (${waitLimitStr})`);
-  
+
         const apiAt = await this.helper.getApi().at(blockHash);
         const eventRecords = (await apiAt.query.system.events()) as any;
-  
+
         const neededEvent = eventRecords.toArray().find((r: FrameSystemEventRecord) => {
           return r.event.section == eventSection && r.event.method == eventMethod;
         });
-  
+
         if (neededEvent) {
           unsubscribe();
           resolve(neededEvent);
modifiedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/unique.ts
+++ b/tests/src/util/playgrounds/unique.ts
@@ -1103,7 +1103,7 @@
   async getPropertiesConsumedSpace(collectionId: number): Promise<number> {
     const api = this.helper.getApi();
     const props = (await api.query.common.collectionProperties(collectionId)).toJSON();
-        
+
     return (props! as any).consumedSpace;
   }
 
@@ -2423,7 +2423,7 @@
   /**
    * Get schedule for recepient of vested transfer
    * @param address Substrate address of recipient
-   * @returns 
+   * @returns
    */
   async getVestingSchedules(address: TSubstrateAccount): Promise<{start: bigint, period: bigint, periodCount: bigint, perPeriod: bigint}[]> {
     const schedule = (await this.helper.callRpc('api.query.vesting.vestingSchedules', [address])).toJSON();
@@ -2506,16 +2506,16 @@
       : typeof key === 'bigint'
         ? hexToU8a(key.toString(16))
         : key;
-  
+
     if (ss58Format < 0 || ss58Format > 16383 || [46, 47].includes(ss58Format)) {
       throw new Error(`ss58Format is not valid, received ${typeof ss58Format} "${ss58Format}"`);
     }
-  
+
     const allowedDecodedLengths = [1, 2, 4, 8, 32, 33];
     if (!allowedDecodedLengths.includes(u8a.length)) {
       throw new Error(`key length is not valid, received ${u8a.length}, valid values are ${allowedDecodedLengths.join(', ')}`);
     }
-  
+
     const u8aPrefix = ss58Format < 64
       ? new Uint8Array([ss58Format])
       : new Uint8Array([
@@ -2524,7 +2524,7 @@
       ]);
 
     const input = u8aConcat(u8aPrefix, u8a);
-  
+
     return base58Encode(u8aConcat(
       input,
       blake2AsU8a(input).subarray(0, [32, 33].includes(u8a.length) ? 2 : 1),
@@ -2556,7 +2556,7 @@
     if (ethCrossAccount.sub === '0') {
       return {Ethereum: ethCrossAccount.eth.toLocaleLowerCase()};
     }
-    
+
     const ss58 = this.restoreCrossAccountFromBigInt(BigInt(ethCrossAccount.sub));
     return {Substrate: ss58};
   }
@@ -3074,14 +3074,14 @@
 
     executeExtrinsic(sender: IKeyringPair, scheduledExtrinsic: string, scheduledParams: any[], expectSuccess?: boolean): Promise<ITransactionResult> {
       const scheduledTx = this.constructApiCall(scheduledExtrinsic, scheduledParams);
-      
+
       const mandatorySchedArgs = [
         this.blocksNum,
         this.options.periodic ? [this.options.periodic.period, this.options.periodic.repetitions] : null,
         this.options.priority ?? null,
         scheduledTx,
       ];
-      
+
       let schedArgs;
       let scheduleFn;
 
@@ -3301,7 +3301,7 @@
   async getTokenPropertiesConsumedSpace(tokenId: number): Promise<number> {
     const api = this.helper.getApi();
     const props = (await api.query.nonfungible.tokenProperties(this.collectionId, tokenId)).toJSON();
-        
+
     return (props! as any).consumedSpace;
   }
 
@@ -3419,7 +3419,7 @@
   async getTokenPropertiesConsumedSpace(tokenId: number): Promise<number> {
     const api = this.helper.getApi();
     const props = (await api.query.refungible.tokenProperties(this.collectionId, tokenId)).toJSON();
-        
+
     return (props! as any).consumedSpace;
   }
 
modifiedtests/src/vesting.test.tsdiffbeforeafterboth
--- a/tests/src/vesting.test.ts
+++ b/tests/src/vesting.test.ts
@@ -73,7 +73,7 @@
     expect(balanceRecepient.feeFrozen).to.eq(250n * nominal);
     expect(balanceRecepient.miscFrozen).to.eq(250n * nominal);
     expect(balanceRecepient.reserved).to.eq(0n);
-    
+
     // Wait first schedule ends and first part od second schedule:
     await helper.wait.forRelayBlockNumber(SCHEDULE_2_START + SCHEDULE_2_PERIOD);
     await helper.balance.claim(recepient);
@@ -84,7 +84,7 @@
     expect(balanceRecepient.feeFrozen).to.eq(100n * nominal);
     expect(balanceRecepient.miscFrozen).to.eq(100n * nominal);
     expect(balanceRecepient.reserved).to.eq(0n);
-    
+
     // Schedules list contain 1 vesting:
     schedule = await helper.balance.getVestingSchedules(recepient.address);
     expect(schedule).to.has.length(1);
@@ -100,7 +100,7 @@
     expect(balanceRecepient.feeFrozen).to.eq(0n);
     expect(balanceRecepient.miscFrozen).to.eq(0n);
     expect(balanceRecepient.reserved).to.eq(0n);
-    
+
     // check sender balance does not changed:
     balanceSender = await helper.balance.getSubstrateFull(sender.address);
     expect(balanceSender.free / nominal).to.eq(699n);
modifiedtests/src/xcm/xcmOpal.test.tsdiffbeforeafterboth
--- a/tests/src/xcm/xcmOpal.test.ts
+++ b/tests/src/xcm/xcmOpal.test.ts
@@ -37,12 +37,12 @@
 const TRANSFER_AMOUNT = 1_000_000_000_000_000_000n;
 
 // 10,000.00 (ten thousands) USDT
-const ASSET_AMOUNT = 1_000_000_000_000_000_000_000n; 
+const ASSET_AMOUNT = 1_000_000_000_000_000_000_000n;
 
 describeXCM('[XCM] Integration test: Exchanging USDT with Westmint', () => {
   let alice: IKeyringPair;
   let bob: IKeyringPair;
-  
+
   let balanceStmnBefore: bigint;
   let balanceStmnAfter: bigint;
 
@@ -66,7 +66,7 @@
 
     await usingWestmintPlaygrounds(westmintUrl, async (helper) => {
       // 350.00 (three hundred fifty) DOT
-      const fundingAmount = 3_500_000_000_000n; 
+      const fundingAmount = 3_500_000_000_000n;
 
       await helper.assets.create(alice, ASSET_ID, alice.address, ASSET_METADATA_MINIMAL_BALANCE);
       await helper.assets.setMetadata(alice, ASSET_ID, ASSET_METADATA_NAME, ASSET_METADATA_DESCRIPTION, ASSET_METADATA_DECIMALS);
@@ -151,7 +151,7 @@
 
       await helper.xcm.limitedReserveTransferAssets(alice, destination, beneficiary, assets, feeAssetItem, 'Unlimited');
     });
-  
+
   });
 
   itSub('Should connect and send USDT from Westmint to Opal', async ({helper}) => {
@@ -190,7 +190,7 @@
                     },
                     {
                       GeneralIndex: ASSET_ID,
-                    }, 
+                    },
                   ]},
               },
             },
@@ -266,7 +266,7 @@
         },
         //10_000_000_000_000_000n,
         TRANSFER_AMOUNT,
-      ], 
+      ],
       [
         {
           NativeAssetId: 'Parent',
@@ -278,16 +278,16 @@
     const feeItem = 1;
 
     await helper.xTokens.transferMulticurrencies(alice, currencies, feeItem, destination, 'Unlimited');
-    
+
     // the commission has been paid in parachain native token
     balanceOpalFinal = await helper.balance.getSubstrate(alice.address);
     expect(balanceOpalAfter > balanceOpalFinal).to.be.true;
 
     await usingWestmintPlaygrounds(westmintUrl, async (helper) => {
       await helper.wait.newBlocks(3);
-      
+
       // The USDT token never paid fees. Its amount not changed from begin value.
-      // Also check that xcm transfer has been succeeded 
+      // Also check that xcm transfer has been succeeded
       expect((await helper.assets.account(ASSET_ID, alice.address))! == ASSET_AMOUNT).to.be.true;
     });
   });
@@ -341,13 +341,13 @@
 
       await helper.xcm.limitedReserveTransferAssets(bob, destination, beneficiary, assets, feeAssetItem, 'Unlimited');
     });
-  
+
     await helper.wait.newBlocks(3);
 
-    balanceBobAfter = await helper.balance.getSubstrate(bob.address);  
+    balanceBobAfter = await helper.balance.getSubstrate(bob.address);
     balanceBobRelayTokenAfter = await helper.tokens.accounts(bob.address, {NativeAssetId: 'Parent'});
 
-    const wndFee = balanceBobRelayTokenAfter - TRANSFER_AMOUNT_RELAY - balanceBobRelayTokenBefore; 
+    const wndFee = balanceBobRelayTokenAfter - TRANSFER_AMOUNT_RELAY - balanceBobRelayTokenBefore;
     console.log(
       'Relay (Westend) to Opal transaction fees: %s OPL',
       helper.util.bigIntToDecimals(balanceBobAfter - balanceBobBefore),
modifiedtests/src/xcm/xcmQuartz.test.tsdiffbeforeafterboth
--- a/tests/src/xcm/xcmQuartz.test.ts
+++ b/tests/src/xcm/xcmQuartz.test.ts
@@ -38,7 +38,7 @@
 
 const TRANSFER_AMOUNT = 2000000000000000000000000n;
 
-const FUNDING_AMOUNT = 3_500_000_0000_000_000n; 
+const FUNDING_AMOUNT = 3_500_000_0000_000_000n;
 
 const TRANSFER_AMOUNT_RELAY = 50_000_000_000_000_000n;
 
@@ -52,7 +52,7 @@
 describeXCM('[XCM] Integration test: Exchanging USDT with Statemine', () => {
   let alice: IKeyringPair;
   let bob: IKeyringPair;
-  
+
   let balanceStmnBefore: bigint;
   let balanceStmnAfter: bigint;
 
@@ -81,7 +81,7 @@
     });
 
     await usingStateminePlaygrounds(statemineUrl, async (helper) => {
-      const sovereignFundingAmount = 3_500_000_000n; 
+      const sovereignFundingAmount = 3_500_000_000n;
 
       await helper.assets.create(
         alice,
@@ -185,7 +185,7 @@
 
       await helper.xcm.limitedReserveTransferAssets(alice, destination, beneficiary, assets, feeAssetItem, 'Unlimited');
     });
-  
+
   });
 
   itSub('Should connect and send USDT from Statemine to Quartz', async ({helper}) => {
@@ -224,7 +224,7 @@
                     },
                     {
                       GeneralIndex: USDT_ASSET_ID,
-                    }, 
+                    },
                   ]},
               },
             },
@@ -267,7 +267,7 @@
     console.log(
       '[Statemine -> Quartz] transaction fees on Quartz: %s QTZ',
       helper.util.bigIntToDecimals(balanceQuartzAfter - balanceQuartzBefore),
-    );    
+    );
     // commission has not paid in USDT token
     expect(free).to.be.equal(TRANSFER_AMOUNT);
     // ... and parachain native token
@@ -299,7 +299,7 @@
           ForeignAssetId: 0,
         },
         TRANSFER_AMOUNT,
-      ], 
+      ],
       [
         {
           NativeAssetId: 'Parent',
@@ -311,7 +311,7 @@
     const feeItem = 1;
 
     await helper.xTokens.transferMulticurrencies(alice, currencies, feeItem, destination, 'Unlimited');
-    
+
     // the commission has been paid in parachain native token
     balanceQuartzFinal = await helper.balance.getSubstrate(alice.address);
     console.log('[Quartz -> Statemine] transaction fees on Quartz: %s QTZ', helper.util.bigIntToDecimals(balanceQuartzFinal - balanceQuartzAfter));
@@ -319,9 +319,9 @@
 
     await usingStateminePlaygrounds(statemineUrl, async (helper) => {
       await helper.wait.newBlocks(3);
-      
+
       // The USDT token never paid fees. Its amount not changed from begin value.
-      // Also check that xcm transfer has been succeeded 
+      // Also check that xcm transfer has been succeeded
       expect((await helper.assets.account(USDT_ASSET_ID, alice.address))! == USDT_ASSET_AMOUNT).to.be.true;
     });
   });
@@ -372,10 +372,10 @@
 
       await helper.xcm.limitedReserveTransferAssets(bob, destination, beneficiary, assets, feeAssetItem, 'Unlimited');
     });
-  
+
     await helper.wait.newBlocks(3);
 
-    balanceBobAfter = await helper.balance.getSubstrate(bob.address);  
+    balanceBobAfter = await helper.balance.getSubstrate(bob.address);
     balanceBobRelayTokenAfter = await helper.tokens.accounts(bob.address, {NativeAssetId: 'Parent'});
 
     const wndFeeOnQuartz = balanceBobRelayTokenAfter - TRANSFER_AMOUNT_RELAY - balanceBobRelayTokenBefore;
modifiedtests/src/xcm/xcmUnique.test.tsdiffbeforeafterboth
--- a/tests/src/xcm/xcmUnique.test.ts
+++ b/tests/src/xcm/xcmUnique.test.ts
@@ -38,7 +38,7 @@
 
 const TRANSFER_AMOUNT = 2000000000000000000000000n;
 
-const FUNDING_AMOUNT = 3_500_000_0000_000_000n; 
+const FUNDING_AMOUNT = 3_500_000_0000_000_000n;
 
 const TRANSFER_AMOUNT_RELAY = 50_000_000_000_000_000n;
 
@@ -52,7 +52,7 @@
 describeXCM('[XCM] Integration test: Exchanging USDT with Statemint', () => {
   let alice: IKeyringPair;
   let bob: IKeyringPair;
-  
+
   let balanceStmnBefore: bigint;
   let balanceStmnAfter: bigint;
 
@@ -81,7 +81,7 @@
     });
 
     await usingStatemintPlaygrounds(statemintUrl, async (helper) => {
-      const sovereignFundingAmount = 3_500_000_000n; 
+      const sovereignFundingAmount = 3_500_000_000n;
 
       await helper.assets.create(
         alice,
@@ -185,7 +185,7 @@
 
       await helper.xcm.limitedReserveTransferAssets(alice, destination, beneficiary, assets, feeAssetItem, 'Unlimited');
     });
-  
+
   });
 
   itSub('Should connect and send USDT from Statemint to Unique', async ({helper}) => {
@@ -224,7 +224,7 @@
                     },
                     {
                       GeneralIndex: USDT_ASSET_ID,
-                    }, 
+                    },
                   ]},
               },
             },
@@ -267,7 +267,7 @@
     console.log(
       '[Statemint -> Unique] transaction fees on Unique: %s UNQ',
       helper.util.bigIntToDecimals(balanceUniqueAfter - balanceUniqueBefore),
-    );    
+    );
     // commission has not paid in USDT token
     expect(free).to.be.equal(TRANSFER_AMOUNT);
     // ... and parachain native token
@@ -299,7 +299,7 @@
           ForeignAssetId: 0,
         },
         TRANSFER_AMOUNT,
-      ], 
+      ],
       [
         {
           NativeAssetId: 'Parent',
@@ -311,7 +311,7 @@
     const feeItem = 1;
 
     await helper.xTokens.transferMulticurrencies(alice, currencies, feeItem, destination, 'Unlimited');
-    
+
     // the commission has been paid in parachain native token
     balanceUniqueFinal = await helper.balance.getSubstrate(alice.address);
     console.log('[Unique -> Statemint] transaction fees on Unique: %s UNQ', helper.util.bigIntToDecimals(balanceUniqueFinal - balanceUniqueAfter));
@@ -319,9 +319,9 @@
 
     await usingStatemintPlaygrounds(statemintUrl, async (helper) => {
       await helper.wait.newBlocks(3);
-      
+
       // The USDT token never paid fees. Its amount not changed from begin value.
-      // Also check that xcm transfer has been succeeded 
+      // Also check that xcm transfer has been succeeded
       expect((await helper.assets.account(USDT_ASSET_ID, alice.address))! == USDT_ASSET_AMOUNT).to.be.true;
     });
   });
@@ -372,10 +372,10 @@
 
       await helper.xcm.limitedReserveTransferAssets(bob, destination, beneficiary, assets, feeAssetItem, 'Unlimited');
     });
-  
+
     await helper.wait.newBlocks(3);
 
-    balanceBobAfter = await helper.balance.getSubstrate(bob.address);  
+    balanceBobAfter = await helper.balance.getSubstrate(bob.address);
     balanceBobRelayTokenAfter = await helper.tokens.accounts(bob.address, {NativeAssetId: 'Parent'});
 
     const wndFeeOnUnique = balanceBobRelayTokenAfter - TRANSFER_AMOUNT_RELAY - balanceBobRelayTokenBefore;
@@ -909,7 +909,7 @@
       const unqRandomAccountAsset = await helper.assets.account(assetId, randomAccountMoonbeam.address);
 
       expect(unqRandomAccountAsset).to.be.null;
-      
+
       balanceForeignUnqTokenFinal = 0n;
 
       const unqOutcomeTransfer = balanceForeignUnqTokenMiddle - balanceForeignUnqTokenFinal;
modifiedtests/yarn.lockdiffbeforeafterboth
--- a/tests/yarn.lock
+++ b/tests/yarn.lock
@@ -1065,7 +1065,7 @@
   dependencies:
     "@types/node" "*"
 
-"@typescript-eslint/eslint-plugin@^5.40.1":
+"@typescript-eslint/eslint-plugin@^5.47.0":
   version "5.47.0"
   resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.0.tgz#dadb79df3b0499699b155839fd6792f16897d910"
   integrity sha512-AHZtlXAMGkDmyLuLZsRpH3p4G/1iARIwc/T0vIem2YB+xW6pZaXYXzCBnZSF/5fdM97R9QqZWZ+h3iW10XgevQ==
@@ -1080,7 +1080,7 @@
     semver "^7.3.7"
     tsutils "^3.21.0"
 
-"@typescript-eslint/parser@^5.40.1":
+"@typescript-eslint/parser@^5.47.0":
   version "5.47.0"
   resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.47.0.tgz#62e83de93499bf4b500528f74bf2e0554e3a6c8d"
   integrity sha512-udPU4ckK+R1JWCGdQC4Qa27NtBg7w020ffHqGyAK8pAgOVuNw7YaKXGChk+udh+iiGIJf6/E/0xhVXyPAbsczw==