git.delta.rocks / unique-network / refs/commits / 8057bddf39cb

difftreelog

Merge remote-tracking branch 'origin/develop' into feature/CORE-37

str-mv2021-08-31parents: #fee4139 #c1ca9e8.patch.diff
in: master

144 files changed

modified.devcontainer/Dockerfilediffbeforeafterboth
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -13,8 +13,8 @@
     [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && \
     nvm install v16.2.0 && \
     npm install -g yarn && \
-    rustup toolchain install nightly-2021-05-30 && \
-    rustup default nightly-2021-05-30 && \
+    rustup toolchain install nightly-2021-05-20 && \
+    rustup default nightly-2021-05-20 && \
     rustup target add wasm32-unknown-unknown && \
     rustup component add rustfmt clippy && \
     cargo install cargo-expand cargo-edit cargo-contract
modified.devcontainer/devcontainer.jsondiffbeforeafterboth
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -1,9 +1,8 @@
 {
 	"name": "Rust",
-	"build": {
-		"dockerfile": "Dockerfile"
-	},
-	"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ],
+    "dockerComposeFile": "./docker-compose.yml",
+    "service": "nft_private",
+    "workspaceFolder": "/workspaces/nft_private",
 	"settings": { 
 		"terminal.integrated.shell.linux": "/bin/bash",
 		"lldb.executable": "/usr/bin/lldb",
@@ -13,7 +12,8 @@
 	},
 	"extensions": [
 		"matklad.rust-analyzer",
-		"dbaeumer.vscode-eslint"
+		"dbaeumer.vscode-eslint",
+		"tamasfe.even-better-toml"
 	],
 	"remoteUser": "vscode"
 }
added.devcontainer/docker-compose.ymldiffbeforeafterboth
--- /dev/null
+++ b/.devcontainer/docker-compose.yml
@@ -0,0 +1,23 @@
+version: '3'
+services:
+  nft_private:
+    build: 
+        context: .
+    environment:
+      - JAEGER_AGENT_HOST=jaeger
+      - JAEGER_AGENT_PORT=6831
+    volumes:
+      - ..:/workspaces/nft_private:cached
+      - ../../polkadot:/workspaces/polkadot:cached
+      - ../../polkadot-launch:/workspaces/polkadot-launch:cached
+      #- ../../frontier:/workspaces/frontier
+    cap_add:
+      - SYS_PTRACE
+    security_opt:
+      - seccomp:unconfined
+    command: /bin/sh -c "while sleep 1000; do :; done"
+  jaeger:
+    image: jaegertracing/all-in-one:latest
+    ports:
+      - "6831:6831/udp"
+      - "16686:16686"
\ No newline at end of file
modified.github/workflows/node_build_test.ymldiffbeforeafterboth
--- a/.github/workflows/node_build_test.yml
+++ b/.github/workflows/node_build_test.yml
@@ -31,11 +31,11 @@
           username: ${{ secrets.SERVER_USERNAME }}
           key: ${{ secrets.KEY }}
           port: ${{ secrets.SERVER_PORT }}
-          command_timeout: 240m
+          command_timeout: 300m
           script: |
             eval $(ssh-agent -s)
-            ssh-add /home/polkadot/.ssh/git_hub
-            git clone git@github.com:usetech-llc/nft_private.git
+            ssh-add /home/devops/.ssh/git_hub
+            git clone git@github.com:UniqueNetwork/nft_private.git
             cd nft_private
             git checkout develop
             # git pull --all
added.maintain/frame-weight-template.hbsdiffbeforeafterboth
--- /dev/null
+++ b/.maintain/frame-weight-template.hbs
@@ -0,0 +1,95 @@
+// Template adopted from https://github.com/paritytech/substrate/blob/master/.maintain/frame-weight-template.hbs
+
+//! Autogenerated weights for {{pallet}}
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION {{version}}
+//! DATE: {{date}}, STEPS: `{{cmd.steps}}`, REPEAT: {{cmd.repeat}}, LOW RANGE: `{{cmd.lowest_range_values}}`, HIGH RANGE: `{{cmd.highest_range_values}}`
+//! EXECUTION: {{cmd.execution}}, WASM-EXECUTION: {{cmd.wasm_execution}}, CHAIN: {{cmd.chain}}, DB CACHE: {{cmd.db_cache}}
+
+// Executed Command:
+{{#each args as |arg|~}}
+// {{arg}}
+{{/each}}
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+
+use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
+use sp_std::marker::PhantomData;
+
+/// Weight functions needed for {{pallet}}.
+pub trait WeightInfo {
+	{{~#each benchmarks as |benchmark|}}
+	fn {{benchmark.name~}}
+	(
+		{{~#each benchmark.components as |c| ~}}
+		{{c.name}}: u32, {{/each~}}
+	) -> Weight;
+	{{~/each}}
+}
+
+/// Weights for {{pallet}} using the Substrate node and recommended hardware.
+pub struct SubstrateWeight<T>(PhantomData<T>);
+impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
+	{{~#each benchmarks as |benchmark|}}
+	{{~#each benchmark.comments as |comment|}}
+	// {{comment}}
+	{{~/each}}
+	fn {{benchmark.name~}}
+	(
+		{{~#each benchmark.components as |c| ~}}
+		{{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}}
+	) -> Weight {
+		({{underscore benchmark.base_weight}} as Weight)
+			{{~#each benchmark.component_weight as |cw|}}
+			// Standard Error: {{underscore cw.error}}
+			.saturating_add(({{underscore cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight))
+			{{~/each}}
+			{{~#if (ne benchmark.base_reads "0")}}
+			.saturating_add(T::DbWeight::get().reads({{benchmark.base_reads}} as Weight))
+			{{~/if}}
+			{{~#each benchmark.component_reads as |cr|}}
+			.saturating_add(T::DbWeight::get().reads(({{cr.slope}} as Weight).saturating_mul({{cr.name}} as Weight)))
+			{{~/each}}
+			{{~#if (ne benchmark.base_writes "0")}}
+			.saturating_add(T::DbWeight::get().writes({{benchmark.base_writes}} as Weight))
+			{{~/if}}
+			{{~#each benchmark.component_writes as |cw|}}
+			.saturating_add(T::DbWeight::get().writes(({{cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight)))
+			{{~/each}}
+	}
+	{{~/each}}
+}
+
+// For backwards compatibility and tests
+impl WeightInfo for () {
+	{{~#each benchmarks as |benchmark|}}
+	{{~#each benchmark.comments as |comment|}}
+	// {{comment}}
+	{{~/each}}
+	fn {{benchmark.name~}}
+	(
+		{{~#each benchmark.components as |c| ~}}
+		{{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}}
+	) -> Weight {
+		({{underscore benchmark.base_weight}} as Weight)
+			{{~#each benchmark.component_weight as |cw|}}
+			// Standard Error: {{underscore cw.error}}
+			.saturating_add(({{underscore cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight))
+			{{~/each}}
+			{{~#if (ne benchmark.base_reads "0")}}
+			.saturating_add(RocksDbWeight::get().reads({{benchmark.base_reads}} as Weight))
+			{{~/if}}
+			{{~#each benchmark.component_reads as |cr|}}
+			.saturating_add(RocksDbWeight::get().reads(({{cr.slope}} as Weight).saturating_mul({{cr.name}} as Weight)))
+			{{~/each}}
+			{{~#if (ne benchmark.base_writes "0")}}
+			.saturating_add(RocksDbWeight::get().writes({{benchmark.base_writes}} as Weight))
+			{{~/if}}
+			{{~#each benchmark.component_writes as |cw|}}
+			.saturating_add(RocksDbWeight::get().writes(({{cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight)))
+			{{~/each}}
+	}
+	{{~/each}}
+}
\ No newline at end of file
added.maintain/scripts/compile_stub.shdiffbeforeafterboth
--- /dev/null
+++ b/.maintain/scripts/compile_stub.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+set -eu
+
+dir=$PWD
+
+tmp=$(mktemp -d)
+cd $tmp
+cp $dir/$INPUT input.sol
+solcjs --optimize --bin input.sol
+
+mv input_sol_$(basename $OUTPUT .raw).bin out.bin
+xxd -r -p out.bin out.raw
+
+mv out.raw $dir/$OUTPUT
\ No newline at end of file
added.maintain/scripts/generate_api.shdiffbeforeafterboth
--- /dev/null
+++ b/.maintain/scripts/generate_api.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+set -eu
+
+tmp=$(mktemp)
+cargo test --package $PACKAGE -- $NAME --exact --nocapture --ignored | tee $tmp
+raw=$(mktemp --suffix .sol)
+sed -n '/=== SNIP START ===/, /=== SNIP END ===/{ /=== SNIP START ===/! { /=== SNIP END ===/! p } }' $tmp > $raw
+formatted=$(mktemp)
+prettier --use-tabs $raw > $formatted
+solhint --fix $formatted
+
+mv $formatted $OUTPUT
\ No newline at end of file
modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -18,7 +18,16 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e7a2e47a1fbe209ee101dd6d61285226744c6c8d3c21c8dc878ba6cb9f467f3a"
 dependencies = [
- "gimli",
+ "gimli 0.24.0",
+]
+
+[[package]]
+name = "addr2line"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd"
+dependencies = [
+ "gimli 0.25.0",
 ]
 
 [[package]]
@@ -57,7 +66,7 @@
  "aes",
  "block-cipher",
  "ghash",
- "subtle 2.4.0",
+ "subtle 2.4.1",
 ]
 
 [[package]]
@@ -88,6 +97,17 @@
 checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
 
 [[package]]
+name = "ahash"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98"
+dependencies = [
+ "getrandom 0.2.3",
+ "once_cell",
+ "version_check",
+]
+
+[[package]]
 name = "aho-corasick"
 version = "0.7.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -122,18 +142,9 @@
 
 [[package]]
 name = "anyhow"
-version = "1.0.41"
+version = "1.0.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61"
-
-[[package]]
-name = "approx"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278"
-dependencies = [
- "num-traits",
-]
+checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486"
 
 [[package]]
 name = "approx"
@@ -236,12 +247,11 @@
 
 [[package]]
 name = "async-io"
-version = "1.4.1"
+version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bbfd5cf2794b1e908ea8457e6c45f8f8f1f6ec5f74617bf4662623f47503c3b"
+checksum = "a811e6a479f2439f0c04038796b5cfb3d2ad56c230e0f2d3f7b04d68cfee607b"
 dependencies = [
  "concurrent-queue",
- "fastrand",
  "futures-lite",
  "libc",
  "log",
@@ -312,7 +322,7 @@
  "memchr",
  "num_cpus",
  "once_cell",
- "pin-project-lite 0.2.6",
+ "pin-project-lite 0.2.7",
  "pin-utils",
  "slab",
  "wasm-bindgen-futures",
@@ -359,7 +369,7 @@
  "futures-sink",
  "futures-util",
  "memchr",
- "pin-project-lite 0.2.6",
+ "pin-project-lite 0.2.7",
 ]
 
 [[package]]
@@ -372,7 +382,7 @@
  "futures-sink",
  "futures-util",
  "memchr",
- "pin-project-lite 0.2.6",
+ "pin-project-lite 0.2.7",
 ]
 
 [[package]]
@@ -409,16 +419,16 @@
 
 [[package]]
 name = "backtrace"
-version = "0.3.60"
+version = "0.3.61"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7815ea54e4d821e791162e078acbebfd6d8c8939cd559c9335dceb1c8ca7282"
+checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01"
 dependencies = [
- "addr2line",
+ "addr2line 0.16.0",
  "cc",
  "cfg-if 1.0.0",
  "libc",
  "miniz_oxide",
- "object 0.25.3",
+ "object 0.26.0",
  "rustc-demangle",
 ]
 
@@ -448,9 +458,9 @@
 
 [[package]]
 name = "beef"
-version = "0.5.0"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6736e2428df2ca2848d846c43e88745121a6654696e349ce0054a420815a7409"
+checksum = "bed554bd50246729a1ec158d08aa3235d1b69d94ad120ebe187e28894787e736"
 dependencies = [
  "serde",
 ]
@@ -458,13 +468,13 @@
 [[package]]
 name = "beefy-gadget"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/grandpa-bridge-gadget?branch=polkadot-v0.9.7#299dd5fd3fabd99c3c919f1312001283ddc5b365"
+source = "git+https://github.com/paritytech/grandpa-bridge-gadget?branch=polkadot-v0.9.8#55ae3329847e0bbde51c9d45991d99f444777555"
 dependencies = [
  "beefy-primitives",
- "futures 0.3.15",
+ "futures 0.3.16",
  "hex",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
  "sc-client-api",
  "sc-keystore",
@@ -486,17 +496,17 @@
 [[package]]
 name = "beefy-gadget-rpc"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/grandpa-bridge-gadget?branch=polkadot-v0.9.7#299dd5fd3fabd99c3c919f1312001283ddc5b365"
+source = "git+https://github.com/paritytech/grandpa-bridge-gadget?branch=polkadot-v0.9.8#55ae3329847e0bbde51c9d45991d99f444777555"
 dependencies = [
  "beefy-gadget",
  "beefy-primitives",
- "futures 0.3.15",
+ "futures 0.3.16",
  "jsonrpc-core 15.1.0",
  "jsonrpc-core-client 15.1.0",
  "jsonrpc-derive 15.1.0",
  "jsonrpc-pubsub 15.1.0",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sc-rpc",
  "serde",
  "serde_json",
@@ -507,9 +517,9 @@
 [[package]]
 name = "beefy-primitives"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/grandpa-bridge-gadget?branch=polkadot-v0.9.7#299dd5fd3fabd99c3c919f1312001283ddc5b365"
+source = "git+https://github.com/paritytech/grandpa-bridge-gadget?branch=polkadot-v0.9.8#55ae3329847e0bbde51c9d45991d99f444777555"
 dependencies = [
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-api",
  "sp-application-crypto",
  "sp-core",
@@ -528,9 +538,9 @@
 
 [[package]]
 name = "bindgen"
-version = "0.57.0"
+version = "0.59.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd4865004a46a0aafb2a0a5eb19d3c9fc46ee5f063a6cfc605c69ac9ecf5263d"
+checksum = "453c49e5950bb0eb63bb3df640e31618846c89d5b7faa54040d76e98e0134375"
 dependencies = [
  "bitflags",
  "cexpr",
@@ -553,12 +563,14 @@
 
 [[package]]
 name = "bitvec"
-version = "0.17.4"
+version = "0.19.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c"
+checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321"
 dependencies = [
- "either",
- "radium 0.3.0",
+ "funty",
+ "radium 0.5.3",
+ "tap",
+ "wyz",
 ]
 
 [[package]]
@@ -692,6 +704,117 @@
 ]
 
 [[package]]
+name = "bp-header-chain"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "finality-grandpa",
+ "frame-support",
+ "parity-scale-codec",
+ "serde",
+ "sp-core",
+ "sp-finality-grandpa",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
+name = "bp-messages"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "bitvec 0.20.4",
+ "bp-runtime",
+ "frame-support",
+ "frame-system",
+ "impl-trait-for-tuples",
+ "parity-scale-codec",
+ "serde",
+ "sp-std",
+]
+
+[[package]]
+name = "bp-polkadot-core"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "bp-messages",
+ "bp-runtime",
+ "frame-support",
+ "frame-system",
+ "parity-scale-codec",
+ "sp-api",
+ "sp-core",
+ "sp-runtime",
+ "sp-std",
+ "sp-version",
+]
+
+[[package]]
+name = "bp-rococo"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "bp-messages",
+ "bp-polkadot-core",
+ "bp-runtime",
+ "frame-support",
+ "parity-scale-codec",
+ "smallvec 1.6.1",
+ "sp-api",
+ "sp-runtime",
+ "sp-std",
+ "sp-version",
+]
+
+[[package]]
+name = "bp-runtime"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "frame-support",
+ "hash-db",
+ "num-traits",
+ "parity-scale-codec",
+ "sp-core",
+ "sp-io",
+ "sp-runtime",
+ "sp-state-machine",
+ "sp-std",
+ "sp-trie",
+]
+
+[[package]]
+name = "bp-test-utils"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "bp-header-chain",
+ "ed25519-dalek",
+ "finality-grandpa",
+ "parity-scale-codec",
+ "sp-application-crypto",
+ "sp-finality-grandpa",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
+name = "bp-wococo"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "bp-messages",
+ "bp-polkadot-core",
+ "bp-rococo",
+ "bp-runtime",
+ "parity-scale-codec",
+ "sp-api",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
 name = "bs58"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -720,12 +843,6 @@
 version = "3.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
-
-[[package]]
-name = "byte-slice-cast"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3"
 
 [[package]]
 name = "byte-slice-cast"
@@ -775,6 +892,15 @@
 checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba"
 
 [[package]]
+name = "camino"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4648c6d00a709aa069a236adcaae4f605a6241c72bf5bee79331a4b625921a9"
+dependencies = [
+ "serde",
+]
+
+[[package]]
 name = "cargo-platform"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -797,19 +923,33 @@
 ]
 
 [[package]]
+name = "cargo_metadata"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "081e3f0755c1f380c2d010481b6fa2e02973586d5f2b24eebb7a2a1d98b143d8"
+dependencies = [
+ "camino",
+ "cargo-platform",
+ "semver 0.11.0",
+ "semver-parser 0.10.2",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
 name = "cc"
-version = "1.0.68"
+version = "1.0.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787"
+checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
 dependencies = [
  "jobserver",
 ]
 
 [[package]]
 name = "cexpr"
-version = "0.4.0"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
+checksum = "db507a7679252d2276ed0dd8113c6875ec56d3089f9225b2b42c30cc1f8e5c89"
 dependencies = [
  "nom",
 ]
@@ -987,19 +1127,18 @@
 
 [[package]]
 name = "cpp_demangle"
-version = "0.3.2"
+version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44919ecaf6f99e8e737bc239408931c9a01e9a6c74814fee8242dd2506b65390"
+checksum = "8ea47428dc9d2237f3c6bc134472edfd63ebba0af932e783506dcfd66f10d18a"
 dependencies = [
  "cfg-if 1.0.0",
- "glob",
 ]
 
 [[package]]
 name = "cpufeatures"
-version = "0.1.4"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8"
+checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef"
 dependencies = [
  "libc",
 ]
@@ -1029,7 +1168,7 @@
  "cranelift-codegen-meta",
  "cranelift-codegen-shared",
  "cranelift-entity",
- "gimli",
+ "gimli 0.24.0",
  "log",
  "regalloc",
  "serde",
@@ -1228,7 +1367,7 @@
 checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab"
 dependencies = [
  "generic-array 0.14.4",
- "subtle 2.4.0",
+ "subtle 2.4.1",
 ]
 
 [[package]]
@@ -1264,7 +1403,7 @@
 [[package]]
 name = "cumulus-client-cli"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
 dependencies = [
  "sc-cli",
  "sc-service",
@@ -1274,13 +1413,13 @@
 [[package]]
 name = "cumulus-client-collator"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
 dependencies = [
  "cumulus-client-consensus-common",
  "cumulus-client-network",
  "cumulus-primitives-core",
- "futures 0.3.15",
- "parity-scale-codec 2.1.3",
+ "futures 0.3.16",
+ "parity-scale-codec",
  "parking_lot 0.10.2",
  "polkadot-node-primitives",
  "polkadot-node-subsystem",
@@ -1298,13 +1437,13 @@
 [[package]]
 name = "cumulus-client-consensus-aura"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
 dependencies = [
  "async-trait",
  "cumulus-client-consensus-common",
  "cumulus-primitives-core",
- "futures 0.3.15",
- "parity-scale-codec 2.1.3",
+ "futures 0.3.16",
+ "parity-scale-codec",
  "parking_lot 0.10.2",
  "polkadot-client",
  "sc-client-api",
@@ -1328,12 +1467,12 @@
 [[package]]
 name = "cumulus-client-consensus-common"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
 dependencies = [
  "async-trait",
  "dyn-clone",
- "futures 0.3.15",
- "parity-scale-codec 2.1.3",
+ "futures 0.3.16",
+ "parity-scale-codec",
  "polkadot-primitives",
  "polkadot-runtime",
  "sc-client-api",
@@ -1352,12 +1491,12 @@
 [[package]]
 name = "cumulus-client-network"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
 dependencies = [
  "derive_more",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.10.2",
  "polkadot-client",
  "polkadot-node-primitives",
@@ -1376,12 +1515,12 @@
 [[package]]
 name = "cumulus-client-pov-recovery"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
 dependencies = [
  "cumulus-primitives-core",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "polkadot-node-primitives",
  "polkadot-node-subsystem",
  "polkadot-overseer",
@@ -1399,13 +1538,13 @@
 [[package]]
 name = "cumulus-client-service"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
 dependencies = [
  "cumulus-client-collator",
  "cumulus-client-consensus-common",
  "cumulus-client-pov-recovery",
  "cumulus-primitives-core",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.10.2",
  "polkadot-overseer",
  "polkadot-primitives",
@@ -1427,13 +1566,13 @@
 [[package]]
 name = "cumulus-pallet-aura-ext"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
 dependencies = [
  "frame-executive",
  "frame-support",
  "frame-system",
  "pallet-aura",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-application-crypto",
  "sp-consensus-aura",
@@ -1444,13 +1583,13 @@
 [[package]]
 name = "cumulus-pallet-dmp-queue"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
 dependencies = [
  "cumulus-primitives-core",
  "frame-support",
  "frame-system",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "rand 0.8.4",
  "rand_chacha 0.3.1",
  "sp-io",
@@ -1463,7 +1602,7 @@
 [[package]]
 name = "cumulus-pallet-parachain-system"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
 dependencies = [
  "cumulus-pallet-parachain-system-proc-macro",
  "cumulus-primitives-core",
@@ -1473,7 +1612,7 @@
  "frame-system",
  "log",
  "pallet-balances",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "polkadot-parachain",
  "serde",
  "sp-core",
@@ -1491,7 +1630,7 @@
 [[package]]
 name = "cumulus-pallet-parachain-system-proc-macro"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
 dependencies = [
  "proc-macro-crate 1.0.0",
  "proc-macro2",
@@ -1502,12 +1641,12 @@
 [[package]]
 name = "cumulus-pallet-xcm"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
 dependencies = [
  "cumulus-primitives-core",
  "frame-support",
  "frame-system",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-io",
  "sp-runtime",
@@ -1518,13 +1657,13 @@
 [[package]]
 name = "cumulus-pallet-xcmp-queue"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
 dependencies = [
  "cumulus-primitives-core",
  "frame-support",
  "frame-system",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "rand 0.8.4",
  "rand_chacha 0.3.1",
  "sp-runtime",
@@ -1536,11 +1675,11 @@
 [[package]]
 name = "cumulus-primitives-core"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
 dependencies = [
  "frame-support",
- "impl-trait-for-tuples 0.2.1",
- "parity-scale-codec 2.1.3",
+ "impl-trait-for-tuples",
+ "parity-scale-codec",
  "polkadot-core-primitives",
  "polkadot-parachain",
  "polkadot-primitives",
@@ -1554,11 +1693,12 @@
 [[package]]
 name = "cumulus-primitives-parachain-inherent"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
 dependencies = [
  "async-trait",
  "cumulus-primitives-core",
- "parity-scale-codec 2.1.3",
+ "cumulus-test-relay-sproof-builder",
+ "parity-scale-codec",
  "polkadot-client",
  "sc-client-api",
  "sp-api",
@@ -1574,7 +1714,7 @@
 [[package]]
 name = "cumulus-primitives-timestamp"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
 dependencies = [
  "cumulus-primitives-core",
  "sp-inherents",
@@ -1585,12 +1725,12 @@
 [[package]]
 name = "cumulus-primitives-utility"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
 dependencies = [
  "cumulus-primitives-core",
  "frame-support",
- "impl-trait-for-tuples 0.2.1",
- "parity-scale-codec 2.1.3",
+ "impl-trait-for-tuples",
+ "parity-scale-codec",
  "polkadot-core-primitives",
  "polkadot-parachain",
  "polkadot-primitives",
@@ -1601,15 +1741,28 @@
 ]
 
 [[package]]
+name = "cumulus-test-relay-sproof-builder"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
+dependencies = [
+ "cumulus-primitives-core",
+ "parity-scale-codec",
+ "polkadot-primitives",
+ "sp-runtime",
+ "sp-state-machine",
+ "sp-std",
+]
+
+[[package]]
 name = "curve25519-dalek"
-version = "2.1.2"
+version = "2.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "434e1720189a637d44fe464f4df1e6eb900b4835255b14354497c78af37d9bb8"
+checksum = "4a9b85542f99a2dfa2a1b8e192662741c9859a846b296bef1c92ef9b58b5a216"
 dependencies = [
  "byteorder",
  "digest 0.8.1",
  "rand_core 0.5.1",
- "subtle 2.4.0",
+ "subtle 2.4.1",
  "zeroize",
 ]
 
@@ -1622,7 +1775,7 @@
  "byteorder",
  "digest 0.9.0",
  "rand_core 0.5.1",
- "subtle 2.4.0",
+ "subtle 2.4.1",
  "zeroize",
 ]
 
@@ -1700,13 +1853,14 @@
 
 [[package]]
 name = "derive_more"
-version = "0.99.14"
+version = "0.99.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cc7b9cef1e351660e5443924e4f43ab25fbbed3e9a5f052df3677deb4d6b320"
+checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df"
 dependencies = [
  "convert_case",
  "proc-macro2",
  "quote",
+ "rustc_version 0.3.3",
  "syn",
 ]
 
@@ -1814,9 +1968,9 @@
 
 [[package]]
 name = "ed25519"
-version = "1.1.1"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d0860415b12243916284c67a9be413e044ee6668247b99ba26d94b2bc06c8f6"
+checksum = "4620d40f6d2601794401d6dd95a5cf69b6c157852539470eeda433a99b3c0efc"
 dependencies = [
  "signature",
 ]
@@ -1918,9 +2072,9 @@
 
 [[package]]
 name = "erased-serde"
-version = "0.3.15"
+version = "0.3.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5b36e6f2295f393f44894c6031f67df4d185b984cd54d08f768ce678007efcd"
+checksum = "3de9ad4541d99dc22b59134e7ff8dc3d6c988c89ecd7324bf10a8362b07a2afa"
 dependencies = [
  "serde",
 ]
@@ -1944,19 +2098,6 @@
 dependencies = [
  "gcc",
  "libc",
-]
-
-[[package]]
-name = "ethbloom"
-version = "0.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71a6567e6fd35589fea0c63b94b4cf2e55573e413901bdbe60ab15cf0e25e5df"
-dependencies = [
- "crunchy",
- "fixed-hash 0.6.1",
- "impl-rlp 0.2.1",
- "impl-serde",
- "tiny-keccak",
 ]
 
 [[package]]
@@ -1966,9 +2107,9 @@
 checksum = "779864b9c7f7ead1f092972c3257496c6a84b46dba2ce131dd8a282cb2cc5972"
 dependencies = [
  "crunchy",
- "fixed-hash 0.7.0",
- "impl-codec 0.5.0",
- "impl-rlp 0.3.0",
+ "fixed-hash",
+ "impl-codec",
+ "impl-rlp",
  "impl-serde",
  "tiny-keccak",
 ]
@@ -1979,12 +2120,12 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "567ce064a8232c16e2b2c2173a936b91fbe35c2f2c5278871f5a1a31688b42e9"
 dependencies = [
- "ethereum-types 0.11.0",
+ "ethereum-types",
  "funty",
  "hash-db",
  "hash256-std-hasher",
- "parity-scale-codec 2.1.3",
- "rlp 0.5.0",
+ "parity-scale-codec",
+ "rlp",
  "rlp-derive",
  "serde",
  "sha3 0.9.1",
@@ -1992,48 +2133,18 @@
 ]
 
 [[package]]
-name = "ethereum-tx-sign"
-version = "3.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bdcbb5f48282fa71ba2864818a442d0ee0ca04ebc9ef9eb1837c48298c3b8cbf"
-dependencies = [
- "ethereum-types 0.9.2",
- "num-traits",
- "rlp 0.4.6",
- "secp256k1",
- "serde",
- "serde_derive",
- "serde_json",
- "tiny-keccak",
-]
-
-[[package]]
 name = "ethereum-types"
-version = "0.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "473aecff686bd8e7b9db0165cbbb53562376b39bf35b427f0c60446a9e1634b0"
-dependencies = [
- "ethbloom 0.9.2",
- "fixed-hash 0.6.1",
- "impl-rlp 0.2.1",
- "impl-serde",
- "primitive-types 0.7.3",
- "uint 0.8.5",
-]
-
-[[package]]
-name = "ethereum-types"
 version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f64b5df66a228d85e4b17e5d6c6aa43b0310898ffe8a85988c4c032357aaabfd"
 dependencies = [
- "ethbloom 0.11.0",
- "fixed-hash 0.7.0",
- "impl-codec 0.5.0",
- "impl-rlp 0.3.0",
+ "ethbloom",
+ "fixed-hash",
+ "impl-codec",
+ "impl-rlp",
  "impl-serde",
- "primitive-types 0.9.0",
- "uint 0.9.0",
+ "primitive-types",
+ "uint",
 ]
 
 [[package]]
@@ -2045,7 +2156,7 @@
 [[package]]
 name = "evm"
 version = "0.27.0"
-source = "git+https://github.com/usetech-llc/evm.git?branch=precompile-output-parachain#e13990a627375f327ca7da3c85d9bdfa0a9e903b"
+source = "git+https://github.com/uniquenetwork/evm.git?branch=precompile-output-parachain#e13990a627375f327ca7da3c85d9bdfa0a9e903b"
 dependencies = [
  "environmental",
  "ethereum",
@@ -2053,9 +2164,9 @@
  "evm-gasometer",
  "evm-runtime",
  "log",
- "parity-scale-codec 2.1.3",
- "primitive-types 0.9.0",
- "rlp 0.5.0",
+ "parity-scale-codec",
+ "primitive-types",
+ "rlp",
  "serde",
  "sha3 0.8.2",
 ]
@@ -2066,9 +2177,11 @@
 dependencies = [
  "ethereum",
  "evm-coder-macros",
+ "evm-core",
  "hex",
  "hex-literal",
- "primitive-types 0.9.0",
+ "impl-trait-for-tuples",
+ "primitive-types",
 ]
 
 [[package]]
@@ -2087,33 +2200,33 @@
 [[package]]
 name = "evm-core"
 version = "0.27.1"
-source = "git+https://github.com/usetech-llc/evm.git?branch=precompile-output-parachain#e13990a627375f327ca7da3c85d9bdfa0a9e903b"
+source = "git+https://github.com/uniquenetwork/evm.git?branch=precompile-output-parachain#e13990a627375f327ca7da3c85d9bdfa0a9e903b"
 dependencies = [
  "funty",
- "parity-scale-codec 2.1.3",
- "primitive-types 0.9.0",
+ "parity-scale-codec",
+ "primitive-types",
  "serde",
 ]
 
 [[package]]
 name = "evm-gasometer"
 version = "0.27.0"
-source = "git+https://github.com/usetech-llc/evm.git?branch=precompile-output-parachain#e13990a627375f327ca7da3c85d9bdfa0a9e903b"
+source = "git+https://github.com/uniquenetwork/evm.git?branch=precompile-output-parachain#e13990a627375f327ca7da3c85d9bdfa0a9e903b"
 dependencies = [
  "environmental",
  "evm-core",
  "evm-runtime",
- "primitive-types 0.9.0",
+ "primitive-types",
 ]
 
 [[package]]
 name = "evm-runtime"
 version = "0.27.0"
-source = "git+https://github.com/usetech-llc/evm.git?branch=precompile-output-parachain#e13990a627375f327ca7da3c85d9bdfa0a9e903b"
+source = "git+https://github.com/uniquenetwork/evm.git?branch=precompile-output-parachain#e13990a627375f327ca7da3c85d9bdfa0a9e903b"
 dependencies = [
  "environmental",
  "evm-core",
- "primitive-types 0.9.0",
+ "primitive-types",
  "sha3 0.8.2",
 ]
 
@@ -2123,7 +2236,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
 ]
 
 [[package]]
@@ -2162,9 +2275,9 @@
 
 [[package]]
 name = "fastrand"
-version = "1.4.1"
+version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77b705829d1e87f762c2df6da140b26af5839e1033aa84aa5f56bb688e4e1bdb"
+checksum = "b394ed3d285a429378d3b384b9eb1285267e7df4b166df24b7a6939a04dc392e"
 dependencies = [
  "instant",
 ]
@@ -2172,16 +2285,16 @@
 [[package]]
 name = "fc-consensus"
 version = "2.0.0"
-source = "git+https://github.com/usetech-llc/frontier.git?branch=injected-transactions-parachain#c1388c13be6d59b9a70e1277f1295977090adb63"
+source = "git+https://github.com/uniquenetwork/frontier.git?branch=injected-transactions-parachain#1e2a0537db656af0b300493b4f8eda72c22e9421"
 dependencies = [
  "async-trait",
  "derive_more",
  "fc-db",
  "fp-consensus",
  "fp-rpc",
- "futures 0.3.15",
+ "futures 0.3.16",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sc-client-api",
  "sp-api",
  "sp-block-builder",
@@ -2197,11 +2310,11 @@
 [[package]]
 name = "fc-db"
 version = "1.0.0"
-source = "git+https://github.com/usetech-llc/frontier.git?branch=injected-transactions-parachain#c1388c13be6d59b9a70e1277f1295977090adb63"
+source = "git+https://github.com/uniquenetwork/frontier.git?branch=injected-transactions-parachain#1e2a0537db656af0b300493b4f8eda72c22e9421"
 dependencies = [
  "kvdb",
  "kvdb-rocksdb",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
  "sp-core",
  "sp-database",
@@ -2211,13 +2324,13 @@
 [[package]]
 name = "fc-mapping-sync"
 version = "2.0.0-dev"
-source = "git+https://github.com/usetech-llc/frontier.git?branch=injected-transactions-parachain#c1388c13be6d59b9a70e1277f1295977090adb63"
+source = "git+https://github.com/uniquenetwork/frontier.git?branch=injected-transactions-parachain#1e2a0537db656af0b300493b4f8eda72c22e9421"
 dependencies = [
  "fc-consensus",
  "fc-db",
  "fp-consensus",
  "fp-rpc",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "log",
  "sc-client-api",
@@ -2229,10 +2342,10 @@
 [[package]]
 name = "fc-rpc"
 version = "2.0.0-dev"
-source = "git+https://github.com/usetech-llc/frontier.git?branch=injected-transactions-parachain#c1388c13be6d59b9a70e1277f1295977090adb63"
+source = "git+https://github.com/uniquenetwork/frontier.git?branch=injected-transactions-parachain#1e2a0537db656af0b300493b4f8eda72c22e9421"
 dependencies = [
  "ethereum",
- "ethereum-types 0.11.0",
+ "ethereum-types",
  "evm",
  "fc-consensus",
  "fc-db",
@@ -2241,7 +2354,7 @@
  "fp-evm",
  "fp-rpc",
  "fp-storage",
- "futures 0.3.15",
+ "futures 0.3.16",
  "jsonrpc-core 15.1.0",
  "jsonrpc-core-client 14.2.0",
  "jsonrpc-derive 14.2.2",
@@ -2250,9 +2363,9 @@
  "log",
  "pallet-ethereum",
  "pallet-evm",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "rand 0.7.3",
- "rlp 0.5.0",
+ "rlp",
  "rustc-hex",
  "sc-client-api",
  "sc-network",
@@ -2270,9 +2383,9 @@
 [[package]]
 name = "fc-rpc-core"
 version = "1.1.0-dev"
-source = "git+https://github.com/usetech-llc/frontier.git?branch=injected-transactions-parachain#c1388c13be6d59b9a70e1277f1295977090adb63"
+source = "git+https://github.com/uniquenetwork/frontier.git?branch=injected-transactions-parachain#1e2a0537db656af0b300493b4f8eda72c22e9421"
 dependencies = [
- "ethereum-types 0.11.0",
+ "ethereum-types",
  "jsonrpc-core 15.1.0",
  "jsonrpc-core-client 14.2.0",
  "jsonrpc-derive 14.2.2",
@@ -2308,28 +2421,16 @@
 checksum = "74a1bfdcc776e63e49f741c7ce6116fa1b887e8ac2e3ccb14dd4aa113e54feb9"
 dependencies = [
  "either",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "log",
  "num-traits",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
 ]
 
 [[package]]
 name = "fixed-hash"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11498d382790b7a8f2fd211780bec78619bba81cdad3a283997c0c41f836759c"
-dependencies = [
- "byteorder",
- "rand 0.7.3",
- "rustc-hex",
- "static_assertions",
-]
-
-[[package]]
-name = "fixed-hash"
 version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c"
@@ -2384,9 +2485,9 @@
 [[package]]
 name = "fork-tree"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
 ]
 
 [[package]]
@@ -2402,11 +2503,11 @@
 [[package]]
 name = "fp-consensus"
 version = "1.0.0"
-source = "git+https://github.com/usetech-llc/frontier.git?branch=injected-transactions-parachain#c1388c13be6d59b9a70e1277f1295977090adb63"
+source = "git+https://github.com/uniquenetwork/frontier.git?branch=injected-transactions-parachain#1e2a0537db656af0b300493b4f8eda72c22e9421"
 dependencies = [
  "ethereum",
- "parity-scale-codec 2.1.3",
- "rlp 0.5.0",
+ "parity-scale-codec",
+ "rlp",
  "sha3 0.8.2",
  "sp-core",
  "sp-runtime",
@@ -2416,11 +2517,11 @@
 [[package]]
 name = "fp-evm"
 version = "2.0.0"
-source = "git+https://github.com/usetech-llc/frontier.git?branch=injected-transactions-parachain#c1388c13be6d59b9a70e1277f1295977090adb63"
+source = "git+https://github.com/uniquenetwork/frontier.git?branch=injected-transactions-parachain#1e2a0537db656af0b300493b4f8eda72c22e9421"
 dependencies = [
  "evm",
- "impl-trait-for-tuples 0.1.3",
- "parity-scale-codec 2.1.3",
+ "impl-trait-for-tuples",
+ "parity-scale-codec",
  "serde",
  "sp-core",
  "sp-std",
@@ -2429,12 +2530,12 @@
 [[package]]
 name = "fp-rpc"
 version = "2.1.0"
-source = "git+https://github.com/usetech-llc/frontier.git?branch=injected-transactions-parachain#c1388c13be6d59b9a70e1277f1295977090adb63"
+source = "git+https://github.com/uniquenetwork/frontier.git?branch=injected-transactions-parachain#1e2a0537db656af0b300493b4f8eda72c22e9421"
 dependencies = [
  "ethereum",
- "ethereum-types 0.11.0",
+ "ethereum-types",
  "fp-evm",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-api",
  "sp-core",
  "sp-io",
@@ -2445,18 +2546,18 @@
 [[package]]
 name = "fp-storage"
 version = "1.0.1"
-source = "git+https://github.com/usetech-llc/frontier.git?branch=injected-transactions-parachain#c1388c13be6d59b9a70e1277f1295977090adb63"
+source = "git+https://github.com/uniquenetwork/frontier.git?branch=injected-transactions-parachain#1e2a0537db656af0b300493b4f8eda72c22e9421"
 
 [[package]]
 name = "frame-benchmarking"
 version = "3.1.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-support",
  "frame-system",
  "linregress",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "paste",
  "sp-api",
  "sp-io",
@@ -2469,13 +2570,13 @@
 [[package]]
 name = "frame-benchmarking-cli"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "Inflector",
  "chrono",
  "frame-benchmarking",
  "handlebars",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sc-cli",
  "sc-client-db",
  "sc-executor",
@@ -2492,11 +2593,11 @@
 [[package]]
 name = "frame-election-provider-support"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-support",
  "frame-system",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-arithmetic",
  "sp-npos-elections",
  "sp-std",
@@ -2505,11 +2606,11 @@
 [[package]]
 name = "frame-executive"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-support",
  "frame-system",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-core",
  "sp-io",
  "sp-runtime",
@@ -2520,9 +2621,9 @@
 [[package]]
 name = "frame-metadata"
 version = "13.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-core",
  "sp-std",
@@ -2531,16 +2632,16 @@
 [[package]]
 name = "frame-support"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "bitflags",
  "frame-metadata",
  "frame-support-procedural",
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "log",
  "max-encoded-len",
  "once_cell",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "paste",
  "serde",
  "smallvec 1.6.1",
@@ -2558,7 +2659,7 @@
 [[package]]
 name = "frame-support-procedural"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "Inflector",
  "frame-support-procedural-tools",
@@ -2570,7 +2671,7 @@
 [[package]]
 name = "frame-support-procedural-tools"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-support-procedural-tools-derive",
  "proc-macro-crate 1.0.0",
@@ -2582,7 +2683,7 @@
 [[package]]
 name = "frame-support-procedural-tools-derive"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2592,12 +2693,12 @@
 [[package]]
 name = "frame-system"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-support",
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-core",
  "sp-io",
@@ -2609,12 +2710,12 @@
 [[package]]
 name = "frame-system-benchmarking"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-core",
  "sp-runtime",
  "sp-std",
@@ -2623,19 +2724,19 @@
 [[package]]
 name = "frame-system-rpc-runtime-api"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-api",
 ]
 
 [[package]]
 name = "frame-try-runtime"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-support",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-api",
  "sp-runtime",
  "sp-std",
@@ -2705,9 +2806,9 @@
 
 [[package]]
 name = "futures"
-version = "0.3.15"
+version = "0.3.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27"
+checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -2720,9 +2821,9 @@
 
 [[package]]
 name = "futures-channel"
-version = "0.3.15"
+version = "0.3.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2"
+checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9"
 dependencies = [
  "futures-core",
  "futures-sink",
@@ -2730,9 +2831,9 @@
 
 [[package]]
 name = "futures-core"
-version = "0.3.15"
+version = "0.3.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1"
+checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99"
 
 [[package]]
 name = "futures-cpupool"
@@ -2746,9 +2847,9 @@
 
 [[package]]
 name = "futures-executor"
-version = "0.3.15"
+version = "0.3.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79"
+checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c"
 dependencies = [
  "futures-core",
  "futures-task",
@@ -2758,9 +2859,9 @@
 
 [[package]]
 name = "futures-io"
-version = "0.3.15"
+version = "0.3.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1"
+checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582"
 
 [[package]]
 name = "futures-lite"
@@ -2773,15 +2874,15 @@
  "futures-io",
  "memchr",
  "parking",
- "pin-project-lite 0.2.6",
+ "pin-project-lite 0.2.7",
  "waker-fn",
 ]
 
 [[package]]
 name = "futures-macro"
-version = "0.3.15"
+version = "0.3.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121"
+checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57"
 dependencies = [
  "autocfg",
  "proc-macro-hack",
@@ -2803,15 +2904,15 @@
 
 [[package]]
 name = "futures-sink"
-version = "0.3.15"
+version = "0.3.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282"
+checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53"
 
 [[package]]
 name = "futures-task"
-version = "0.3.15"
+version = "0.3.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae"
+checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2"
 
 [[package]]
 name = "futures-timer"
@@ -2827,9 +2928,9 @@
 
 [[package]]
 name = "futures-util"
-version = "0.3.15"
+version = "0.3.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967"
+checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78"
 dependencies = [
  "autocfg",
  "futures 0.1.31",
@@ -2840,7 +2941,7 @@
  "futures-sink",
  "futures-task",
  "memchr",
- "pin-project-lite 0.2.6",
+ "pin-project-lite 0.2.7",
  "pin-utils",
  "proc-macro-hack",
  "proc-macro-nested",
@@ -2916,6 +3017,12 @@
 ]
 
 [[package]]
+name = "gimli"
+version = "0.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7"
+
+[[package]]
 name = "glob"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2923,9 +3030,9 @@
 
 [[package]]
 name = "globset"
-version = "0.4.7"
+version = "0.4.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0fc1b9fa0e64ffb1aa5b95daa0f0f167734fd528b7c02eabc581d9d843649b1"
+checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd"
 dependencies = [
  "aho-corasick",
  "bstr",
@@ -3020,7 +3127,16 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
 dependencies = [
- "ahash",
+ "ahash 0.4.7",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
+dependencies = [
+ "ahash 0.7.4",
 ]
 
 [[package]]
@@ -3034,9 +3150,9 @@
 
 [[package]]
 name = "hermit-abi"
-version = "0.1.18"
+version = "0.1.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
 dependencies = [
  "libc",
 ]
@@ -3049,9 +3165,9 @@
 
 [[package]]
 name = "hex-literal"
-version = "0.3.1"
+version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5af1f635ef1bc545d78392b136bfe1c9809e029023c84a3638a864a10b8819c8"
+checksum = "21e4590e13640f19f249fe3e4eca5113bc4289f2497710378190e7f4bd96f45b"
 
 [[package]]
 name = "hex_fmt"
@@ -3164,7 +3280,7 @@
 dependencies = [
  "bytes 1.0.1",
  "http 0.2.4",
- "pin-project-lite 0.2.6",
+ "pin-project-lite 0.2.7",
 ]
 
 [[package]]
@@ -3217,7 +3333,7 @@
  "itoa",
  "log",
  "net2",
- "rustc_version",
+ "rustc_version 0.2.3",
  "time",
  "tokio 0.1.22",
  "tokio-buf",
@@ -3246,7 +3362,7 @@
  "httparse",
  "httpdate 0.3.2",
  "itoa",
- "pin-project 1.0.7",
+ "pin-project 1.0.8",
  "socket2 0.3.19",
  "tokio 0.2.25",
  "tower-service",
@@ -3256,9 +3372,9 @@
 
 [[package]]
 name = "hyper"
-version = "0.14.10"
+version = "0.14.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7728a72c4c7d72665fde02204bcbd93b247721025b222ef78606f14513e0fd03"
+checksum = "0b61cf2d1aebcf6e6352c97b81dc2244ca29194be1b276f5d8ad5c6330fffb11"
 dependencies = [
  "bytes 1.0.1",
  "futures-channel",
@@ -3269,8 +3385,8 @@
  "httparse",
  "httpdate 1.0.1",
  "itoa",
- "pin-project-lite 0.2.6",
- "tokio 1.8.1",
+ "pin-project-lite 0.2.7",
+ "tokio 1.9.0",
  "tower-service",
  "tracing",
  "want 0.3.0",
@@ -3350,7 +3466,7 @@
 checksum = "ae8ab7f67bad3240049cb24fb9cb0b4c2c6af4c245840917fbbdededeee91179"
 dependencies = [
  "async-io",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-lite",
  "if-addrs",
  "ipnet",
@@ -3361,29 +3477,11 @@
 
 [[package]]
 name = "impl-codec"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53"
-dependencies = [
- "parity-scale-codec 1.3.7",
-]
-
-[[package]]
-name = "impl-codec"
-version = "0.5.0"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df170efa359aebdd5cb7fe78edcc67107748e4737bdca8a8fb40d15ea7a877ed"
+checksum = "161ebdfec3c8e3b52bf61c4f3550a1eea4f9579d10dc1b936f3171ebdcd6c443"
 dependencies = [
- "parity-scale-codec 2.1.3",
-]
-
-[[package]]
-name = "impl-rlp"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f7a72f11830b52333f36e3b09a288333888bf54380fd0ac0790a3c31ab0f3c5"
-dependencies = [
- "rlp 0.4.6",
+ "parity-scale-codec",
 ]
 
 [[package]]
@@ -3392,7 +3490,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808"
 dependencies = [
- "rlp 0.5.0",
+ "rlp",
 ]
 
 [[package]]
@@ -3402,17 +3500,6 @@
 checksum = "b47ca4d2b6931707a55fce5cf66aff80e2178c8b63bbb4ecb5695cbc870ddf6f"
 dependencies = [
  "serde",
-]
-
-[[package]]
-name = "impl-trait-for-tuples"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
 ]
 
 [[package]]
@@ -3428,20 +3515,20 @@
 
 [[package]]
 name = "indexmap"
-version = "1.6.2"
+version = "1.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
+checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
 dependencies = [
  "autocfg",
- "hashbrown",
+ "hashbrown 0.11.2",
  "serde",
 ]
 
 [[package]]
 name = "instant"
-version = "0.1.9"
+version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
+checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d"
 dependencies = [
  "cfg-if 1.0.0",
 ]
@@ -3467,7 +3554,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "64fa110ec7b8f493f416eed552740d10e7030ad5f63b2308f82c9608ec2df275"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 2.0.2",
 ]
 
@@ -3754,7 +3841,7 @@
  "beef",
  "futures-channel",
  "futures-util",
- "hyper 0.14.10",
+ "hyper 0.14.11",
  "log",
  "serde",
  "serde_json",
@@ -3770,10 +3857,10 @@
 dependencies = [
  "async-trait",
  "fnv",
- "futures 0.3.15",
+ "futures 0.3.16",
  "jsonrpsee-types",
  "log",
- "pin-project 1.0.7",
+ "pin-project 1.0.8",
  "rustls 0.19.1",
  "rustls-native-certs 0.5.0",
  "serde",
@@ -3803,6 +3890,91 @@
 ]
 
 [[package]]
+name = "kusama-runtime"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "beefy-primitives",
+ "bitvec 0.20.4",
+ "frame-benchmarking",
+ "frame-election-provider-support",
+ "frame-executive",
+ "frame-support",
+ "frame-system",
+ "frame-system-benchmarking",
+ "frame-system-rpc-runtime-api",
+ "frame-try-runtime",
+ "hex-literal",
+ "log",
+ "max-encoded-len",
+ "pallet-authority-discovery",
+ "pallet-authorship",
+ "pallet-babe",
+ "pallet-balances",
+ "pallet-bounties",
+ "pallet-collective",
+ "pallet-democracy",
+ "pallet-election-provider-multi-phase",
+ "pallet-elections-phragmen",
+ "pallet-gilt",
+ "pallet-grandpa",
+ "pallet-identity",
+ "pallet-im-online",
+ "pallet-indices",
+ "pallet-membership",
+ "pallet-mmr-primitives",
+ "pallet-multisig",
+ "pallet-nicks",
+ "pallet-offences",
+ "pallet-offences-benchmarking",
+ "pallet-proxy",
+ "pallet-recovery",
+ "pallet-scheduler 3.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
+ "pallet-session",
+ "pallet-session-benchmarking",
+ "pallet-society",
+ "pallet-staking",
+ "pallet-staking-reward-fn",
+ "pallet-timestamp",
+ "pallet-tips",
+ "pallet-transaction-payment",
+ "pallet-transaction-payment-rpc-runtime-api",
+ "pallet-treasury",
+ "pallet-utility",
+ "pallet-vesting",
+ "pallet-xcm",
+ "parity-scale-codec",
+ "polkadot-primitives",
+ "polkadot-runtime-common",
+ "polkadot-runtime-parachains",
+ "rustc-hex",
+ "serde",
+ "serde_derive",
+ "smallvec 1.6.1",
+ "sp-api",
+ "sp-arithmetic",
+ "sp-authority-discovery",
+ "sp-block-builder",
+ "sp-consensus-babe",
+ "sp-core",
+ "sp-inherents",
+ "sp-io",
+ "sp-npos-elections",
+ "sp-offchain",
+ "sp-runtime",
+ "sp-session",
+ "sp-staking",
+ "sp-std",
+ "sp-transaction-pool",
+ "sp-version",
+ "static_assertions",
+ "substrate-wasm-builder 4.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
+ "xcm",
+ "xcm-builder",
+ "xcm-executor",
+]
+
+[[package]]
 name = "kv-log-macro"
 version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3870,9 +4042,9 @@
 
 [[package]]
 name = "libc"
-version = "0.2.97"
+version = "0.2.98"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
+checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
 
 [[package]]
 name = "libloading"
@@ -3908,7 +4080,7 @@
 dependencies = [
  "atomic",
  "bytes 1.0.1",
- "futures 0.3.15",
+ "futures 0.3.16",
  "lazy_static",
  "libp2p-core",
  "libp2p-deflate",
@@ -3934,7 +4106,7 @@
  "libp2p-yamux",
  "parity-multiaddr",
  "parking_lot 0.11.1",
- "pin-project 1.0.7",
+ "pin-project 1.0.8",
  "smallvec 1.6.1",
  "wasm-timer",
 ]
@@ -3950,7 +4122,7 @@
  "ed25519-dalek",
  "either",
  "fnv",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "lazy_static",
  "libsecp256k1 0.3.5",
@@ -3959,7 +4131,7 @@
  "multistream-select",
  "parity-multiaddr",
  "parking_lot 0.11.1",
- "pin-project 1.0.7",
+ "pin-project 1.0.8",
  "prost",
  "prost-build",
  "rand 0.7.3",
@@ -3980,7 +4152,7 @@
 checksum = "a2181a641cd15f9b6ba71b1335800f309012a0a97a29ffaabbbf40e9d3d58f08"
 dependencies = [
  "flate2",
- "futures 0.3.15",
+ "futures 0.3.16",
  "libp2p-core",
 ]
 
@@ -3991,7 +4163,7 @@
 checksum = "62e63dab8b5ff35e0c101a3e51e843ba782c07bbb1682f5fd827622e0d02b98b"
 dependencies = [
  "async-std-resolver",
- "futures 0.3.15",
+ "futures 0.3.16",
  "libp2p-core",
  "log",
  "smallvec 1.6.1",
@@ -4006,7 +4178,7 @@
 dependencies = [
  "cuckoofilter",
  "fnv",
- "futures 0.3.15",
+ "futures 0.3.16",
  "libp2p-core",
  "libp2p-swarm",
  "log",
@@ -4027,7 +4199,7 @@
  "byteorder",
  "bytes 1.0.1",
  "fnv",
- "futures 0.3.15",
+ "futures 0.3.16",
  "hex_fmt",
  "libp2p-core",
  "libp2p-swarm",
@@ -4048,7 +4220,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5f668f00efd9883e8b7bcc582eaf0164615792608f886f6577da18bcbeea0a46"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "libp2p-core",
  "libp2p-swarm",
  "log",
@@ -4069,7 +4241,7 @@
  "bytes 1.0.1",
  "either",
  "fnv",
- "futures 0.3.15",
+ "futures 0.3.16",
  "libp2p-core",
  "libp2p-swarm",
  "log",
@@ -4078,7 +4250,7 @@
  "rand 0.7.3",
  "sha2 0.9.5",
  "smallvec 1.6.1",
- "uint 0.9.0",
+ "uint",
  "unsigned-varint 0.7.0",
  "void",
  "wasm-timer",
@@ -4093,7 +4265,7 @@
  "async-io",
  "data-encoding",
  "dns-parser",
- "futures 0.3.15",
+ "futures 0.3.16",
  "if-watch",
  "lazy_static",
  "libp2p-core",
@@ -4113,7 +4285,7 @@
 dependencies = [
  "asynchronous-codec 0.6.0",
  "bytes 1.0.1",
- "futures 0.3.15",
+ "futures 0.3.16",
  "libp2p-core",
  "log",
  "nohash-hasher",
@@ -4131,7 +4303,7 @@
 dependencies = [
  "bytes 1.0.1",
  "curve25519-dalek 3.1.0",
- "futures 0.3.15",
+ "futures 0.3.16",
  "lazy_static",
  "libp2p-core",
  "log",
@@ -4151,7 +4323,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bf4bfaffac63bf3c7ec11ed9d8879d455966ddea7e78ee14737f0b6dce0d1cd1"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "libp2p-core",
  "libp2p-swarm",
  "log",
@@ -4168,7 +4340,7 @@
 dependencies = [
  "asynchronous-codec 0.6.0",
  "bytes 1.0.1",
- "futures 0.3.15",
+ "futures 0.3.16",
  "libp2p-core",
  "log",
  "prost",
@@ -4183,9 +4355,9 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6ce3374f3b28162db9d3442c9347c4f14cb01e8290052615c7d341d40eae0599"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "log",
- "pin-project 1.0.7",
+ "pin-project 1.0.8",
  "rand 0.7.3",
  "salsa20",
  "sha3 0.9.1",
@@ -4199,12 +4371,12 @@
 dependencies = [
  "asynchronous-codec 0.6.0",
  "bytes 1.0.1",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "libp2p-core",
  "libp2p-swarm",
  "log",
- "pin-project 1.0.7",
+ "pin-project 1.0.8",
  "prost",
  "prost-build",
  "rand 0.7.3",
@@ -4222,7 +4394,7 @@
 dependencies = [
  "async-trait",
  "bytes 1.0.1",
- "futures 0.3.15",
+ "futures 0.3.16",
  "libp2p-core",
  "libp2p-swarm",
  "log",
@@ -4241,7 +4413,7 @@
 checksum = "1e04d8e1eef675029ec728ba14e8d0da7975d84b6679b699b4ae91a1de9c3a92"
 dependencies = [
  "either",
- "futures 0.3.15",
+ "futures 0.3.16",
  "libp2p-core",
  "log",
  "rand 0.7.3",
@@ -4267,7 +4439,7 @@
 checksum = "2b1a27d21c477951799e99d5c105d78868258502ce092988040a808d5a19bbd9"
 dependencies = [
  "async-io",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "if-watch",
  "ipnet",
@@ -4284,7 +4456,7 @@
 checksum = "ffd6564bb3b7ff203661ccbb69003c2b551e34cef974f2d6c6a28306a12170b5"
 dependencies = [
  "async-std",
- "futures 0.3.15",
+ "futures 0.3.16",
  "libp2p-core",
  "log",
 ]
@@ -4295,7 +4467,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e2d413e4cf9b8e5dfbcd2a60d3dc5a3391308bdb463684093d4f67137b7113de"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "js-sys",
  "libp2p-core",
  "parity-send-wrapper",
@@ -4310,7 +4482,7 @@
 checksum = "cace60995ef6f637e4752cccbb2590f6bc358e8741a0d066307636c69a4b3a74"
 dependencies = [
  "either",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-rustls",
  "libp2p-core",
  "log",
@@ -4327,7 +4499,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f35da42cfc6d5cb0dcf3ad6881bc68d146cdf38f98655e09e33fbba4d13eabc4"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "libp2p-core",
  "parking_lot 0.11.1",
  "thiserror",
@@ -4336,9 +4508,9 @@
 
 [[package]]
 name = "librocksdb-sys"
-version = "6.17.3"
+version = "6.20.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5da125e1c0f22c7cae785982115523a0738728498547f415c9054cb17c7e89f9"
+checksum = "c309a9d2470844aceb9a4a098cf5286154d20596868b75a6b36357d2bb9ca25d"
 dependencies = [
  "bindgen",
  "cc",
@@ -4358,7 +4530,7 @@
  "hmac-drbg 0.2.0",
  "rand 0.7.3",
  "sha2 0.8.2",
- "subtle 2.4.0",
+ "subtle 2.4.1",
  "typenum",
 ]
 
@@ -4383,29 +4555,29 @@
 
 [[package]]
 name = "libsecp256k1-core"
-version = "0.2.1"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ee11012b293ea30093c129173cac4335513064094619f4639a25b310fd33c11"
+checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80"
 dependencies = [
  "crunchy",
  "digest 0.9.0",
- "subtle 2.4.0",
+ "subtle 2.4.1",
 ]
 
 [[package]]
 name = "libsecp256k1-gen-ecmult"
-version = "0.2.0"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32239626ffbb6a095b83b37a02ceb3672b2443a87a000a884fc3c4d16925c9c0"
+checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3"
 dependencies = [
  "libsecp256k1-core",
 ]
 
 [[package]]
 name = "libsecp256k1-gen-genmult"
-version = "0.2.0"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76acb433e21d10f5f9892b1962c2856c58c7f39a9e4bd68ac82b9436a0ffd5b9"
+checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d"
 dependencies = [
  "libsecp256k1-core",
 ]
@@ -4438,11 +4610,11 @@
 
 [[package]]
 name = "linregress"
-version = "0.4.2"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1ff7f341d23e1275eec0656a9a07225fcc86216c4322392868adffe59023d1a"
+checksum = "1e6e407dadb4ca4b31bc69c27aff00e7ca4534fdcee855159b039a7cebb5f395"
 dependencies = [
- "nalgebra 0.27.1",
+ "nalgebra",
  "statrs",
 ]
 
@@ -4480,7 +4652,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1f374d42cdfc1d7dbf3d3dec28afab2eb97ffbf43a3234d795b5986dbf4b90ba"
 dependencies = [
- "hashbrown",
+ "hashbrown 0.9.1",
 ]
 
 [[package]]
@@ -4540,18 +4712,18 @@
 [[package]]
 name = "max-encoded-len"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "max-encoded-len-derive",
- "parity-scale-codec 2.1.3",
- "primitive-types 0.9.0",
+ "parity-scale-codec",
+ "primitive-types",
 ]
 
 [[package]]
 name = "max-encoded-len-derive"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "proc-macro-crate 1.0.0",
  "proc-macro2",
@@ -4605,7 +4777,7 @@
 checksum = "814bbecfc0451fc314eeea34f05bbcd5b98a7ad7af37faee088b86a1e633f1d4"
 dependencies = [
  "hash-db",
- "hashbrown",
+ "hashbrown 0.9.1",
  "parity-util-mem",
 ]
 
@@ -4639,10 +4811,10 @@
 [[package]]
 name = "metered-channel"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "derive_more",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
 ]
 
@@ -4652,7 +4824,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c023c3f16109e7f33aa451f773fd61070e265b4977d0b6e344a51049296dd7df"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "rand 0.7.3",
  "thrift",
 ]
@@ -4668,9 +4840,9 @@
 
 [[package]]
 name = "minicbor-derive"
-version = "0.6.3"
+version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f2b9e8883d58e34b18facd16c4564a77ea50fce028ad3d0ee6753440e37acc8"
+checksum = "54999f917cd092b13904737e26631aa2b2b88d625db68e4bab461dcd8006c788"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -4823,43 +4995,28 @@
 checksum = "7d91ec0a2440aaff5f78ec35631a7027d50386c6163aa975f7caa0d5da4b6ff8"
 dependencies = [
  "bytes 1.0.1",
- "futures 0.3.15",
+ "futures 0.3.16",
  "log",
- "pin-project 1.0.7",
+ "pin-project 1.0.8",
  "smallvec 1.6.1",
  "unsigned-varint 0.7.0",
 ]
 
 [[package]]
 name = "nalgebra"
-version = "0.26.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "476d1d59fe02fe54c86356e91650cd892f392782a1cb9fc524ec84f7aa9e1d06"
-dependencies = [
- "approx 0.4.0",
- "matrixmultiply",
- "num-complex 0.3.1",
- "num-rational 0.3.2",
- "num-traits",
- "rand 0.8.4",
- "rand_distr",
- "simba 0.4.0",
- "typenum",
-]
-
-[[package]]
-name = "nalgebra"
 version = "0.27.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "462fffe4002f4f2e1f6a9dcf12cc1a6fc0e15989014efc02a941d3e0f5dc2120"
 dependencies = [
- "approx 0.5.0",
+ "approx",
  "matrixmultiply",
  "nalgebra-macros",
- "num-complex 0.4.0",
+ "num-complex",
  "num-rational 0.4.0",
  "num-traits",
- "simba 0.5.1",
+ "rand 0.8.4",
+ "rand_distr",
+ "simba",
  "typenum",
 ]
 
@@ -4915,7 +5072,7 @@
  "fp-rpc",
  "frame-benchmarking",
  "frame-benchmarking-cli",
- "futures 0.3.15",
+ "futures 0.3.16",
  "jsonrpc-core 15.1.0",
  "jsonrpc-pubsub 15.1.0",
  "log",
@@ -4924,7 +5081,7 @@
  "nft-runtime",
  "pallet-ethereum",
  "pallet-transaction-payment-rpc",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.10.2",
  "polkadot-cli",
  "polkadot-parachain",
@@ -4974,12 +5131,15 @@
 name = "nft-data-structs"
 version = "0.9.0"
 dependencies = [
+ "derivative",
  "frame-support",
  "frame-system",
- "parity-scale-codec 2.1.3",
+ "max-encoded-len",
+ "parity-scale-codec",
  "serde",
  "sp-core",
  "sp-runtime",
+ "sp-std",
 ]
 
 [[package]]
@@ -4991,7 +5151,7 @@
  "fc-rpc",
  "fc-rpc-core",
  "fp-rpc",
- "futures 0.3.15",
+ "futures 0.3.16",
  "jsonrpc-core 15.1.0",
  "jsonrpc-pubsub 15.1.0",
  "nft-runtime",
@@ -5038,6 +5198,7 @@
  "cumulus-primitives-core",
  "cumulus-primitives-timestamp",
  "cumulus-primitives-utility",
+ "derivative",
  "fp-rpc",
  "frame-benchmarking",
  "frame-executive",
@@ -5046,11 +5207,16 @@
  "frame-system-benchmarking",
  "frame-system-rpc-runtime-api",
  "hex-literal",
+ "max-encoded-len",
  "nft-data-structs",
  "pallet-aura",
  "pallet-balances",
  "pallet-ethereum",
  "pallet-evm",
+ "pallet-evm-coder-substrate",
+ "pallet-evm-contract-helpers",
+ "pallet-evm-migration",
+ "pallet-evm-transaction-payment",
  "pallet-inflation",
  "pallet-nft",
  "pallet-nft-charge-transaction",
@@ -5065,7 +5231,7 @@
  "pallet-vesting",
  "pallet-xcm",
  "parachain-info",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "polkadot-parachain",
  "serde",
  "smallvec 1.6.1",
@@ -5082,7 +5248,7 @@
  "sp-std",
  "sp-transaction-pool",
  "sp-version",
- "substrate-wasm-builder 4.0.0",
+ "substrate-wasm-builder 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "xcm",
  "xcm-builder",
  "xcm-executor",
@@ -5102,10 +5268,12 @@
 
 [[package]]
 name = "nom"
-version = "5.1.2"
+version = "6.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
+checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2"
 dependencies = [
+ "bitvec 0.19.5",
+ "funty",
  "memchr",
  "version_check",
 ]
@@ -5118,15 +5286,6 @@
 dependencies = [
  "autocfg",
  "num-integer",
- "num-traits",
-]
-
-[[package]]
-name = "num-complex"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5"
-dependencies = [
  "num-traits",
 ]
 
@@ -5163,17 +5322,6 @@
 
 [[package]]
 name = "num-rational"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
-dependencies = [
- "autocfg",
- "num-integer",
- "num-traits",
-]
-
-[[package]]
-name = "num-rational"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a"
@@ -5215,9 +5363,9 @@
 
 [[package]]
 name = "object"
-version = "0.25.3"
+version = "0.26.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a38f2be3697a57b4060074ff41b44c16870d916ad7877c17696e063257482bc7"
+checksum = "c55827317fb4c08822499848a14237d2874d6f139828893017237e7ab93eb386"
 dependencies = [
  "memchr",
 ]
@@ -5270,13 +5418,13 @@
 [[package]]
 name = "pallet-aura"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-support",
  "frame-system",
  "pallet-session",
  "pallet-timestamp",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-application-crypto",
  "sp-consensus-aura",
  "sp-runtime",
@@ -5286,12 +5434,12 @@
 [[package]]
 name = "pallet-authority-discovery"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-support",
  "frame-system",
  "pallet-session",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-application-crypto",
  "sp-authority-discovery",
  "sp-runtime",
@@ -5301,12 +5449,12 @@
 [[package]]
 name = "pallet-authorship"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-support",
  "frame-system",
- "impl-trait-for-tuples 0.2.1",
- "parity-scale-codec 2.1.3",
+ "impl-trait-for-tuples",
+ "parity-scale-codec",
  "sp-authorship",
  "sp-runtime",
  "sp-std",
@@ -5315,7 +5463,7 @@
 [[package]]
 name = "pallet-babe"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
@@ -5324,7 +5472,7 @@
  "pallet-authorship",
  "pallet-session",
  "pallet-timestamp",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-application-crypto",
  "sp-consensus-babe",
  "sp-consensus-vrf",
@@ -5338,14 +5486,14 @@
 [[package]]
 name = "pallet-balances"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
  "log",
  "max-encoded-len",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-runtime",
  "sp-std",
 ]
@@ -5353,13 +5501,13 @@
 [[package]]
 name = "pallet-beefy"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/grandpa-bridge-gadget?branch=polkadot-v0.9.7#299dd5fd3fabd99c3c919f1312001283ddc5b365"
+source = "git+https://github.com/paritytech/grandpa-bridge-gadget?branch=polkadot-v0.9.8#55ae3329847e0bbde51c9d45991d99f444777555"
 dependencies = [
  "beefy-primitives",
  "frame-support",
  "frame-system",
  "pallet-session",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-runtime",
  "sp-std",
@@ -5368,25 +5516,48 @@
 [[package]]
 name = "pallet-bounties"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
+ "frame-benchmarking",
  "frame-support",
  "frame-system",
  "pallet-treasury",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-runtime",
  "sp-std",
 ]
 
 [[package]]
+name = "pallet-bridge-grandpa"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "bp-header-chain",
+ "bp-runtime",
+ "bp-test-utils",
+ "finality-grandpa",
+ "frame-support",
+ "frame-system",
+ "log",
+ "num-traits",
+ "parity-scale-codec",
+ "serde",
+ "sp-finality-grandpa",
+ "sp-runtime",
+ "sp-std",
+ "sp-trie",
+]
+
+[[package]]
 name = "pallet-collective"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
+ "frame-benchmarking",
  "frame-support",
  "frame-system",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-core",
  "sp-io",
  "sp-runtime",
@@ -5400,7 +5571,7 @@
  "frame-support",
  "frame-system",
  "pallet-contracts",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-runtime",
  "sp-std",
  "up-sponsorship",
@@ -5409,7 +5580,7 @@
 [[package]]
 name = "pallet-contracts"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "bitflags",
  "frame-support",
@@ -5417,7 +5588,7 @@
  "log",
  "pallet-contracts-primitives",
  "pallet-contracts-proc-macro",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "pwasm-utils",
  "serde",
  "smallvec 1.6.1",
@@ -5432,10 +5603,10 @@
 [[package]]
 name = "pallet-contracts-primitives"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "bitflags",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-core",
  "sp-runtime",
@@ -5445,7 +5616,7 @@
 [[package]]
 name = "pallet-contracts-proc-macro"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -5455,12 +5626,12 @@
 [[package]]
 name = "pallet-democracy"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-io",
  "sp-runtime",
@@ -5470,13 +5641,15 @@
 [[package]]
 name = "pallet-election-provider-multi-phase"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
+ "frame-benchmarking",
  "frame-election-provider-support",
  "frame-support",
  "frame-system",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
+ "rand 0.7.3",
  "sp-arithmetic",
  "sp-core",
  "sp-io",
@@ -5489,12 +5662,13 @@
 [[package]]
 name = "pallet-elections-phragmen"
 version = "4.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
+ "frame-benchmarking",
  "frame-support",
  "frame-system",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-core",
  "sp-io",
  "sp-npos-elections",
@@ -5505,10 +5679,10 @@
 [[package]]
 name = "pallet-ethereum"
 version = "3.0.0-dev"
-source = "git+https://github.com/usetech-llc/frontier.git?branch=injected-transactions-parachain#c1388c13be6d59b9a70e1277f1295977090adb63"
+source = "git+https://github.com/uniquenetwork/frontier.git?branch=injected-transactions-parachain#1e2a0537db656af0b300493b4f8eda72c22e9421"
 dependencies = [
  "ethereum",
- "ethereum-types 0.11.0",
+ "ethereum-types",
  "evm",
  "fp-consensus",
  "fp-evm",
@@ -5520,8 +5694,8 @@
  "pallet-balances",
  "pallet-evm",
  "pallet-timestamp",
- "parity-scale-codec 2.1.3",
- "rlp 0.5.0",
+ "parity-scale-codec",
+ "rlp",
  "rustc-hex",
  "serde",
  "sha3 0.8.2",
@@ -5533,21 +5707,23 @@
 [[package]]
 name = "pallet-evm"
 version = "5.0.0-dev"
-source = "git+https://github.com/usetech-llc/frontier.git?branch=injected-transactions-parachain#c1388c13be6d59b9a70e1277f1295977090adb63"
+source = "git+https://github.com/uniquenetwork/frontier.git?branch=injected-transactions-parachain#1e2a0537db656af0b300493b4f8eda72c22e9421"
 dependencies = [
  "evm",
  "evm-gasometer",
  "evm-runtime",
  "fp-evm",
+ "frame-benchmarking",
  "frame-support",
  "frame-system",
- "impl-trait-for-tuples 0.2.1",
+ "hex",
+ "impl-trait-for-tuples",
  "log",
  "pallet-balances",
  "pallet-timestamp",
- "parity-scale-codec 2.1.3",
- "primitive-types 0.9.0",
- "rlp 0.5.0",
+ "parity-scale-codec",
+ "primitive-types",
+ "rlp",
  "serde",
  "sha3 0.8.2",
  "sp-core",
@@ -5557,9 +5733,88 @@
 ]
 
 [[package]]
+name = "pallet-evm-coder-substrate"
+version = "0.1.0"
+dependencies = [
+ "ethereum",
+ "evm-coder",
+ "frame-support",
+ "frame-system",
+ "pallet-ethereum",
+ "pallet-evm",
+ "parity-scale-codec",
+ "sp-core",
+ "sp-std",
+]
+
+[[package]]
+name = "pallet-evm-contract-helpers"
+version = "0.1.0"
+dependencies = [
+ "evm-coder",
+ "frame-support",
+ "frame-system",
+ "log",
+ "pallet-evm",
+ "pallet-evm-coder-substrate",
+ "parity-scale-codec",
+ "sp-core",
+ "sp-runtime",
+ "sp-std",
+ "up-sponsorship",
+]
+
+[[package]]
+name = "pallet-evm-migration"
+version = "0.1.0"
+dependencies = [
+ "fp-evm",
+ "frame-benchmarking",
+ "frame-support",
+ "frame-system",
+ "pallet-evm",
+ "parity-scale-codec",
+ "sp-core",
+ "sp-io",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
+name = "pallet-evm-transaction-payment"
+version = "0.1.0"
+dependencies = [
+ "fp-evm",
+ "frame-support",
+ "frame-system",
+ "pallet-ethereum",
+ "pallet-evm",
+ "parity-scale-codec",
+ "sp-core",
+ "sp-io",
+ "sp-runtime",
+ "sp-std",
+ "up-sponsorship",
+]
+
+[[package]]
+name = "pallet-gilt"
+version = "3.0.0"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
+dependencies = [
+ "frame-benchmarking",
+ "frame-support",
+ "frame-system",
+ "parity-scale-codec",
+ "sp-arithmetic",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
 name = "pallet-grandpa"
 version = "3.1.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
@@ -5567,7 +5822,7 @@
  "log",
  "pallet-authorship",
  "pallet-session",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-application-crypto",
  "sp-core",
  "sp-finality-grandpa",
@@ -5581,13 +5836,13 @@
 [[package]]
 name = "pallet-identity"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "enumflags2",
  "frame-benchmarking",
  "frame-support",
  "frame-system",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-io",
  "sp-runtime",
  "sp-std",
@@ -5596,13 +5851,14 @@
 [[package]]
 name = "pallet-im-online"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
+ "frame-benchmarking",
  "frame-support",
  "frame-system",
  "log",
  "pallet-authorship",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-application-crypto",
  "sp-core",
  "sp-io",
@@ -5614,11 +5870,12 @@
 [[package]]
 name = "pallet-indices"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
+ "frame-benchmarking",
  "frame-support",
  "frame-system",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-core",
  "sp-io",
  "sp-keyring",
@@ -5636,7 +5893,7 @@
  "pallet-balances",
  "pallet-randomness-collective-flip",
  "pallet-timestamp",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-core",
  "sp-io",
@@ -5647,13 +5904,13 @@
 [[package]]
 name = "pallet-membership"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-io",
  "sp-runtime",
  "sp-std",
@@ -5662,14 +5919,14 @@
 [[package]]
 name = "pallet-mmr"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "ckb-merkle-mountain-range",
  "frame-benchmarking",
  "frame-support",
  "frame-system",
  "pallet-mmr-primitives",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-core",
  "sp-io",
  "sp-runtime",
@@ -5679,12 +5936,12 @@
 [[package]]
 name = "pallet-mmr-primitives"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-support",
  "frame-system",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-api",
  "sp-core",
@@ -5695,13 +5952,13 @@
 [[package]]
 name = "pallet-mmr-rpc"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "jsonrpc-core 15.1.0",
  "jsonrpc-core-client 15.1.0",
  "jsonrpc-derive 15.1.0",
  "pallet-mmr-primitives",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-api",
  "sp-blockchain",
@@ -5713,11 +5970,12 @@
 [[package]]
 name = "pallet-multisig"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
+ "frame-benchmarking",
  "frame-support",
  "frame-system",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-core",
  "sp-io",
  "sp-runtime",
@@ -5729,7 +5987,6 @@
 version = "3.0.0"
 dependencies = [
  "ethereum",
- "ethereum-tx-sign",
  "evm-coder",
  "fp-evm",
  "frame-benchmarking",
@@ -5740,12 +5997,13 @@
  "pallet-balances",
  "pallet-ethereum",
  "pallet-evm",
+ "pallet-evm-coder-substrate",
  "pallet-randomness-collective-flip",
  "pallet-timestamp",
  "pallet-transaction-payment",
- "parity-scale-codec 2.1.3",
- "primitive-types 0.9.0",
- "rlp 0.5.0",
+ "parity-scale-codec",
+ "primitive-types",
+ "rlp",
  "serde",
  "sp-api",
  "sp-core",
@@ -5765,7 +6023,7 @@
  "pallet-balances",
  "pallet-nft-transaction-payment",
  "pallet-transaction-payment",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-core",
  "sp-io",
@@ -5781,7 +6039,7 @@
  "frame-support",
  "frame-system",
  "pallet-transaction-payment",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-core",
  "sp-io",
@@ -5793,11 +6051,11 @@
 [[package]]
 name = "pallet-nicks"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-support",
  "frame-system",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-io",
  "sp-runtime",
  "sp-std",
@@ -5806,13 +6064,13 @@
 [[package]]
 name = "pallet-offences"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-support",
  "frame-system",
  "log",
  "pallet-balances",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-runtime",
  "sp-staking",
@@ -5820,14 +6078,37 @@
 ]
 
 [[package]]
+name = "pallet-offences-benchmarking"
+version = "3.0.0"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
+dependencies = [
+ "frame-benchmarking",
+ "frame-election-provider-support",
+ "frame-support",
+ "frame-system",
+ "pallet-babe",
+ "pallet-balances",
+ "pallet-grandpa",
+ "pallet-im-online",
+ "pallet-offences",
+ "pallet-session",
+ "pallet-staking",
+ "parity-scale-codec",
+ "sp-runtime",
+ "sp-staking",
+ "sp-std",
+]
+
+[[package]]
 name = "pallet-proxy"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
+ "frame-benchmarking",
  "frame-support",
  "frame-system",
  "max-encoded-len",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-core",
  "sp-io",
  "sp-runtime",
@@ -5837,26 +6118,40 @@
 [[package]]
 name = "pallet-randomness-collective-flip"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-support",
  "frame-system",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "safe-mix",
  "sp-runtime",
  "sp-std",
 ]
 
 [[package]]
+name = "pallet-recovery"
+version = "3.0.0"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
+dependencies = [
+ "enumflags2",
+ "frame-support",
+ "frame-system",
+ "parity-scale-codec",
+ "sp-io",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
 name = "pallet-scheduler"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-io",
  "sp-runtime",
  "sp-std",
@@ -5870,7 +6165,7 @@
  "frame-support",
  "frame-system",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-core",
  "sp-io",
@@ -5883,14 +6178,14 @@
 [[package]]
 name = "pallet-session"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-support",
  "frame-system",
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "log",
  "pallet-timestamp",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-core",
  "sp-io",
  "sp-runtime",
@@ -5901,18 +6196,49 @@
 ]
 
 [[package]]
+name = "pallet-session-benchmarking"
+version = "3.0.0"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
+dependencies = [
+ "frame-benchmarking",
+ "frame-support",
+ "frame-system",
+ "pallet-session",
+ "pallet-staking",
+ "rand 0.7.3",
+ "sp-runtime",
+ "sp-session",
+ "sp-std",
+]
+
+[[package]]
+name = "pallet-society"
+version = "3.0.0"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
+dependencies = [
+ "frame-support",
+ "frame-system",
+ "parity-scale-codec",
+ "rand_chacha 0.2.2",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
 name = "pallet-staking"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
+ "frame-benchmarking",
  "frame-election-provider-support",
  "frame-support",
  "frame-system",
  "log",
  "pallet-authorship",
  "pallet-session",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "paste",
+ "rand_chacha 0.2.2",
  "serde",
  "sp-application-crypto",
  "sp-io",
@@ -5925,7 +6251,7 @@
 [[package]]
 name = "pallet-staking-reward-curve"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "proc-macro-crate 1.0.0",
  "proc-macro2",
@@ -5934,13 +6260,22 @@
 ]
 
 [[package]]
+name = "pallet-staking-reward-fn"
+version = "3.0.0"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
+dependencies = [
+ "log",
+ "sp-arithmetic",
+]
+
+[[package]]
 name = "pallet-sudo"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-support",
  "frame-system",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-io",
  "sp-runtime",
  "sp-std",
@@ -5949,14 +6284,14 @@
 [[package]]
 name = "pallet-timestamp"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-inherents",
  "sp-io",
  "sp-runtime",
@@ -5967,12 +6302,13 @@
 [[package]]
 name = "pallet-tips"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
+ "frame-benchmarking",
  "frame-support",
  "frame-system",
  "pallet-treasury",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-runtime",
  "sp-std",
@@ -5981,11 +6317,11 @@
 [[package]]
 name = "pallet-transaction-payment"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-support",
  "frame-system",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "smallvec 1.6.1",
  "sp-core",
@@ -5997,13 +6333,13 @@
 [[package]]
 name = "pallet-transaction-payment-rpc"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "jsonrpc-core 15.1.0",
  "jsonrpc-core-client 15.1.0",
  "jsonrpc-derive 15.1.0",
  "pallet-transaction-payment-rpc-runtime-api",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-api",
  "sp-blockchain",
  "sp-core",
@@ -6014,10 +6350,10 @@
 [[package]]
 name = "pallet-transaction-payment-rpc-runtime-api"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "pallet-transaction-payment",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-api",
  "sp-runtime",
 ]
@@ -6025,13 +6361,14 @@
 [[package]]
 name = "pallet-treasury"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
+ "frame-benchmarking",
  "frame-support",
  "frame-system",
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "pallet-balances",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-runtime",
  "sp-std",
@@ -6040,11 +6377,12 @@
 [[package]]
 name = "pallet-utility"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
+ "frame-benchmarking",
  "frame-support",
  "frame-system",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-core",
  "sp-io",
  "sp-runtime",
@@ -6054,12 +6392,13 @@
 [[package]]
 name = "pallet-vesting"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "enumflags2",
+ "frame-benchmarking",
  "frame-support",
  "frame-system",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-runtime",
  "sp-std",
 ]
@@ -6067,11 +6406,12 @@
 [[package]]
 name = "pallet-xcm"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "frame-support",
  "frame-system",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
+ "serde",
  "sp-runtime",
  "sp-std",
  "xcm",
@@ -6081,12 +6421,12 @@
 [[package]]
 name = "parachain-info"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc"
+source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.8#ed6ba5dfb2c112c29505e856e8971da3420ce6d0"
 dependencies = [
  "cumulus-primitives-core",
  "frame-support",
  "frame-system",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
 ]
 
@@ -6127,34 +6467,23 @@
 
 [[package]]
 name = "parity-scale-codec"
-version = "1.3.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4b26b16c7687c3075982af47719e481815df30bc544f7a6690763a25ca16e9d"
-dependencies = [
- "arrayvec 0.5.2",
- "bitvec 0.17.4",
- "byte-slice-cast 0.3.5",
- "serde",
-]
-
-[[package]]
-name = "parity-scale-codec"
-version = "2.1.3"
+version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b310f220c335f9df1b3d2e9fbe3890bbfeef5030dad771620f48c5c229877cd3"
+checksum = "8975095a2a03bbbdc70a74ab11a4f76a6d0b84680d87c68d722531b0ac28e8a9"
 dependencies = [
  "arrayvec 0.7.1",
  "bitvec 0.20.4",
- "byte-slice-cast 1.0.0",
+ "byte-slice-cast",
+ "impl-trait-for-tuples",
  "parity-scale-codec-derive",
  "serde",
 ]
 
 [[package]]
 name = "parity-scale-codec-derive"
-version = "2.1.3"
+version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81038e13ca2c32587201d544ea2e6b6c47120f1e4eae04478f9f60b6bcb89145"
+checksum = "40dbbfef7f0a1143c5b06e0d76a6278e25dac0bc1af4be51a0fbb73f07e7ad09"
 dependencies = [
  "proc-macro-crate 1.0.0",
  "proc-macro2",
@@ -6194,13 +6523,13 @@
 checksum = "664a8c6b8e62d8f9f2f937e391982eb433ab285b4cd9545b342441e04a906e42"
 dependencies = [
  "cfg-if 1.0.0",
- "ethereum-types 0.11.0",
- "hashbrown",
- "impl-trait-for-tuples 0.2.1",
+ "ethereum-types",
+ "hashbrown 0.9.1",
+ "impl-trait-for-tuples",
  "lru",
  "parity-util-mem-derive",
  "parking_lot 0.11.1",
- "primitive-types 0.9.0",
+ "primitive-types",
  "smallvec 1.6.1",
  "winapi 0.3.9",
 ]
@@ -6233,9 +6562,9 @@
 
 [[package]]
 name = "parity-ws"
-version = "0.10.0"
+version = "0.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e02a625dd75084c2a7024f07c575b61b782f729d18702dabb3cdbf31911dc61"
+checksum = "322d72dfe461b8b9e367d057ceace105379d64d5b03907d23c481ccf3fbf8aa4"
 dependencies = [
  "byteorder",
  "bytes 0.4.12",
@@ -6263,7 +6592,7 @@
 dependencies = [
  "lock_api 0.3.4",
  "parking_lot_core 0.6.2",
- "rustc_version",
+ "rustc_version 0.2.3",
 ]
 
 [[package]]
@@ -6297,7 +6626,7 @@
  "cloudabi",
  "libc",
  "redox_syscall 0.1.57",
- "rustc_version",
+ "rustc_version 0.2.3",
  "smallvec 0.6.14",
  "winapi 0.3.9",
 ]
@@ -6443,11 +6772,11 @@
 
 [[package]]
 name = "pin-project"
-version = "1.0.7"
+version = "1.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4"
+checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08"
 dependencies = [
- "pin-project-internal 1.0.7",
+ "pin-project-internal 1.0.8",
 ]
 
 [[package]]
@@ -6463,9 +6792,9 @@
 
 [[package]]
 name = "pin-project-internal"
-version = "1.0.7"
+version = "1.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f"
+checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -6480,9 +6809,9 @@
 
 [[package]]
 name = "pin-project-lite"
-version = "0.2.6"
+version = "0.2.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905"
+checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
 
 [[package]]
 name = "pin-utils"
@@ -6505,9 +6834,9 @@
 [[package]]
 name = "polkadot-approval-distribution"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "polkadot-node-network-protocol",
  "polkadot-node-primitives",
  "polkadot-node-subsystem",
@@ -6519,9 +6848,9 @@
 [[package]]
 name = "polkadot-availability-bitfield-distribution"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "polkadot-node-network-protocol",
  "polkadot-node-subsystem",
  "polkadot-node-subsystem-util",
@@ -6532,11 +6861,11 @@
 [[package]]
 name = "polkadot-availability-distribution"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "lru",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "polkadot-erasure-coding",
  "polkadot-node-core-runtime-api",
  "polkadot-node-network-protocol",
@@ -6555,11 +6884,11 @@
 [[package]]
 name = "polkadot-availability-recovery"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "lru",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "polkadot-erasure-coding",
  "polkadot-node-network-protocol",
  "polkadot-node-primitives",
@@ -6573,11 +6902,11 @@
 
 [[package]]
 name = "polkadot-cli"
-version = "0.9.7"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "frame-benchmarking-cli",
- "futures 0.3.15",
+ "futures 0.3.16",
  "log",
  "polkadot-node-core-pvf",
  "polkadot-service",
@@ -6593,8 +6922,8 @@
 
 [[package]]
 name = "polkadot-client"
-version = "0.9.7"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "beefy-primitives",
  "frame-benchmarking",
@@ -6623,10 +6952,10 @@
 [[package]]
 name = "polkadot-collator-protocol"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "always-assert",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "polkadot-node-network-protocol",
  "polkadot-node-primitives",
@@ -6642,10 +6971,10 @@
 
 [[package]]
 name = "polkadot-core-primitives"
-version = "0.9.7"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parity-util-mem",
  "sp-core",
  "sp-runtime",
@@ -6654,10 +6983,10 @@
 
 [[package]]
 name = "polkadot-erasure-coding"
-version = "0.9.7"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "polkadot-node-primitives",
  "polkadot-primitives",
  "reed-solomon-novelpoly",
@@ -6669,14 +6998,17 @@
 [[package]]
 name = "polkadot-gossip-support"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "polkadot-node-network-protocol",
  "polkadot-node-subsystem",
  "polkadot-node-subsystem-util",
  "polkadot-primitives",
+ "rand 0.8.4",
+ "rand_chacha 0.3.1",
  "sp-application-crypto",
+ "sp-core",
  "sp-keystore",
  "tracing",
 ]
@@ -6684,11 +7016,11 @@
 [[package]]
 name = "polkadot-network-bridge"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "async-trait",
- "futures 0.3.15",
- "parity-scale-codec 2.1.3",
+ "futures 0.3.16",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
  "polkadot-node-network-protocol",
  "polkadot-node-subsystem",
@@ -6704,10 +7036,10 @@
 [[package]]
 name = "polkadot-node-collation-generation"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
- "futures 0.3.15",
- "parity-scale-codec 2.1.3",
+ "futures 0.3.16",
+ "parity-scale-codec",
  "polkadot-erasure-coding",
  "polkadot-node-primitives",
  "polkadot-node-subsystem",
@@ -6722,15 +7054,16 @@
 [[package]]
 name = "polkadot-node-core-approval-voting"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "bitvec 0.20.4",
  "derive_more",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "kvdb",
+ "lru",
  "merlin",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "polkadot-node-jaeger",
  "polkadot-node-primitives",
  "polkadot-node-subsystem",
@@ -6751,13 +7084,13 @@
 [[package]]
 name = "polkadot-node-core-av-store"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "bitvec 0.20.4",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "kvdb",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "polkadot-erasure-coding",
  "polkadot-node-primitives",
  "polkadot-node-subsystem",
@@ -6771,10 +7104,10 @@
 [[package]]
 name = "polkadot-node-core-backing"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "bitvec 0.20.4",
- "futures 0.3.15",
+ "futures 0.3.16",
  "polkadot-erasure-coding",
  "polkadot-node-primitives",
  "polkadot-node-subsystem",
@@ -6789,9 +7122,9 @@
 [[package]]
 name = "polkadot-node-core-bitfield-signing"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "polkadot-node-subsystem",
  "polkadot-node-subsystem-util",
  "polkadot-primitives",
@@ -6804,11 +7137,11 @@
 [[package]]
 name = "polkadot-node-core-candidate-validation"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "async-trait",
- "futures 0.3.15",
- "parity-scale-codec 2.1.3",
+ "futures 0.3.16",
+ "parity-scale-codec",
  "polkadot-node-core-pvf",
  "polkadot-node-primitives",
  "polkadot-node-subsystem",
@@ -6822,12 +7155,14 @@
 [[package]]
 name = "polkadot-node-core-chain-api"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "polkadot-node-subsystem",
  "polkadot-node-subsystem-util",
  "polkadot-primitives",
+ "sc-client-api",
+ "sc-consensus-babe",
  "sp-blockchain",
  "tracing",
 ]
@@ -6835,10 +7170,10 @@
 [[package]]
 name = "polkadot-node-core-parachains-inherent"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "async-trait",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "polkadot-node-subsystem",
  "polkadot-overseer",
@@ -6853,10 +7188,10 @@
 [[package]]
 name = "polkadot-node-core-provisioner"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "bitvec 0.20.4",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "polkadot-node-subsystem",
  "polkadot-node-subsystem-util",
@@ -6868,17 +7203,17 @@
 [[package]]
 name = "polkadot-node-core-pvf"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "always-assert",
  "assert_matches",
  "async-process",
  "async-std",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "libc",
- "parity-scale-codec 2.1.3",
- "pin-project 1.0.7",
+ "parity-scale-codec",
+ "pin-project 1.0.8",
  "polkadot-core-primitives",
  "polkadot-parachain",
  "rand 0.8.4",
@@ -6889,6 +7224,7 @@
  "sp-core",
  "sp-externalities",
  "sp-io",
+ "sp-maybe-compressed-blob",
  "sp-wasm-interface",
  "tracing",
 ]
@@ -6896,9 +7232,9 @@
 [[package]]
 name = "polkadot-node-core-runtime-api"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "memory-lru",
  "parity-util-mem",
  "polkadot-node-subsystem",
@@ -6914,13 +7250,13 @@
 [[package]]
 name = "polkadot-node-jaeger"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "async-std",
  "lazy_static",
  "log",
  "mick-jaeger",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
  "polkadot-node-primitives",
  "polkadot-primitives",
@@ -6932,10 +7268,10 @@
 [[package]]
 name = "polkadot-node-network-protocol"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
- "futures 0.3.15",
- "parity-scale-codec 2.1.3",
+ "futures 0.3.16",
+ "parity-scale-codec",
  "polkadot-node-jaeger",
  "polkadot-node-primitives",
  "polkadot-primitives",
@@ -6947,10 +7283,10 @@
 [[package]]
 name = "polkadot-node-primitives"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
- "futures 0.3.15",
- "parity-scale-codec 2.1.3",
+ "futures 0.3.16",
+ "parity-scale-codec",
  "polkadot-parachain",
  "polkadot-primitives",
  "polkadot-statement-table",
@@ -6970,19 +7306,19 @@
 [[package]]
 name = "polkadot-node-subsystem"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "async-std",
  "async-trait",
  "derive_more",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "lazy_static",
  "log",
  "mick-jaeger",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
- "pin-project 1.0.7",
+ "pin-project 1.0.8",
  "polkadot-node-jaeger",
  "polkadot-node-network-protocol",
  "polkadot-node-primitives",
@@ -7000,15 +7336,16 @@
 [[package]]
 name = "polkadot-node-subsystem-util"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "async-trait",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
+ "itertools 0.10.1",
  "lru",
  "metered-channel",
- "parity-scale-codec 2.1.3",
- "pin-project 1.0.7",
+ "parity-scale-codec",
+ "pin-project 1.0.8",
  "polkadot-node-jaeger",
  "polkadot-node-network-protocol",
  "polkadot-node-primitives",
@@ -7019,7 +7356,6 @@
  "sp-application-crypto",
  "sp-core",
  "sp-keystore",
- "streamunordered",
  "substrate-prometheus-endpoint",
  "thiserror",
  "tracing",
@@ -7028,10 +7364,10 @@
 [[package]]
 name = "polkadot-overseer"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "async-trait",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "lru",
  "polkadot-node-primitives",
@@ -7046,11 +7382,11 @@
 
 [[package]]
 name = "polkadot-parachain"
-version = "0.9.7"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "derive_more",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parity-util-mem",
  "polkadot-core-primitives",
  "serde",
@@ -7061,13 +7397,13 @@
 
 [[package]]
 name = "polkadot-primitives"
-version = "0.9.7"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "bitvec 0.20.4",
  "frame-system",
  "hex-literal",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parity-util-mem",
  "polkadot-core-primitives",
  "polkadot-parachain",
@@ -7092,7 +7428,7 @@
 [[package]]
 name = "polkadot-procmacro-overseer-subsystems-gen"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "assert_matches",
  "proc-macro2",
@@ -7103,7 +7439,7 @@
 [[package]]
 name = "polkadot-procmacro-subsystem-dispatch-gen"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "assert_matches",
  "proc-macro2",
@@ -7113,15 +7449,15 @@
 
 [[package]]
 name = "polkadot-rpc"
-version = "0.9.7"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "beefy-gadget",
  "beefy-gadget-rpc",
  "jsonrpc-core 15.1.0",
  "pallet-mmr-rpc",
  "pallet-transaction-payment-rpc",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "polkadot-primitives",
  "sc-chain-spec",
  "sc-client-api",
@@ -7146,17 +7482,20 @@
 
 [[package]]
 name = "polkadot-runtime"
-version = "0.9.7"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "beefy-primitives",
  "bitvec 0.20.4",
+ "frame-benchmarking",
  "frame-election-provider-support",
  "frame-executive",
  "frame-support",
  "frame-system",
+ "frame-system-benchmarking",
  "frame-system-rpc-runtime-api",
  "frame-try-runtime",
+ "hex-literal",
  "log",
  "max-encoded-len",
  "pallet-authority-discovery",
@@ -7177,10 +7516,11 @@
  "pallet-multisig",
  "pallet-nicks",
  "pallet-offences",
+ "pallet-offences-benchmarking",
  "pallet-proxy",
- "pallet-randomness-collective-flip",
- "pallet-scheduler 3.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7)",
+ "pallet-scheduler 3.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
  "pallet-session",
+ "pallet-session-benchmarking",
  "pallet-staking",
  "pallet-staking-reward-curve",
  "pallet-timestamp",
@@ -7190,7 +7530,7 @@
  "pallet-treasury",
  "pallet-utility",
  "pallet-vesting",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "polkadot-primitives",
  "polkadot-runtime-common",
  "rustc-hex",
@@ -7213,24 +7553,27 @@
  "sp-transaction-pool",
  "sp-version",
  "static_assertions",
- "substrate-wasm-builder 3.0.0",
+ "substrate-wasm-builder 4.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
 ]
 
 [[package]]
 name = "polkadot-runtime-common"
-version = "0.9.7"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "beefy-primitives",
  "bitvec 0.20.4",
+ "frame-benchmarking",
  "frame-support",
  "frame-system",
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "libsecp256k1 0.3.5",
  "log",
  "pallet-authorship",
+ "pallet-babe",
  "pallet-balances",
  "pallet-beefy",
+ "pallet-election-provider-multi-phase",
  "pallet-mmr",
  "pallet-offences",
  "pallet-session",
@@ -7239,7 +7582,7 @@
  "pallet-transaction-payment",
  "pallet-treasury",
  "pallet-vesting",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "polkadot-primitives",
  "polkadot-runtime-parachains",
  "rustc-hex",
@@ -7260,13 +7603,15 @@
 
 [[package]]
 name = "polkadot-runtime-parachains"
-version = "0.9.7"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "bitvec 0.20.4",
  "derive_more",
+ "frame-benchmarking",
  "frame-support",
  "frame-system",
+ "libsecp256k1 0.3.5",
  "log",
  "pallet-authority-discovery",
  "pallet-authorship",
@@ -7276,7 +7621,7 @@
  "pallet-staking",
  "pallet-timestamp",
  "pallet-vesting",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "polkadot-primitives",
  "rand 0.8.4",
  "rand_chacha 0.3.1",
@@ -7297,14 +7642,16 @@
 
 [[package]]
 name = "polkadot-service"
-version = "0.9.7"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
+ "async-trait",
  "beefy-gadget",
  "beefy-primitives",
  "frame-system-rpc-runtime-api",
- "futures 0.3.15",
+ "futures 0.3.16",
  "hex-literal",
+ "kusama-runtime",
  "kvdb",
  "kvdb-rocksdb",
  "pallet-babe",
@@ -7340,6 +7687,7 @@
  "polkadot-runtime",
  "polkadot-runtime-parachains",
  "polkadot-statement-distribution",
+ "rococo-runtime",
  "sc-authority-discovery",
  "sc-basic-authorship",
  "sc-block-builder",
@@ -7381,17 +7729,18 @@
  "substrate-prometheus-endpoint",
  "thiserror",
  "tracing",
+ "westend-runtime",
 ]
 
 [[package]]
 name = "polkadot-statement-distribution"
 version = "0.1.0"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "arrayvec 0.5.2",
- "futures 0.3.15",
+ "futures 0.3.16",
  "indexmap",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "polkadot-node-network-protocol",
  "polkadot-node-primitives",
  "polkadot-node-subsystem",
@@ -7406,18 +7755,18 @@
 
 [[package]]
 name = "polkadot-statement-table"
-version = "0.9.7"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "polkadot-primitives",
  "sp-core",
 ]
 
 [[package]]
 name = "polkadot-test-runtime"
-version = "0.9.7"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "beefy-primitives",
  "bitvec 0.20.4",
@@ -7436,7 +7785,6 @@
  "pallet-mmr-primitives",
  "pallet-nicks",
  "pallet-offences",
- "pallet-randomness-collective-flip",
  "pallet-session",
  "pallet-staking",
  "pallet-staking-reward-curve",
@@ -7445,7 +7793,7 @@
  "pallet-transaction-payment",
  "pallet-transaction-payment-rpc-runtime-api",
  "pallet-vesting",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "polkadot-parachain",
  "polkadot-primitives",
  "polkadot-runtime-common",
@@ -7468,18 +7816,18 @@
  "sp-std",
  "sp-transaction-pool",
  "sp-version",
- "substrate-wasm-builder 3.0.0",
+ "substrate-wasm-builder 4.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
 ]
 
 [[package]]
 name = "polkadot-test-service"
-version = "0.9.7"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "frame-benchmarking",
  "frame-system",
  "futures 0.1.31",
- "futures 0.3.15",
+ "futures 0.3.16",
  "hex",
  "pallet-balances",
  "pallet-staking",
@@ -7565,28 +7913,15 @@
 
 [[package]]
 name = "primitive-types"
-version = "0.7.3"
+version = "0.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7dd39dcacf71411ba488570da7bbc89b717225e46478b30ba99b92db6b149809"
-dependencies = [
- "fixed-hash 0.6.1",
- "impl-codec 0.4.2",
- "impl-rlp 0.2.1",
- "impl-serde",
- "uint 0.8.5",
-]
-
-[[package]]
-name = "primitive-types"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2415937401cb030a2a0a4d922483f945fa068f52a7dbb22ce0fe5f2b6f6adace"
+checksum = "06345ee39fbccfb06ab45f3a1a5798d9dafa04cb8921a76d227040003a234b0e"
 dependencies = [
- "fixed-hash 0.7.0",
- "impl-codec 0.5.0",
- "impl-rlp 0.3.0",
+ "fixed-hash",
+ "impl-codec",
+ "impl-rlp",
  "impl-serde",
- "uint 0.9.0",
+ "uint",
 ]
 
 [[package]]
@@ -7646,9 +7981,9 @@
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.27"
+version = "1.0.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
+checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
 dependencies = [
  "unicode-xid",
 ]
@@ -7720,9 +8055,9 @@
 
 [[package]]
 name = "psm"
-version = "0.1.13"
+version = "0.1.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "21ff0279b4a85e576b97e4a21d13e437ebcd56612706cde5d3f0d5c9399490c0"
+checksum = "14ce37fa8c0428a37307d163292add09b3aedc003472e6b3622486878404191d"
 dependencies = [
  "cc",
 ]
@@ -7772,9 +8107,9 @@
 
 [[package]]
 name = "radium"
-version = "0.3.0"
+version = "0.5.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac"
+checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
 
 [[package]]
 name = "radium"
@@ -8072,14 +8407,14 @@
 [[package]]
 name = "remote-externalities"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "env_logger 0.8.4",
  "hex",
  "jsonrpsee-proc-macros",
  "jsonrpsee-ws-client",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "serde_json",
  "sp-core",
@@ -8125,15 +8460,6 @@
  "untrusted",
  "web-sys",
  "winapi 0.3.9",
-]
-
-[[package]]
-name = "rlp"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1190dcc8c3a512f1eef5d09bb8c84c7f39e1054e174d1795482e18f5272f2e73"
-dependencies = [
- "rustc-hex",
 ]
 
 [[package]]
@@ -8168,6 +8494,73 @@
 ]
 
 [[package]]
+name = "rococo-runtime"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "beefy-primitives",
+ "bp-rococo",
+ "bp-wococo",
+ "frame-executive",
+ "frame-support",
+ "frame-system",
+ "frame-system-rpc-runtime-api",
+ "hex-literal",
+ "log",
+ "max-encoded-len",
+ "pallet-authority-discovery",
+ "pallet-authorship",
+ "pallet-babe",
+ "pallet-balances",
+ "pallet-beefy",
+ "pallet-bridge-grandpa",
+ "pallet-collective",
+ "pallet-grandpa",
+ "pallet-im-online",
+ "pallet-indices",
+ "pallet-membership",
+ "pallet-mmr",
+ "pallet-mmr-primitives",
+ "pallet-offences",
+ "pallet-proxy",
+ "pallet-session",
+ "pallet-staking",
+ "pallet-staking-reward-curve",
+ "pallet-sudo",
+ "pallet-timestamp",
+ "pallet-transaction-payment",
+ "pallet-transaction-payment-rpc-runtime-api",
+ "pallet-utility",
+ "pallet-xcm",
+ "parity-scale-codec",
+ "polkadot-parachain",
+ "polkadot-primitives",
+ "polkadot-runtime-common",
+ "polkadot-runtime-parachains",
+ "serde",
+ "serde_derive",
+ "smallvec 1.6.1",
+ "sp-api",
+ "sp-authority-discovery",
+ "sp-block-builder",
+ "sp-consensus-babe",
+ "sp-core",
+ "sp-inherents",
+ "sp-io",
+ "sp-offchain",
+ "sp-runtime",
+ "sp-session",
+ "sp-staking",
+ "sp-std",
+ "sp-transaction-pool",
+ "sp-version",
+ "substrate-wasm-builder 4.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
+ "xcm",
+ "xcm-builder",
+ "xcm-executor",
+]
+
+[[package]]
 name = "rpassword"
 version = "5.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -8179,9 +8572,9 @@
 
 [[package]]
 name = "rustc-demangle"
-version = "0.1.19"
+version = "0.1.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "410f7acf3cb3a44527c5d9546bad4bf4e6c460915d5f9f2fc524498bfe8f70ce"
+checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49"
 
 [[package]]
 name = "rustc-hash"
@@ -8205,6 +8598,15 @@
 ]
 
 [[package]]
+name = "rustc_version"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee"
+dependencies = [
+ "semver 0.11.0",
+]
+
+[[package]]
 name = "rustls"
 version = "0.18.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -8256,9 +8658,9 @@
 
 [[package]]
 name = "ruzstd"
-version = "0.2.2"
+version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d425143485a37727c7a46e689bbe3b883a00f42b4a52c4ac0f44855c1009b00"
+checksum = "8cada0ef59efa6a5f4dc5e491f93d9f31e3fc7758df421ff1de8a706338e1100"
 dependencies = [
  "byteorder",
  "twox-hash",
@@ -8270,7 +8672,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "pin-project 0.4.28",
  "static_assertions",
 ]
@@ -8287,7 +8689,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6d3d055a2582e6b00ed7a31c1524040aa391092bf636328350813f3a0605215c"
 dependencies = [
- "rustc_version",
+ "rustc_version 0.2.3",
 ]
 
 [[package]]
@@ -8309,19 +8711,31 @@
 ]
 
 [[package]]
+name = "sc-allocator"
+version = "3.0.0"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
+dependencies = [
+ "log",
+ "sp-core",
+ "sp-std",
+ "sp-wasm-interface",
+ "thiserror",
+]
+
+[[package]]
 name = "sc-authority-discovery"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "async-trait",
  "derive_more",
  "either",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "ip_network",
  "libp2p",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "prost",
  "prost-build",
  "rand 0.7.3",
@@ -8340,12 +8754,12 @@
 [[package]]
 name = "sc-basic-authorship"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sc-block-builder",
  "sc-client-api",
  "sc-proposer-metrics",
@@ -8363,9 +8777,9 @@
 [[package]]
 name = "sc-block-builder"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sc-client-api",
  "sp-api",
  "sp-block-builder",
@@ -8379,10 +8793,10 @@
 [[package]]
 name = "sc-chain-spec"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "impl-trait-for-tuples 0.2.1",
- "parity-scale-codec 2.1.3",
+ "impl-trait-for-tuples",
+ "parity-scale-codec",
  "sc-chain-spec-derive",
  "sc-consensus-babe",
  "sc-consensus-epochs",
@@ -8391,7 +8805,6 @@
  "sc-telemetry",
  "serde",
  "serde_json",
- "sp-chain-spec",
  "sp-consensus-babe",
  "sp-core",
  "sp-runtime",
@@ -8400,7 +8813,7 @@
 [[package]]
 name = "sc-chain-spec-derive"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "proc-macro-crate 1.0.0",
  "proc-macro2",
@@ -8411,16 +8824,16 @@
 [[package]]
 name = "sc-cli"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "chrono",
  "fdlimit",
- "futures 0.3.15",
+ "futures 0.3.16",
  "hex",
  "libp2p",
  "log",
  "names",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "rand 0.7.3",
  "regex",
  "rpassword",
@@ -8449,16 +8862,16 @@
 [[package]]
 name = "sc-client-api"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "derive_more",
  "fnv",
- "futures 0.3.15",
+ "futures 0.3.16",
  "hash-db",
  "kvdb",
  "lazy_static",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
  "sc-executor",
  "sp-api",
@@ -8483,7 +8896,7 @@
 [[package]]
 name = "sc-client-db"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "blake2-rfc",
  "hash-db",
@@ -8493,7 +8906,7 @@
  "linked-hash-map",
  "log",
  "parity-db",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parity-util-mem",
  "parking_lot 0.11.1",
  "sc-client-api",
@@ -8513,8 +8926,9 @@
 [[package]]
 name = "sc-consensus"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
+ "async-trait",
  "parking_lot 0.11.1",
  "sc-client-api",
  "sp-blockchain",
@@ -8525,14 +8939,14 @@
 [[package]]
 name = "sc-consensus-aura"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "async-trait",
  "derive_more",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sc-block-builder",
  "sc-client-api",
  "sc-consensus-slots",
@@ -8556,19 +8970,19 @@
 [[package]]
 name = "sc-consensus-babe"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "async-trait",
  "derive_more",
  "fork-tree",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "log",
  "merlin",
  "num-bigint",
  "num-rational 0.2.4",
  "num-traits",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
  "pdqselect",
  "rand 0.7.3",
@@ -8602,10 +9016,10 @@
 [[package]]
 name = "sc-consensus-babe-rpc"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "derive_more",
- "futures 0.3.15",
+ "futures 0.3.16",
  "jsonrpc-core 15.1.0",
  "jsonrpc-core-client 15.1.0",
  "jsonrpc-derive 15.1.0",
@@ -8626,10 +9040,10 @@
 [[package]]
 name = "sc-consensus-epochs"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "fork-tree",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sc-client-api",
  "sc-consensus",
  "sp-blockchain",
@@ -8639,14 +9053,14 @@
 [[package]]
 name = "sc-consensus-slots"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "async-trait",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sc-client-api",
  "sc-telemetry",
  "sp-api",
@@ -8667,7 +9081,7 @@
 [[package]]
 name = "sc-consensus-uncles"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "sc-client-api",
  "sp-authorship",
@@ -8678,13 +9092,13 @@
 [[package]]
 name = "sc-executor"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "derive_more",
  "lazy_static",
  "libsecp256k1 0.3.5",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parity-wasm 0.42.2",
  "parking_lot 0.11.1",
  "sc-executor-common",
@@ -8707,12 +9121,12 @@
 [[package]]
 name = "sc-executor-common"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "derive_more",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "pwasm-utils",
- "sp-allocator",
+ "sc-allocator",
  "sp-core",
  "sp-maybe-compressed-blob",
  "sp-serializer",
@@ -8724,12 +9138,12 @@
 [[package]]
 name = "sc-executor-wasmi"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
+ "sc-allocator",
  "sc-executor-common",
- "sp-allocator",
  "sp-core",
  "sp-runtime-interface",
  "sp-wasm-interface",
@@ -8739,14 +9153,16 @@
 [[package]]
 name = "sc-executor-wasmtime"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
+ "cfg-if 1.0.0",
+ "libc",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parity-wasm 0.42.2",
+ "sc-allocator",
  "sc-executor-common",
  "scoped-tls",
- "sp-allocator",
  "sp-core",
  "sp-runtime-interface",
  "sp-wasm-interface",
@@ -8756,20 +9172,20 @@
 [[package]]
 name = "sc-finality-grandpa"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "async-trait",
  "derive_more",
  "dyn-clone",
  "finality-grandpa",
  "fork-tree",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "linked-hash-map",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
- "pin-project 1.0.7",
+ "pin-project 1.0.8",
  "rand 0.7.3",
  "sc-block-builder",
  "sc-client-api",
@@ -8797,17 +9213,17 @@
 [[package]]
 name = "sc-finality-grandpa-rpc"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "derive_more",
  "finality-grandpa",
- "futures 0.3.15",
+ "futures 0.3.16",
  "jsonrpc-core 15.1.0",
  "jsonrpc-core-client 15.1.0",
  "jsonrpc-derive 15.1.0",
  "jsonrpc-pubsub 15.1.0",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sc-client-api",
  "sc-finality-grandpa",
  "sc-rpc",
@@ -8821,13 +9237,13 @@
 [[package]]
 name = "sc-finality-grandpa-warp-sync"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "derive_more",
- "futures 0.3.15",
+ "futures 0.3.16",
  "log",
  "num-traits",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
  "prost",
  "sc-client-api",
@@ -8842,10 +9258,10 @@
 [[package]]
 name = "sc-informant"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "ansi_term 0.12.1",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "log",
  "parity-util-mem",
@@ -8860,11 +9276,11 @@
 [[package]]
 name = "sc-keystore"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "async-trait",
  "derive_more",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-util",
  "hex",
  "merlin",
@@ -8874,17 +9290,17 @@
  "sp-application-crypto",
  "sp-core",
  "sp-keystore",
- "subtle 2.4.0",
+ "subtle 2.4.1",
 ]
 
 [[package]]
 name = "sc-light"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "hash-db",
  "lazy_static",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
  "sc-client-api",
  "sc-executor",
@@ -8899,7 +9315,7 @@
 [[package]]
 name = "sc-network"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "async-std",
  "async-trait",
@@ -8913,7 +9329,7 @@
  "erased-serde",
  "fnv",
  "fork-tree",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "hex",
  "ip_network",
@@ -8923,9 +9339,9 @@
  "log",
  "lru",
  "nohash-hasher",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
- "pin-project 1.0.7",
+ "pin-project 1.0.8",
  "prost",
  "prost-build",
  "rand 0.7.3",
@@ -8952,9 +9368,9 @@
 [[package]]
 name = "sc-network-gossip"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "libp2p",
  "log",
@@ -8969,18 +9385,18 @@
 [[package]]
 name = "sc-offchain"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "bytes 0.5.6",
  "fnv",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "hex",
  "hyper 0.13.10",
  "hyper-rustls",
  "log",
  "num_cpus",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
  "rand 0.7.3",
  "sc-client-api",
@@ -8997,9 +9413,9 @@
 [[package]]
 name = "sc-peerset"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "libp2p",
  "log",
  "serde_json",
@@ -9010,7 +9426,7 @@
 [[package]]
 name = "sc-proposer-metrics"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "log",
  "substrate-prometheus-endpoint",
@@ -9019,16 +9435,17 @@
 [[package]]
 name = "sc-rpc"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "hash-db",
  "jsonrpc-core 15.1.0",
  "jsonrpc-pubsub 15.1.0",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
  "sc-block-builder",
+ "sc-chain-spec",
  "sc-client-api",
  "sc-executor",
  "sc-keystore",
@@ -9037,7 +9454,6 @@
  "serde_json",
  "sp-api",
  "sp-blockchain",
- "sp-chain-spec",
  "sp-core",
  "sp-keystore",
  "sp-offchain",
@@ -9054,20 +9470,20 @@
 [[package]]
 name = "sc-rpc-api"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "derive_more",
- "futures 0.3.15",
+ "futures 0.3.16",
  "jsonrpc-core 15.1.0",
  "jsonrpc-core-client 15.1.0",
  "jsonrpc-derive 15.1.0",
  "jsonrpc-pubsub 15.1.0",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
+ "sc-chain-spec",
  "serde",
  "serde_json",
- "sp-chain-spec",
  "sp-core",
  "sp-rpc",
  "sp-runtime",
@@ -9079,7 +9495,7 @@
 [[package]]
 name = "sc-rpc-server"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "futures 0.1.31",
  "jsonrpc-core 15.1.0",
@@ -9097,23 +9513,23 @@
 [[package]]
 name = "sc-service"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "async-trait",
  "directories",
  "exit-future",
  "futures 0.1.31",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "hash-db",
  "jsonrpc-core 15.1.0",
  "jsonrpc-pubsub 15.1.0",
  "lazy_static",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parity-util-mem",
  "parking_lot 0.11.1",
- "pin-project 1.0.7",
+ "pin-project 1.0.8",
  "rand 0.7.3",
  "sc-block-builder",
  "sc-chain-spec",
@@ -9145,6 +9561,7 @@
  "sp-runtime",
  "sp-session",
  "sp-state-machine",
+ "sp-storage",
  "sp-tracing",
  "sp-transaction-pool",
  "sp-transaction-storage-proof",
@@ -9162,10 +9579,10 @@
 [[package]]
 name = "sc-state-db"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parity-util-mem",
  "parity-util-mem-derive",
  "parking_lot 0.11.1",
@@ -9177,7 +9594,7 @@
 [[package]]
 name = "sc-sync-state-rpc"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "jsonrpc-core 15.1.0",
  "jsonrpc-core-client 15.1.0",
@@ -9197,14 +9614,14 @@
 [[package]]
 name = "sc-telemetry"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "chrono",
- "futures 0.3.15",
+ "futures 0.3.16",
  "libp2p",
  "log",
  "parking_lot 0.11.1",
- "pin-project 1.0.7",
+ "pin-project 1.0.8",
  "rand 0.7.3",
  "serde",
  "serde_json",
@@ -9217,7 +9634,7 @@
 [[package]]
 name = "sc-tracing"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "ansi_term 0.12.1",
  "atty",
@@ -9254,7 +9671,7 @@
 [[package]]
 name = "sc-tracing-proc-macro"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "proc-macro-crate 1.0.0",
  "proc-macro2",
@@ -9265,10 +9682,10 @@
 [[package]]
 name = "sc-transaction-graph"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "derive_more",
- "futures 0.3.15",
+ "futures 0.3.16",
  "linked-hash-map",
  "log",
  "parity-util-mem",
@@ -9287,12 +9704,12 @@
 [[package]]
 name = "sc-transaction-pool"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "intervalier",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parity-util-mem",
  "parking_lot 0.11.1",
  "sc-client-api",
@@ -9327,13 +9744,13 @@
 dependencies = [
  "arrayref",
  "arrayvec 0.5.2",
- "curve25519-dalek 2.1.2",
+ "curve25519-dalek 2.1.3",
  "getrandom 0.1.16",
  "merlin",
  "rand 0.7.3",
  "rand_core 0.5.1",
  "sha2 0.8.2",
- "subtle 2.4.0",
+ "subtle 2.4.1",
  "zeroize",
 ]
 
@@ -9380,24 +9797,6 @@
 ]
 
 [[package]]
-name = "secp256k1"
-version = "0.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6179428c22c73ac0fbb7b5579a56353ce78ba29759b3b8575183336ea74cdfb"
-dependencies = [
- "secp256k1-sys",
-]
-
-[[package]]
-name = "secp256k1-sys"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11553d210db090930f4432bea123b31f70bbf693ace14504ea2a35e796c28dd2"
-dependencies = [
- "cc",
-]
-
-[[package]]
 name = "secrecy"
 version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -9540,9 +9939,9 @@
 
 [[package]]
 name = "sha-1"
-version = "0.9.6"
+version = "0.9.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16"
+checksum = "1a0c8611594e2ab4ebbf06ec7cbbf0a99450b8570e96cbf5188b5d5f6ef18d81"
 dependencies = [
  "block-buffer 0.9.0",
  "cfg-if 1.0.0",
@@ -9612,9 +10011,9 @@
 
 [[package]]
 name = "shlex"
-version = "0.1.1"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
+checksum = "42a568c8f2cd051a4d283bd6eb0343ac214c1b0f1ac19f93e1175b2dee38c73d"
 
 [[package]]
 name = "signal-hook"
@@ -9637,21 +10036,9 @@
 
 [[package]]
 name = "signature"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f0242b8e50dd9accdd56170e94ca1ebd223b098eb9c83539a6e367d0f36ae68"
-
-[[package]]
-name = "simba"
-version = "0.4.0"
+version = "1.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5132a955559188f3d13c9ba831e77c802ddc8782783f050ed0c52f5988b95f4c"
-dependencies = [
- "approx 0.4.0",
- "num-complex 0.3.1",
- "num-traits",
- "paste",
-]
+checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335"
 
 [[package]]
 name = "simba"
@@ -9659,8 +10046,8 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8e82063457853d00243beda9952e910b82593e4b07ae9f721b9278a99a0d3d5c"
 dependencies = [
- "approx 0.5.0",
- "num-complex 0.4.0",
+ "approx",
+ "num-complex",
  "num-traits",
  "paste",
 ]
@@ -9682,11 +10069,11 @@
 
 [[package]]
 name = "slot-range-helper"
-version = "0.9.7"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "enumn",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "paste",
  "sp-runtime",
  "sp-std",
@@ -9694,9 +10081,9 @@
 
 [[package]]
 name = "slotmap"
-version = "1.0.3"
+version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "585cd5dffe4e9e06f6dfdf66708b70aca3f781bed561f4f667b2d9c0d4559e36"
+checksum = "a952280edbecfb1d4bd3cf2dbc309dc6ab523e53487c438ae21a6df09fe84bc4"
 dependencies = [
  "version_check",
 ]
@@ -9728,9 +10115,9 @@
  "rand 0.7.3",
  "rand_core 0.5.1",
  "ring",
- "rustc_version",
+ "rustc_version 0.2.3",
  "sha2 0.9.5",
- "subtle 2.4.0",
+ "subtle 2.4.1",
  "x25519-dalek",
 ]
 
@@ -9764,11 +10151,11 @@
  "base64 0.12.3",
  "bytes 0.5.6",
  "flate2",
- "futures 0.3.15",
+ "futures 0.3.16",
  "httparse",
  "log",
  "rand 0.7.3",
- "sha-1 0.9.6",
+ "sha-1 0.9.7",
 ]
 
 [[package]]
@@ -9779,33 +10166,21 @@
 dependencies = [
  "base64 0.13.0",
  "bytes 1.0.1",
- "futures 0.3.15",
+ "futures 0.3.16",
  "httparse",
  "log",
  "rand 0.8.4",
- "sha-1 0.9.6",
-]
-
-[[package]]
-name = "sp-allocator"
-version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
-dependencies = [
- "log",
- "sp-core",
- "sp-std",
- "sp-wasm-interface",
- "thiserror",
+ "sha-1 0.9.7",
 ]
 
 [[package]]
 name = "sp-api"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "hash-db",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-api-proc-macro",
  "sp-core",
  "sp-runtime",
@@ -9818,7 +10193,7 @@
 [[package]]
 name = "sp-api-proc-macro"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "blake2-rfc",
  "proc-macro-crate 1.0.0",
@@ -9830,10 +10205,10 @@
 [[package]]
 name = "sp-application-crypto"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "max-encoded-len",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-core",
  "sp-io",
@@ -9843,11 +10218,11 @@
 [[package]]
 name = "sp-arithmetic"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "integer-sqrt",
  "num-traits",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-debug-derive",
  "sp-std",
@@ -9857,9 +10232,9 @@
 [[package]]
 name = "sp-authority-discovery"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-api",
  "sp-application-crypto",
  "sp-runtime",
@@ -9869,10 +10244,10 @@
 [[package]]
 name = "sp-authorship"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "async-trait",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-inherents",
  "sp-runtime",
  "sp-std",
@@ -9881,9 +10256,9 @@
 [[package]]
 name = "sp-block-builder"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-api",
  "sp-inherents",
  "sp-runtime",
@@ -9893,12 +10268,12 @@
 [[package]]
 name = "sp-blockchain"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "log",
  "lru",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
  "sp-api",
  "sp-consensus",
@@ -9909,25 +10284,16 @@
 ]
 
 [[package]]
-name = "sp-chain-spec"
-version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
-dependencies = [
- "serde",
- "serde_json",
-]
-
-[[package]]
 name = "sp-consensus"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "async-trait",
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-timer 3.0.2",
  "libp2p",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
  "serde",
  "sp-api",
@@ -9947,10 +10313,10 @@
 [[package]]
 name = "sp-consensus-aura"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "async-trait",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-api",
  "sp-application-crypto",
  "sp-consensus",
@@ -9964,11 +10330,11 @@
 [[package]]
 name = "sp-consensus-babe"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "async-trait",
  "merlin",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-api",
  "sp-application-crypto",
@@ -9986,9 +10352,9 @@
 [[package]]
 name = "sp-consensus-slots"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-arithmetic",
  "sp-runtime",
 ]
@@ -9996,9 +10362,9 @@
 [[package]]
 name = "sp-consensus-vrf"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "schnorrkel",
  "sp-core",
  "sp-runtime",
@@ -10008,14 +10374,14 @@
 [[package]]
 name = "sp-core"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "base58",
  "blake2-rfc",
  "byteorder",
  "dyn-clonable",
  "ed25519-dalek",
- "futures 0.3.15",
+ "futures 0.3.16",
  "hash-db",
  "hash256-std-hasher",
  "hex",
@@ -10026,10 +10392,10 @@
  "max-encoded-len",
  "merlin",
  "num-traits",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parity-util-mem",
  "parking_lot 0.11.1",
- "primitive-types 0.9.0",
+ "primitive-types",
  "rand 0.7.3",
  "regex",
  "schnorrkel",
@@ -10053,7 +10419,7 @@
 [[package]]
 name = "sp-database"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "kvdb",
  "parking_lot 0.11.1",
@@ -10062,7 +10428,7 @@
 [[package]]
 name = "sp-debug-derive"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -10072,10 +10438,10 @@
 [[package]]
 name = "sp-externalities"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "environmental",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-std",
  "sp-storage",
 ]
@@ -10083,11 +10449,11 @@
 [[package]]
 name = "sp-finality-grandpa"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "finality-grandpa",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-api",
  "sp-application-crypto",
@@ -10100,11 +10466,11 @@
 [[package]]
 name = "sp-inherents"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "async-trait",
- "impl-trait-for-tuples 0.2.1",
- "parity-scale-codec 2.1.3",
+ "impl-trait-for-tuples",
+ "parity-scale-codec",
  "sp-core",
  "sp-runtime",
  "sp-std",
@@ -10114,13 +10480,13 @@
 [[package]]
 name = "sp-io"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "hash-db",
  "libsecp256k1 0.3.5",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
  "sp-core",
  "sp-externalities",
@@ -10139,7 +10505,7 @@
 [[package]]
 name = "sp-keyring"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "lazy_static",
  "sp-core",
@@ -10150,13 +10516,13 @@
 [[package]]
 name = "sp-keystore"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "async-trait",
  "derive_more",
- "futures 0.3.15",
+ "futures 0.3.16",
  "merlin",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
  "schnorrkel",
  "serde",
@@ -10167,7 +10533,7 @@
 [[package]]
 name = "sp-maybe-compressed-blob"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "ruzstd",
  "zstd",
@@ -10176,9 +10542,9 @@
 [[package]]
 name = "sp-npos-elections"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-arithmetic",
  "sp-core",
@@ -10189,7 +10555,7 @@
 [[package]]
 name = "sp-npos-elections-compact"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "proc-macro-crate 1.0.0",
  "proc-macro2",
@@ -10200,7 +10566,7 @@
 [[package]]
 name = "sp-offchain"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "sp-api",
  "sp-core",
@@ -10210,7 +10576,7 @@
 [[package]]
 name = "sp-panic-handler"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "backtrace",
 ]
@@ -10218,7 +10584,7 @@
 [[package]]
 name = "sp-rpc"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "rustc-hash",
  "serde",
@@ -10229,14 +10595,14 @@
 [[package]]
 name = "sp-runtime"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "either",
  "hash256-std-hasher",
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "log",
  "max-encoded-len",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parity-util-mem",
  "paste",
  "rand 0.7.3",
@@ -10251,11 +10617,11 @@
 [[package]]
 name = "sp-runtime-interface"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "impl-trait-for-tuples 0.2.1",
- "parity-scale-codec 2.1.3",
- "primitive-types 0.9.0",
+ "impl-trait-for-tuples",
+ "parity-scale-codec",
+ "primitive-types",
  "sp-externalities",
  "sp-runtime-interface-proc-macro",
  "sp-std",
@@ -10268,7 +10634,7 @@
 [[package]]
 name = "sp-runtime-interface-proc-macro"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "Inflector",
  "proc-macro-crate 1.0.0",
@@ -10280,9 +10646,9 @@
 [[package]]
 name = "sp-sandbox"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-core",
  "sp-io",
  "sp-std",
@@ -10293,7 +10659,7 @@
 [[package]]
 name = "sp-serializer"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "serde",
  "serde_json",
@@ -10302,9 +10668,9 @@
 [[package]]
 name = "sp-session"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-api",
  "sp-core",
  "sp-runtime",
@@ -10315,9 +10681,9 @@
 [[package]]
 name = "sp-staking"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-runtime",
  "sp-std",
 ]
@@ -10325,12 +10691,12 @@
 [[package]]
 name = "sp-state-machine"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "hash-db",
  "log",
  "num-traits",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.11.1",
  "rand 0.7.3",
  "smallvec 1.6.1",
@@ -10348,15 +10714,15 @@
 [[package]]
 name = "sp-std"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 
 [[package]]
 name = "sp-storage"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "impl-serde",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "ref-cast",
  "serde",
  "sp-debug-derive",
@@ -10366,7 +10732,7 @@
 [[package]]
 name = "sp-tasks"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "log",
  "sp-core",
@@ -10379,12 +10745,12 @@
 [[package]]
 name = "sp-timestamp"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "async-trait",
  "futures-timer 3.0.2",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-api",
  "sp-inherents",
  "sp-runtime",
@@ -10396,11 +10762,11 @@
 [[package]]
 name = "sp-tracing"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "erased-serde",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "parking_lot 0.10.2",
  "serde",
  "serde_json",
@@ -10414,12 +10780,12 @@
 [[package]]
 name = "sp-transaction-pool"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "derive_more",
- "futures 0.3.15",
+ "futures 0.3.16",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-api",
  "sp-blockchain",
@@ -10430,11 +10796,11 @@
 [[package]]
 name = "sp-transaction-storage-proof"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "async-trait",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-core",
  "sp-inherents",
  "sp-runtime",
@@ -10445,11 +10811,11 @@
 [[package]]
 name = "sp-trie"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "hash-db",
  "memory-db",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-core",
  "sp-std",
  "trie-db",
@@ -10459,9 +10825,9 @@
 [[package]]
 name = "sp-utils"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "futures-core",
  "futures-timer 3.0.2",
  "lazy_static",
@@ -10471,10 +10837,10 @@
 [[package]]
 name = "sp-version"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "impl-serde",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "serde",
  "sp-runtime",
  "sp-std",
@@ -10484,9 +10850,9 @@
 [[package]]
 name = "sp-version-proc-macro"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "proc-macro-crate 1.0.0",
  "proc-macro2",
  "quote",
@@ -10496,10 +10862,10 @@
 [[package]]
 name = "sp-wasm-interface"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "impl-trait-for-tuples 0.2.1",
- "parity-scale-codec 2.1.3",
+ "impl-trait-for-tuples",
+ "parity-scale-codec",
  "sp-std",
  "wasmi",
 ]
@@ -10549,13 +10915,13 @@
 
 [[package]]
 name = "statrs"
-version = "0.14.0"
+version = "0.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e0c1f144861fbfd2a8cc82d564ccbf7fb3b7834d4fa128b84e9c2a73371aead"
+checksum = "05bdbb8e4e78216a85785a85d3ec3183144f98d0097b9281802c019bb07a6f05"
 dependencies = [
- "approx 0.4.0",
+ "approx",
  "lazy_static",
- "nalgebra 0.26.2",
+ "nalgebra",
  "num-traits",
  "rand 0.8.4",
 ]
@@ -10571,18 +10937,6 @@
 ]
 
 [[package]]
-name = "streamunordered"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e68576e37c8a37f5372796df15202190349dd80e7ed6a79544c0232213e90e35"
-dependencies = [
- "futures-core",
- "futures-sink",
- "futures-util",
- "slab",
-]
-
-[[package]]
 name = "string"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -10605,9 +10959,9 @@
 
 [[package]]
 name = "structopt"
-version = "0.3.21"
+version = "0.3.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5277acd7ee46e63e5168a80734c9f6ee81b1367a7d8772a2d765df2a3705d28c"
+checksum = "69b041cdcb67226aca307e6e7be44c8806423d83e018bd662360a93dabce4d71"
 dependencies = [
  "clap",
  "lazy_static",
@@ -10616,9 +10970,9 @@
 
 [[package]]
 name = "structopt-derive"
-version = "0.4.14"
+version = "0.4.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90"
+checksum = "7813934aecf5f51a54775e00068c237de98489463968231a51746bbbc03f9c10"
 dependencies = [
  "heck",
  "proc-macro-error",
@@ -10664,7 +11018,7 @@
 [[package]]
 name = "substrate-build-script-utils"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "platforms",
 ]
@@ -10672,15 +11026,15 @@
 [[package]]
 name = "substrate-frame-rpc-system"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-system-rpc-runtime-api",
- "futures 0.3.15",
+ "futures 0.3.16",
  "jsonrpc-core 15.1.0",
  "jsonrpc-core-client 15.1.0",
  "jsonrpc-derive 15.1.0",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sc-client-api",
  "sc-rpc-api",
  "serde",
@@ -10695,7 +11049,7 @@
 [[package]]
 name = "substrate-prometheus-endpoint"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "async-std",
  "derive_more",
@@ -10709,14 +11063,14 @@
 [[package]]
 name = "substrate-test-client"
 version = "2.0.1"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "async-trait",
  "futures 0.1.31",
- "futures 0.3.15",
+ "futures 0.3.16",
  "hash-db",
  "hex",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sc-client-api",
  "sc-client-db",
  "sc-consensus",
@@ -10738,9 +11092,9 @@
 [[package]]
 name = "substrate-test-utils"
 version = "3.0.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "substrate-test-utils-derive",
  "tokio 0.2.25",
 ]
@@ -10748,7 +11102,7 @@
 [[package]]
 name = "substrate-test-utils-derive"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "proc-macro-crate 1.0.0",
  "quote",
@@ -10757,14 +11111,14 @@
 
 [[package]]
 name = "substrate-wasm-builder"
-version = "3.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79091baab813855ddf65b191de9fe53e656b6b67c1e9bd23fdcbff8788164684"
+version = "4.0.0"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "ansi_term 0.12.1",
  "atty",
  "build-helper",
- "cargo_metadata",
+ "cargo_metadata 0.13.1",
+ "sp-maybe-compressed-blob",
  "tempfile",
  "toml",
  "walkdir",
@@ -10780,7 +11134,7 @@
  "ansi_term 0.12.1",
  "atty",
  "build-helper",
- "cargo_metadata",
+ "cargo_metadata 0.12.3",
  "tempfile",
  "toml",
  "walkdir",
@@ -10795,15 +11149,15 @@
 
 [[package]]
 name = "subtle"
-version = "2.4.0"
+version = "2.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2"
+checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
 
 [[package]]
 name = "syn"
-version = "1.0.73"
+version = "1.0.74"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7"
+checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -10812,9 +11166,9 @@
 
 [[package]]
 name = "synstructure"
-version = "0.12.4"
+version = "0.12.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
+checksum = "474aaa926faa1603c40b7885a9eaea29b444d1cb2850cb7c0e37bb1a4182f4fa"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -10836,9 +11190,9 @@
 
 [[package]]
 name = "target-lexicon"
-version = "0.12.0"
+version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64ae3b39281e4b14b8123bdbaddd472b7dfe215e444181f2f9d2443c2444f834"
+checksum = "b0652da4c4121005e9ed22b79f6c5f2d9e2752906b53a33e9490489ba421a6fb"
 
 [[package]]
 name = "tempfile"
@@ -10874,18 +11228,18 @@
 
 [[package]]
 name = "thiserror"
-version = "1.0.25"
+version = "1.0.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6"
+checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.25"
+version = "1.0.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d"
+checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -10963,9 +11317,9 @@
 
 [[package]]
 name = "tinyvec"
-version = "1.2.0"
+version = "1.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342"
+checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338"
 dependencies = [
  "tinyvec_macros",
 ]
@@ -11025,12 +11379,12 @@
 
 [[package]]
 name = "tokio"
-version = "1.8.1"
+version = "1.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98c8b05dc14c75ea83d63dd391100353789f5f24b8b3866542a5e85c8be8e985"
+checksum = "4b7b349f11a7047e6d1276853e612d152f5e8a352c61917887cc2169e2366b4c"
 dependencies = [
  "autocfg",
- "pin-project-lite 0.2.6",
+ "pin-project-lite 0.2.7",
 ]
 
 [[package]]
@@ -11297,7 +11651,7 @@
 dependencies = [
  "cfg-if 1.0.0",
  "log",
- "pin-project-lite 0.2.6",
+ "pin-project-lite 0.2.7",
  "tracing-attributes",
  "tracing-core",
 ]
@@ -11328,7 +11682,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
 dependencies = [
- "pin-project 1.0.7",
+ "pin-project 1.0.8",
  "tracing",
 ]
 
@@ -11355,9 +11709,9 @@
 
 [[package]]
 name = "tracing-subscriber"
-version = "0.2.18"
+version = "0.2.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa5553bf0883ba7c9cbe493b085c29926bd41b66afc31ff72cf17ff4fb60dcd5"
+checksum = "ab69019741fca4d98be3c62d2b75254528b5432233fd8a4d2739fec20278de48"
 dependencies = [
  "ansi_term 0.12.1",
  "chrono",
@@ -11377,12 +11731,12 @@
 
 [[package]]
 name = "trie-db"
-version = "0.22.5"
+version = "0.22.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd81fe0c8bc2b528a51c9d2c31dae4483367a26a723a3c9a4a8120311d7774e3"
+checksum = "9eac131e334e81b6b3be07399482042838adcd7957aa0010231d0813e39e02fa"
 dependencies = [
  "hash-db",
- "hashbrown",
+ "hashbrown 0.11.2",
  "log",
  "rustc-hex",
  "smallvec 1.6.1",
@@ -11404,7 +11758,7 @@
 checksum = "a1631b201eb031b563d2e85ca18ec8092508e262a3196ce9bd10a67ec87b9f5c"
 dependencies = [
  "hash-db",
- "rlp 0.5.0",
+ "rlp",
 ]
 
 [[package]]
@@ -11459,11 +11813,11 @@
 [[package]]
 name = "try-runtime-cli"
 version = "0.9.0"
-source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc"
+source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
 dependencies = [
  "frame-try-runtime",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "remote-externalities",
  "sc-chain-spec",
  "sc-cli",
@@ -11475,6 +11829,7 @@
  "sp-blockchain",
  "sp-core",
  "sp-externalities",
+ "sp-io",
  "sp-keystore",
  "sp-runtime",
  "sp-state-machine",
@@ -11488,7 +11843,7 @@
 checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59"
 dependencies = [
  "cfg-if 0.1.10",
- "rand 0.3.23",
+ "rand 0.7.3",
  "static_assertions",
 ]
 
@@ -11506,21 +11861,9 @@
 
 [[package]]
 name = "uint"
-version = "0.8.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9db035e67dfaf7edd9aebfe8676afcd63eed53c8a4044fed514c8cccf1835177"
-dependencies = [
- "byteorder",
- "crunchy",
- "rustc-hex",
- "static_assertions",
-]
-
-[[package]]
-name = "uint"
-version = "0.9.0"
+version = "0.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e11fe9a9348741cf134085ad57c249508345fe16411b3d7fb4ff2da2f1d6382e"
+checksum = "6470ab50f482bde894a037a57064480a246dbfdd5960bd65a44824693f08da5f"
 dependencies = [
  "byteorder",
  "crunchy",
@@ -11557,9 +11900,9 @@
 
 [[package]]
 name = "unicode-segmentation"
-version = "1.7.1"
+version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
+checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
 
 [[package]]
 name = "unicode-width"
@@ -11575,12 +11918,12 @@
 
 [[package]]
 name = "universal-hash"
-version = "0.4.0"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402"
+checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05"
 dependencies = [
  "generic-array 0.14.4",
- "subtle 2.4.0",
+ "subtle 2.4.1",
 ]
 
 [[package]]
@@ -11623,7 +11966,7 @@
 name = "up-sponsorship"
 version = "0.1.0"
 dependencies = [
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
 ]
 
 [[package]]
@@ -11661,9 +12004,9 @@
 
 [[package]]
 name = "vcpkg"
-version = "0.2.14"
+version = "0.2.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70455df2fdf4e9bf580a92e443f1eb0303c390d682e2ea817312c9e81f8c3399"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
 
 [[package]]
 name = "vec_map"
@@ -11816,7 +12159,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "js-sys",
  "parking_lot 0.11.1",
  "pin-utils",
@@ -11931,7 +12274,7 @@
 checksum = "c5d2a763e7a6fc734218e0e463196762a4f409c483063d81e0e85f96343b2e0a"
 dependencies = [
  "anyhow",
- "gimli",
+ "gimli 0.24.0",
  "more-asserts",
  "object 0.24.0",
  "target-lexicon",
@@ -11950,7 +12293,7 @@
  "cranelift-codegen",
  "cranelift-entity",
  "cranelift-wasm",
- "gimli",
+ "gimli 0.24.0",
  "indexmap",
  "log",
  "more-asserts",
@@ -11976,7 +12319,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4d4539ea734422b7c868107e2187d7746d8affbcaa71916d72639f53757ad707"
 dependencies = [
- "addr2line",
+ "addr2line 0.15.2",
  "anyhow",
  "cfg-if 1.0.0",
  "cranelift-codegen",
@@ -11984,7 +12327,7 @@
  "cranelift-frontend",
  "cranelift-native",
  "cranelift-wasm",
- "gimli",
+ "gimli 0.24.0",
  "log",
  "more-asserts",
  "object 0.24.0",
@@ -12025,7 +12368,7 @@
 dependencies = [
  "anyhow",
  "cfg-if 1.0.0",
- "gimli",
+ "gimli 0.24.0",
  "lazy_static",
  "libc",
  "object 0.24.0",
@@ -12118,6 +12461,89 @@
 ]
 
 [[package]]
+name = "westend-runtime"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "beefy-primitives",
+ "bitvec 0.20.4",
+ "frame-benchmarking",
+ "frame-election-provider-support",
+ "frame-executive",
+ "frame-support",
+ "frame-system",
+ "frame-system-benchmarking",
+ "frame-system-rpc-runtime-api",
+ "frame-try-runtime",
+ "hex-literal",
+ "log",
+ "max-encoded-len",
+ "pallet-authority-discovery",
+ "pallet-authorship",
+ "pallet-babe",
+ "pallet-balances",
+ "pallet-collective",
+ "pallet-democracy",
+ "pallet-election-provider-multi-phase",
+ "pallet-elections-phragmen",
+ "pallet-grandpa",
+ "pallet-identity",
+ "pallet-im-online",
+ "pallet-indices",
+ "pallet-membership",
+ "pallet-mmr-primitives",
+ "pallet-multisig",
+ "pallet-nicks",
+ "pallet-offences",
+ "pallet-offences-benchmarking",
+ "pallet-proxy",
+ "pallet-recovery",
+ "pallet-scheduler 3.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
+ "pallet-session",
+ "pallet-session-benchmarking",
+ "pallet-society",
+ "pallet-staking",
+ "pallet-staking-reward-curve",
+ "pallet-sudo",
+ "pallet-timestamp",
+ "pallet-transaction-payment",
+ "pallet-transaction-payment-rpc-runtime-api",
+ "pallet-treasury",
+ "pallet-utility",
+ "pallet-vesting",
+ "pallet-xcm",
+ "parity-scale-codec",
+ "polkadot-parachain",
+ "polkadot-primitives",
+ "polkadot-runtime-common",
+ "polkadot-runtime-parachains",
+ "rustc-hex",
+ "serde",
+ "serde_derive",
+ "smallvec 1.6.1",
+ "sp-api",
+ "sp-authority-discovery",
+ "sp-block-builder",
+ "sp-consensus-babe",
+ "sp-core",
+ "sp-inherents",
+ "sp-io",
+ "sp-npos-elections",
+ "sp-offchain",
+ "sp-runtime",
+ "sp-session",
+ "sp-staking",
+ "sp-std",
+ "sp-transaction-pool",
+ "sp-version",
+ "static_assertions",
+ "substrate-wasm-builder 4.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
+ "xcm",
+ "xcm-builder",
+ "xcm-executor",
+]
+
+[[package]]
 name = "which"
 version = "4.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -12214,24 +12640,24 @@
 
 [[package]]
 name = "xcm"
-version = "0.9.7"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "derivative",
- "impl-trait-for-tuples 0.2.1",
- "parity-scale-codec 2.1.3",
+ "impl-trait-for-tuples",
+ "parity-scale-codec",
 ]
 
 [[package]]
 name = "xcm-builder"
-version = "0.9.7"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "frame-support",
  "frame-system",
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "pallet-transaction-payment",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "polkadot-parachain",
  "sp-arithmetic",
  "sp-io",
@@ -12243,13 +12669,13 @@
 
 [[package]]
 name = "xcm-executor"
-version = "0.9.7"
-source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
 dependencies = [
  "frame-support",
- "impl-trait-for-tuples 0.2.1",
+ "impl-trait-for-tuples",
  "log",
- "parity-scale-codec 2.1.3",
+ "parity-scale-codec",
  "sp-arithmetic",
  "sp-core",
  "sp-io",
@@ -12264,7 +12690,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e7d9028f208dd5e63c614be69f115c1b53cacc1111437d4c765185856666c107"
 dependencies = [
- "futures 0.3.15",
+ "futures 0.3.16",
  "log",
  "nohash-hasher",
  "parking_lot 0.11.1",
@@ -12280,9 +12706,9 @@
 
 [[package]]
 name = "zeroize"
-version = "1.3.0"
+version = "1.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd"
+checksum = "377db0846015f7ae377174787dd452e1c5f5a9050bc6f954911d01f116daa0cd"
 dependencies = [
  "zeroize_derive",
 ]
modifiedCargo.tomldiffbeforeafterboth
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,8 +5,7 @@
     'pallets/*',
     'primitives/*',
     'runtime',
-    'crates/evm-coder',
-    'crates/evm-coder-macros',
+    'crates/*',
 ]
 [profile.release]
 panic = 'unwind'
addedMakefilediffbeforeafterboth
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,43 @@
+.PHONY: _eth_codegen
+_eth_codegen:
+
+.PHONY: regenerate_solidity
+regenerate_solidity:
+	PACKAGE=pallet-nft NAME=eth::erc::fungible_iface OUTPUT=./tests/src/eth/api/UniqueFungible.sol ./.maintain/scripts/generate_api.sh
+	PACKAGE=pallet-nft NAME=eth::erc::nft_iface OUTPUT=./tests/src/eth/api/UniqueNFT.sol ./.maintain/scripts/generate_api.sh
+	PACKAGE=pallet-evm-contract-helpers NAME=eth::contract_helpers_iface OUTPUT=./tests/src/eth/api/ContractHelpers.sol ./.maintain/scripts/generate_api.sh
+
+	PACKAGE=pallet-nft NAME=eth::erc::fungible_impl OUTPUT=./pallets/nft/src/eth/stubs/UniqueFungible.sol ./.maintain/scripts/generate_api.sh
+	PACKAGE=pallet-nft NAME=eth::erc::nft_impl OUTPUT=./pallets/nft/src/eth/stubs/UniqueNFT.sol ./.maintain/scripts/generate_api.sh
+	PACKAGE=pallet-evm-contract-helpers NAME=eth::contract_helpers_impl OUTPUT=./pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol ./.maintain/scripts/generate_api.sh
+
+NFT_EVM_STUBS=./pallets/nft/src/eth/stubs
+CONTRACT_HELPERS_STUBS=./pallets/evm-contract-helpers/src/stubs/
+
+$(NFT_EVM_STUBS)/UniqueFungible.raw: $(NFT_EVM_STUBS)/UniqueFungible.sol
+	INPUT=$< OUTPUT=$@ ./.maintain/scripts/compile_stub.sh
+$(NFT_EVM_STUBS)/UniqueNFT.raw: $(NFT_EVM_STUBS)/UniqueNFT.sol
+	INPUT=$< OUTPUT=$@ ./.maintain/scripts/compile_stub.sh
+$(CONTRACT_HELPERS_STUBS)/ContractHelpers.raw: $(CONTRACT_HELPERS_STUBS)/ContractHelpers.sol
+	INPUT=$< OUTPUT=$@ ./.maintain/scripts/compile_stub.sh
+
+evm_stubs: $(NFT_EVM_STUBS)/UniqueFungible.raw $(NFT_EVM_STUBS)/UniqueNFT.raw $(CONTRACT_HELPERS_STUBS)/ContractHelpers.raw
+
+.PHONY: _bench
+_bench:
+	cargo run --release --features runtime-benchmarks -- \
+	benchmark --pallet pallet-$(PALLET) \
+	--wasm-execution compiled --extrinsic '*' \
+	--template .maintain/frame-weight-template.hbs --steps=50 --repeat=20 \
+	--output=./pallets/$(PALLET)/src/weights.rs
+
+.PHONY: bench-evm-migration
+bench-evm-migration:
+	make _bench PALLET=evm-migration
+
+.PHONY: bench-nft
+bench-nft:
+	make _bench PALLET=nft
+
+.PHONY: bench
+bench: bench-evm-migration bench-nft
modifiedREADME.mddiffbeforeafterboth
--- a/README.md
+++ b/README.md
@@ -257,7 +257,7 @@
 Uncomment following lies:
 1. In node/rpc/Cargo.toml
 ```
-# pallet-contracts-rpc = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
+# pallet-contracts-rpc = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
 ```
 
 2. In node/rpc/src/lib.rs
@@ -280,19 +280,19 @@
     # [dependencies.pallet-contracts]
     # git = 'https://github.com/paritytech/substrate.git'
     # default-features = false
-    # branch = 'polkadot-v0.9.7'
+    # branch = 'polkadot-v0.9.8'
     # version = '3.0.0'
 
     # [dependencies.pallet-contracts-primitives]
     # git = 'https://github.com/paritytech/substrate.git'
     # default-features = false
-    # branch = 'polkadot-v0.9.7'
+    # branch = 'polkadot-v0.9.8'
     # version = '3.0.0'
 
     # [dependencies.pallet-contracts-rpc-runtime-api]
     # git = 'https://github.com/paritytech/substrate.git'
     # default-features = false
-    # branch = 'polkadot-v0.9.7'
+    # branch = 'polkadot-v0.9.8'
     # version = '3.0.0'
 ...
     # pallet-contract-helpers = { path = '../pallets/contract-helpers', default-features = false, version = '0.1.0' }
modifiedcrates/evm-coder-macros/src/lib.rsdiffbeforeafterboth
--- a/crates/evm-coder-macros/src/lib.rs
+++ b/crates/evm-coder-macros/src/lib.rs
@@ -6,7 +6,7 @@
 use quote::quote;
 use sha3::{Digest, Keccak256};
 use syn::{
-	AttributeArgs, DeriveInput, GenericArgument, Ident, ItemTrait, Pat, Path, PathArguments,
+	AttributeArgs, DeriveInput, GenericArgument, Ident, ItemImpl, Pat, Path, PathArguments,
 	PathSegment, Type, parse_macro_input, spanned::Spanned,
 };
 
@@ -106,8 +106,8 @@
 	}
 }
 
-fn parse_ident_from_segment(segment: &PathSegment) -> syn::Result<&Ident> {
-	if segment.arguments != PathArguments::None {
+fn parse_ident_from_segment(segment: &PathSegment, allow_generics: bool) -> syn::Result<&Ident> {
+	if segment.arguments != PathArguments::None && !allow_generics {
 		return Err(syn::Error::new(
 			segment.arguments.span(),
 			"unexpected generic type",
@@ -116,18 +116,18 @@
 	Ok(&segment.ident)
 }
 
-fn parse_ident_from_path(path: &Path) -> syn::Result<&Ident> {
+fn parse_ident_from_path(path: &Path, allow_generics: bool) -> syn::Result<&Ident> {
 	let segment = parse_path_segment(path)?;
-	parse_ident_from_segment(segment)
+	parse_ident_from_segment(segment, allow_generics)
 }
 
-fn parse_ident_from_type(ty: &Type) -> syn::Result<&Ident> {
+fn parse_ident_from_type(ty: &Type, allow_generics: bool) -> syn::Result<&Ident> {
 	let path = parse_path(ty)?;
-	parse_ident_from_path(path)
+	parse_ident_from_path(path, allow_generics)
 }
 
 // Gets T out of Result<T>
-fn parse_result_ok(ty: &Type) -> syn::Result<&Ident> {
+fn parse_result_ok(ty: &Type) -> syn::Result<&Type> {
 	let path = parse_path(ty)?;
 	let segment = parse_path_segment(path)?;
 
@@ -160,7 +160,7 @@
 		}
 	};
 
-	parse_ident_from_type(ty)
+	Ok(ty)
 }
 
 fn pascal_ident_to_call(ident: &Ident) -> Ident {
@@ -182,14 +182,6 @@
 	let name = cases::snakecase::to_snake_case(&name);
 	let name = format!("call_{}", name);
 	Ident::new(&name, ident.span())
-}
-
-fn format_ty(ty: &Ident) -> String {
-	if ty == "string" {
-		format!("{} memory", ty)
-	} else {
-		ty.to_string()
-	}
 }
 
 #[proc_macro_attribute]
@@ -197,15 +189,21 @@
 	let args = parse_macro_input!(args as AttributeArgs);
 	let args = solidity_interface::InterfaceInfo::from_list(&args).unwrap();
 
-	let input: ItemTrait = match syn::parse(stream) {
+	let input: ItemImpl = match syn::parse(stream) {
 		Ok(t) => t,
 		Err(e) => return e.to_compile_error().into(),
 	};
 
-	match solidity_interface::SolidityInterface::try_from(args, &input) {
+	let expanded = match solidity_interface::SolidityInterface::try_from(args, &input) {
 		Ok(v) => v.expand(),
 		Err(e) => e.to_compile_error(),
-	}
+	};
+
+	(quote! {
+		#input
+
+		#expanded
+	})
 	.into()
 }
 
modifiedcrates/evm-coder-macros/src/solidity_interface.rsdiffbeforeafterboth
--- a/crates/evm-coder-macros/src/solidity_interface.rs
+++ b/crates/evm-coder-macros/src/solidity_interface.rs
@@ -5,12 +5,12 @@
 use inflector::cases;
 use std::fmt::Write;
 use syn::{
-	FnArg, Ident, ItemTrait, Meta, NestedMeta, PatType, Path, ReturnType, TraitItem,
-	TraitItemMethod, Visibility, spanned::Spanned,
+	FnArg, Generics, Ident, ImplItem, ImplItemMethod, ItemImpl, Meta, NestedMeta, PatType, Path,
+	ReturnType, Type, spanned::Spanned,
 };
 
 use crate::{
-	fn_selector_str, format_ty, parse_ident_from_pat, parse_ident_from_path, parse_ident_from_type,
+	fn_selector_str, parse_ident_from_pat, parse_ident_from_path, parse_ident_from_type,
 	parse_result_ok, pascal_ident_to_call, pascal_ident_to_snake_call, snake_ident_to_pascal,
 	snake_ident_to_screaming,
 };
@@ -22,7 +22,7 @@
 }
 impl Is {
 	fn try_from(path: &Path) -> syn::Result<Self> {
-		let name = parse_ident_from_path(path)?.clone();
+		let name = parse_ident_from_path(path, false)?.clone();
 		Ok(Self {
 			pascal_call_name: pascal_ident_to_call(&name),
 			snake_call_name: pascal_ident_to_snake_call(&name),
@@ -54,9 +54,9 @@
 
 	fn expand_variant_call(&self) -> proc_macro2::TokenStream {
 		let name = &self.name;
-		let snake_call_name = &self.snake_call_name;
+		let pascal_call_name = &self.pascal_call_name;
 		quote! {
-			InternalCall::#name(call) => return self.#snake_call_name(Msg {
+			InternalCall::#name(call) => return <Self as ::evm_coder::Callable<#pascal_call_name>>::call(self, Msg {
 				call,
 				caller: c.caller,
 				value: c.value,
@@ -64,23 +64,29 @@
 		}
 	}
 
-	fn expand_call_inner(&self) -> proc_macro2::TokenStream {
-		let snake_call_name = &self.snake_call_name;
+	fn expand_parse(&self) -> proc_macro2::TokenStream {
+		let name = &self.name;
 		let pascal_call_name = &self.pascal_call_name;
 		quote! {
-			fn #snake_call_name(&mut self, c: Msg<#pascal_call_name>) -> ::core::result::Result<::evm_coder::abi::AbiWriter, Self::Error>;
+			if let Some(parsed_call) = #pascal_call_name::parse(method_id, reader)? {
+				return Ok(Some(Self::#name(parsed_call)))
+			}
 		}
 	}
 
-	fn expand_parse(&self) -> proc_macro2::TokenStream {
-		let name = &self.name;
+	fn expand_generator(&self) -> proc_macro2::TokenStream {
 		let pascal_call_name = &self.pascal_call_name;
 		quote! {
-			if let Some(parsed_call) = #pascal_call_name::parse(method_id, reader)? {
-				return Ok(Some(Self::#name(parsed_call)))
-			}
+			#pascal_call_name::generate_solidity_interface(out_set, is_impl);
 		}
 	}
+
+	fn expand_event_generator(&self) -> proc_macro2::TokenStream {
+		let name = &self.name;
+		quote! {
+			#name::generate_solidity_interface(out_set, is_impl);
+		}
+	}
 }
 
 #[derive(Default)]
@@ -100,6 +106,7 @@
 
 #[derive(FromMeta)]
 pub struct InterfaceInfo {
+	name: Ident,
 	#[darling(default)]
 	is: IsList,
 	#[darling(default)]
@@ -116,13 +123,16 @@
 
 struct MethodArg {
 	name: Ident,
+	camel_name: String,
 	ty: Ident,
 }
 impl MethodArg {
 	fn try_from(value: &PatType) -> syn::Result<Self> {
+		let name = parse_ident_from_pat(&value.pat)?.clone();
 		Ok(Self {
-			name: parse_ident_from_pat(&value.pat)?.clone(),
-			ty: parse_ident_from_type(&value.ty)?.clone(),
+			camel_name: cases::camelcase::to_camel_case(&name.to_string()),
+			name,
+			ty: parse_ident_from_type(&value.ty, false)?.clone(),
 		})
 	}
 	fn is_value(&self) -> bool {
@@ -174,9 +184,12 @@
 		}
 	}
 
-	fn solidity_def(&self) -> String {
-		assert!(!self.is_special());
-		format!("{} {}", format_ty(&self.ty), self.name)
+	fn expand_solidity_argument(&self) -> proc_macro2::TokenStream {
+		let camel_name = &self.camel_name.to_string();
+		let ty = &self.ty;
+		quote! {
+			<NamedArgument<#ty>>::new(#camel_name)
+		}
 	}
 }
 
@@ -197,15 +210,15 @@
 	args: Vec<MethodArg>,
 	has_normal_args: bool,
 	mutability: Mutability,
-	result: Ident,
+	result: Type,
 }
 impl Method {
-	fn try_from(value: &TraitItemMethod) -> syn::Result<Self> {
+	fn try_from(value: &ImplItemMethod) -> syn::Result<Self> {
 		let mut info = MethodInfo {
 			rename_selector: None,
 		};
 		for attr in &value.attrs {
-			let ident = parse_ident_from_path(&attr.path)?;
+			let ident = parse_ident_from_path(&attr.path, false)?;
 			if ident == "solidity" {
 				let args = attr.parse_meta().unwrap();
 				info = MethodInfo::from_meta(&args).unwrap();
@@ -392,71 +405,64 @@
 		}
 	}
 
-	fn solidity_def(&self) -> String {
-		let mut out = format!("function {}(", self.camel_name);
-		for (i, arg) in self.args.iter().filter(|a| !a.is_special()).enumerate() {
-			if i != 0 {
-				out.push_str(", ");
+	fn expand_solidity_function(&self) -> proc_macro2::TokenStream {
+		let camel_name = &self.camel_name;
+		let mutability = match self.mutability {
+			Mutability::Mutable => quote! {SolidityMutability::Mutable},
+			Mutability::View => quote! { SolidityMutability::View },
+			Mutability::Pure => quote! {SolidityMutability::Pure},
+		};
+		let result = &self.result;
+
+		let args = self
+			.args
+			.iter()
+			.filter(|a| !a.is_special())
+			.map(MethodArg::expand_solidity_argument);
+
+		quote! {
+			SolidityFunction {
+				name: #camel_name,
+				mutability: #mutability,
+				args: (
+					#(
+						#args,
+					)*
+				),
+				result: <UnnamedArgument<#result>>::default(),
 			}
-			out.push_str(&arg.solidity_def());
 		}
-		out.push(')');
-		match self.mutability {
-			Mutability::Mutable => {}
-			Mutability::View => write!(out, " view").unwrap(),
-			Mutability::Pure => write!(out, " pure").unwrap(),
-		}
-		if self.result != "void" {
-			write!(out, " returns ({})", format_ty(&self.result)).unwrap();
-		}
-		out.push(';');
-		out
 	}
 }
 
 pub struct SolidityInterface {
-	vis: Visibility,
-	name: Ident,
+	generics: Generics,
+	name: Box<syn::Type>,
 	info: InterfaceInfo,
 	methods: Vec<Method>,
-	items: Vec<TraitItem>,
 }
 impl SolidityInterface {
-	pub fn try_from(info: InterfaceInfo, value: &ItemTrait) -> syn::Result<Self> {
-		let mut found_error = false;
+	pub fn try_from(info: InterfaceInfo, value: &ItemImpl) -> syn::Result<Self> {
 		let mut methods = Vec::new();
 
 		for item in &value.items {
-			match item {
-				TraitItem::Type(ty) => {
-					if ty.ident == "Error" {
-						found_error = true;
-					}
-				}
-				TraitItem::Method(method) => methods.push(Method::try_from(method)?),
-				_ => {}
+			if let ImplItem::Method(method) = item {
+				methods.push(Method::try_from(method)?)
 			}
 		}
-		if !found_error {
-			return Err(syn::Error::new(
-				value.span(),
-				"expected associated type called Error, which should implement From<&str>",
-			));
-		}
 		Ok(Self {
-			vis: value.vis.clone(),
-			name: value.ident.clone(),
+			generics: value.generics.clone(),
+			name: value.self_ty.clone(),
 			info,
 			methods,
-			items: value.items.clone(),
 		})
 	}
 	pub fn expand(self) -> proc_macro2::TokenStream {
-		let vis = self.vis;
 		let name = self.name;
-		let items = self.items;
 
-		let call_name = pascal_ident_to_call(&name);
+		let solidity_name = self.info.name.to_string();
+		let call_name = pascal_ident_to_call(&self.info.name);
+		let generics = self.generics;
 
 		let call_sub = self
 			.info
@@ -465,13 +471,6 @@
 			.iter()
 			.chain(self.info.is.0.iter())
 			.map(Is::expand_call_def);
-		let call_inner = self
-			.info
-			.inline_is
-			.0
-			.iter()
-			.chain(self.info.is.0.iter())
-			.map(Is::expand_call_inner);
 		let call_parse = self
 			.info
 			.inline_is
@@ -495,12 +494,31 @@
 		let interface_id = self.methods.iter().map(Method::expand_interface_id);
 		let parsers = self.methods.iter().map(Method::expand_parse);
 		let call_variants_this = self.methods.iter().map(Method::expand_variant_call);
+		let solidity_functions = self.methods.iter().map(Method::expand_solidity_function);
 
+		// TODO: Inline inline_is
+		let solidity_is = self
+			.info
+			.is
+			.0
+			.iter()
+			.chain(self.info.inline_is.0.iter())
+			.map(|is| is.name.to_string());
+		let solidity_events_is = self.info.events.0.iter().map(|is| is.name.to_string());
+		let solidity_generators = self
+			.info
+			.is
+			.0
+			.iter()
+			.chain(self.info.inline_is.0.iter())
+			.map(Is::expand_generator);
+		let solidity_event_generators = self.info.events.0.iter().map(Is::expand_event_generator);
+
 		// let methods = self.methods.iter().map(Method::solidity_def);
 
 		quote! {
 			#[derive(Debug)]
-			#vis enum #call_name {
+			pub enum #call_name {
 				#(
 					#calls,
 				)*
@@ -512,19 +530,6 @@
 				#(
 					#consts
 				)*
-				pub fn parse(method_id: u32, reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::abi::Result<Option<Self>> {
-					use ::evm_coder::abi::AbiRead;
-					match method_id {
-						#(
-							#parsers,
-						)*
-						_ => {},
-					}
-					#(
-						#call_parse
-					)else*
-					return Ok(None);
-				}
 				pub const fn interface_id() -> u32 {
 					let mut interface_id = 0;
 					#(#interface_id)*
@@ -539,16 +544,60 @@
 						)*
 					)
 				}
+				pub fn generate_solidity_interface(out_set: &mut sp_std::collections::btree_set::BTreeSet<string>, is_impl: bool) {
+					use evm_coder::solidity::*;
+					use core::fmt::Write;
+					let interface = SolidityInterface {
+						name: #solidity_name,
+						is: &["Dummy", #(
+							#solidity_is,
+						)* #(
+							#solidity_events_is,
+						)* ],
+						functions: (#(
+							#solidity_functions,
+						)*),
+					};
+					if is_impl {
+						out_set.insert("// Common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\n".into());
+					} else {
+						out_set.insert("// Common stubs holder\ninterface Dummy {\n}\n".into());
+					}
+					#(
+						#solidity_generators
+					)*
+					#(
+						#solidity_event_generators
+					)*
+
+					let mut out = string::new();
+					// In solidity interface usage (is) should be preceeded by interface definition
+					// This comment helps to sort it in a set
+					if #solidity_name.starts_with("Inline") {
+						out.push_str("// Inline\n");
+					}
+					let _ = interface.format(is_impl, &mut out);
+					out_set.insert(out);
+				}
 			}
-			#vis trait #name {
-				#(
-					#items
-				)*
-				#(
-					#call_inner
-				)*
+			impl ::evm_coder::Call for #call_name {
+				fn parse(method_id: u32, reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Option<Self>> {
+					use ::evm_coder::abi::AbiRead;
+					match method_id {
+						#(
+							#parsers,
+						)*
+						_ => {},
+					}
+					#(
+						#call_parse
+					)else*
+					return Ok(None);
+				}
+			}
+			impl #generics ::evm_coder::Callable<#call_name> for #name {
 				#[allow(unreachable_code)] // In case of no inner calls
-				fn call(&mut self, c: Msg<#call_name>) -> ::core::result::Result<::evm_coder::abi::AbiWriter, Self::Error> {
+				fn call(&mut self, c: Msg<#call_name>) -> Result<::evm_coder::abi::AbiWriter> {
 					use ::evm_coder::abi::AbiWrite;
 					type InternalCall = #call_name;
 					match c.call {
modifiedcrates/evm-coder-macros/src/to_log.rsdiffbeforeafterboth
--- a/crates/evm-coder-macros/src/to_log.rs
+++ b/crates/evm-coder-macros/src/to_log.rs
@@ -1,3 +1,4 @@
+use inflector::cases;
 use syn::{Data, DeriveInput, Field, Fields, Ident, Variant, spanned::Spanned};
 use std::fmt::Write;
 use quote::quote;
@@ -6,6 +7,7 @@
 
 struct EventField {
 	name: Ident,
+	camel_name: String,
 	ty: Ident,
 	indexed: bool,
 }
@@ -13,10 +15,10 @@
 impl EventField {
 	fn try_from(field: &Field) -> syn::Result<Self> {
 		let name = field.ident.as_ref().unwrap();
-		let ty = parse_ident_from_type(&field.ty)?;
+		let ty = parse_ident_from_type(&field.ty, false)?;
 		let mut indexed = false;
 		for attr in &field.attrs {
-			if let Ok(ident) = parse_ident_from_path(&attr.path) {
+			if let Ok(ident) = parse_ident_from_path(&attr.path, false) {
 				if ident == "indexed" {
 					indexed = true;
 				}
@@ -24,10 +26,19 @@
 		}
 		Ok(Self {
 			name: name.to_owned(),
+			camel_name: cases::camelcase::to_camel_case(&name.to_string()),
 			ty: ty.to_owned(),
 			indexed,
 		})
 	}
+	fn expand_solidity_argument(&self) -> proc_macro2::TokenStream {
+		let camel_name = &self.camel_name;
+		let ty = &self.ty;
+		let indexed = self.indexed;
+		quote! {
+			<SolidityEventArgument<#ty>>::new(#indexed, #camel_name)
+		}
+	}
 }
 
 struct Event {
@@ -56,6 +67,12 @@
 		for field in &named.named {
 			fields.push(EventField::try_from(field)?);
 		}
+		if fields.iter().filter(|f| f.indexed).count() > 3 {
+			return Err(syn::Error::new(
+				variant.fields.span(),
+				"events can have at most 4 indexed fields (1 indexed field is reserved for event signature)"
+			));
+		}
 		let mut selector_str = format!("{}(", name);
 		for (i, arg) in fields.iter().enumerate() {
 			if i != 0 {
@@ -110,6 +127,21 @@
 			)*];
 		}
 	}
+
+	fn expand_solidity_function(&self) -> proc_macro2::TokenStream {
+		let name = self.name.to_string();
+		let args = self.fields.iter().map(EventField::expand_solidity_argument);
+		quote! {
+			SolidityEvent {
+				name: #name,
+				args: (
+					#(
+						#args,
+					)*
+				),
+			}
+		}
+	}
 }
 
 pub struct Events {
@@ -138,12 +170,30 @@
 
 		let consts = self.events.iter().map(Event::expand_consts);
 		let serializers = self.events.iter().map(Event::expand_serializers);
+		let solidity_name = self.name.to_string();
+		let solidity_functions = self.events.iter().map(Event::expand_solidity_function);
 
 		quote! {
 			impl #name {
 				#(
 					#consts
 				)*
+
+				pub fn generate_solidity_interface(out_set: &mut sp_std::collections::btree_set::BTreeSet<string>, is_impl: bool) {
+					use evm_coder::solidity::*;
+					use core::fmt::Write;
+					let interface = SolidityInterface {
+						name: #solidity_name,
+						is: &[],
+						functions: (#(
+							#solidity_functions,
+						)*),
+					};
+					let mut out = string::new();
+					out.push_str("// Inline\n");
+					let _ = interface.format(is_impl, &mut out);
+					out_set.insert(out);
+				}
 			}
 
 			#[automatically_derived]
modifiedcrates/evm-coder/Cargo.tomldiffbeforeafterboth
--- a/crates/evm-coder/Cargo.toml
+++ b/crates/evm-coder/Cargo.toml
@@ -8,10 +8,12 @@
 primitive-types = { version = "0.9", default-features = false }
 hex-literal = "0.3"
 ethereum = { version = "0.7.1", default-features = false }
+evm-core = { default-features = false, git = "https://github.com/uniquenetwork/evm.git", branch="precompile-output-parachain" }
+impl-trait-for-tuples = "0.2.1"
 
 [dev-dependencies]
 hex = "0.4.3"
 
 [features]
 default = ["std"]
-std = ["ethereum/std", "primitive-types/std"]
\ No newline at end of file
+std = ["ethereum/std", "primitive-types/std", "evm-core/std"]
\ No newline at end of file
modifiedcrates/evm-coder/src/abi.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/abi.rs
+++ b/crates/evm-coder/src/abi.rs
@@ -8,36 +8,48 @@
 	string::{String, ToString},
 	vec::Vec,
 };
+use evm_core::ExitError;
 use primitive_types::{H160, U256};
 
-use crate::types::string;
+use crate::{execution::Error, types::string};
+use crate::execution::Result;
 
 const ABI_ALIGNMENT: usize = 32;
 
-pub type Result<T> = core::result::Result<T, &'static str>;
-
 #[derive(Clone)]
 pub struct AbiReader<'i> {
 	buf: &'i [u8],
+	subresult_offset: usize,
 	offset: usize,
 }
 impl<'i> AbiReader<'i> {
 	pub fn new(buf: &'i [u8]) -> Self {
-		Self { buf, offset: 0 }
+		Self {
+			buf,
+			subresult_offset: 0,
+			offset: 0,
+		}
 	}
 	pub fn new_call(buf: &'i [u8]) -> Result<(u32, Self)> {
 		if buf.len() < 4 {
-			return Err("missing method id");
+			return Err(Error::Error(ExitError::OutOfOffset));
 		}
 		let mut method_id = [0; 4];
 		method_id.copy_from_slice(&buf[0..4]);
 
-		Ok((u32::from_be_bytes(method_id), Self { buf, offset: 4 }))
+		Ok((
+			u32::from_be_bytes(method_id),
+			Self {
+				buf,
+				subresult_offset: 4,
+				offset: 4,
+			},
+		))
 	}
 
 	fn read_padleft<const S: usize>(&mut self) -> Result<[u8; S]> {
-		if self.buf.len() - self.offset < 32 {
-			return Err("missing padding");
+		if self.buf.len() - self.offset < ABI_ALIGNMENT {
+			return Err(Error::Error(ExitError::OutOfOffset));
 		}
 		let mut block = [0; S];
 		// Verify padding is empty
@@ -45,7 +57,7 @@
 			.iter()
 			.all(|&v| v == 0)
 		{
-			return Err("non zero padding (wrong types?)");
+			return Err(Error::Error(ExitError::InvalidRange));
 		}
 		block.copy_from_slice(
 			&self.buf[self.offset + ABI_ALIGNMENT - S..self.offset + ABI_ALIGNMENT],
@@ -63,7 +75,7 @@
 		match data[0] {
 			0 => Ok(false),
 			1 => Ok(true),
-			_ => Err("wrong bool value"),
+			_ => Err(Error::Error(ExitError::InvalidRange)),
 		}
 	}
 
@@ -75,10 +87,13 @@
 		let mut subresult = self.subresult()?;
 		let length = subresult.read_usize()?;
 		if subresult.buf.len() <= subresult.offset + length {
-			return Err("bytes out of bounds");
+			return Err(Error::Error(ExitError::OutOfOffset));
 		}
 		Ok(subresult.buf[subresult.offset..subresult.offset + length].into())
 	}
+	pub fn string(&mut self) -> Result<string> {
+		string::from_utf8(self.bytes()?).map_err(|_| Error::Error(ExitError::InvalidRange))
+	}
 
 	pub fn uint32(&mut self) -> Result<u32> {
 		Ok(u32::from_be_bytes(self.read_padleft()?))
@@ -103,9 +118,13 @@
 
 	fn subresult(&mut self) -> Result<AbiReader<'i>> {
 		let offset = self.read_usize()?;
+		if offset + self.subresult_offset > self.buf.len() {
+			return Err(Error::Error(ExitError::InvalidRange));
+		}
 		Ok(AbiReader {
 			buf: self.buf,
-			offset: offset + self.offset,
+			subresult_offset: offset + self.subresult_offset,
+			offset: offset + self.subresult_offset,
 		})
 	}
 
@@ -163,8 +182,6 @@
 		self.write_padleft(&u128::to_be_bytes(*value))
 	}
 
-	/// This method writes u128, and exists only for convenience, because there is
-	/// no u256 support in rust
 	pub fn uint256(&mut self, value: &U256) {
 		let mut out = [0; 32];
 		value.to_big_endian(&mut out);
@@ -198,7 +215,7 @@
 		for (static_offset, part) in self.dynamic_part {
 			let part_offset = self.static_part.len();
 
-			let encoded_dynamic_offset = usize::to_be_bytes(part_offset - static_offset);
+			let encoded_dynamic_offset = usize::to_be_bytes(part_offset);
 			self.static_part[static_offset + ABI_ALIGNMENT - encoded_dynamic_offset.len()
 				..static_offset + ABI_ALIGNMENT]
 				.copy_from_slice(&encoded_dynamic_offset);
@@ -228,6 +245,7 @@
 impl_abi_readable!(H160, address);
 impl_abi_readable!(Vec<u8>, bytes);
 impl_abi_readable!(bool, bool);
+impl_abi_readable!(string, string);
 
 pub trait AbiWrite {
 	fn abi_write(&self, writer: &mut AbiWriter);
@@ -259,29 +277,7 @@
 impl AbiWrite for () {
 	fn abi_write(&self, _writer: &mut AbiWriter) {}
 }
-
-/// Error, which can be constructed from any ToString type
-/// Encoded to Abi as Error(string)
-#[derive(Debug)]
-pub struct StringError(String);
 
-impl<E> From<E> for StringError
-where
-	E: ToString,
-{
-	fn from(e: E) -> Self {
-		Self(e.to_string())
-	}
-}
-
-impl From<StringError> for AbiWriter {
-	fn from(v: StringError) -> Self {
-		let mut out = AbiWriter::new_call(crate::fn_selector!(Error(string)));
-		out.string(&v.0);
-		out
-	}
-}
-
 #[macro_export]
 macro_rules! abi_decode {
 	($reader:expr, $($name:ident: $typ:ident),+ $(,)?) => {
@@ -309,3 +305,54 @@
 		writer
 	}}
 }
+
+#[cfg(test)]
+pub mod test {
+	use super::{AbiReader, AbiWriter};
+	use hex_literal::hex;
+
+	#[test]
+	fn dynamic_after_static() {
+		let mut encoder = AbiWriter::new();
+		encoder.bool(&true);
+		encoder.string("test");
+		let encoded = encoder.finish();
+
+		let mut encoder = AbiWriter::new();
+		encoder.bool(&true);
+		// Offset to subresult
+		encoder.uint32(&(32 * 2));
+		// Len of "test"
+		encoder.uint32(&4);
+		encoder.write_padright(&[b't', b'e', b's', b't']);
+		let alternative_encoded = encoder.finish();
+
+		assert_eq!(encoded, alternative_encoded);
+
+		let mut decoder = AbiReader::new(&encoded);
+		assert_eq!(decoder.bool().unwrap(), true);
+		assert_eq!(decoder.string().unwrap(), "test");
+	}
+
+	#[test]
+	fn mint_sample() {
+		let (call, mut decoder) = AbiReader::new_call(&hex!(
+			"
+				50bb4e7f
+				000000000000000000000000ad2c0954693c2b5404b7e50967d3481bea432374
+				0000000000000000000000000000000000000000000000000000000000000001
+				0000000000000000000000000000000000000000000000000000000000000060
+				0000000000000000000000000000000000000000000000000000000000000008
+				5465737420555249000000000000000000000000000000000000000000000000
+			"
+		))
+		.unwrap();
+		assert_eq!(call, 0x50bb4e7f);
+		assert_eq!(
+			format!("{:?}", decoder.address().unwrap()),
+			"0xad2c0954693c2b5404b7e50967d3481bea432374"
+		);
+		assert_eq!(decoder.uint32().unwrap(), 1);
+		assert_eq!(decoder.string().unwrap(), "Test URI");
+	}
+}
addedcrates/evm-coder/src/execution.rsdiffbeforeafterboth
--- /dev/null
+++ b/crates/evm-coder/src/execution.rs
@@ -0,0 +1,23 @@
+#[cfg(not(feature = "std"))]
+use alloc::string::{String, ToString};
+use evm_core::{ExitError, ExitFatal};
+#[cfg(feature = "std")]
+use std::string::{String, ToString};
+
+#[derive(Debug)]
+pub enum Error {
+	Revert(String),
+	Fatal(ExitFatal),
+	Error(ExitError),
+}
+
+impl<E> From<E> for Error
+where
+	E: ToString,
+{
+	fn from(e: E) -> Self {
+		Self::Revert(e.to_string())
+	}
+}
+
+pub type Result<T> = core::result::Result<T, Error>;
modifiedcrates/evm-coder/src/lib.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/lib.rs
+++ b/crates/evm-coder/src/lib.rs
@@ -2,10 +2,13 @@
 #[cfg(not(feature = "std"))]
 extern crate alloc;
 
+use abi::{AbiReader, AbiWriter};
 pub use evm_coder_macros::{event_topic, fn_selector, solidity_interface, solidity, ToLog};
 pub mod abi;
 pub mod events;
 pub use events::ToLog;
+pub mod execution;
+pub mod solidity;
 
 /// Solidity type definitions
 pub mod types {
@@ -50,6 +53,37 @@
 	}
 }
 
+pub trait Call: Sized {
+	fn parse(selector: u32, input: &mut AbiReader) -> execution::Result<Option<Self>>;
+}
+
+pub trait Callable<C: Call> {
+	fn call(&mut self, call: types::Msg<C>) -> execution::Result<AbiWriter>;
+}
+
+#[macro_export]
+macro_rules! generate_stubgen {
+	($name:ident, $decl:ident, $is_impl:literal) => {
+		#[test]
+		#[ignore]
+		fn $name() {
+			use sp_std::collections::btree_set::BTreeSet;
+			let mut out = BTreeSet::new();
+			$decl::generate_solidity_interface(&mut out, $is_impl);
+			println!("=== SNIP START ===");
+			println!("// SPDX-License-Identifier: OTHER");
+			println!("// This code is automatically generated");
+			println!();
+			println!("pragma solidity >=0.8.0 <0.9.0;");
+			println!();
+			for b in out {
+				println!("{}", b);
+			}
+			println!("=== SNIP END ===");
+		}
+	};
+}
+
 #[cfg(test)]
 mod tests {
 	use super::*;
addedcrates/evm-coder/src/solidity.rsdiffbeforeafterboth
--- /dev/null
+++ b/crates/evm-coder/src/solidity.rs
@@ -0,0 +1,333 @@
+#[cfg(not(feature = "std"))]
+use alloc::{string::String};
+use core::{fmt, marker::PhantomData};
+use impl_trait_for_tuples::impl_for_tuples;
+use crate::types::*;
+
+pub trait SolidityTypeName: 'static {
+	fn solidity_name(writer: &mut impl fmt::Write) -> fmt::Result;
+	fn solidity_default(writer: &mut impl fmt::Write) -> fmt::Result;
+	fn is_void() -> bool {
+		false
+	}
+}
+
+macro_rules! solidity_type_name {
+    ($($ty:ident => $name:literal = $default:literal),* $(,)?) => {
+        $(
+            impl SolidityTypeName for $ty {
+                fn solidity_name(writer: &mut impl core::fmt::Write) -> core::fmt::Result {
+                    write!(writer, $name)
+                }
+				fn solidity_default(writer: &mut impl core::fmt::Write) -> core::fmt::Result {
+					write!(writer, $default)
+				}
+            }
+        )*
+    };
+}
+
+solidity_type_name! {
+	uint8 => "uint8" = "0",
+	uint32 => "uint32" = "0",
+	uint128 => "uint128" = "0",
+	uint256 => "uint256" = "0",
+	address => "address" = "0x0000000000000000000000000000000000000000",
+	string => "string memory" = "\"\"",
+	bytes => "bytes memory" = "hex\"\"",
+	bool => "bool" = "false",
+}
+impl SolidityTypeName for void {
+	fn solidity_name(_writer: &mut impl fmt::Write) -> fmt::Result {
+		Ok(())
+	}
+	fn solidity_default(_writer: &mut impl fmt::Write) -> fmt::Result {
+		Ok(())
+	}
+	fn is_void() -> bool {
+		true
+	}
+}
+
+pub trait SolidityArguments {
+	fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result;
+	fn solidity_get(&self, writer: &mut impl fmt::Write) -> fmt::Result;
+	fn solidity_default(&self, writer: &mut impl fmt::Write) -> fmt::Result;
+	fn is_empty(&self) -> bool {
+		self.len() == 0
+	}
+	fn len(&self) -> usize;
+}
+
+#[derive(Default)]
+pub struct UnnamedArgument<T>(PhantomData<*const T>);
+
+impl<T: SolidityTypeName> SolidityArguments for UnnamedArgument<T> {
+	fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {
+		if !T::is_void() {
+			T::solidity_name(writer)
+		} else {
+			Ok(())
+		}
+	}
+	fn solidity_get(&self, _writer: &mut impl fmt::Write) -> fmt::Result {
+		Ok(())
+	}
+	fn solidity_default(&self, writer: &mut impl fmt::Write) -> fmt::Result {
+		T::solidity_default(writer)
+	}
+	fn len(&self) -> usize {
+		if T::is_void() {
+			0
+		} else {
+			1
+		}
+	}
+}
+
+pub struct NamedArgument<T>(&'static str, PhantomData<*const T>);
+
+impl<T> NamedArgument<T> {
+	pub fn new(name: &'static str) -> Self {
+		Self(name, Default::default())
+	}
+}
+
+impl<T: SolidityTypeName> SolidityArguments for NamedArgument<T> {
+	fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {
+		if !T::is_void() {
+			T::solidity_name(writer)?;
+			write!(writer, " {}", self.0)
+		} else {
+			Ok(())
+		}
+	}
+	fn solidity_get(&self, writer: &mut impl fmt::Write) -> fmt::Result {
+		writeln!(writer, "\t\t{};", self.0)
+	}
+	fn solidity_default(&self, writer: &mut impl fmt::Write) -> fmt::Result {
+		T::solidity_default(writer)
+	}
+	fn len(&self) -> usize {
+		if T::is_void() {
+			0
+		} else {
+			1
+		}
+	}
+}
+
+pub struct SolidityEventArgument<T>(pub bool, &'static str, PhantomData<*const T>);
+
+impl<T> SolidityEventArgument<T> {
+	pub fn new(indexed: bool, name: &'static str) -> Self {
+		Self(indexed, name, Default::default())
+	}
+}
+
+impl<T: SolidityTypeName> SolidityArguments for SolidityEventArgument<T> {
+	fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {
+		if !T::is_void() {
+			T::solidity_name(writer)?;
+			if self.0 {
+				write!(writer, " indexed")?;
+			}
+			write!(writer, " {}", self.1)
+		} else {
+			Ok(())
+		}
+	}
+	fn solidity_get(&self, writer: &mut impl fmt::Write) -> fmt::Result {
+		writeln!(writer, "\t\t{};", self.1)
+	}
+	fn solidity_default(&self, writer: &mut impl fmt::Write) -> fmt::Result {
+		T::solidity_default(writer)
+	}
+	fn len(&self) -> usize {
+		if T::is_void() {
+			0
+		} else {
+			1
+		}
+	}
+}
+
+impl SolidityArguments for () {
+	fn solidity_name(&self, _writer: &mut impl fmt::Write) -> fmt::Result {
+		Ok(())
+	}
+	fn solidity_get(&self, _writer: &mut impl fmt::Write) -> fmt::Result {
+		Ok(())
+	}
+	fn solidity_default(&self, _writer: &mut impl fmt::Write) -> fmt::Result {
+		Ok(())
+	}
+	fn len(&self) -> usize {
+		0
+	}
+}
+
+#[impl_for_tuples(1, 5)]
+impl SolidityArguments for Tuple {
+	for_tuples!( where #( Tuple: SolidityArguments ),* );
+
+	fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {
+		let mut first = true;
+		for_tuples!( #(
+            if !Tuple.is_empty() {
+                if !first {
+                    write!(writer, ", ")?;
+                }
+                first = false;
+                Tuple.solidity_name(writer)?;
+            }
+        )* );
+		Ok(())
+	}
+	fn solidity_get(&self, writer: &mut impl fmt::Write) -> fmt::Result {
+		for_tuples!( #(
+            Tuple.solidity_get(writer)?;
+        )* );
+		Ok(())
+	}
+	fn solidity_default(&self, writer: &mut impl fmt::Write) -> fmt::Result {
+		if self.is_empty() {
+			Ok(())
+		} else if self.len() == 1 {
+			for_tuples!( #(
+				Tuple.solidity_default(writer)?;
+			)* );
+			Ok(())
+		} else {
+			write!(writer, "(")?;
+			let mut first = true;
+			for_tuples!( #(
+				if !Tuple.is_empty() {
+					if !first {
+						write!(writer, ", ")?;
+					}
+					first = false;
+					Tuple.solidity_name(writer)?;
+				}
+			)* );
+			write!(writer, ")")?;
+			Ok(())
+		}
+	}
+	fn len(&self) -> usize {
+		for_tuples!( #( Tuple.len() )+* )
+	}
+}
+
+pub trait SolidityFunctions {
+	fn solidity_name(&self, is_impl: bool, writer: &mut impl fmt::Write) -> fmt::Result;
+}
+
+pub enum SolidityMutability {
+	Pure,
+	View,
+	Mutable,
+}
+pub struct SolidityFunction<A, R> {
+	pub name: &'static str,
+	pub args: A,
+	pub result: R,
+	pub mutability: SolidityMutability,
+}
+impl<A: SolidityArguments, R: SolidityArguments> SolidityFunctions for SolidityFunction<A, R> {
+	fn solidity_name(&self, is_impl: bool, writer: &mut impl fmt::Write) -> fmt::Result {
+		write!(writer, "\tfunction {}(", self.name)?;
+		self.args.solidity_name(writer)?;
+		write!(writer, ")")?;
+		if is_impl {
+			write!(writer, " public")?;
+		} else {
+			write!(writer, " external")?;
+		}
+		match &self.mutability {
+			SolidityMutability::Pure => write!(writer, " pure")?,
+			SolidityMutability::View => write!(writer, " view")?,
+			SolidityMutability::Mutable => {}
+		}
+		if !self.result.is_empty() {
+			write!(writer, " returns (")?;
+			self.result.solidity_name(writer)?;
+			write!(writer, ")")?;
+		}
+		if is_impl {
+			writeln!(writer, " {{")?;
+			writeln!(writer, "\t\trequire(false, stub_error);")?;
+			self.args.solidity_get(writer)?;
+			match &self.mutability {
+				SolidityMutability::Pure => {}
+				SolidityMutability::View => writeln!(writer, "\t\tdummy;")?,
+				SolidityMutability::Mutable => writeln!(writer, "\t\tdummy = 0;")?,
+			}
+			if !self.result.is_empty() {
+				write!(writer, "\t\treturn ")?;
+				self.result.solidity_default(writer)?;
+				writeln!(writer, ";")?;
+			}
+			writeln!(writer, "\t}}")?;
+		} else {
+			writeln!(writer, ";")?;
+		}
+		Ok(())
+	}
+}
+
+#[impl_for_tuples(0, 12)]
+impl SolidityFunctions for Tuple {
+	for_tuples!( where #( Tuple: SolidityFunctions ),* );
+
+	fn solidity_name(&self, is_impl: bool, writer: &mut impl fmt::Write) -> fmt::Result {
+		let mut first = false;
+		for_tuples!( #(
+            Tuple.solidity_name(is_impl, writer)?;
+        )* );
+		Ok(())
+	}
+}
+
+pub struct SolidityInterface<F: SolidityFunctions> {
+	pub name: &'static str,
+	pub is: &'static [&'static str],
+	pub functions: F,
+}
+
+impl<F: SolidityFunctions> SolidityInterface<F> {
+	pub fn format(&self, is_impl: bool, out: &mut impl fmt::Write) -> fmt::Result {
+		if is_impl {
+			write!(out, "contract ")?;
+		} else {
+			write!(out, "interface ")?;
+		}
+		write!(out, "{}", self.name)?;
+		if !self.is.is_empty() {
+			write!(out, " is")?;
+			for (i, n) in self.is.iter().enumerate() {
+				if i != 0 {
+					write!(out, ",")?;
+				}
+				write!(out, " {}", n)?;
+			}
+		}
+		writeln!(out, " {{")?;
+		self.functions.solidity_name(is_impl, out)?;
+		writeln!(out, "}}")?;
+		Ok(())
+	}
+}
+
+pub struct SolidityEvent<A> {
+	pub name: &'static str,
+	pub args: A,
+}
+
+impl<A: SolidityArguments> SolidityFunctions for SolidityEvent<A> {
+	fn solidity_name(&self, _is_impl: bool, writer: &mut impl fmt::Write) -> fmt::Result {
+		write!(writer, "\tevent {}(", self.name)?;
+		self.args.solidity_name(writer)?;
+		writeln!(writer, ");")
+	}
+}
modifiedcrates/evm-coder/tests/a.rsdiffbeforeafterboth
--- a/crates/evm-coder/tests/a.rs
+++ b/crates/evm-coder/tests/a.rs
@@ -1,29 +1,46 @@
 #![allow(dead_code)] // This test only checks that macros is not panicking
 
-use evm_coder::{solidity_interface, types::*, ToLog};
+use evm_coder::{solidity_interface, types::*, ToLog, execution::Result};
 use evm_coder_macros::solidity;
+use std as sp_std;
 
-#[solidity_interface]
-trait OurInterface {
-	type Error;
-	fn fn_a(&self, input: uint256) -> Result<bool, Self::Error>;
+struct Impls;
+
+#[solidity_interface(name = "OurInterface")]
+impl Impls {
+	fn fn_a(&self, _input: uint256) -> Result<bool> {
+		todo!()
+	}
 }
 
-#[solidity_interface]
-trait OurInterface1 {
-	type Error;
-	fn fn_b(&self, input: uint128) -> Result<uint32, Self::Error>;
+#[solidity_interface(name = "OurInterface1")]
+impl Impls {
+	fn fn_b(&self, _input: uint128) -> Result<uint32> {
+		todo!()
+	}
 }
 
-#[solidity_interface(is(OurInterface), inline_is(OurInterface1), events(ERC721Log))]
-trait OurInterface2 {
-	type Error;
+#[solidity_interface(
+	name = "OurInterface2",
+	is(OurInterface),
+	inline_is(OurInterface1),
+	events(ERC721Log)
+)]
+impl Impls {
 	#[solidity(rename_selector = "fnK")]
-	fn fn_c(&self, input: uint32) -> Result<uint8, Self::Error>;
-	fn fn_d(&self, value: uint32) -> Result<uint32, Self::Error>;
+	fn fn_c(&self, _input: uint32) -> Result<uint8> {
+		todo!()
+	}
+	fn fn_d(&self, _value: uint32) -> Result<uint32> {
+		todo!()
+	}
 
-	fn caller_sensitive(&self, caller: caller) -> Result<uint8, Self::Error>;
-	fn payable(&mut self, value: value) -> Result<uint8, Self::Error>;
+	fn caller_sensitive(&self, _caller: caller) -> Result<uint8> {
+		todo!()
+	}
+	fn payable(&mut self, _value: value) -> Result<uint8> {
+		todo!()
+	}
 }
 
 #[derive(ToLog)]
@@ -42,30 +59,32 @@
 	},
 }
 
-#[solidity_interface]
-trait ERC20 {
-	type Error;
+struct ERC20;
 
-	fn decimals(&self) -> Result<uint8, Self::Error>;
-	fn balance_of(&self, owner: address) -> Result<uint256, Self::Error>;
-	fn transfer(
-		&mut self,
-		caller: caller,
-		to: address,
-		value: uint256,
-	) -> Result<bool, Self::Error>;
+#[solidity_interface(name = "ERC20")]
+impl ERC20 {
+	fn decimals(&self) -> Result<uint8> {
+		todo!()
+	}
+	fn balance_of(&self, _owner: address) -> Result<uint256> {
+		todo!()
+	}
+	fn transfer(&mut self, _caller: caller, _to: address, _value: uint256) -> Result<bool> {
+		todo!()
+	}
 	fn transfer_from(
 		&mut self,
-		caller: caller,
-		from: address,
-		to: address,
-		value: uint256,
-	) -> Result<bool, Self::Error>;
-	fn approve(
-		&mut self,
-		caller: caller,
-		spender: address,
-		value: uint256,
-	) -> Result<bool, Self::Error>;
-	fn allowance(&self, owner: address, spender: address) -> Result<uint256, Self::Error>;
+		_caller: caller,
+		_from: address,
+		_to: address,
+		_value: uint256,
+	) -> Result<bool> {
+		todo!()
+	}
+	fn approve(&mut self, _caller: caller, _spender: address, _value: uint256) -> Result<bool> {
+		todo!()
+	}
+	fn allowance(&self, _owner: address, _spender: address) -> Result<uint256> {
+		todo!()
+	}
 }
modifiedlaunch-config.jsondiffbeforeafterboth
--- a/launch-config.json
+++ b/launch-config.json
@@ -1,71 +1,89 @@
 {
     "relaychain": {
-            "bin": "../polkadot/target/release/polkadot",
-            "chain": "rococo-local",
-            "nodes": [
-                    {
-                            "name": "alice",
-                            "wsPort": 9844,
-                            "rpcPort": 9843,
-                            "port": 30444
-                    },
-                    {
-                            "name": "bob",
-                            "wsPort": 9855,
-                            "rpcPort": 9854,
-                            "port": 30555
-                    },
-                    {
-                            "name": "charlie",
-                            "wsPort": 9866,
-                            "rpcPort": 9865,
-                            "port": 30666
-                    },
-                    {
-                            "name": "dave",
-                            "wsPort": 9877,
-                            "rpcPort": 9876,
-                            "port": 30777
+        "bin": "../polkadot/target/release/polkadot",
+        "chain": "rococo-local",
+        "nodes": [
+            {
+                "name": "alice",
+                "wsPort": 9844,
+                "rpcPort": 9843,
+                "port": 30444,
+                "flags": [
+                    "--rpc-port=9843"
+                ]
+            },
+            {
+                "name": "bob",
+                "wsPort": 9855,
+                "rpcPort": 9854,
+                "port": 30555,
+                "flags": [
+                    "--rpc-port=9854"
+                ]
+            },
+            {
+                "name": "charlie",
+                "wsPort": 9866,
+                "rpcPort": 9865,
+                "port": 30666,
+                "flags": [
+                    "--rpc-port=9865"
+                ]
+            },
+            {
+                "name": "dave",
+                "wsPort": 9877,
+                "rpcPort": 9876,
+                "port": 30777,
+                "flags": [
+                    "--rpc-port=9876"
+                ]
+            }
+        ],
+        "genesis": {
+            "runtime": {
+                "runtime_genesis_config": {
+                    "parachainsConfiguration": {
+                        "config": {
+                            "validation_upgrade_frequency": 1,
+                            "validation_upgrade_delay": 1
+                        }
                     }
-            ],
-            "genesis": {
-                    "runtime": {
-                            "runtime_genesis_config": {
-                                    "parachainsConfiguration": {
-                                            "config": {
-                                                    "validation_upgrade_frequency": 1,
-                                                    "validation_upgrade_delay": 1
-                                            }
-                                    }
-                            }
-                    }
+                }
             }
+        }
     },
     "parachains": [
-            {
-                    "bin": "../nft_private/target/release/nft",
-                    "id": "2000",
-                    "balance": "1000000000000000000000",
-                    "nodes": [
-                            {
-                                    "port": 31200,
-                                    "wsPort": 9944,
-                                    "rpcPort": 9933,
-                                    "name": "alice",
-                                    "flags": []
-                            },
-                            {
-                                    "port": 31201,
-                                    "wsPort": 9945,
-                                    "rpcPort": 9934,
-                                    "name": "bob",
-                                    "flags": []
-                            }
+        {
+            "bin": "../nft_private/target/release/nft",
+            "id": "2000",
+            "balance": "1000000000000000000000",
+            "nodes": [
+                {
+                    "port": 31200,
+                    "wsPort": 9944,
+                    "rpcPort": 9933,
+                    "name": "alice",
+                    "flags": [
+                        "--rpc-cors=all",
+                        "--rpc-port=9933"
+                    ]
+                },
+                {
+                    "port": 31201,
+                    "wsPort": 9945,
+                    "rpcPort": 9934,
+                    "name": "bob",
+                    "flags": [
+                        "--rpc-cors=all",
+                        "--rpc-port=9934"
                     ]
-            }
+                }
+            ]
+        }
     ],
     "simpleParachains": [],
     "hrmpChannels": [],
     "types": "./runtime_types.json",
     "finalization": false
-}
+}
\ No newline at end of file
modifiednode/cli/Cargo.tomldiffbeforeafterboth
--- a/node/cli/Cargo.toml
+++ b/node/cli/Cargo.toml
@@ -3,7 +3,7 @@
 
 [build-dependencies.substrate-build-script-utils]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 ################################################################################
@@ -17,185 +17,185 @@
 
 [dependencies.frame-benchmarking]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.frame-benchmarking-cli]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.pallet-transaction-payment-rpc]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.substrate-prometheus-endpoint]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '0.9.0'
 
 [dependencies.sc-basic-authorship]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '0.9.0'
 
 [dependencies.sc-chain-spec]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sc-cli]
 features = ['wasmtime']
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '0.9.0'
 
 [dependencies.sc-client-api]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sc-consensus]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '0.9.0'
 
 [dependencies.sc-consensus-aura]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '0.9.0'
 
 [dependencies.sc-executor]
 features = ['wasmtime']
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '0.9.0'
 
 [dependencies.sc-finality-grandpa]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '0.9.0'
 
 [dependencies.sc-keystore]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sc-rpc]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sc-rpc-api]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '0.9.0'
 
 [dependencies.sc-service]
 features = ['wasmtime']
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '0.9.0'
 
 [dependencies.sc-telemetry]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sc-transaction-pool]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sc-tracing]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-block-builder]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-api]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-blockchain]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-consensus]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '0.9.0'
 
 [dependencies.sp-consensus-aura]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '0.9.0'
 
 [dependencies.sp-core]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-finality-grandpa]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-inherents]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-keystore]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '0.9.0'
 
 [dependencies.sp-offchain]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-runtime]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-session]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-timestamp]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-transaction-pool]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-trie]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.substrate-frame-rpc-system]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sc-network]
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '0.9.0'
 
 [dependencies.serde]
@@ -211,58 +211,58 @@
 
 [dependencies.cumulus-client-consensus-aura]
 git = 'https://github.com/paritytech/cumulus.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 
 [dependencies.cumulus-client-consensus-common]
 git = 'https://github.com/paritytech/cumulus.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 
 [dependencies.cumulus-client-collator]
 git = 'https://github.com/paritytech/cumulus.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 
 [dependencies.cumulus-client-cli]
 git = 'https://github.com/paritytech/cumulus.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 
 [dependencies.cumulus-client-network]
 git = 'https://github.com/paritytech/cumulus.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 
 [dependencies.cumulus-primitives-core]
 git = 'https://github.com/paritytech/cumulus.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 
 [dependencies.cumulus-primitives-parachain-inherent]
 git = 'https://github.com/paritytech/cumulus.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 
 [dependencies.cumulus-client-service]
 git = 'https://github.com/paritytech/cumulus.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 
 
 ################################################################################
 # Polkadot dependencies
 [dependencies.polkadot-primitives]
 git = "https://github.com/paritytech/polkadot"
-branch = 'release-v0.9.7'
+branch = 'release-v0.9.8'
 
 [dependencies.polkadot-service]
 git = "https://github.com/paritytech/polkadot"
-branch = 'release-v0.9.7'
+branch = 'release-v0.9.8'
 
 [dependencies.polkadot-cli]
 git = "https://github.com/paritytech/polkadot"
-branch = 'release-v0.9.7'
+branch = 'release-v0.9.8'
 
 [dependencies.polkadot-test-service]
 git = "https://github.com/paritytech/polkadot"
-branch = 'release-v0.9.7'
+branch = 'release-v0.9.8'
 
 [dependencies.polkadot-parachain]
 git = "https://github.com/paritytech/polkadot"
-branch = 'release-v0.9.7'
+branch = 'release-v0.9.8'
 
 
 ################################################################################
@@ -273,7 +273,7 @@
 version = '3.0.0'
 
 [dependencies.nft-data-structs]
-path="../../primitives/nft"
+path = "../../primitives/nft"
 default-features = false
 
 ################################################################################
@@ -305,16 +305,19 @@
 jsonrpc-core = '15.0.0'
 jsonrpc-pubsub = "15.0.0"
 
-fc-rpc-core = { version = "1.1.0-dev", git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
-fc-consensus = { version = "2.0.0-dev", git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
-fc-mapping-sync = { version = "2.0.0-dev", git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
-fc-rpc = { version = "2.0.0-dev", git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
-fc-db = { version = "1.0.0", git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
-fp-rpc = { version = "2.0.0", git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
-pallet-ethereum = { version = "3.0.0-dev", git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
+fc-rpc-core = { version = "1.1.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+fc-consensus = { version = "2.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+fc-mapping-sync = { version = "2.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+fc-rpc = { version = "2.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+fc-db = { version = "1.0.0", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+fp-rpc = { version = "2.0.0", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+pallet-ethereum = { version = "3.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
 
 nft-rpc = { path = "../rpc" }
 
 [features]
 default = []
-runtime-benchmarks = ['nft-runtime/runtime-benchmarks']
+runtime-benchmarks = [
+    'nft-runtime/runtime-benchmarks',
+    'polkadot-service/runtime-benchmarks',
+]
modifiednode/cli/src/chain_spec.rsdiffbeforeafterboth
--- a/node/cli/src/chain_spec.rs
+++ b/node/cli/src/chain_spec.rs
@@ -197,23 +197,12 @@
 					variable_on_chain_schema: vec![],
 					limits: CollectionLimits::default(),
 					meta_update_permission: MetaUpdatePermission::ItemOwner,
+					transfers_enabled: true,
 				},
 			)],
 			nft_item_id: vec![],
 			fungible_item_id: vec![],
 			refungible_item_id: vec![],
-			chain_limit: ChainLimits {
-				collection_numbers_limit: 100000,
-				account_token_ownership_limit: 1000000,
-				collections_admins_limit: 5,
-				custom_data_limit: 2048,
-				nft_sponsor_transfer_timeout: 15,
-				fungible_sponsor_transfer_timeout: 15,
-				refungible_sponsor_transfer_timeout: 15,
-				offchain_schema_limit: 1024,
-				variable_on_chain_schema_limit: 1024,
-				const_on_chain_schema_limit: 1024,
-			},
 		},
 		parachain_info: nft_runtime::ParachainInfoConfig { parachain_id: id },
 		aura: nft_runtime::AuraConfig {
modifiednode/cli/src/service.rsdiffbeforeafterboth
--- a/node/cli/src/service.rs
+++ b/node/cli/src/service.rs
@@ -10,6 +10,8 @@
 use std::sync::Mutex;
 use std::collections::BTreeMap;
 use std::collections::HashMap;
+use std::time::Duration;
+use futures::StreamExt;
 
 // Local Runtime Types
 use nft_runtime::RuntimeApi;
@@ -34,10 +36,12 @@
 use sp_keystore::SyncCryptoStorePtr;
 use sp_runtime::traits::BlakeTwo256;
 use substrate_prometheus_endpoint::Registry;
+use sc_client_api::BlockchainEvents;
 
 // Frontier Imports
 use fc_rpc_core::types::FilterPool;
 use fc_rpc_core::types::PendingTransactions;
+use fc_mapping_sync::MappingSyncWorker;
 
 // Runtime type overrides
 type BlockNumber = u32;
@@ -279,9 +283,11 @@
 	let select_chain = params.select_chain.clone();
 	let is_authority = parachain_config.role.clone().is_authority();
 	let rpc_network = network.clone();
+
+	let rpc_frontier_backend = frontier_backend.clone();
 	let rpc_extensions_builder = Box::new(move |deny_unsafe, _| {
 		let full_deps = nft_rpc::FullDeps {
-			backend: frontier_backend.clone(),
+			backend: rpc_frontier_backend.clone(),
 			deny_unsafe,
 			client: rpc_client.clone(),
 			pool: rpc_pool.clone(),
@@ -299,6 +305,18 @@
 		nft_rpc::create_full::<_, _, _, RuntimeApi, _>(full_deps, subscription_executor.clone())
 	});
 
+	task_manager.spawn_essential_handle().spawn(
+		"frontier-mapping-sync-worker",
+		MappingSyncWorker::new(
+			client.import_notification_stream(),
+			Duration::new(6, 0),
+			client.clone(),
+			backend.clone(),
+			frontier_backend.clone(),
+		)
+		.for_each(|()| futures::future::ready(())),
+	);
+
 	sc_service::spawn_tasks(sc_service::SpawnTasksParams {
 		on_demand: None,
 		remote_blockchain: None,
@@ -486,6 +504,7 @@
 				// We got around 500ms for proposing
 				block_proposal_slot_portion: SlotProportion::new(1f32 / 24f32),
 				telemetry,
+				max_block_proposal_slot_portion: None,
 			}))
 		},
 	)
modifiednode/rpc/Cargo.tomldiffbeforeafterboth
--- a/node/rpc/Cargo.toml
+++ b/node/rpc/Cargo.toml
@@ -13,41 +13,41 @@
 futures = { version = "0.3.1", features = ["compat"] }
 jsonrpc-core = "15.0.0"
 jsonrpc-pubsub = "15.0.0"
-# pallet-contracts-rpc = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-pallet-transaction-payment-rpc = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-pallet-transaction-payment-rpc-runtime-api = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sc-client-api = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sc-consensus-aura = { version = "0.9", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sc-consensus-epochs = { version = "0.9", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sc-finality-grandpa = { version = "0.9", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sc-finality-grandpa-rpc = { version = "0.9", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sc-keystore = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sc-network = { version = "0.9", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sc-rpc-api = { version = "0.9", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sc-rpc = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sc-service = { version = "0.9", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-api = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-block-builder = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-blockchain = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-consensus = { version = "0.9", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-consensus-aura = { version = "0.9", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-core = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-offchain = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-runtime = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-storage = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-session = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-transaction-pool = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sc-transaction-pool = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sc-transaction-graph = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-substrate-frame-rpc-system = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
+# pallet-contracts-rpc = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+pallet-transaction-payment-rpc = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+pallet-transaction-payment-rpc-runtime-api = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sc-client-api = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sc-consensus-aura = { version = "0.9", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sc-consensus-epochs = { version = "0.9", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sc-finality-grandpa = { version = "0.9", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sc-finality-grandpa-rpc = { version = "0.9", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sc-keystore = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sc-network = { version = "0.9", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sc-rpc-api = { version = "0.9", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sc-rpc = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sc-service = { version = "0.9", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-api = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-block-builder = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-blockchain = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-consensus = { version = "0.9", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-consensus-aura = { version = "0.9", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-core = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-offchain = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-runtime = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-storage = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-session = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-transaction-pool = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sc-transaction-pool = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sc-transaction-graph = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+substrate-frame-rpc-system = { version = "3.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
 tokio = { version = "0.2.13", features = ["macros", "sync"] }
 
-pallet-ethereum = { git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
-fc-rpc = { default-features = false, git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
-fp-rpc = { default-features = false, git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
-fc-rpc-core = { default-features = false, git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
-fc-db = { default-features = false, git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
-fc-mapping-sync = { default-features = false, git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
+pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+fc-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+fc-rpc-core = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+fc-db = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
 
 pallet-nft = { path = "../../pallets/nft" }
 nft-runtime = { path = "../../runtime" }
modifiedpallets/contract-helpers/Cargo.tomldiffbeforeafterboth
--- a/pallets/contract-helpers/Cargo.toml
+++ b/pallets/contract-helpers/Cargo.toml
@@ -15,11 +15,11 @@
 version = '0.1.0'
 
 [dependencies]
-frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-pallet-contracts = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
+frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+pallet-contracts = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
 
 [features]
 default = ["std"]
@@ -29,4 +29,4 @@
     "pallet-contracts/std",
     "sp-runtime/std",
     "sp-std/std",
-]
\ No newline at end of file
+]
modifiedpallets/contract-helpers/src/lib.rsdiffbeforeafterboth
--- a/pallets/contract-helpers/src/lib.rs
+++ b/pallets/contract-helpers/src/lib.rs
@@ -22,7 +22,9 @@
 	}
 
 	#[pallet::config]
-	pub trait Config: frame_system::Config + pallet_contracts::Config {}
+	pub trait Config: frame_system::Config + pallet_contracts::Config {
+		type DefaultSponsoringRateLimit: Get<Self::BlockNumber>;
+	}
 
 	#[pallet::pallet]
 	#[pallet::generate_store(pub(super) trait Store)]
@@ -60,6 +62,7 @@
 		Key = T::AccountId,
 		Value = T::BlockNumber,
 		QueryKind = ValueQuery,
+		OnEmpty = T::DefaultSponsoringRateLimit,
 	>;
 
 	#[pallet::storage]
@@ -72,6 +75,15 @@
 		QueryKind = ValueQuery,
 	>;
 
+	impl<T: Config> Pallet<T> {
+		pub fn allowed(contract: T::AccountId, user: T::AccountId, default: bool) -> bool {
+			if !<AllowlistEnabled<T>>::get(&contract) {
+				return default;
+			}
+			<Allowlist<T>>::get(&contract, &user) || <Owner<T>>::get(contract) == user
+		}
+	}
+
 	#[pallet::call]
 	impl<T: Config> Pallet<T> {
 		#[pallet::weight(0)]
@@ -191,10 +203,7 @@
 			{
 				let called_contract: T::AccountId =
 					T::Lookup::lookup((*dest).clone()).unwrap_or_default();
-				if <AllowlistEnabled<T>>::get(&called_contract)
-					&& !<Allowlist<T>>::get(&called_contract, who)
-					&& &<Owner<T>>::get(&called_contract) != who
-				{
+				if !<Pallet<T>>::allowed(called_contract, who.clone(), true) {
 					return Err(transaction_validity::InvalidTransaction::Call.into());
 				}
 			}
@@ -251,7 +260,9 @@
 			{
 				let called_contract: T::AccountId =
 					T::Lookup::lookup((*dest).clone()).unwrap_or_default();
-				if <SelfSponsoring<T>>::get(&called_contract) {
+				if <SelfSponsoring<T>>::get(&called_contract)
+					&& <Pallet<T>>::allowed(called_contract.clone(), who.clone(), false)
+				{
 					let last_tx_block = SponsorBasket::<T>::get(&called_contract, &who);
 					let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
 					let rate_limit = SponsoringRateLimit::<T>::get(&called_contract);
addedpallets/evm-coder-substrate/Cargo.tomldiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-coder-substrate/Cargo.toml
@@ -0,0 +1,33 @@
+[package]
+name = "pallet-evm-coder-substrate"
+version = "0.1.0"
+edition = "2018"
+
+[dependencies]
+sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-core = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+ethereum = { default-features = false, version = "0.7.1" }
+evm-coder = { default-features = false, path = "../../crates/evm-coder" }
+pallet-ethereum = { default-features = false, version = "3.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+pallet-evm = { default-features = false, version = "5.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+
+[dependencies.codec]
+default-features = false
+features = ['derive']
+package = 'parity-scale-codec'
+version = '2.0.0'
+
+[features]
+default = ["std"]
+std = [
+    "sp-std/std",
+    "sp-core/std",
+    "ethereum/std",
+    "evm-coder/std",
+    "pallet-ethereum/std",
+    "pallet-evm/std",
+    "frame-support/std",
+    "frame-system/std",
+]
addedpallets/evm-coder-substrate/src/lib.rsdiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-coder-substrate/src/lib.rs
@@ -0,0 +1,227 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+
+#[cfg(not(feature = "std"))]
+extern crate alloc;
+
+pub use pallet::*;
+
+#[frame_support::pallet]
+pub mod pallet {
+	#[cfg(not(feature = "std"))]
+	use alloc::format;
+
+	use evm_coder::{
+		ToLog,
+		abi::{AbiReader, AbiWrite, AbiWriter},
+		execution::{self, Result},
+		types::{Msg, value},
+	};
+	use frame_support::ensure;
+	use pallet_evm::{ExitError, ExitReason, ExitRevert, ExitSucceed, PrecompileOutput};
+	pub use frame_support::dispatch::DispatchResult;
+	use pallet_ethereum::EthereumTransactionSender;
+	use sp_std::cell::RefCell;
+	use sp_std::vec::Vec;
+	use sp_core::{H160, H256};
+	use ethereum::Log;
+	use frame_support::{pallet_prelude::*, traits::PalletInfo};
+
+	/// DispatchError is opaque, but we need to somehow extract correct error in case of OutOfGas failure
+	/// So we have this pallet, which defines OutOfGas error, and knews its own id to check if DispatchError
+	/// is thrown because of it
+	///
+	/// These errors shouldn't end in extrinsic results, as they only used in evm execution path
+	#[pallet::error]
+	pub enum Error<T> {
+		OutOfGas,
+		OutOfFund,
+	}
+
+	#[pallet::config]
+	pub trait Config: frame_system::Config {
+		type EthereumTransactionSender: pallet_ethereum::EthereumTransactionSender;
+	}
+
+	#[pallet::pallet]
+	pub struct Pallet<T>(_);
+
+	// FIXME: those items are defined as private in evm_gasometer::consts, and we can't directly use it
+	pub const G_LOG: u64 = 375;
+	pub const G_LOGDATA: u64 = 8;
+	pub const G_LOGTOPIC: u64 = 375;
+
+	// From instabul hardfork configuration: https://github.com/rust-blockchain/evm/blob/fd4fd6acc0ca3208d6770fdb3ba407c94cdf97c6/runtime/src/lib.rs#L284
+	pub const G_SLOAD_WORD: u64 = 800;
+	pub const G_SSTORE_WORD: u64 = 20000;
+
+	fn log_price(data: usize, topics: usize) -> u64 {
+		G_LOG
+			.saturating_add((data as u64).saturating_mul(G_LOGDATA))
+			.saturating_add((topics as u64).saturating_mul(G_LOGTOPIC))
+	}
+
+	pub fn generate_transaction() -> ethereum::Transaction {
+		use ethereum::{Transaction, TransactionAction, TransactionSignature};
+		Transaction {
+			nonce: 0.into(),
+			gas_price: 0.into(),
+			gas_limit: 0.into(),
+			action: TransactionAction::Call(H160([0; 20])),
+			value: 0.into(),
+			// zero selector, this transaction always has same sender, so all data should be acquired from logs
+			input: Vec::from([0, 0, 0, 0]),
+			// if v is not 27 - then we need to pass some other validity checks
+			signature: TransactionSignature::new(27, H256([0x88; 32]), H256([0x88; 32])).unwrap(),
+		}
+	}
+
+	#[derive(Default)]
+	pub struct SubstrateRecorder<T: Config> {
+		contract: H160,
+		logs: RefCell<Vec<Log>>,
+		initial_gas: u64,
+		gas_limit: RefCell<u64>,
+		_phantom: PhantomData<*const T>,
+	}
+
+	impl<T: Config> SubstrateRecorder<T> {
+		pub fn new(contract: H160, gas_limit: u64) -> Self {
+			Self {
+				contract,
+				logs: RefCell::new(Vec::new()),
+				initial_gas: gas_limit,
+				gas_limit: RefCell::new(gas_limit),
+				_phantom: PhantomData,
+			}
+		}
+
+		pub fn is_empty(&self) -> bool {
+			self.logs.borrow().is_empty()
+		}
+		pub fn log_sub(&self, log: impl ToLog) -> DispatchResult {
+			self.log_raw_sub(log.to_log(self.contract))
+		}
+		pub fn log_raw_sub(&self, log: Log) -> DispatchResult {
+			self.consume_gas_sub(log_price(log.data.len(), log.topics.len()))?;
+			self.logs.borrow_mut().push(log);
+			Ok(())
+		}
+		pub fn retrieve_logs(self) -> Vec<Log> {
+			self.logs.into_inner()
+		}
+
+		pub fn gas_left(&self) -> u64 {
+			*self.gas_limit.borrow()
+		}
+		pub fn consume_sload_sub(&self) -> DispatchResult {
+			self.consume_gas_sub(G_SLOAD_WORD)
+		}
+		pub fn consume_sstore_sub(&self) -> DispatchResult {
+			self.consume_gas_sub(G_SSTORE_WORD)
+		}
+		pub fn consume_gas_sub(&self, gas: u64) -> DispatchResult {
+			ensure!(gas != u64::MAX, Error::<T>::OutOfGas);
+			let mut gas_limit = self.gas_limit.borrow_mut();
+			ensure!(gas <= *gas_limit, Error::<T>::OutOfGas);
+			*gas_limit -= gas;
+			Ok(())
+		}
+
+		pub fn consume_sload(&self) -> Result<()> {
+			self.consume_gas(G_SLOAD_WORD)
+		}
+		pub fn consume_sstore(&self) -> Result<()> {
+			self.consume_gas(G_SSTORE_WORD)
+		}
+		pub fn consume_gas(&self, gas: u64) -> Result<()> {
+			if gas == u64::MAX {
+				return Err(execution::Error::Error(ExitError::OutOfGas));
+			}
+			let mut gas_limit = self.gas_limit.borrow_mut();
+			if gas > *gas_limit {
+				return Err(execution::Error::Error(ExitError::OutOfGas));
+			}
+			*gas_limit -= gas;
+			Ok(())
+		}
+
+		pub fn evm_to_precompile_output(
+			self,
+			result: evm_coder::execution::Result<Option<AbiWriter>>,
+		) -> Option<PrecompileOutput> {
+			use evm_coder::execution::Error;
+			let (writer, reason) = match result {
+				Ok(Some(v)) => (v, ExitReason::Succeed(ExitSucceed::Returned)),
+				Ok(None) => return None,
+				Err(Error::Revert(e)) => {
+					let mut writer = AbiWriter::new_call(evm_coder::fn_selector!(Error(string)));
+					(&e as &str).abi_write(&mut writer);
+
+					(writer, ExitReason::Revert(ExitRevert::Reverted))
+				}
+				Err(Error::Fatal(f)) => (AbiWriter::new(), ExitReason::Fatal(f)),
+				Err(Error::Error(e)) => (AbiWriter::new(), ExitReason::Error(e)),
+			};
+
+			Some(PrecompileOutput {
+				cost: self.initial_gas - self.gas_left(),
+				exit_status: reason,
+				logs: self.retrieve_logs(),
+				output: writer.finish(),
+			})
+		}
+
+		pub fn submit_logs(self) -> DispatchResult {
+			let logs = self.retrieve_logs();
+			if logs.is_empty() {
+				return Ok(());
+			}
+			T::EthereumTransactionSender::submit_logs_transaction(generate_transaction(), logs)
+		}
+	}
+
+	pub fn dispatch_to_evm<T: Config>(err: DispatchError) -> evm_coder::execution::Error {
+		use evm_coder::execution::Error as ExError;
+		match err {
+			DispatchError::Module { index, error, .. }
+				if index
+					== T::PalletInfo::index::<Pallet<T>>()
+						.expect("evm-coder-substrate is a pallet, which should be added to runtime")
+						as u8 =>
+			{
+				match error {
+					v if v == Error::<T>::OutOfGas.as_u8() => ExError::Error(ExitError::OutOfGas),
+					v if v == Error::<T>::OutOfFund.as_u8() => ExError::Error(ExitError::OutOfFund),
+					_ => unreachable!("this pallet only defines two possible errors"),
+				}
+			}
+			DispatchError::Module {
+				message: Some(msg), ..
+			} => ExError::Revert(msg.into()),
+			DispatchError::Module { index, error, .. } => {
+				ExError::Revert(format!("error {} in pallet {}", error, index))
+			}
+			e => ExError::Revert(format!("substrate error: {:?}", e)),
+		}
+	}
+
+	pub fn call_internal<C: evm_coder::Call, E: evm_coder::Callable<C>>(
+		caller: H160,
+		e: &mut E,
+		value: value,
+		input: &[u8],
+	) -> evm_coder::execution::Result<Option<AbiWriter>> {
+		let (selector, mut reader) = AbiReader::new_call(input)?;
+		let call = C::parse(selector, &mut reader)?;
+		if call.is_none() {
+			return Ok(None);
+		}
+		let call = call.unwrap();
+		e.call(Msg {
+			call,
+			caller,
+			value,
+		})
+		.map(Some)
+	}
+}
addedpallets/evm-contract-helpers/Cargo.tomldiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-contract-helpers/Cargo.toml
@@ -0,0 +1,36 @@
+[package]
+name = "pallet-evm-contract-helpers"
+version = "0.1.0"
+edition = "2018"
+
+[dependencies]
+frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-core = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+evm-coder = { default-features = false, path = '../../crates/evm-coder' }
+pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }
+pallet-evm = { default-features = false, version = "5.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+up-sponsorship = { default-features = false, path = '../../primitives/sponsorship' }
+log = "0.4.14"
+
+[dependencies.codec]
+default-features = false
+features = ['derive']
+package = 'parity-scale-codec'
+version = '2.0.0'
+
+[features]
+default = ["std"]
+std = [
+    "frame-support/std",
+    "frame-system/std",
+    "sp-runtime/std",
+    "sp-std/std",
+    "sp-core/std",
+    "evm-coder/std",
+    "pallet-evm-coder-substrate/std",
+    "pallet-evm/std",
+    "up-sponsorship/std",
+]
addedpallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-contract-helpers/src/eth.rs
@@ -0,0 +1,167 @@
+use core::marker::PhantomData;
+use evm_coder::{abi::AbiWriter, execution::Result, generate_stubgen, solidity_interface, types::*};
+use pallet_evm_coder_substrate::SubstrateRecorder;
+use pallet_evm::{ExitReason, ExitRevert, OnCreate, OnMethodCall, PrecompileOutput};
+use sp_core::H160;
+use crate::{
+	AllowlistEnabled, Config, Owner, Pallet, SelfSponsoring, SponsorBasket, SponsoringRateLimit,
+};
+use frame_support::traits::Get;
+use up_sponsorship::SponsorshipHandler;
+use sp_std::vec::Vec;
+
+struct ContractHelpers<T: Config>(SubstrateRecorder<T>);
+
+#[solidity_interface(name = "ContractHelpers")]
+impl<T: Config> ContractHelpers<T> {
+	fn contract_owner(&self, contract_address: address) -> Result<address> {
+		self.0.consume_sload()?;
+		Ok(<Owner<T>>::get(contract_address))
+	}
+
+	fn sponsoring_enabled(&self, contract_address: address) -> Result<bool> {
+		self.0.consume_sload()?;
+		Ok(<SelfSponsoring<T>>::get(contract_address))
+	}
+
+	fn toggle_sponsoring(
+		&mut self,
+		caller: caller,
+		contract_address: address,
+		enabled: bool,
+	) -> Result<void> {
+		self.0.consume_sload()?;
+		<Pallet<T>>::ensure_owner(contract_address, caller)?;
+		self.0.consume_sstore()?;
+		<Pallet<T>>::toggle_sponsoring(contract_address, enabled);
+		Ok(())
+	}
+
+	fn set_sponsoring_rate_limit(
+		&mut self,
+		caller: caller,
+		contract_address: address,
+		rate_limit: uint32,
+	) -> Result<void> {
+		self.0.consume_sload()?;
+		<Pallet<T>>::ensure_owner(contract_address, caller)?;
+		self.0.consume_sstore()?;
+		<Pallet<T>>::set_sponsoring_rate_limit(contract_address, rate_limit.into());
+		Ok(())
+	}
+
+	fn allowed(&self, contract_address: address, user: address) -> Result<bool> {
+		self.0.consume_sload()?;
+		Ok(<Pallet<T>>::allowed(contract_address, user, true))
+	}
+
+	fn allowlist_enabled(&self, contract_address: address) -> Result<bool> {
+		self.0.consume_sload()?;
+		Ok(<AllowlistEnabled<T>>::get(contract_address))
+	}
+
+	fn toggle_allowlist(
+		&mut self,
+		caller: caller,
+		contract_address: address,
+		enabled: bool,
+	) -> Result<void> {
+		self.0.consume_sload()?;
+		<Pallet<T>>::ensure_owner(contract_address, caller)?;
+		self.0.consume_sstore()?;
+		<Pallet<T>>::toggle_allowlist(contract_address, enabled);
+		Ok(())
+	}
+
+	fn toggle_allowed(
+		&mut self,
+		caller: caller,
+		contract_address: address,
+		user: address,
+		allowed: bool,
+	) -> Result<void> {
+		self.0.consume_sload()?;
+		<Pallet<T>>::ensure_owner(contract_address, caller)?;
+		self.0.consume_sstore()?;
+		<Pallet<T>>::toggle_allowed(contract_address, user, allowed);
+		Ok(())
+	}
+}
+
+pub struct HelpersOnMethodCall<T: Config>(PhantomData<*const T>);
+impl<T: Config> OnMethodCall<T> for HelpersOnMethodCall<T> {
+	fn is_reserved(contract: &sp_core::H160) -> bool {
+		contract == &T::ContractAddress::get()
+	}
+
+	fn is_used(contract: &sp_core::H160) -> bool {
+		contract == &T::ContractAddress::get()
+	}
+
+	fn call(
+		source: &sp_core::H160,
+		target: &sp_core::H160,
+		gas_left: u64,
+		input: &[u8],
+		value: sp_core::U256,
+	) -> Option<PrecompileOutput> {
+		// TODO: Extract to another OnMethodCall handler
+		if !<Pallet<T>>::allowed(*target, *source, true) {
+			return Some(PrecompileOutput {
+				exit_status: ExitReason::Revert(ExitRevert::Reverted),
+				cost: 0,
+				output: {
+					let mut writer = AbiWriter::new_call(evm_coder::fn_selector!(Error(string)));
+					writer.string("Target contract is allowlisted");
+					writer.finish()
+				},
+				logs: sp_std::vec![],
+			});
+		}
+
+		if target != &T::ContractAddress::get() {
+			return None;
+		}
+
+		let mut helpers = ContractHelpers::<T>(SubstrateRecorder::<T>::new(*target, gas_left));
+		let result = pallet_evm_coder_substrate::call_internal(*source, &mut helpers, value, input);
+		helpers.0.evm_to_precompile_output(result)
+	}
+
+	fn get_code(contract: &sp_core::H160) -> Option<Vec<u8>> {
+		(contract == &T::ContractAddress::get())
+			.then(|| include_bytes!("./stubs/ContractHelpers.raw").to_vec())
+	}
+}
+
+pub struct HelpersOnCreate<T: Config>(PhantomData<*const T>);
+impl<T: Config> OnCreate<T> for HelpersOnCreate<T> {
+	fn on_create(owner: H160, contract: H160) {
+		<Owner<T>>::insert(contract, owner);
+	}
+}
+
+pub struct HelpersContractSponsoring<T: Config>(PhantomData<*const T>);
+impl<T: Config> SponsorshipHandler<H160, (H160, Vec<u8>)> for HelpersContractSponsoring<T> {
+	fn get_sponsor(who: &H160, call: &(H160, Vec<u8>)) -> Option<H160> {
+		if <SelfSponsoring<T>>::get(&call.0) && <Pallet<T>>::allowed(call.0, *who, false) {
+			let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
+			if let Some(last_tx_block) = <SponsorBasket<T>>::get(&call.0, who) {
+				let rate_limit = <SponsoringRateLimit<T>>::get(&call.0);
+				let limit_time = last_tx_block + rate_limit;
+
+				if block_number > limit_time {
+					<SponsorBasket<T>>::insert(&call.0, who, block_number);
+					return Some(call.0);
+				}
+			} else {
+				<SponsorBasket<T>>::insert(&call.0, who, block_number);
+				return Some(call.0);
+			}
+		}
+		None
+	}
+}
+
+generate_stubgen!(contract_helpers_impl, ContractHelpersCall, true);
+generate_stubgen!(contract_helpers_iface, ContractHelpersCall, false);
addedpallets/evm-contract-helpers/src/lib.rsdiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-contract-helpers/src/lib.rs
@@ -0,0 +1,100 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+
+pub use pallet::*;
+pub use eth::*;
+pub mod eth;
+
+#[frame_support::pallet]
+pub mod pallet {
+	use evm_coder::execution::Result;
+	use frame_support::pallet_prelude::*;
+	use sp_core::H160;
+
+	#[pallet::config]
+	pub trait Config: frame_system::Config + pallet_evm_coder_substrate::Config {
+		type ContractAddress: Get<H160>;
+		type DefaultSponsoringRateLimit: Get<Self::BlockNumber>;
+	}
+
+	#[pallet::error]
+	pub enum Error<T> {
+		/// This method is only executable by owner
+		NoPermission,
+	}
+
+	#[pallet::pallet]
+	#[pallet::generate_store(pub(super) trait Store)]
+	pub struct Pallet<T>(_);
+
+	#[pallet::storage]
+	pub(super) type Owner<T: Config> =
+		StorageMap<Hasher = Twox128, Key = H160, Value = H160, QueryKind = ValueQuery>;
+
+	#[pallet::storage]
+	pub(super) type SelfSponsoring<T: Config> =
+		StorageMap<Hasher = Twox128, Key = H160, Value = bool, QueryKind = ValueQuery>;
+
+	#[pallet::storage]
+	pub(super) type SponsoringRateLimit<T: Config> = StorageMap<
+		Hasher = Twox128,
+		Key = H160,
+		Value = T::BlockNumber,
+		QueryKind = ValueQuery,
+		OnEmpty = T::DefaultSponsoringRateLimit,
+	>;
+
+	#[pallet::storage]
+	pub(super) type SponsorBasket<T: Config> = StorageDoubleMap<
+		Hasher1 = Twox128,
+		Key1 = H160,
+		Hasher2 = Twox128,
+		Key2 = H160,
+		Value = T::BlockNumber,
+		QueryKind = OptionQuery,
+	>;
+
+	#[pallet::storage]
+	pub(super) type AllowlistEnabled<T: Config> =
+		StorageMap<Hasher = Twox128, Key = H160, Value = bool, QueryKind = ValueQuery>;
+
+	#[pallet::storage]
+	pub(super) type Allowlist<T: Config> = StorageDoubleMap<
+		Hasher1 = Twox128,
+		Key1 = H160,
+		Hasher2 = Twox128,
+		Key2 = H160,
+		Value = bool,
+		QueryKind = ValueQuery,
+	>;
+
+	impl<T: Config> Pallet<T> {
+		pub fn toggle_sponsoring(contract: H160, enabled: bool) {
+			<SelfSponsoring<T>>::insert(contract, enabled);
+		}
+
+		pub fn set_sponsoring_rate_limit(contract: H160, rate_limit: T::BlockNumber) {
+			<SponsoringRateLimit<T>>::insert(contract, rate_limit);
+		}
+
+		/// Default is returned if allowlist is disabled
+		pub fn allowed(contract: H160, user: H160, default: bool) -> bool {
+			if !<AllowlistEnabled<T>>::get(contract) {
+				return default;
+			}
+			<Allowlist<T>>::get(&contract, &user) || <Owner<T>>::get(&contract) == user
+		}
+
+		pub fn toggle_allowlist(contract: H160, enabled: bool) {
+			<AllowlistEnabled<T>>::insert(contract, enabled)
+		}
+
+		pub fn toggle_allowed(contract: H160, user: H160, allowed: bool) {
+			<Allowlist<T>>::insert(contract, user, allowed);
+		}
+
+		pub fn ensure_owner(contract: H160, user: H160) -> Result<()> {
+			ensure!(<Owner<T>>::get(&contract) == user, "no permission");
+			Ok(())
+		}
+	}
+}
addedpallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterboth

binary blob — no preview

addedpallets/evm-contract-helpers/src/stubs/ContractHelpers.soldiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: OTHER
+// This code is automatically generated
+
+pragma solidity >=0.8.0 <0.9.0;
+
+// Common stubs holder
+contract Dummy {
+	uint8 dummy;
+	string stub_error = "this contract is implemented in native";
+}
+
+contract ContractHelpers is Dummy {
+	function contractOwner(address contractAddress)
+		public
+		view
+		returns (address)
+	{
+		require(false, stub_error);
+		contractAddress;
+		dummy;
+		return 0x0000000000000000000000000000000000000000;
+	}
+
+	function sponsoringEnabled(address contractAddress)
+		public
+		view
+		returns (bool)
+	{
+		require(false, stub_error);
+		contractAddress;
+		dummy;
+		return false;
+	}
+
+	function toggleSponsoring(address contractAddress, bool enabled) public {
+		require(false, stub_error);
+		contractAddress;
+		enabled;
+		dummy = 0;
+	}
+
+	function setSponsoringRateLimit(address contractAddress, uint32 rateLimit)
+		public
+	{
+		require(false, stub_error);
+		contractAddress;
+		rateLimit;
+		dummy = 0;
+	}
+
+	function allowed(address contractAddress, address user)
+		public
+		view
+		returns (bool)
+	{
+		require(false, stub_error);
+		contractAddress;
+		user;
+		dummy;
+		return false;
+	}
+
+	function allowlistEnabled(address contractAddress)
+		public
+		view
+		returns (bool)
+	{
+		require(false, stub_error);
+		contractAddress;
+		dummy;
+		return false;
+	}
+
+	function toggleAllowlist(address contractAddress, bool enabled) public {
+		require(false, stub_error);
+		contractAddress;
+		enabled;
+		dummy = 0;
+	}
+
+	function toggleAllowed(
+		address contractAddress,
+		address user,
+		bool allowed
+	) public {
+		require(false, stub_error);
+		contractAddress;
+		user;
+		allowed;
+		dummy = 0;
+	}
+}
addedpallets/evm-migration/Cargo.tomldiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-migration/Cargo.toml
@@ -0,0 +1,36 @@
+[package]
+name = "pallet-evm-migration"
+version = "0.1.0"
+edition = "2018"
+
+[dependencies]
+frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+frame-benchmarking = { default-features = false, version = '3.0.0', optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-io = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-core = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+pallet-evm = { default-features = false, version = "5.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+fp-evm = { default-features = false, version = "2.0.0", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+
+[dependencies.codec]
+default-features = false
+features = ['derive']
+package = 'parity-scale-codec'
+version = '2.0.0'
+
+[features]
+default = ["std", "runtime-benchmarks"]
+std = [
+    "frame-support/std",
+    "frame-system/std",
+    "frame-benchmarking/std",
+    "sp-runtime/std",
+    "sp-std/std",
+    "sp-io/std",
+    "sp-core/std",
+    "pallet-evm/std",
+    "fp-evm/std",
+]
+runtime-benchmarks = ["frame-benchmarking"]
addedpallets/evm-migration/src/benchmarking.rsdiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-migration/src/benchmarking.rs
@@ -0,0 +1,30 @@
+use super::{Call, Config, Pallet};
+use frame_benchmarking::benchmarks;
+use frame_system::RawOrigin;
+use sp_core::{H160, H256};
+use sp_std::vec::Vec;
+
+benchmarks! {
+	begin {
+	}: _(RawOrigin::Root, H160::default())
+
+	set_data {
+		let b in 0..80;
+		let address = H160::from_low_u64_be(b as u64);
+		let mut data = Vec::new();
+		for i in 0..b {
+			data.push((
+				H256::from_low_u64_be(i as u64),
+				H256::from_low_u64_be(i as u64),
+			));
+		}
+		<Pallet<T>>::begin(RawOrigin::Root.into(), address)?;
+	}: _(RawOrigin::Root, address, data)
+
+	finish {
+		let b in 0..80;
+		let address = H160::from_low_u64_be(b as u64);
+		let data: Vec<u8> = (0..b as u8).collect();
+		<Pallet<T>>::begin(RawOrigin::Root.into(), address)?;
+	}: _(RawOrigin::Root, address, data)
+}
addedpallets/evm-migration/src/lib.rsdiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-migration/src/lib.rs
@@ -0,0 +1,111 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+
+pub use pallet::*;
+#[cfg(feature = "runtime-benchmarks")]
+pub mod benchmarking;
+pub mod weights;
+
+#[frame_support::pallet]
+pub mod pallet {
+	use frame_support::{pallet_prelude::*, transactional};
+	use frame_system::pallet_prelude::*;
+	use sp_core::{H160, H256};
+	use sp_std::vec::Vec;
+	use super::weights::WeightInfo;
+
+	#[pallet::config]
+	pub trait Config: frame_system::Config + pallet_evm::Config {
+		type WeightInfo: WeightInfo;
+	}
+
+	type SelfWeightOf<T> = <T as Config>::WeightInfo;
+
+	#[pallet::pallet]
+	#[pallet::generate_store(pub(super) trait Store)]
+	pub struct Pallet<T>(_);
+
+	#[pallet::error]
+	pub enum Error<T> {
+		AccountNotEmpty,
+		AccountIsNotMigrating,
+	}
+
+	#[pallet::storage]
+	pub(super) type MigrationPending<T: Config> =
+		StorageMap<Hasher = Twox64Concat, Key = H160, Value = bool, QueryKind = ValueQuery>;
+
+	#[pallet::call]
+	impl<T: Config> Pallet<T> {
+		#[pallet::weight(<SelfWeightOf<T>>::begin())]
+		pub fn begin(origin: OriginFor<T>, address: H160) -> DispatchResult {
+			ensure_root(origin)?;
+			ensure!(
+				<pallet_evm::Pallet<T>>::is_account_empty(&address)
+					&& !<MigrationPending<T>>::get(&address),
+				<Error<T>>::AccountNotEmpty,
+			);
+
+			<MigrationPending<T>>::insert(address, true);
+			Ok(())
+		}
+
+		#[pallet::weight(<SelfWeightOf<T>>::set_data(data.len() as u32))]
+		pub fn set_data(
+			origin: OriginFor<T>,
+			address: H160,
+			data: Vec<(H256, H256)>,
+		) -> DispatchResult {
+			use frame_support::StorageDoubleMap;
+			ensure_root(origin)?;
+			ensure!(
+				<MigrationPending<T>>::get(&address),
+				<Error<T>>::AccountIsNotMigrating,
+			);
+
+			for (k, v) in data {
+				pallet_evm::AccountStorages::insert(&address, k, v);
+			}
+			Ok(())
+		}
+
+		#[pallet::weight(<SelfWeightOf<T>>::finish(code.len() as u32))]
+		#[transactional]
+		pub fn finish(origin: OriginFor<T>, address: H160, code: Vec<u8>) -> DispatchResult {
+			use frame_support::StorageMap;
+			ensure_root(origin)?;
+			ensure!(
+				<MigrationPending<T>>::get(&address),
+				<Error<T>>::AccountIsNotMigrating,
+			);
+
+			pallet_evm::AccountCodes::insert(&address, code);
+			<MigrationPending<T>>::remove(address);
+			Ok(())
+		}
+	}
+
+	pub struct OnMethodCall<T>(PhantomData<T>);
+	impl<T: Config> pallet_evm::OnMethodCall<T> for OnMethodCall<T> {
+		fn is_reserved(contract: &H160) -> bool {
+			<MigrationPending<T>>::get(&contract)
+		}
+
+		fn is_used(_contract: &H160) -> bool {
+			false
+		}
+
+		fn call(
+			_source: &H160,
+			_arget: &H160,
+			_gas_left: u64,
+			_input: &[u8],
+			_value: sp_core::U256,
+		) -> Option<pallet_evm::PrecompileOutput> {
+			None
+		}
+
+		fn get_code(_contract: &H160) -> Option<Vec<u8>> {
+			None
+		}
+	}
+}
addedpallets/evm-migration/src/weights.rsdiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-migration/src/weights.rs
@@ -0,0 +1,80 @@
+// Template adopted from https://github.com/paritytech/substrate/blob/master/.maintain/frame-weight-template.hbs
+
+//! Autogenerated weights for pallet_evm_migration
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
+//! DATE: 2021-08-12, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 128
+
+// Executed Command:
+// target/release/nft
+// benchmark
+// --pallet
+// pallet-evm-migration
+// --wasm-execution
+// compiled
+// --extrinsic
+// *
+// --template
+// .maintain/frame-weight-template.hbs
+// --steps=50
+// --repeat=20
+// --output=./pallets/evm-migration/src/weights.rs
+
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+
+use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
+use sp_std::marker::PhantomData;
+
+/// Weight functions needed for pallet_evm_migration.
+pub trait WeightInfo {
+	fn begin() -> Weight;
+	fn set_data(b: u32, ) -> Weight;
+	fn finish(b: u32, ) -> Weight;
+}
+
+/// Weights for pallet_evm_migration using the Substrate node and recommended hardware.
+pub struct SubstrateWeight<T>(PhantomData<T>);
+impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
+	fn begin() -> Weight {
+		(6_210_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(3 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn set_data(b: u32, ) -> Weight {
+		(2_926_000 as Weight)
+			// Standard Error: 4_000
+			.saturating_add((649_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(b as Weight)))
+	}
+	fn finish(_b: u32, ) -> Weight {
+		(4_309_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes(2 as Weight))
+	}
+}
+
+// For backwards compatibility and tests
+impl WeightInfo for () {
+	fn begin() -> Weight {
+		(6_210_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(3 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn set_data(b: u32, ) -> Weight {
+		(2_926_000 as Weight)
+			// Standard Error: 4_000
+			.saturating_add((649_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(b as Weight)))
+	}
+	fn finish(_b: u32, ) -> Weight {
+		(4_309_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(2 as Weight))
+	}
+}
\ No newline at end of file
addedpallets/evm-transaction-payment/Cargo.tomldiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-transaction-payment/Cargo.toml
@@ -0,0 +1,37 @@
+[package]
+name = "pallet-evm-transaction-payment"
+version = "0.1.0"
+edition = "2018"
+
+[dependencies]
+frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-io = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-core = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+pallet-evm = { default-features = false, version = "5.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+fp-evm = { default-features = false, version = "2.0.0", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+pallet-ethereum = { default-features = false, version = "3.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+up-sponsorship = { default-features = false, path = '../../primitives/sponsorship' }
+
+[dependencies.codec]
+default-features = false
+features = ['derive']
+package = 'parity-scale-codec'
+version = '2.0.0'
+
+[features]
+default = ["std"]
+std = [
+    "frame-support/std",
+    "frame-system/std",
+    "sp-runtime/std",
+    "sp-std/std",
+    "sp-io/std",
+    "sp-core/std",
+    "pallet-evm/std",
+    "pallet-ethereum/std",
+    "fp-evm/std",
+    "up-sponsorship/std",
+]
addedpallets/evm-transaction-payment/src/lib.rsdiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-transaction-payment/src/lib.rs
@@ -0,0 +1,98 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+
+pub use pallet::*;
+
+#[frame_support::pallet]
+pub mod pallet {
+	use core::marker::PhantomData;
+	use frame_support::traits::Currency;
+	use pallet_evm::EVMCurrencyAdapter;
+	use fp_evm::WithdrawReason;
+	use sp_core::{H160, U256};
+	use sp_runtime::TransactionOutcome;
+	use up_sponsorship::SponsorshipHandler;
+	use sp_std::vec::Vec;
+
+	type NegativeImbalanceOf<C, T> =
+		<C as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance;
+
+	#[pallet::config]
+	pub trait Config: frame_system::Config {
+		type SponsorshipHandler: SponsorshipHandler<H160, (H160, Vec<u8>)>;
+		type Currency: Currency<Self::AccountId>;
+	}
+
+	#[pallet::pallet]
+	#[pallet::generate_store(pub(super) trait Store)]
+	pub struct Pallet<T>(_);
+
+	pub struct ChargeEvmLiquidityInfo<T>
+	where
+		T: Config,
+		T: pallet_evm::Config,
+	{
+		who: H160,
+		negative_imbalance: NegativeImbalanceOf<<T as Config>::Currency, T>,
+	}
+
+	pub struct TransactionValidityHack<T: Config>(PhantomData<*const T>);
+	impl<T: Config> fp_evm::TransactionValidityHack for TransactionValidityHack<T> {
+		fn who_pays_fee(origin: H160, reason: &WithdrawReason) -> Option<H160> {
+			match reason {
+				WithdrawReason::Call { target, input } => {
+					// This method is only used for checking, we shouldn't touch storage in it
+					frame_support::storage::with_transaction(|| {
+						TransactionOutcome::Rollback(T::SponsorshipHandler::get_sponsor(
+							&origin,
+							&(*target, input.clone()),
+						))
+					})
+				}
+				_ => None,
+			}
+		}
+	}
+
+	pub struct OnChargeTransaction<T: Config>(PhantomData<*const T>);
+	impl<T> pallet_evm::OnChargeEVMTransaction<T> for OnChargeTransaction<T>
+	where
+		T: Config,
+		T: pallet_evm::Config,
+	{
+		type LiquidityInfo = Option<ChargeEvmLiquidityInfo<T>>;
+
+		fn withdraw_fee(
+			who: &H160,
+			reason: WithdrawReason,
+			fee: U256,
+		) -> core::result::Result<Self::LiquidityInfo, pallet_evm::Error<T>> {
+			let mut who_pays_fee = *who;
+			if let WithdrawReason::Call { target, input } = &reason {
+				who_pays_fee = T::SponsorshipHandler::get_sponsor(who, &(*target, input.clone()))
+					.unwrap_or(who_pays_fee);
+			}
+			let negative_imbalance =
+				EVMCurrencyAdapter::<<T as Config>::Currency, ()>::withdraw_fee(
+					&who_pays_fee,
+					reason,
+					fee,
+				)?;
+			Ok(negative_imbalance.map(|i| ChargeEvmLiquidityInfo {
+				who: who_pays_fee,
+				negative_imbalance: i,
+			}))
+		}
+
+		fn correct_and_deposit_fee(
+			who: &H160,
+			corrected_fee: U256,
+			already_withdrawn: Self::LiquidityInfo,
+		) -> core::result::Result<(), pallet_evm::Error<T>> {
+			EVMCurrencyAdapter::<<T as Config>::Currency, ()>::correct_and_deposit_fee(
+				&already_withdrawn.as_ref().map(|e| e.who).unwrap_or(*who),
+				corrected_fee,
+				already_withdrawn.map(|e| e.negative_imbalance),
+			)
+		}
+	}
+}
modifiedpallets/inflation/Cargo.tomldiffbeforeafterboth
--- a/pallets/inflation/Cargo.toml
+++ b/pallets/inflation/Cargo.toml
@@ -43,43 +43,43 @@
 default-features = false
 optional = true
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.frame-support]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.frame-system]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.pallet-balances]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.pallet-timestamp]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.pallet-randomness-collective-flip]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-std]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.serde]
@@ -90,18 +90,18 @@
 [dependencies.sp-runtime]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-core]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-io]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
modifiedpallets/inflation/src/tests.rsdiffbeforeafterboth
--- a/pallets/inflation/src/tests.rs
+++ b/pallets/inflation/src/tests.rs
@@ -32,7 +32,7 @@
 	type WeightInfo = ();
 	type MaxLocks = MaxLocks;
 	type MaxReserves = ();
-	type ReserveIdentifier = [u8; 8];
+	type ReserveIdentifier = ();
 }
 
 frame_support::construct_runtime!(
@@ -91,7 +91,6 @@
 	type InflationBlockInterval = InflationBlockInterval;
 }
 
-// Build genesis storage according to the mock runtime.
 pub fn new_test_ext() -> sp_io::TestExternalities {
 	frame_system::GenesisConfig::default()
 		.build_storage::<Test>()
@@ -110,7 +109,9 @@
 		// BlockInflation should be set after 1st block and
 		// first inflation deposit should be equal to BlockInflation
 		Inflation::on_initialize(1);
-		assert!(Inflation::block_inflation() > 0);
+
+		// SBP M2 review: Verify expected block inflation for year 1
+		assert_eq!(Inflation::block_inflation(), 1901);
 		assert_eq!(
 			Balances::free_balance(1234) - initial_issuance,
 			Inflation::block_inflation()
@@ -157,11 +158,24 @@
 		Inflation::on_initialize(1);
 		let block_inflation_year_0 = Inflation::block_inflation();
 
+		// SBP M2 review: go through all the block inflations for year 1,
+		// total issuance will be updated accordingly
+		for block in (100..YEAR).step_by(100) {
+			Inflation::on_initialize(block);
+		}
+		assert_eq!(
+			initial_issuance + (1901 * (YEAR / 100)),
+			<Balances as Currency<_>>::total_issuance()
+		);
+
 		Inflation::on_initialize(YEAR);
 		let block_inflation_year_1 = Inflation::block_inflation();
+		// SBP M2 review: Verify expected block inflation for year 2
+		assert_eq!(block_inflation_year_1, 1952);
 
+		// SBP M2 review: this is actually not true
 		// Assert that year 1 inflation is less than year 0
-		assert!(block_inflation_year_0 > block_inflation_year_1);
+		// assert!(block_inflation_year_0 > block_inflation_year_1);
 	});
 }
 
@@ -179,6 +193,7 @@
 			Inflation::on_initialize(YEAR * year);
 			let block_inflation_year_after = Inflation::block_inflation();
 
+			// SBP M2 review: this is actually not true (not for the first few years)
 			// Assert that next year inflation is less than previous year inflation
 			assert!(block_inflation_year_before > block_inflation_year_after);
 		}
modifiedpallets/nft-charge-transaction/Cargo.tomldiffbeforeafterboth
--- a/pallets/nft-charge-transaction/Cargo.toml
+++ b/pallets/nft-charge-transaction/Cargo.toml
@@ -20,15 +20,15 @@
 
 [dependencies]
 serde = { version = "1.0.119", default-features = false }
-frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-pallet-balances = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-pallet-transaction-payment = { default-features = false, version = "3.0.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-frame-benchmarking = { default-features = false, version = "3.0.0", optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-core = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-io = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
+frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+pallet-balances = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+pallet-transaction-payment = { default-features = false, version = "3.0.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+frame-benchmarking = { default-features = false, version = "3.0.0", optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-core = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-io = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
 
 pallet-nft-transaction-payment = { default-features = false, path="../nft-transaction-payment" }
 
modifiedpallets/nft-charge-transaction/src/lib.rsdiffbeforeafterboth
--- a/pallets/nft-charge-transaction/src/lib.rs
+++ b/pallets/nft-charge-transaction/src/lib.rs
@@ -76,7 +76,7 @@
 	where
 		T::Call: Dispatchable<Info = DispatchInfo>,
 	{
-		<pallet_transaction_payment::Module<T>>::compute_fee(len as u32, info, tip)
+		<pallet_transaction_payment::Pallet<T>>::compute_fee(len as u32, info, tip)
 	}
 
 	fn get_priority(
modifiedpallets/nft-transaction-payment/Cargo.tomldiffbeforeafterboth
--- a/pallets/nft-transaction-payment/Cargo.toml
+++ b/pallets/nft-transaction-payment/Cargo.toml
@@ -20,14 +20,14 @@
 
 [dependencies]
 serde = { version = "1.0.119", default-features = false }
-frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-pallet-transaction-payment = { default-features = false, version = "3.0.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-frame-benchmarking = { default-features = false, version = "3.0.0", optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-core = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-io = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
+frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+pallet-transaction-payment = { default-features = false, version = "3.0.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+frame-benchmarking = { default-features = false, version = "3.0.0", optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-core = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-io = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
 
 up-sponsorship = { default-features = false, path = "../../primitives/sponsorship", version = "0.1.0" }
 
deletedpallets/nft-transaction-payment/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/nft-transaction-payment/src/benchmarking.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#![cfg(feature = "runtime-benchmarks")]
-
-use super::*;
-
-use sp_std::prelude::*;
-use frame_system::RawOrigin;
-use frame_benchmarking::{benchmarks};
-use frame_support::traits::OnInitialize;
-
-benchmarks! {
-
-	// on_initialize {
-		// let block1: T::BlockNumber = T::BlockNumber::from(1u32);
-		// let block2: T::BlockNumber = T::BlockNumber::from(2u32);
-		// Inflation::<T>::on_initialize(block1); // Create Treasury account
-	// }: { Inflation::<T>::on_initialize(block2); } // Benchmark deposit_into_existing path
-
-}
modifiedpallets/nft-transaction-payment/src/lib.rsdiffbeforeafterboth
--- a/pallets/nft-transaction-payment/src/lib.rs
+++ b/pallets/nft-transaction-payment/src/lib.rs
@@ -11,9 +11,6 @@
 #[cfg(feature = "std")]
 pub use serde::*;
 
-#[cfg(feature = "runtime-benchmarks")]
-mod benchmarking;
-
 use frame_support::{decl_module, decl_storage};
 use sp_std::prelude::*;
 use up_sponsorship::SponsorshipHandler;
modifiedpallets/nft/Cargo.tomldiffbeforeafterboth
--- a/pallets/nft/Cargo.toml
+++ b/pallets/nft/Cargo.toml
@@ -37,10 +37,11 @@
     'ethereum/std',
     'rlp/std',
 
-    'ethereum-tx-sign',
     'primitive-types/std',
     'evm-coder/std',
+    'pallet-evm-coder-substrate/std',
 ]
+limit-testing = ["nft-data-structs/limit-testing"]
 
 ################################################################################
 # Substrate Dependencies
@@ -55,49 +56,49 @@
 default-features = false
 optional = true
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.frame-support]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.frame-system]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.pallet-balances]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.pallet-timestamp]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.pallet-randomness-collective-flip]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-std]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.pallet-transaction-payment]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.serde]
@@ -108,19 +109,19 @@
 [dependencies.sp-runtime]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-core]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-io]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 
@@ -139,15 +140,17 @@
 
 
 [dependencies]
-ethereum-tx-sign = { version = "3.0.4", optional = true }
 ethereum = { default-features = false, version = "0.7.1" }
 rlp = { default-features = false, version = "0.5.0" }
-sp-api = { default-features = false, version = '3.0.0', git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.7" }
+sp-api = { default-features = false, version = '3.0.0', git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.8" }
 
 evm-coder = { default-features = false, path = "../../crates/evm-coder" }
-primitive-types = { version = "0.9.0", default-features = false, features = ["serde_no_std"] }
+pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }
+primitive-types = { version = "0.9.0", default-features = false, features = [
+    "serde_no_std",
+] }
 
-pallet-evm = { default-features = false, version = "5.0.0-dev", git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
-pallet-ethereum = { default-features = false, version = "3.0.0-dev", git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
-fp-evm = { default-features = false, version = '2.0.0', git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
-hex-literal = "0.3.1"
\ No newline at end of file
+pallet-evm = { default-features = false, version = "5.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+pallet-ethereum = { default-features = false, version = "3.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+fp-evm = { default-features = false, version = '2.0.0', git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+hex-literal = "0.3.1"
modifiedpallets/nft/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/nft/src/benchmarking.rs
+++ b/pallets/nft/src/benchmarking.rs
@@ -1,419 +1,342 @@
 #![cfg(feature = "runtime-benchmarks")]
 
 use super::*;
-use crate::Module as Nft;
-
-use sp_std::prelude::*;
+use crate::Pallet;
 use frame_system::RawOrigin;
-use frame_benchmarking::{benchmarks, account, whitelisted_caller}; // , TrackedStorageKey,
+use frame_benchmarking::{benchmarks, account};
+use nft_data_structs::*;
+use core::convert::TryInto;
+use sp_runtime::DispatchError;
 
 const SEED: u32 = 1;
-/*
+
+fn create_data(size: usize) -> Vec<u8> {
+	(0..size).map(|v| (v & 0xff) as u8).collect()
+}
+fn create_u16_data(size: usize) -> Vec<u16> {
+	(0..size).map(|v| (v & 0xffff) as u16).collect()
+}
+
 fn default_nft_data() -> CreateItemData {
-	CreateItemData::NFT(CreateNftData { const_data: vec![1, 2, 3], variable_data: vec![3, 2, 1] })
+	CreateItemData::NFT(CreateNftData {
+		const_data: create_data(CUSTOM_DATA_LIMIT as usize).try_into().unwrap(),
+		variable_data: create_data(CUSTOM_DATA_LIMIT as usize).try_into().unwrap(),
+	})
 }
 
-fn default_fungible_data () -> CreateItemData {
-	CreateItemData::Fungible(CreateFungibleData { })
+fn default_fungible_data() -> CreateItemData {
+	CreateItemData::Fungible(CreateFungibleData { value: 1000 })
 }
 
-fn default_re_fungible_data () -> CreateItemData {
-	CreateItemData::ReFungible(CreateReFungibleData { const_data: vec![1, 2, 3], variable_data: vec![3, 2, 1] })
+fn default_re_fungible_data() -> CreateItemData {
+	CreateItemData::ReFungible(CreateReFungibleData {
+		const_data: create_data(CUSTOM_DATA_LIMIT as usize).try_into().unwrap(),
+		variable_data: create_data(CUSTOM_DATA_LIMIT as usize).try_into().unwrap(),
+		pieces: 1000,
+	})
+}
+
+fn create_collection_helper<T: Config>(
+	owner: T::AccountId,
+	mode: CollectionMode,
+) -> Result<CollectionId, DispatchError> {
+	T::Currency::deposit_creating(&owner, T::CollectionCreationPrice::get());
+	let col_name = create_u16_data(MAX_COLLECTION_NAME_LENGTH)
+		.try_into()
+		.unwrap();
+	let col_desc = create_u16_data(MAX_COLLECTION_DESCRIPTION_LENGTH)
+		.try_into()
+		.unwrap();
+	let token_prefix = create_data(MAX_TOKEN_PREFIX_LENGTH).try_into().unwrap();
+	<Pallet<T>>::create_collection(
+		RawOrigin::Signed(owner).into(),
+		col_name,
+		col_desc,
+		token_prefix,
+		mode,
+	)?;
+	Ok(CreatedCollectionCount::get())
+}
+fn create_nft_collection<T: Config>(owner: T::AccountId) -> Result<CollectionId, DispatchError> {
+	create_collection_helper::<T>(owner, CollectionMode::NFT)
+}
+fn create_fungible_collection<T: Config>(
+	owner: T::AccountId,
+) -> Result<CollectionId, DispatchError> {
+	create_collection_helper::<T>(owner, CollectionMode::Fungible(0))
+}
+fn create_refungible_collection<T: Config>(
+	owner: T::AccountId,
+) -> Result<CollectionId, DispatchError> {
+	create_collection_helper::<T>(owner, CollectionMode::ReFungible)
 }
-*/
 
 benchmarks! {
 
 	create_collection {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
+		let col_name: Vec<u16> = create_u16_data(MAX_COLLECTION_NAME_LENGTH);
+		let col_desc: Vec<u16> = create_u16_data(MAX_COLLECTION_DESCRIPTION_LENGTH);
+		let token_prefix: Vec<u8> = create_data(MAX_TOKEN_PREFIX_LENGTH);
 		let mode: CollectionMode = CollectionMode::NFT;
 		let caller: T::AccountId = account("caller", 0, SEED);
-	}: _(RawOrigin::Signed(caller.clone()), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode)
-/*
+		T::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());
+	}: _(RawOrigin::Signed(caller.clone()), col_name.clone(), col_desc.clone(), token_prefix.clone(), mode)
 	verify {
-		assert_eq!(Nft::<T>::collection_id(2).owner, caller);
+		assert_eq!(<Pallet<T>>::collection_id(2).unwrap().owner, caller);
 	}
+
 	destroy_collection {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
-	}: _(RawOrigin::Signed(caller.clone()), 2)
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
+	}: _(RawOrigin::Signed(caller.clone()), collection)
 
 	add_to_white_list {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
+		let caller: T::AccountId = account("caller", 0, SEED);
 		let whitelist_account: T::AccountId = account("admin", 0, SEED);
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
-	}: add_to_white_list(RawOrigin::Signed(caller.clone()), 2, whitelist_account)
+		let collection = create_nft_collection::<T>(caller.clone())?;
+	}: _(RawOrigin::Signed(caller.clone()), collection, T::CrossAccountId::from_sub(whitelist_account))
 
 	remove_from_white_list {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
+		let caller: T::AccountId = account("caller", 0, SEED);
 		let whitelist_account: T::AccountId = account("admin", 0, SEED);
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
-		Nft::<T>::add_to_white_list(RawOrigin::Signed(caller.clone()).into(), 2, whitelist_account.clone())?;
-	}: remove_from_white_list(RawOrigin::Signed(caller.clone()), 2, whitelist_account)
+		let collection = create_nft_collection::<T>(caller.clone())?;
+		<Pallet<T>>::add_to_white_list(RawOrigin::Signed(caller.clone()).into(), collection, T::CrossAccountId::from_sub(whitelist_account.clone()))?;
+	}: _(RawOrigin::Signed(caller.clone()), collection, T::CrossAccountId::from_sub(whitelist_account))
 
 	set_public_access_mode {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
-	}: set_public_access_mode(RawOrigin::Signed(caller.clone()), 2, AccessMode::WhiteList)
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
+	}: _(RawOrigin::Signed(caller.clone()), collection, AccessMode::WhiteList)
 
 	set_mint_permission {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
-	}: set_mint_permission(RawOrigin::Signed(caller.clone()), 2, true)
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
+	}: _(RawOrigin::Signed(caller.clone()), collection, true)
 
 	change_collection_owner {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
 		let new_owner: T::AccountId = account("admin", 0, SEED);
-	}: change_collection_owner(RawOrigin::Signed(caller.clone()), 2, new_owner)
+	}: _(RawOrigin::Signed(caller.clone()), collection, new_owner)
 
 	add_collection_admin {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
 		let new_admin: T::AccountId = account("admin", 0, SEED);
-	}: add_collection_admin(RawOrigin::Signed(caller.clone()), 2, new_admin)
+	}: _(RawOrigin::Signed(caller.clone()), collection, T::CrossAccountId::from_sub(new_admin))
 
 	remove_collection_admin {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
 		let new_admin: T::AccountId = account("admin", 0, SEED);
-		Nft::<T>::add_collection_admin(RawOrigin::Signed(caller.clone()).into(), 2, new_admin.clone())?;
-	}: remove_collection_admin(RawOrigin::Signed(caller.clone()), 2, new_admin)
+		<Pallet<T>>::add_collection_admin(RawOrigin::Signed(caller.clone()).into(), 2, T::CrossAccountId::from_sub(new_admin.clone()))?;
+	}: _(RawOrigin::Signed(caller.clone()), collection, T::CrossAccountId::from_sub(new_admin))
 
 	set_collection_sponsor {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
-	}: set_collection_sponsor(RawOrigin::Signed(caller.clone()), 2, caller.clone())
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
+	}: _(RawOrigin::Signed(caller.clone()), collection, caller.clone())
 
 	confirm_sponsorship {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
-		Nft::<T>::set_collection_sponsor(RawOrigin::Signed(caller.clone()).into(), 2, caller.clone())?;
-	}: confirm_sponsorship(RawOrigin::Signed(caller.clone()), 2)
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
+		<Pallet<T>>::set_collection_sponsor(RawOrigin::Signed(caller.clone()).into(), 2, caller.clone())?;
+	}: _(RawOrigin::Signed(caller.clone()), collection)
 
 	remove_collection_sponsor {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
-		Nft::<T>::set_collection_sponsor(RawOrigin::Signed(caller.clone()).into(), 2, caller.clone())?;
-		Nft::<T>::confirm_sponsorship(RawOrigin::Signed(caller.clone()).into(), 2)?;
-	}: remove_collection_sponsor(RawOrigin::Signed(caller.clone()), 2)
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
+		<Pallet<T>>::set_collection_sponsor(RawOrigin::Signed(caller.clone()).into(), 2, caller.clone())?;
+		<Pallet<T>>::confirm_sponsorship(RawOrigin::Signed(caller.clone()).into(), 2)?;
+	}: _(RawOrigin::Signed(caller.clone()), collection)
 
 	// nft item
 	create_item_nft {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
-		let data = default_nft_data();
+		let b in 0..(CUSTOM_DATA_LIMIT * 2);
 
-	}: create_item(RawOrigin::Signed(caller.clone()), 2, caller.clone(), data)
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
+		let data = CreateItemData::NFT(CreateNftData {
+			const_data: create_data(b.min(CUSTOM_DATA_LIMIT) as usize).try_into().unwrap(),
+			variable_data: create_data(b.saturating_sub(CUSTOM_DATA_LIMIT) as usize).try_into().unwrap(),
+		});
+	}: create_item(RawOrigin::Signed(caller.clone()), collection, T::CrossAccountId::from_sub(caller.clone()), data)
 
-	#[extra]
-	create_item_nft_large {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		let mut nft_data = CreateNftData {
-			const_data: vec![],
-			variable_data: vec![]
-		};
-		for i in 0..1998 {
-			nft_data.const_data.push(10);
-			nft_data.variable_data.push(10);
-		}
-		let data = CreateItemData::NFT(nft_data);
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
+	create_multiple_items_nft {
+		// TODO: Take item data size into account. As create_item_nft bench shows, this parameter has no effect on execution time,
+		// but it may if we increase CUSTOM_DATA_LIMIT
+		let b in 1..1000;
 
-	}: create_item(RawOrigin::Signed(caller.clone()), 2, caller.clone(), data)
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
+		let data = (0..b).map(|_| default_nft_data()).collect();
+	}: create_multiple_items(RawOrigin::Signed(caller.clone()), collection, T::CrossAccountId::from_sub(caller.clone()), data)
 
 	// fungible item
 	create_item_fungible {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::Fungible(3);
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
-		let data = default_fungible_data();
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_fungible_collection::<T>(caller.clone())?;
+		let data = CreateItemData::Fungible(CreateFungibleData {
+			value: 1000,
+		});
+	}: create_item(RawOrigin::Signed(caller.clone()), collection, T::CrossAccountId::from_sub(caller.clone()), data)
+
+	create_multiple_items_fungible {
+		let b in 1..1000;
 
-	}: create_item(RawOrigin::Signed(caller.clone()), 2, caller.clone(), data)
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_fungible_collection::<T>(caller.clone())?;
+		let data = (0..b).map(|_| default_fungible_data()).collect();
+	}: create_multiple_items(RawOrigin::Signed(caller.clone()), collection, T::CrossAccountId::from_sub(caller.clone()), data)
 
 	// refungible item
 	create_item_refungible {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::ReFungible(3);
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
-		let data = default_re_fungible_data();
+		let b in 0..(CUSTOM_DATA_LIMIT * 2);
 
-	}: create_item(RawOrigin::Signed(caller.clone()), 2, caller.clone(), data)
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_refungible_collection::<T>(caller.clone())?;
+		let data = CreateItemData::ReFungible(CreateReFungibleData {
+			const_data: create_data(b.min(CUSTOM_DATA_LIMIT) as usize).try_into().unwrap(),
+			variable_data: create_data(b.saturating_sub(CUSTOM_DATA_LIMIT) as usize).try_into().unwrap(),
+			pieces: 1000,
+		});
+	}: create_item(RawOrigin::Signed(caller.clone()), collection, T::CrossAccountId::from_sub(caller.clone()), data)
 
-	burn_item {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
-		let data = default_nft_data();
-		Nft::<T>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, caller.clone(), data)?;
+	create_multiple_items_refungible {
+		// TODO: Take item data size into account. As create_item_nft bench shows, this parameter has no effect on execution time,
+		// but it may if we increase CUSTOM_DATA_LIMIT
+		let b in 1..1000;
 
-	}: burn_item(RawOrigin::Signed(caller.clone()), 2, 1)
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_refungible_collection::<T>(caller.clone())?;
+		let data = (0..b).map(|_| default_re_fungible_data()).collect();
+	}: create_multiple_items(RawOrigin::Signed(caller.clone()), collection, T::CrossAccountId::from_sub(caller.clone()), data)
 
+	burn_item_nft {
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
+		let data = default_nft_data();
+		<Pallet<T>>::create_item(RawOrigin::Signed(caller.clone()).into(), collection, T::CrossAccountId::from_sub(caller.clone()), data)?;
+	}: burn_item(RawOrigin::Signed(caller.clone()), collection, 1, 1)
+
 	transfer_nft {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
 		let recipient: T::AccountId = account("recipient", 0, SEED);
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
 		let data = default_nft_data();
-		Nft::<T>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, caller.clone(), data)?;
-
-	}: transfer(RawOrigin::Signed(caller.clone()), recipient.clone(), 2, 1, 1)
+		<Pallet<T>>::create_item(RawOrigin::Signed(caller.clone()).into(), collection, T::CrossAccountId::from_sub(caller.clone()), data)?;
+	}: transfer(RawOrigin::Signed(caller.clone()), T::CrossAccountId::from_sub(recipient.clone()), collection, 1, 1)
 
 	transfer_fungible {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::Fungible(3);
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_fungible_collection::<T>(caller.clone())?;
 		let recipient: T::AccountId = account("recipient", 0, SEED);
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
 		let data = default_fungible_data();
-		Nft::<T>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, caller.clone(), data)?;
-
-	}: transfer(RawOrigin::Signed(caller.clone()), recipient.clone(), 2, 1, 1)
+		<Pallet<T>>::create_item(RawOrigin::Signed(caller.clone()).into(), collection, T::CrossAccountId::from_sub(caller.clone()), data)?;
+	}: transfer(RawOrigin::Signed(caller.clone()), T::CrossAccountId::from_sub(recipient.clone()), collection, 1, 1)
 
 	transfer_refungible {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::ReFungible(3);
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_refungible_collection::<T>(caller.clone())?;
 		let recipient: T::AccountId = account("recipient", 0, SEED);
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
 		let data = default_re_fungible_data();
-		Nft::<T>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, caller.clone(), data)?;
+		<Pallet<T>>::create_item(RawOrigin::Signed(caller.clone()).into(), collection, T::CrossAccountId::from_sub(caller.clone()), data)?;
+	}: transfer(RawOrigin::Signed(caller.clone()), T::CrossAccountId::from_sub(recipient.clone()), collection, 1, 1)
 
-	}: transfer(RawOrigin::Signed(caller.clone()), recipient.clone(), 2, 1, 1)
+	set_transfers_enabled_flag {
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
+	}: _(RawOrigin::Signed(caller.clone()), collection, false)
 
-	approve {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::ReFungible(3);
+	approve_nft {
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
 		let recipient: T::AccountId = account("recipient", 0, SEED);
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
-		let data = default_re_fungible_data();
-		Nft::<T>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, caller.clone(), data)?;
-
-	}: approve(RawOrigin::Signed(caller.clone()), recipient.clone(), 2, 1)
+		let data = default_nft_data();
+		<Pallet<T>>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, T::CrossAccountId::from_sub(caller.clone()), data)?;
+	}: approve(RawOrigin::Signed(caller.clone()), T::CrossAccountId::from_sub(recipient.clone()), collection, 1, 1)
 
 	// Nft
 	transfer_from_nft {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
 		let recipient: T::AccountId = account("recipient", 0, SEED);
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
 		let data = default_nft_data();
-		Nft::<T>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, caller.clone(), data)?;
-		Nft::<T>::approve(RawOrigin::Signed(caller.clone()).into(), recipient.clone(), 2, 1)?;
-
-	}: transfer_from(RawOrigin::Signed(caller.clone()), caller.clone(), recipient.clone(), 2, 1, 1)
+		<Pallet<T>>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, T::CrossAccountId::from_sub(caller.clone()), data)?;
+		<Pallet<T>>::approve(RawOrigin::Signed(caller.clone()).into(), T::CrossAccountId::from_sub(recipient.clone()), 2, 1, 1)?;
+	}: transfer_from(RawOrigin::Signed(caller.clone()), T::CrossAccountId::from_sub(caller.clone()), T::CrossAccountId::from_sub(recipient.clone()), 2, 1, 1)
 
 	// Fungible
 	transfer_from_fungible {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::Fungible(3);
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_fungible_collection::<T>(caller.clone())?;
 		let recipient: T::AccountId = account("recipient", 0, SEED);
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
 		let data = default_fungible_data();
-		Nft::<T>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, caller.clone(), data)?;
-		Nft::<T>::approve(RawOrigin::Signed(caller.clone()).into(), recipient.clone(), 2, 1)?;
-
-	}: transfer_from(RawOrigin::Signed(caller.clone()), caller.clone(), recipient.clone(), 2, 1, 1)
+		<Pallet<T>>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, T::CrossAccountId::from_sub(caller.clone()), data)?;
+		<Pallet<T>>::approve(RawOrigin::Signed(caller.clone()).into(), T::CrossAccountId::from_sub(recipient.clone()), 2, 1, 1)?;
+	}: transfer_from(RawOrigin::Signed(caller.clone()), T::CrossAccountId::from_sub(caller.clone()), T::CrossAccountId::from_sub(recipient.clone()), 2, 1, 1)
 
 	// ReFungible
 	transfer_from_refungible {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::ReFungible(3);
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_refungible_collection::<T>(caller.clone())?;
 		let recipient: T::AccountId = account("recipient", 0, SEED);
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
 		let data = default_re_fungible_data();
-		Nft::<T>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, caller.clone(), data)?;
-		Nft::<T>::approve(RawOrigin::Signed(caller.clone()).into(), recipient.clone(), 2, 1)?;
-
-	}: transfer_from(RawOrigin::Signed(caller.clone()), caller.clone(), recipient.clone(), 2, 1, 1)
-
-	enable_contract_sponsoring {
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-
-	}: enable_contract_sponsoring(RawOrigin::Signed(caller.clone()), caller.clone(), true)
+		<Pallet<T>>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, T::CrossAccountId::from_sub(caller.clone()), data)?;
+		<Pallet<T>>::approve(RawOrigin::Signed(caller.clone()).into(), T::CrossAccountId::from_sub(recipient.clone()), 2, 1, 1)?;
+	}: transfer_from(RawOrigin::Signed(caller.clone()), T::CrossAccountId::from_sub(caller.clone()), T::CrossAccountId::from_sub(recipient.clone()), 2, 1, 1)
 
 	set_offchain_schema {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::ReFungible(3);
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
+		let b in 0..OFFCHAIN_SCHEMA_LIMIT;
 
-	}: set_offchain_schema(RawOrigin::Signed(caller.clone()), 2, [1,2,3].to_vec())
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
+		let data = create_data(b as usize);
+	}: set_offchain_schema(RawOrigin::Signed(caller.clone()), collection, data)
 
 	set_const_on_chain_schema {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::ReFungible(3);
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
-	}: set_const_on_chain_schema(RawOrigin::Signed(caller.clone()), 2, [1,2,3].to_vec())
+		let b in 0..CONST_ON_CHAIN_SCHEMA_LIMIT;
 
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
+		let data = create_data(b as usize);
+	}: set_const_on_chain_schema(RawOrigin::Signed(caller.clone()), collection, data)
+
 	set_variable_on_chain_schema {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::ReFungible(3);
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
-	}: set_variable_on_chain_schema(RawOrigin::Signed(caller.clone()), 2, [1,2,3].to_vec())
+		let b in 0..VARIABLE_ON_CHAIN_SCHEMA_LIMIT;
 
-	set_variable_meta_data {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
-		let data = default_nft_data();
-		Nft::<T>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, caller.clone(), data)?;
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
+		let data = create_data(b as usize);
+	}: set_variable_on_chain_schema(RawOrigin::Signed(caller.clone()), 2, data)
 
-	}: set_variable_meta_data(RawOrigin::Signed(caller.clone()), 2, 1, [1, 2, 3].to_vec())
+	set_variable_meta_data_nft {
+		let b in 0..CUSTOM_DATA_LIMIT;
 
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
+		let data = default_nft_data();
+		<Pallet<T>>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, T::CrossAccountId::from_sub(caller.clone()), data)?;
+		let data = create_data(b as usize);
+	}: set_variable_meta_data(RawOrigin::Signed(caller.clone()), collection, 1, data)
+
 	set_schema_version {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
 	}: set_schema_version(RawOrigin::Signed(caller.clone()), 2, SchemaVersion::Unique)
-
-	set_chain_limits {
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		let limits = ChainLimits {
-			collection_numbers_limit: 0,
-			account_token_ownership_limit: 0,
-			collections_admins_limit: 0,
-			custom_data_limit: 0,
-			nft_sponsor_transfer_timeout: 0,
-			fungible_sponsor_transfer_timeout: 0,
-			refungible_sponsor_transfer_timeout: 0
-		};
-	}: set_chain_limits(RawOrigin::Signed(caller.clone()), limits)
-
-	set_contract_sponsoring_rate_limit {
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
-		let block_number: T::BlockNumber = 0.into();
-	}: set_contract_sponsoring_rate_limit(RawOrigin::Signed(caller.clone()), caller.clone(), block_number)
 
 	set_collection_limits{
-		let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
-		let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
-		let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
-		let mode: CollectionMode = CollectionMode::NFT;
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
+		let caller: T::AccountId = account("caller", 0, SEED);
+		let collection = create_nft_collection::<T>(caller.clone())?;
 
 		let cl = CollectionLimits {
 			account_token_ownership_limit: 0,
 			sponsored_data_size: 0,
-			token_limit: 0,
-			sponsor_transfer_timeout: 0
+			token_limit: 1,
+			sponsor_transfer_timeout: 0,
+			owner_can_destroy: true,
+			owner_can_transfer: true,
+			sponsored_data_rate_limit: None,
 		};
-
 	}: set_collection_limits(RawOrigin::Signed(caller.clone()), 2, cl)
-
-	add_to_contract_white_list{
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-	}: add_to_contract_white_list(RawOrigin::Signed(caller.clone()), caller.clone(), caller.clone())
-
-	remove_from_contract_white_list{
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-		Nft::<T>::add_to_contract_white_list(RawOrigin::Signed(caller.clone()).into(), caller.clone(), caller.clone())?;
-	}: remove_from_contract_white_list(RawOrigin::Signed(caller.clone()), caller.clone(), caller.clone())
-
-	toggle_contract_white_list{
-		let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
-	}: toggle_contract_white_list(RawOrigin::Signed(caller.clone()), caller.clone(), true)
-*/
 }
deletedpallets/nft/src/default_weights.rsdiffbeforeafterboth
--- a/pallets/nft/src/default_weights.rs
+++ /dev/null
@@ -1,155 +0,0 @@
-use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight};
-
-impl crate::WeightInfo for () {
-	fn create_collection() -> Weight {
-		70_000_000_u64
-			.saturating_add(DbWeight::get().reads(7_u64))
-			.saturating_add(DbWeight::get().writes(5_u64))
-	}
-	fn destroy_collection() -> Weight {
-		90_000_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(5_u64))
-	}
-	fn add_to_white_list() -> Weight {
-		30_000_000_u64
-			.saturating_add(DbWeight::get().reads(3_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn remove_from_white_list() -> Weight {
-		35_000_000_u64
-			.saturating_add(DbWeight::get().reads(3_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn set_public_access_mode() -> Weight {
-		27_000_000_u64
-			.saturating_add(DbWeight::get().reads(1_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn set_mint_permission() -> Weight {
-		27_000_000_u64
-			.saturating_add(DbWeight::get().reads(1_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn change_collection_owner() -> Weight {
-		27_000_000_u64
-			.saturating_add(DbWeight::get().reads(1_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn add_collection_admin() -> Weight {
-		32_000_000_u64
-			.saturating_add(DbWeight::get().reads(3_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn remove_collection_admin() -> Weight {
-		50_000_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn set_collection_sponsor() -> Weight {
-		32_000_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn confirm_sponsorship() -> Weight {
-		22_000_000_u64
-			.saturating_add(DbWeight::get().reads(1_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn remove_collection_sponsor() -> Weight {
-		24_000_000_u64
-			.saturating_add(DbWeight::get().reads(1_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn create_item(s: usize) -> Weight {
-		130_000_000_u64
-			.saturating_add(2135_u64.saturating_mul(s as Weight).saturating_mul(500_u64)) // 500 is temporary multiplier, fee for storage
-			.saturating_add(DbWeight::get().reads(10_u64))
-			.saturating_add(DbWeight::get().writes(8_u64))
-	}
-	fn burn_item() -> Weight {
-		170_000_000_u64
-			.saturating_add(DbWeight::get().reads(9_u64))
-			.saturating_add(DbWeight::get().writes(7_u64))
-	}
-	fn transfer() -> Weight {
-		125_000_000_u64
-			.saturating_add(DbWeight::get().reads(7_u64))
-			.saturating_add(DbWeight::get().writes(7_u64))
-	}
-	fn approve() -> Weight {
-		45_000_000_u64
-			.saturating_add(DbWeight::get().reads(3_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn transfer_from() -> Weight {
-		150_000_000_u64
-			.saturating_add(DbWeight::get().reads(9_u64))
-			.saturating_add(DbWeight::get().writes(8_u64))
-	}
-	fn set_offchain_schema() -> Weight {
-		33_000_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn set_const_on_chain_schema() -> Weight {
-		11_100_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn set_variable_on_chain_schema() -> Weight {
-		11_100_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn set_variable_meta_data() -> Weight {
-		17_500_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn enable_contract_sponsoring() -> Weight {
-		13_000_000_u64
-			.saturating_add(DbWeight::get().reads(1_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn set_schema_version() -> Weight {
-		8_500_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn set_chain_limits() -> Weight {
-		1_300_000_u64
-			.saturating_add(DbWeight::get().reads(0_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn set_contract_sponsoring_rate_limit() -> Weight {
-		3_500_000_u64
-			.saturating_add(DbWeight::get().reads(0_u64))
-			.saturating_add(DbWeight::get().writes(2_u64))
-	}
-	fn set_variable_meta_data_sponsoring_rate_limit() -> Weight {
-		3_500_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn toggle_contract_white_list() -> Weight {
-		3_000_000_u64
-			.saturating_add(DbWeight::get().reads(0_u64))
-			.saturating_add(DbWeight::get().writes(2_u64))
-	}
-	fn add_to_contract_white_list() -> Weight {
-		3_000_000_u64
-			.saturating_add(DbWeight::get().reads(0_u64))
-			.saturating_add(DbWeight::get().writes(2_u64))
-	}
-	fn remove_from_contract_white_list() -> Weight {
-		3_200_000_u64
-			.saturating_add(DbWeight::get().reads(0_u64))
-			.saturating_add(DbWeight::get().writes(2_u64))
-	}
-	fn set_collection_limits() -> Weight {
-		8_900_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-}
modifiedpallets/nft/src/eth/erc.rsdiffbeforeafterboth
--- a/pallets/nft/src/eth/erc.rs
+++ b/pallets/nft/src/eth/erc.rs
@@ -1,46 +1,72 @@
-use evm_coder::{solidity_interface, solidity, types::*, ToLog};
-use sp_std::vec::Vec;
+use core::char::{decode_utf16, REPLACEMENT_CHARACTER};
+use evm_coder::{ToLog, execution::Result, generate_stubgen, solidity, solidity_interface, types::*};
+use nft_data_structs::{CreateItemData, CreateNftData};
+use core::convert::TryInto;
+use crate::{
+	Allowances, Module, Balance, CollectionHandle, CollectionMode, Config, NftItemList,
+	ItemListIndex,
+};
+use frame_support::storage::{StorageMap, StorageDoubleMap};
+use pallet_evm::AddressMapping;
+use super::account::CrossAccountId;
+use sp_std::{vec, vec::Vec};
 
-#[solidity_interface]
-pub trait InlineNameSymbol {
-	type Error;
-
-	fn name(&self) -> Result<string, Self::Error>;
-	fn symbol(&self) -> Result<string, Self::Error>;
+#[solidity_interface(name = "ERC165")]
+impl<T: Config> CollectionHandle<T> {
+	fn supports_interface(&self, interface_id: bytes4) -> Result<bool> {
+		Ok(match self.mode {
+			CollectionMode::Fungible(_) => UniqueFungibleCall::supports_interface(interface_id),
+			CollectionMode::NFT => UniqueNFTCall::supports_interface(interface_id),
+			_ => false,
+		})
+	}
 }
 
-#[solidity_interface]
-pub trait InlineTotalSupply {
-	type Error;
+#[solidity_interface(name = "InlineNameSymbol")]
+impl<T: Config> CollectionHandle<T> {
+	fn name(&self) -> Result<string> {
+		Ok(decode_utf16(self.name.iter().copied())
+			.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
+			.collect::<string>())
+	}
 
-	fn total_supply(&self) -> Result<uint256, Self::Error>;
+	fn symbol(&self) -> Result<string> {
+		Ok(string::from_utf8_lossy(&self.token_prefix).into())
+	}
 }
 
-#[solidity_interface]
-pub trait ERC165 {
-	type Error;
-
-	fn supports_interface(&self, interface_id: bytes4) -> Result<bool, Self::Error>;
+#[solidity_interface(name = "InlineTotalSupply")]
+impl<T: Config> CollectionHandle<T> {
+	fn total_supply(&self) -> Result<uint256> {
+		// TODO: we do not track total amount of all tokens
+		Ok(0.into())
+	}
 }
 
-#[solidity_interface(inline_is(InlineNameSymbol))]
-pub trait ERC721Metadata {
-	type Error;
-
+#[solidity_interface(name = "ERC721Metadata", inline_is(InlineNameSymbol))]
+impl<T: Config> CollectionHandle<T> {
 	#[solidity(rename_selector = "tokenURI")]
-	fn token_uri(&self, token_id: uint256) -> Result<string, Self::Error>;
+	fn token_uri(&self, token_id: uint256) -> Result<string> {
+		let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
+		Ok(string::from_utf8_lossy(
+			&<NftItemList<T>>::get(self.id, token_id)
+				.ok_or("token not found")?
+				.const_data,
+		)
+		.into())
+	}
 }
 
-#[solidity_interface(inline_is(InlineTotalSupply))]
-pub trait ERC721Enumerable {
-	type Error;
+#[solidity_interface(name = "ERC721Enumerable", inline_is(InlineTotalSupply))]
+impl<T: Config> CollectionHandle<T> {
+	fn token_by_index(&self, index: uint256) -> Result<uint256> {
+		Ok(index)
+	}
 
-	fn token_by_index(&self, index: uint256) -> Result<uint256, Self::Error>;
-	fn token_of_owner_by_index(
-		&self,
-		owner: address,
-		index: uint256,
-	) -> Result<uint256, Self::Error>;
+	fn token_of_owner_by_index(&self, _owner: address, _index: uint256) -> Result<uint256> {
+		// TODO: Not implemetable
+		Err("not implemented".into())
+	}
 }
 
 #[derive(ToLog)]
@@ -71,29 +97,40 @@
 	},
 }
 
-#[solidity_interface(is(ERC165), events(ERC721Events))]
-pub trait ERC721 {
-	type Error;
-
-	fn balance_of(&self, owner: address) -> Result<uint256, Self::Error>;
-	fn owner_of(&self, token_id: uint256) -> Result<address, Self::Error>;
-
-	#[solidity(rename_selector = "safeTransferFrom")]
+#[solidity_interface(name = "ERC721", is(ERC165), events(ERC721Events))]
+impl<T: Config> CollectionHandle<T> {
+	#[solidity(rename_selector = "balanceOf")]
+	fn balance_of_nft(&self, owner: address) -> Result<uint256> {
+		let owner = T::EvmAddressMapping::into_account_id(owner);
+		let balance = <Balance<T>>::get(self.id, owner);
+		Ok(balance.into())
+	}
+	fn owner_of(&self, token_id: uint256) -> Result<address> {
+		let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
+		let token = <NftItemList<T>>::get(self.id, token_id).ok_or("unknown token")?;
+		Ok(*token.owner.as_eth())
+	}
 	fn safe_transfer_from_with_data(
 		&mut self,
-		from: address,
-		to: address,
-		token_id: uint256,
-		data: bytes,
-		value: value,
-	) -> Result<void, Self::Error>;
+		_from: address,
+		_to: address,
+		_token_id: uint256,
+		_data: bytes,
+		_value: value,
+	) -> Result<void> {
+		// TODO: Not implemetable
+		Err("not implemented".into())
+	}
 	fn safe_transfer_from(
 		&mut self,
-		from: address,
-		to: address,
-		token_id: uint256,
-		value: value,
-	) -> Result<void, Self::Error>;
+		_from: address,
+		_to: address,
+		_token_id: uint256,
+		_value: value,
+	) -> Result<void> {
+		// TODO: Not implemetable
+		Err("not implemented".into())
+	}
 
 	fn transfer_from(
 		&mut self,
@@ -101,54 +138,183 @@
 		from: address,
 		to: address,
 		token_id: uint256,
-		value: value,
-	) -> Result<void, Self::Error>;
+		_value: value,
+	) -> Result<void> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		let from = T::CrossAccountId::from_eth(from);
+		let to = T::CrossAccountId::from_eth(to);
+		let token_id = token_id.try_into().map_err(|_| "token_id overflow")?;
+
+		<Module<T>>::transfer_from_internal(&caller, &from, &to, self, token_id, 1)
+			.map_err(|_| "transferFrom error")?;
+		Ok(())
+	}
+
 	fn approve(
 		&mut self,
 		caller: caller,
 		approved: address,
 		token_id: uint256,
-		value: value,
-	) -> Result<void, Self::Error>;
+		_value: value,
+	) -> Result<void> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		let approved = T::CrossAccountId::from_eth(approved);
+		let token_id = token_id.try_into().map_err(|_| "token_id overflow")?;
+
+		<Module<T>>::approve_internal(&caller, &approved, self, token_id, 1)
+			.map_err(|_| "approve internal")?;
+		Ok(())
+	}
+
 	fn set_approval_for_all(
 		&mut self,
-		caller: caller,
-		operator: address,
-		approved: bool,
-	) -> Result<void, Self::Error>;
+		_caller: caller,
+		_operator: address,
+		_approved: bool,
+	) -> Result<void> {
+		// TODO: Not implemetable
+		Err("not implemented".into())
+	}
 
-	fn get_approved(&self, token_id: uint256) -> Result<address, Self::Error>;
-	fn is_approved_for_all(
-		&self,
-		owner: address,
-		operator: address,
-	) -> Result<address, Self::Error>;
+	fn get_approved(&self, _token_id: uint256) -> Result<address> {
+		// TODO: Not implemetable
+		Err("not implemented".into())
+	}
+
+	fn is_approved_for_all(&self, _owner: address, _operator: address) -> Result<address> {
+		// TODO: Not implemetable
+		Err("not implemented".into())
+	}
+}
+
+#[solidity_interface(name = "ERC721Burnable")]
+impl<T: Config> CollectionHandle<T> {
+	fn burn(&mut self, caller: caller, token_id: uint256) -> Result<void> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		let token_id = token_id.try_into().map_err(|_| "amount overflow")?;
+
+		<Module<T>>::burn_item_internal(&caller, &self, token_id, 1).map_err(|_| "burn error")?;
+		Ok(())
+	}
+}
+
+#[derive(ToLog)]
+pub enum ERC721MintableEvents {
+	#[allow(dead_code)]
+	MintingFinished {},
 }
 
-#[solidity_interface]
-pub trait ERC721UniqueExtensions {
-	type Error;
+#[solidity_interface(name = "ERC721Mintable", events(ERC721MintableEvents))]
+impl<T: Config> CollectionHandle<T> {
+	fn minting_finished(&self) -> Result<bool> {
+		Ok(false)
+	}
+
+	fn mint(&mut self, caller: caller, to: address, token_id: uint256) -> Result<bool> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		let to = T::CrossAccountId::from_eth(to);
+		let token_id: u32 = token_id.try_into().map_err(|_| "amount overflow")?;
+		if <ItemListIndex>::get(self.id)
+			.checked_add(1)
+			.ok_or("item id overflow")?
+			!= token_id
+		{
+			return Err("item id should be next".into());
+		}
+
+		<Module<T>>::create_item_internal(
+			&caller,
+			&self,
+			&to,
+			CreateItemData::NFT(CreateNftData {
+				const_data: vec![].try_into().unwrap(),
+				variable_data: vec![].try_into().unwrap(),
+			}),
+		)
+		.map_err(|_| "mint error")?;
+		Ok(true)
+	}
 
-	fn transfer(
+	#[solidity(rename_selector = "mintWithTokenURI")]
+	fn mint_with_token_uri(
 		&mut self,
 		caller: caller,
 		to: address,
 		token_id: uint256,
-		value: value,
-	) -> Result<void, Self::Error>;
+		token_uri: string,
+	) -> Result<bool> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		let to = T::CrossAccountId::from_eth(to);
+		let token_id: u32 = token_id.try_into().map_err(|_| "amount overflow")?;
+		if <ItemListIndex>::get(self.id)
+			.checked_add(1)
+			.ok_or("item id overflow")?
+			!= token_id
+		{
+			return Err("item id should be next".into());
+		}
+
+		<Module<T>>::create_item_internal(
+			&caller,
+			&self,
+			&to,
+			CreateItemData::NFT(CreateNftData {
+				const_data: Vec::<u8>::from(token_uri)
+					.try_into()
+					.map_err(|_| "token uri is too long")?,
+				variable_data: vec![].try_into().unwrap(),
+			}),
+		)
+		.map_err(|_| "mint error")?;
+		Ok(true)
+	}
+
+	fn finish_minting(&mut self, _caller: caller) -> Result<bool> {
+		Err("not implementable".into())
+	}
 }
 
-#[solidity_interface(is(
-	ERC165,
-	ERC721,
-	ERC721Metadata,
-	ERC721Enumerable,
-	ERC721UniqueExtensions
-))]
-pub trait UniqueNFT {
-	type Error;
+#[solidity_interface(name = "ERC721UniqueExtensions")]
+impl<T: Config> CollectionHandle<T> {
+	#[solidity(rename_selector = "transfer")]
+	fn transfer_nft(
+		&mut self,
+		caller: caller,
+		to: address,
+		token_id: uint256,
+		_value: value,
+	) -> Result<void> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		let to = T::CrossAccountId::from_eth(to);
+		let token_id = token_id.try_into().map_err(|_| "amount overflow")?;
+
+		<Module<T>>::transfer_internal(&caller, &to, self, token_id, 1)
+			.map_err(|_| "transfer error")?;
+		Ok(())
+	}
+
+	fn next_token_id(&self) -> Result<uint256> {
+		Ok(ItemListIndex::get(self.id)
+			.checked_add(1)
+			.ok_or("item id overflow")?
+			.into())
+	}
 }
 
+#[solidity_interface(
+	name = "UniqueNFT",
+	is(
+		ERC165,
+		ERC721,
+		ERC721Metadata,
+		ERC721Enumerable,
+		ERC721UniqueExtensions,
+		ERC721Mintable,
+		ERC721Burnable,
+	)
+)]
+impl<T: Config> CollectionHandle<T> {}
+
 #[derive(ToLog)]
 pub enum ERC20Events {
 	Transfer {
@@ -167,35 +333,79 @@
 	},
 }
 
-#[solidity_interface(inline_is(InlineNameSymbol, InlineTotalSupply), events(ERC20Events))]
-pub trait ERC20 {
-	type Error;
+#[solidity_interface(
+	name = "ERC20",
+	inline_is(InlineNameSymbol, InlineTotalSupply),
+	events(ERC20Events)
+)]
+impl<T: Config> CollectionHandle<T> {
+	fn decimals(&self) -> Result<uint8> {
+		Ok(if let CollectionMode::Fungible(decimals) = &self.mode {
+			*decimals
+		} else {
+			unreachable!()
+		})
+	}
+	fn balance_of(&self, owner: address) -> Result<uint256> {
+		let owner = T::EvmAddressMapping::into_account_id(owner);
+		let balance = <Balance<T>>::get(self.id, owner);
+		Ok(balance.into())
+	}
+	fn transfer(&mut self, caller: caller, to: address, amount: uint256) -> Result<bool> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		let to = T::CrossAccountId::from_eth(to);
+		let amount = amount.try_into().map_err(|_| "amount overflow")?;
 
-	fn decimals(&self) -> Result<uint8, Self::Error>;
-	fn balance_of(&self, owner: address) -> Result<uint256, Self::Error>;
-	fn transfer(
-		&mut self,
-		caller: caller,
-		to: address,
-		value: uint256,
-	) -> Result<bool, Self::Error>;
-	fn transfer_from(
+		<Module<T>>::transfer_internal(&caller, &to, self, 1, amount)
+			.map_err(|_| "transfer error")?;
+		Ok(true)
+	}
+	#[solidity(rename_selector = "transferFrom")]
+	fn transfer_from_fungible(
 		&mut self,
 		caller: caller,
 		from: address,
 		to: address,
-		value: uint256,
-	) -> Result<bool, Self::Error>;
-	fn approve(
+		amount: uint256,
+	) -> Result<bool> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		let from = T::CrossAccountId::from_eth(from);
+		let to = T::CrossAccountId::from_eth(to);
+		let amount = amount.try_into().map_err(|_| "amount overflow")?;
+
+		<Module<T>>::transfer_from_internal(&caller, &from, &to, self, 1, amount)
+			.map_err(|_| "transferFrom error")?;
+		Ok(true)
+	}
+	#[solidity(rename_selector = "approve")]
+	fn approve_fungible(
 		&mut self,
 		caller: caller,
 		spender: address,
-		value: uint256,
-	) -> Result<bool, Self::Error>;
-	fn allowance(&self, owner: address, spender: address) -> Result<uint256, Self::Error>;
-}
+		amount: uint256,
+	) -> Result<bool> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		let spender = T::CrossAccountId::from_eth(spender);
+		let amount = amount.try_into().map_err(|_| "amount overflow")?;
 
-#[solidity_interface(is(ERC165, ERC20))]
-pub trait UniqueFungible {
-	type Error;
+		<Module<T>>::approve_internal(&caller, &spender, self, 1, amount)
+			.map_err(|_| "approve internal")?;
+		Ok(true)
+	}
+	fn allowance(&self, owner: address, spender: address) -> Result<uint256> {
+		let owner = T::CrossAccountId::from_eth(owner);
+		let spender = T::CrossAccountId::from_eth(spender);
+
+		Ok(<Allowances<T>>::get(self.id, (1, owner.as_sub(), spender.as_sub())).into())
+	}
 }
+
+#[solidity_interface(name = "UniqueFungible", is(ERC165, ERC20))]
+impl<T: Config> CollectionHandle<T> {}
+
+// Not a tests, but code generators
+generate_stubgen!(nft_impl, UniqueNFTCall, true);
+generate_stubgen!(nft_iface, UniqueNFTCall, false);
+
+generate_stubgen!(fungible_impl, UniqueFungibleCall, true);
+generate_stubgen!(fungible_iface, UniqueFungibleCall, false);
deletedpallets/nft/src/eth/erc_impl.rsdiffbeforeafterboth
--- a/pallets/nft/src/eth/erc_impl.rs
+++ /dev/null
@@ -1,283 +0,0 @@
-use core::char::{decode_utf16, REPLACEMENT_CHARACTER};
-use evm_coder::{
-	abi::{AbiWriter, StringError},
-	types::*,
-};
-use core::convert::TryInto;
-use alloc::format;
-use crate::{Allowances, Module, Balance, CollectionHandle, CollectionMode, Config, NftItemList};
-use frame_support::storage::StorageDoubleMap;
-use pallet_evm::AddressMapping;
-use super::erc::*;
-use super::account::CrossAccountId;
-
-type Result<T> = core::result::Result<T, StringError>;
-
-impl<T: Config> InlineNameSymbol for CollectionHandle<T> {
-	type Error = StringError;
-
-	fn name(&self) -> Result<string> {
-		Ok(decode_utf16(self.name.iter().copied())
-			.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
-			.collect::<string>())
-	}
-
-	fn symbol(&self) -> Result<string> {
-		Ok(string::from_utf8_lossy(&self.token_prefix).into())
-	}
-}
-
-impl<T: Config> InlineTotalSupply for CollectionHandle<T> {
-	type Error = StringError;
-
-	fn total_supply(&self) -> Result<uint256> {
-		// TODO: we do not track total amount of all tokens
-		Ok(0.into())
-	}
-}
-
-impl<T: Config> ERC721Metadata for CollectionHandle<T> {
-	type Error = StringError;
-
-	fn token_uri(&self, token_id: uint256) -> Result<string> {
-		// TODO: We should standartize url prefix, maybe via offchain schema?
-		Ok(format!("unique.network/{}/{}", self.id, token_id))
-	}
-
-	fn call_inline_name_symbol(&mut self, c: Msg<InlineNameSymbolCall>) -> Result<AbiWriter> {
-		<Self as InlineNameSymbol>::call(self, c)
-	}
-}
-
-impl<T: Config> ERC721Enumerable for CollectionHandle<T> {
-	type Error = StringError;
-
-	fn token_by_index(&self, index: uint256) -> Result<uint256> {
-		Ok(index)
-	}
-
-	fn token_of_owner_by_index(&self, _owner: address, _index: uint256) -> Result<uint256> {
-		// TODO: Not implemetable
-		Err("not implemented".into())
-	}
-
-	fn call_inline_total_supply(&mut self, c: Msg<InlineTotalSupplyCall>) -> Result<AbiWriter> {
-		<Self as InlineTotalSupply>::call(self, c)
-	}
-}
-
-impl<T: Config> ERC721 for CollectionHandle<T> {
-	type Error = StringError;
-
-	fn balance_of(&self, owner: address) -> Result<uint256> {
-		let owner = T::EvmAddressMapping::into_account_id(owner);
-		let balance = <Balance<T>>::get(self.id, owner);
-		Ok(balance.into())
-	}
-	fn owner_of(&self, token_id: uint256) -> Result<address> {
-		let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
-		let token = <NftItemList<T>>::get(self.id, token_id).ok_or("unknown token")?;
-		Ok(*token.owner.as_eth())
-	}
-	fn safe_transfer_from_with_data(
-		&mut self,
-		_from: address,
-		_to: address,
-		_token_id: uint256,
-		_data: bytes,
-		_value: value,
-	) -> Result<void> {
-		// TODO: Not implemetable
-		Err("not implemented".into())
-	}
-	fn safe_transfer_from(
-		&mut self,
-		_from: address,
-		_to: address,
-		_token_id: uint256,
-		_value: value,
-	) -> Result<void> {
-		// TODO: Not implemetable
-		Err("not implemented".into())
-	}
-
-	fn transfer_from(
-		&mut self,
-		caller: caller,
-		from: address,
-		to: address,
-		token_id: uint256,
-		_value: value,
-	) -> Result<void> {
-		let caller = T::CrossAccountId::from_eth(caller);
-		let from = T::CrossAccountId::from_eth(from);
-		let to = T::CrossAccountId::from_eth(to);
-		let token_id = token_id.try_into().map_err(|_| "token_id overflow")?;
-
-		<Module<T>>::transfer_from_internal(&caller, &from, &to, self, token_id, 1)
-			.map_err(|_| "transferFrom error")?;
-		Ok(())
-	}
-
-	fn approve(
-		&mut self,
-		caller: caller,
-		approved: address,
-		token_id: uint256,
-		_value: value,
-	) -> Result<void> {
-		let caller = T::CrossAccountId::from_eth(caller);
-		let approved = T::CrossAccountId::from_eth(approved);
-		let token_id = token_id.try_into().map_err(|_| "token_id overflow")?;
-
-		<Module<T>>::approve_internal(&caller, &approved, self, token_id, 1)
-			.map_err(|_| "approve internal")?;
-		Ok(())
-	}
-
-	fn set_approval_for_all(
-		&mut self,
-		_caller: caller,
-		_operator: address,
-		_approved: bool,
-	) -> Result<void> {
-		// TODO: Not implemetable
-		Err("not implemented".into())
-	}
-
-	fn get_approved(&self, _token_id: uint256) -> Result<address> {
-		// TODO: Not implemetable
-		Err("not implemented".into())
-	}
-
-	fn is_approved_for_all(&self, _owner: address, _operator: address) -> Result<address> {
-		// TODO: Not implemetable
-		Err("not implemented".into())
-	}
-
-	fn call_erc165(&mut self, c: Msg<ERC165Call>) -> Result<AbiWriter> {
-		let ERC165Call::SupportsInterface { interface_id } = c.call;
-		Ok(evm_coder::abi_encode!(bool(
-			&ERC721Call::supports_interface(interface_id)
-		)))
-	}
-}
-
-impl<T: Config> ERC721UniqueExtensions for CollectionHandle<T> {
-	type Error = StringError;
-	fn transfer(
-		&mut self,
-		caller: caller,
-		to: address,
-		token_id: uint256,
-		_value: value,
-	) -> Result<void> {
-		let caller = T::CrossAccountId::from_eth(caller);
-		let to = T::CrossAccountId::from_eth(to);
-		let token_id = token_id.try_into().map_err(|_| "amount overflow")?;
-
-		<Module<T>>::transfer_internal(&caller, &to, self, token_id, 1)
-			.map_err(|_| "transfer error")?;
-		Ok(())
-	}
-}
-
-impl<T: Config> UniqueNFT for CollectionHandle<T> {
-	type Error = StringError;
-	fn call_erc165(&mut self, c: Msg<ERC165Call>) -> Result<AbiWriter> {
-		let ERC165Call::SupportsInterface { interface_id } = c.call;
-		Ok(evm_coder::abi_encode!(bool(
-			&UniqueNFTCall::supports_interface(interface_id)
-		)))
-	}
-	fn call_erc721(&mut self, c: Msg<ERC721Call>) -> Result<AbiWriter> {
-		<Self as ERC721>::call(self, c)
-	}
-	fn call_erc721_metadata(&mut self, c: Msg<ERC721MetadataCall>) -> Result<AbiWriter> {
-		<Self as ERC721Metadata>::call(self, c)
-	}
-	fn call_erc721_enumerable(&mut self, c: Msg<ERC721EnumerableCall>) -> Result<AbiWriter> {
-		<Self as ERC721Enumerable>::call(self, c)
-	}
-	fn call_erc721_unique_extensions(
-		&mut self,
-		c: Msg<ERC721UniqueExtensionsCall>,
-	) -> Result<AbiWriter> {
-		<Self as ERC721UniqueExtensions>::call(self, c)
-	}
-}
-
-impl<T: Config> ERC20 for CollectionHandle<T> {
-	type Error = StringError;
-	fn decimals(&self) -> Result<uint8> {
-		Ok(if let CollectionMode::Fungible(decimals) = &self.mode {
-			*decimals
-		} else {
-			unreachable!()
-		})
-	}
-	fn balance_of(&self, owner: address) -> Result<uint256> {
-		let owner = T::EvmAddressMapping::into_account_id(owner);
-		let balance = <Balance<T>>::get(self.id, owner);
-		Ok(balance.into())
-	}
-	fn transfer(&mut self, caller: caller, to: address, amount: uint256) -> Result<bool> {
-		let caller = T::CrossAccountId::from_eth(caller);
-		let to = T::CrossAccountId::from_eth(to);
-		let amount = amount.try_into().map_err(|_| "amount overflow")?;
-
-		<Module<T>>::transfer_internal(&caller, &to, self, 1, amount)
-			.map_err(|_| "transfer error")?;
-		Ok(true)
-	}
-	fn transfer_from(
-		&mut self,
-		caller: caller,
-		from: address,
-		to: address,
-		amount: uint256,
-	) -> Result<bool> {
-		let caller = T::CrossAccountId::from_eth(caller);
-		let from = T::CrossAccountId::from_eth(from);
-		let to = T::CrossAccountId::from_eth(to);
-		let amount = amount.try_into().map_err(|_| "amount overflow")?;
-
-		<Module<T>>::transfer_from_internal(&caller, &from, &to, self, 1, amount)
-			.map_err(|_| "transferFrom error")?;
-		Ok(true)
-	}
-	fn approve(&mut self, caller: caller, spender: address, amount: uint256) -> Result<bool> {
-		let caller = T::CrossAccountId::from_eth(caller);
-		let spender = T::CrossAccountId::from_eth(spender);
-		let amount = amount.try_into().map_err(|_| "amount overflow")?;
-
-		<Module<T>>::approve_internal(&caller, &spender, self, 1, amount)
-			.map_err(|_| "approve internal")?;
-		Ok(true)
-	}
-	fn allowance(&self, owner: address, spender: address) -> Result<uint256> {
-		let owner = T::CrossAccountId::from_eth(owner);
-		let spender = T::CrossAccountId::from_eth(spender);
-
-		Ok(<Allowances<T>>::get(self.id, (1, owner.as_sub(), spender.as_sub())).into())
-	}
-	fn call_inline_name_symbol(&mut self, c: Msg<InlineNameSymbolCall>) -> Result<AbiWriter> {
-		<Self as InlineNameSymbol>::call(self, c)
-	}
-	fn call_inline_total_supply(&mut self, c: Msg<InlineTotalSupplyCall>) -> Result<AbiWriter> {
-		<Self as InlineTotalSupply>::call(self, c)
-	}
-}
-
-impl<T: Config> UniqueFungible for CollectionHandle<T> {
-	type Error = StringError;
-	fn call_erc165(&mut self, c: Msg<ERC165Call>) -> Result<AbiWriter> {
-		let ERC165Call::SupportsInterface { interface_id } = c.call;
-		Ok(evm_coder::abi_encode!(bool(
-			&UniqueNFTCall::supports_interface(interface_id)
-		)))
-	}
-	fn call_erc20(&mut self, c: Msg<ERC20Call>) -> Result<AbiWriter> {
-		<Self as ERC20>::call(self, c)
-	}
-}
deletedpallets/nft/src/eth/log.rsdiffbeforeafterboth
--- a/pallets/nft/src/eth/log.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-use sp_std::cell::RefCell;
-use sp_std::vec::Vec;
-
-use ethereum::Log;
-
-#[derive(Default)]
-pub struct LogRecorder(RefCell<Vec<Log>>);
-
-impl LogRecorder {
-	pub fn is_empty(&self) -> bool {
-		self.0.borrow().is_empty()
-	}
-	pub fn log(&self, log: Log) {
-		self.0.borrow_mut().push(log);
-	}
-	pub fn retrieve_logs(self) -> Vec<Log> {
-		self.0.into_inner()
-	}
-}
modifiedpallets/nft/src/eth/mod.rsdiffbeforeafterboth
--- a/pallets/nft/src/eth/mod.rs
+++ b/pallets/nft/src/eth/mod.rs
@@ -1,23 +1,15 @@
 pub mod account;
 pub mod erc;
-mod erc_impl;
-pub mod log;
 pub mod sponsoring;
 
-use evm_coder::abi::AbiWriter;
-use evm_coder::abi::StringError;
-use sp_std::prelude::*;
+use pallet_evm_coder_substrate::call_internal;
 use sp_std::borrow::ToOwned;
 use sp_std::vec::Vec;
-
-use pallet_evm::{PrecompileOutput, ExitReason, ExitRevert, ExitSucceed};
+use pallet_evm::{PrecompileOutput};
 use sp_core::{H160, U256};
 use frame_support::storage::StorageMap;
-
 use crate::{Config, CollectionById, CollectionHandle, CollectionId, CollectionMode};
-
-use erc::{UniqueFungible, UniqueFungibleCall, UniqueNFT, UniqueNFTCall};
-use evm_coder::{types::*, abi::AbiReader};
+use erc::{UniqueFungibleCall, UniqueNFTCall};
 
 pub struct NftErcSupport<T: Config>(core::marker::PhantomData<T>);
 
@@ -42,19 +34,17 @@
 	H160(out)
 }
 
+/*
 fn call_internal<T: Config>(
 	collection: &mut CollectionHandle<T>,
 	caller: caller,
 	method_id: u32,
 	mut input: AbiReader,
 	value: U256,
-) -> Result<Option<AbiWriter>, evm_coder::abi::StringError> {
+) -> Result<Option<AbiWriter>> {
 	match collection.mode.clone() {
 		CollectionMode::Fungible(_) => {
-			#[cfg(feature = "std")]
-			{
-				println!("Parse fungible call {:x}", method_id);
-			}
+			call_internal();
 			let call = match UniqueFungibleCall::parse(method_id, &mut input)? {
 				Some(v) => v,
 				None => {
@@ -65,10 +55,6 @@
 					return Ok(None);
 				}
 			};
-			#[cfg(feature = "std")]
-			{
-				dbg!(&call);
-			}
 			Ok(Some(<CollectionHandle<T> as UniqueFungible>::call(
 				collection,
 				Msg {
@@ -92,11 +78,9 @@
 				},
 			)?))
 		}
-		_ => Err(StringError::from(
-			"erc calls only supported to fungible and nft collections for now",
-		)),
+		_ => Err("erc calls only supported to fungible and nft collections for now".into()),
 	}
-}
+}*/
 
 impl<T: Config> pallet_evm::OnMethodCall<T> for NftErcSupport<T> {
 	fn is_reserved(target: &H160) -> bool {
@@ -112,10 +96,14 @@
 			.and_then(<CollectionById<T>>::get)
 			.map(|collection| {
 				match collection.mode {
-					CollectionMode::NFT => include_bytes!("stubs/ERC721.bin") as &[u8],
-					CollectionMode::Fungible(_) => include_bytes!("stubs/ERC20.bin") as &[u8],
-					CollectionMode::ReFungible => include_bytes!("stubs/ERC1633.bin") as &[u8],
-					CollectionMode::Invalid => include_bytes!("stubs/Invalid.bin") as &[u8],
+					CollectionMode::NFT => include_bytes!("stubs/UniqueNFT.raw") as &[u8],
+					CollectionMode::Fungible(_) => {
+						include_bytes!("stubs/UniqueFungible.raw") as &[u8]
+					}
+					CollectionMode::ReFungible => {
+						include_bytes!("stubs/UniqueRefungible.raw") as &[u8]
+					}
+					CollectionMode::Invalid => include_bytes!("stubs/UniqueInvalid.raw") as &[u8],
 				}
 				.to_owned()
 			})
@@ -129,56 +117,15 @@
 	) -> Option<PrecompileOutput> {
 		let mut collection = map_eth_to_id(target)
 			.and_then(|id| <CollectionHandle<T>>::get_with_gas_limit(id, gas_limit))?;
-		let (method_id, input) = AbiReader::new_call(input).unwrap();
-		let result = call_internal(&mut collection, *source, method_id, input, value);
-		let cost = gas_limit - collection.gas_left();
-		let logs = collection.logs.retrieve_logs();
-		match result {
-			Ok(Some(v)) => Some(PrecompileOutput {
-				exit_status: ExitReason::Succeed(ExitSucceed::Returned),
-				cost,
-				logs,
-				output: v.finish(),
-			}),
-			Ok(None) => None,
-			Err(e) => Some(PrecompileOutput {
-				exit_status: ExitReason::Revert(ExitRevert::Reverted),
-				cost: 0,
-				logs: Default::default(),
-				output: AbiWriter::from(e).finish(),
-			}),
-		}
-	}
-}
-
-// TODO: This function is slow, and output can be memoized
-pub fn generate_transaction(collection_id: u32, chain_id: u64) -> ethereum::Transaction {
-	// FIXME: Can be done on wasm runtime with https://github.com/paritytech/substrate/pull/8728
-	#[cfg(feature = "std")]
-	{
-		let contract = collection_id_to_address(collection_id);
-		let signed = ethereum_tx_sign::RawTransaction {
-			nonce: 0.into(),
-			to: Some(contract.0.into()),
-			value: 0.into(),
-			gas_price: 0.into(),
-			gas: 0.into(),
-			// zero selector, this transaction always have same sender, so all data should be acquired from logs
-			data: Vec::from([0, 0, 0, 0]),
-		}
-		.sign(
-			// TODO: move to pallet config
-			// 0xF70631E55faff9f3FD3681545aa6c724226a3853
-			// 9dbaef9b3ebc00e53f67c6a77bcfbf2c4f2aebe4d70d94af4f2df01744b7a91a
-			&hex_literal::hex!("9dbaef9b3ebc00e53f67c6a77bcfbf2c4f2aebe4d70d94af4f2df01744b7a91a")
-				.into(),
-			&chain_id,
-		);
-		rlp::decode::<ethereum::Transaction>(&signed)
-			.expect("transaction is just created, it can't be broken")
-	}
-	#[cfg(not(feature = "std"))]
-	{
-		panic!("transaction generation not yet supported by wasm runtime while generating transaction for collection_id {}, chain_id {}", collection_id, chain_id)
+		let result = match collection.mode {
+			CollectionMode::NFT => {
+				call_internal::<UniqueNFTCall, _>(*source, &mut collection, value, input)
+			}
+			CollectionMode::Fungible(_) => {
+				call_internal::<UniqueFungibleCall, _>(*source, &mut collection, value, input)
+			}
+			_ => return None,
+		};
+		collection.recorder.evm_to_precompile_output(result)
 	}
 }
modifiedpallets/nft/src/eth/sponsoring.rsdiffbeforeafterboth
--- a/pallets/nft/src/eth/sponsoring.rs
+++ b/pallets/nft/src/eth/sponsoring.rs
@@ -1,35 +1,23 @@
 //! Implements EVM sponsoring logic via OnChargeEVMTransaction
 
 use crate::{
-	Collection, ChainLimit, CollectionById, Config, NftTransferBasket, FungibleTransferBasket,
-	eth::account::EvmBackwardsAddressMapping,
+	Collection, CollectionById, Config, FungibleTransferBasket, NftTransferBasket,
+	eth::{account::EvmBackwardsAddressMapping, map_eth_to_id},
 };
-use evm_coder::abi::AbiReader;
+use evm_coder::{Call, abi::AbiReader};
 use frame_support::{
-	storage::{StorageMap, StorageDoubleMap, StorageValue},
-	traits::Currency,
+	storage::{StorageMap, StorageDoubleMap},
 };
-use pallet_evm::{EVMCurrencyAdapter, WithdrawReason};
-use sp_core::{H160, U256};
+use sp_core::H160;
 use sp_std::prelude::*;
+use up_sponsorship::SponsorshipHandler;
 use super::{
 	account::CrossAccountId,
 	erc::{UniqueFungibleCall, UniqueNFTCall, ERC721Call, ERC20Call, ERC721UniqueExtensionsCall},
 };
 use core::convert::TryInto;
-
-type NegativeImbalanceOf<C, T> =
-	<C as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance;
-
-pub struct ChargeEvmTransaction;
-pub struct ChargeEvmLiquidityInfo<T>
-where
-	T: Config,
-	T: pallet_evm::Config,
-{
-	who: H160,
-	negative_imbalance: NegativeImbalanceOf<<T as Config>::Currency, T>,
-}
+use core::marker::PhantomData;
+use nft_data_structs::{NFT_SPONSOR_TRANSFER_TIMEOUT, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT};
 
 struct AnyError;
 
@@ -46,10 +34,9 @@
 				.map_err(|_| AnyError)?
 				.ok_or(AnyError)?;
 			match call {
-				UniqueNFTCall::ERC721UniqueExtensions(ERC721UniqueExtensionsCall::Transfer {
-					token_id,
-					..
-				})
+				UniqueNFTCall::ERC721UniqueExtensions(
+					ERC721UniqueExtensionsCall::TransferNft { token_id, .. },
+				)
 				| UniqueNFTCall::ERC721(ERC721Call::TransferFrom { token_id, .. }) => {
 					let token_id: u32 = token_id.try_into().map_err(|_| AnyError)?;
 					let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
@@ -57,7 +44,7 @@
 					let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {
 						collection_limits.sponsor_transfer_timeout
 					} else {
-						ChainLimit::get().nft_sponsor_transfer_timeout
+						NFT_SPONSOR_TRANSFER_TIMEOUT
 					};
 
 					let mut sponsor = true;
@@ -88,7 +75,7 @@
 					let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {
 						collection_limits.sponsor_transfer_timeout
 					} else {
-						ChainLimit::get().fungible_sponsor_transfer_timeout
+						FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT
 					};
 
 					let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
@@ -117,54 +104,24 @@
 	}
 	Err(AnyError)
 }
-
-impl<T> pallet_evm::OnChargeEVMTransaction<T> for ChargeEvmTransaction
-where
-	T: Config,
-	T: pallet_evm::Config,
-{
-	type LiquidityInfo = Option<ChargeEvmLiquidityInfo<T>>;
 
-	fn withdraw_fee(
-		who: &H160,
-		reason: WithdrawReason,
-		fee: U256,
-	) -> Result<Self::LiquidityInfo, pallet_evm::Error<T>> {
-		let mut who_pays_fee = *who;
-		if let WithdrawReason::Call { target, input } = &reason {
-			if let Some(collection_id) = crate::eth::map_eth_to_id(target) {
-				if let Some(collection) = <CollectionById<T>>::get(collection_id) {
-					if let Some(sponsor) = collection.sponsorship.sponsor() {
-						if try_sponsor(who, collection_id, &collection, input).is_ok() {
-							who_pays_fee =
-								T::EvmBackwardsAddressMapping::from_account_id(sponsor.clone());
-						}
-					}
+pub struct NftEthSponsorshipHandler<T: Config>(PhantomData<*const T>);
+impl<T: Config> SponsorshipHandler<H160, (H160, Vec<u8>)> for NftEthSponsorshipHandler<T> {
+	fn get_sponsor(who: &H160, call: &(H160, Vec<u8>)) -> Option<H160> {
+		if let Some(collection_id) = map_eth_to_id(&call.0) {
+			if let Some(collection) = <CollectionById<T>>::get(collection_id) {
+				if !collection.sponsorship.confirmed() {
+					return None;
+				}
+				if try_sponsor(who, collection_id, &collection, &call.1).is_ok() {
+					return collection
+						.sponsorship
+						.sponsor()
+						.cloned()
+						.map(T::EvmBackwardsAddressMapping::from_account_id);
 				}
 			}
 		}
-
-		// TODO: Pay fee from substrate address
-		let negative_imbalance = EVMCurrencyAdapter::<<T as Config>::Currency, ()>::withdraw_fee(
-			&who_pays_fee,
-			reason,
-			fee,
-		)?;
-		Ok(negative_imbalance.map(|i| ChargeEvmLiquidityInfo {
-			who: who_pays_fee,
-			negative_imbalance: i,
-		}))
-	}
-
-	fn correct_and_deposit_fee(
-		who: &H160,
-		corrected_fee: U256,
-		already_withdrawn: Self::LiquidityInfo,
-	) -> Result<(), pallet_evm::Error<T>> {
-		EVMCurrencyAdapter::<<T as Config>::Currency, ()>::correct_and_deposit_fee(
-			&already_withdrawn.as_ref().map(|e| e.who).unwrap_or(*who),
-			corrected_fee,
-			already_withdrawn.map(|e| e.negative_imbalance),
-		)
+		None
 	}
 }
deletedpallets/nft/src/eth/stubs/ERC1633.bindiffbeforeafterboth
--- a/pallets/nft/src/eth/stubs/ERC1633.bin
+++ /dev/null
@@ -1 +0,0 @@
-TODO
\ No newline at end of file
deletedpallets/nft/src/eth/stubs/ERC20.bindiffbeforeafterboth

binary blob — no preview

deletedpallets/nft/src/eth/stubs/ERC20.soldiffbeforeafterboth
--- a/pallets/nft/src/eth/stubs/ERC20.sol
+++ /dev/null
@@ -1,69 +0,0 @@
-// SPDX-License-Identifier: OTHER
-
-pragma solidity >=0.8.0 <0.9.0;
-
-contract ERC20 {
-	uint8 _dummy = 0;
-	string stub_error = "this contract does not exists, code for collections is implemented at pallet side";
-
-	// 0x18160ddd
-	function totalSupply() external view returns (uint256) {
-		require(false, stub_error);
-		_dummy;
-		return 0;
-	}
-
-	// 0x70a08231
-	function balanceOf(address account) external view returns (uint256) {
-		require(false, stub_error);
-		account;
-		_dummy;
-		return 0;
-	}
-
-	// 0xa9059cbb
-	function transfer(address recipient, uint256 amount) external returns (bool) {
-		require(false, stub_error);
-		recipient;
-		amount;
-		_dummy = 0;
-		return false;
-	}
-
-	// 0xdd62ed3e
-	function allowance(address owner, address spender) external view returns (uint256) {
-		require(false, stub_error);
-		owner;
-		spender;
-		return _dummy;
-	}
-
-	// 0x095ea7b3
-	function approve(address spender, uint256 amount) external returns (bool) {
-		require(false, stub_error);
-		spender;
-		amount;
-		_dummy = 0;
-		return false;
-	}
-
-	// 0x23b872dd
-	function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) {
-		require(false, stub_error);
-		sender;
-		recipient;
-		amount;
-		_dummy = 0;
-		return false;
-	}
-
-	// While ERC165 is not required by spec of ERC20, better implement it
-	// 0x01ffc9a7
-	function supportsInterface(bytes4 interfaceID) public pure returns (bool) {
-		return 
-			// ERC20
-			interfaceID == 0x36372b07 || 
-			// ERC165
-			interfaceID == 0x01ffc9a7;
-	}
-}
\ No newline at end of file
deletedpallets/nft/src/eth/stubs/ERC721.bindiffbeforeafterboth
--- a/pallets/nft/src/eth/stubs/ERC721.bin
+++ /dev/null
@@ -1 +0,0 @@
-0x608060405260008060006101000a81548160ff021916908360ff16021790555060008060016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060405180608001604052806051815260200162000cd6605191396001908051906020019061008f9291906100a2565b5034801561009c57600080fd5b506101a6565b8280546100ae90610145565b90600052602060002090601f0160209004810192826100d05760008555610117565b82601f106100e957805160ff1916838001178555610117565b82800160010185558215610117579182015b828111156101165782518255916020019190600101906100fb565b5b5090506101249190610128565b5090565b5b80821115610141576000816000905550600101610129565b5090565b6000600282049050600182168061015d57607f821691505b6020821081141561017157610170610177565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b610b2080620001b66000396000f3fe6080604052600436106100915760003560e01c80636352211e116100595780636352211e1461016457806370a08231146101a1578063a22cb465146101de578063b88d4fde14610207578063e985e9c51461022357610091565b806301ffc9a714610096578063081812fc146100d3578063095ea7b31461011057806323b872dd1461012c57806342842e0e14610148575b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190610821565b610260565b6040516100ca919061093b565b60405180910390f35b3480156100df57600080fd5b506100fa60048036038101906100f5919061084a565b6102c2565b6040516101079190610920565b60405180910390f35b61012a600480360381019061012591906107e5565b610333565b005b610146600480360381019061014191906106da565b61037d565b005b610162600480360381019061015d91906106da565b6103c8565b005b34801561017057600080fd5b5061018b6004803603810190610186919061084a565b610413565b6040516101989190610920565b60405180910390f35b3480156101ad57600080fd5b506101c860048036038101906101c39190610675565b610484565b6040516101d59190610978565b60405180910390f35b3480156101ea57600080fd5b50610205600480360381019061020091906107a9565b6104d4565b005b610221600480360381019061021c9190610729565b610539565b005b34801561022f57600080fd5b5061024a6004803603810190610245919061069e565b610586565b604051610257919061093b565b60405180910390f35b60006380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806102bb57506301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600080600190610308576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102ff9190610956565b60405180910390fd5b50600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600190610378576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161036f9190610956565b60405180910390fd5b505050565b60006001906103c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103b99190610956565b60405180910390fd5b50505050565b600060019061040d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104049190610956565b60405180910390fd5b50505050565b600080600190610459576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104509190610956565b60405180910390fd5b50600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000806001906104ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104c19190610956565b60405180910390fd5b5060009050919050565b6000600190610519576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105109190610956565b60405180910390fd5b5060008060006101000a81548160ff021916908360ff1602179055505050565b600060019061057e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105759190610956565b60405180910390fd5b505050505050565b6000806001906105cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105c39190610956565b60405180910390fd5b506000905092915050565b6000813590506105e681610a8e565b92915050565b6000813590506105fb81610aa5565b92915050565b60008135905061061081610abc565b92915050565b60008083601f84011261062857600080fd5b8235905067ffffffffffffffff81111561064157600080fd5b60208301915083600182028301111561065957600080fd5b9250929050565b60008135905061066f81610ad3565b92915050565b60006020828403121561068757600080fd5b6000610695848285016105d7565b91505092915050565b600080604083850312156106b157600080fd5b60006106bf858286016105d7565b92505060206106d0858286016105d7565b9150509250929050565b6000806000606084860312156106ef57600080fd5b60006106fd868287016105d7565b935050602061070e868287016105d7565b925050604061071f86828701610660565b9150509250925092565b60008060008060006080868803121561074157600080fd5b600061074f888289016105d7565b9550506020610760888289016105d7565b945050604061077188828901610660565b935050606086013567ffffffffffffffff81111561078e57600080fd5b61079a88828901610616565b92509250509295509295909350565b600080604083850312156107bc57600080fd5b60006107ca858286016105d7565b92505060206107db858286016105ec565b9150509250929050565b600080604083850312156107f857600080fd5b6000610806858286016105d7565b925050602061081785828601610660565b9150509250929050565b60006020828403121561083357600080fd5b600061084184828501610601565b91505092915050565b60006020828403121561085c57600080fd5b600061086a84828501610660565b91505092915050565b61087c816109b9565b82525050565b61088b816109cb565b82525050565b6000815461089e81610a2d565b6108a881866109a8565b945060018216600081146108c357600181146108d557610908565b60ff1983168652602086019350610908565b6108de85610993565b60005b83811015610900578154818901526001820191506020810190506108e1565b808801955050505b50505092915050565b61091a81610a23565b82525050565b60006020820190506109356000830184610873565b92915050565b60006020820190506109506000830184610882565b92915050565b600060208201905081810360008301526109708184610891565b905092915050565b600060208201905061098d6000830184610911565b92915050565b60008190508160005260206000209050919050565b600082825260208201905092915050565b60006109c482610a03565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006002820490506001821680610a4557607f821691505b60208210811415610a5957610a58610a5f565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b610a97816109b9565b8114610aa257600080fd5b50565b610aae816109cb565b8114610ab957600080fd5b50565b610ac5816109d7565b8114610ad057600080fd5b50565b610adc81610a23565b8114610ae757600080fd5b5056fea26469706673582212206e53fcc41e6b23f5bd49a262462ecf5ff647f480649658ee8b67c91a8f733ba864736f6c634300080100337468697320636f6e747261637420646f6573206e6f74206578697374732c20636f646520666f7220636f6c6c656374696f6e7320697320696d706c656d656e7465642061742070616c6c65742073696465
\ No newline at end of file
deletedpallets/nft/src/eth/stubs/ERC721.soldiffbeforeafterboth
--- a/pallets/nft/src/eth/stubs/ERC721.sol
+++ /dev/null
@@ -1,163 +0,0 @@
-// SPDX-License-Identifier: OTHER
-
-pragma solidity >=0.8.0 <0.9.0;
-
-contract ERC721 {
-    uint8 _dummy = 0;
-    address _dummy_addr = 0x0000000000000000000000000000000000000000;
-    string _dummy_string = "";
-    string stub_error =
-        "this contract does not exists, code for collections is implemented at pallet side";
-
-    event Transfer(
-        address indexed from,
-        address indexed to,
-        uint256 indexed tokenId
-    );
-
-    event Approval(
-        address indexed owner,
-        address indexed approved,
-        uint256 indexed tokenId
-    );
-
-    event ApprovalForAll(
-        address indexed owner,
-        address indexed operator,
-        bool approved
-    );
-
-	// 0x18160ddd
-    function totalSupply() external view returns (uint256) {
-        require(false, stub_error);
-        return 0;
-    }
-
-    function name() external view returns (string memory res_name) {
-        require(false, stub_error);
-        res_name = _dummy_string;
-    }
-
-    function symbol() external view returns (string memory res_symbol) {
-        require(false, stub_error);
-        res_symbol = _dummy_string;
-    }
-
-    function tokenURI(uint256 tokenId) external view returns (string memory) {
-        require(false, stub_error);
-        tokenId;
-        return _dummy_string;
-    }
-
-    function tokenByIndex(uint256 index) external view returns (uint256) {
-        require(false, stub_error);
-        index;
-		return 0;
-    }
-
-    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256) {
-        require(false, stub_error);
-		owner;
-		index;
-		return 0;
-    }
-
-    // 0x70a08231
-    function balanceOf(address owner) external view returns (uint256) {
-        require(false, stub_error);
-        owner;
-        return 0;
-    }
-
-    // 0x6352211e
-    function ownerOf(uint256 tokenId) external view returns (address) {
-        require(false, stub_error);
-        tokenId;
-        return _dummy_addr;
-    }
-
-    // 0xb88d4fde
-    function safeTransferFrom(
-        address from,
-        address to,
-        uint256 tokenId,
-        bytes calldata data
-    ) external payable {
-        require(false, stub_error);
-        from;
-        to;
-        tokenId;
-        data;
-    }
-
-    // 0x42842e0e
-    function safeTransferFrom(
-        address from,
-        address to,
-        uint256 tokenId
-    ) external payable {
-        require(false, stub_error);
-        from;
-        to;
-        tokenId;
-    }
-
-    // 0x23b872dd
-    function transferFrom(
-        address from,
-        address to,
-        uint256 tokenId
-    ) external payable {
-        require(false, stub_error);
-        from;
-        to;
-        tokenId;
-    }
-
-    // 0x095ea7b3
-    function approve(address approved, uint256 tokenId) external payable {
-        require(false, stub_error);
-        approved;
-        tokenId;
-    }
-
-    // 0xa22cb465
-    function setApprovalForAll(address operator, bool approved) external {
-        require(false, stub_error);
-        operator;
-        approved;
-        _dummy = 0;
-    }
-
-    // 0x081812fc
-    function getApproved(uint256 tokenId) external view returns (address) {
-        require(false, stub_error);
-        tokenId;
-        return _dummy_addr;
-    }
-
-    // 0xe985e9c5
-    function isApprovedForAll(address owner, address operator)
-        external
-        view
-        returns (bool)
-    {
-        require(false, stub_error);
-        owner;
-        operator;
-        return false;
-    }
-
-    // 0x01ffc9a7
-    function supportsInterface(bytes4 interfaceID) public pure returns (bool) {
-        return
-            // ERC721
-            interfaceID == 0x80ac58cd ||
-            // ERC721Metadata
-            interfaceID == 0x5b5e139f ||
-            // ERC721Enumerable
-            interfaceID == 0x780e9d63 ||
-            // ERC165
-            interfaceID == 0x01ffc9a7;
-    }
-}
deletedpallets/nft/src/eth/stubs/Invalid.bindiffbeforeafterboth
--- a/pallets/nft/src/eth/stubs/Invalid.bin
+++ /dev/null
@@ -1 +0,0 @@
-TODO
\ No newline at end of file
addedpallets/nft/src/eth/stubs/UniqueFungible.rawdiffbeforeafterboth

binary blob — no preview

addedpallets/nft/src/eth/stubs/UniqueFungible.soldiffbeforeafterboth
--- /dev/null
+++ b/pallets/nft/src/eth/stubs/UniqueFungible.sol
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: OTHER
+// This code is automatically generated
+
+pragma solidity >=0.8.0 <0.9.0;
+
+// Common stubs holder
+contract Dummy {
+	uint8 dummy;
+	string stub_error = "this contract is implemented in native";
+}
+
+// Inline
+contract ERC20Events {
+	event Transfer(address indexed from, address indexed to, uint256 value);
+	event Approval(
+		address indexed owner,
+		address indexed spender,
+		uint256 value
+	);
+}
+
+// Inline
+contract InlineNameSymbol is Dummy {
+	function name() public view returns (string memory) {
+		require(false, stub_error);
+		dummy;
+		return "";
+	}
+
+	function symbol() public view returns (string memory) {
+		require(false, stub_error);
+		dummy;
+		return "";
+	}
+}
+
+// Inline
+contract InlineTotalSupply is Dummy {
+	function totalSupply() public view returns (uint256) {
+		require(false, stub_error);
+		dummy;
+		return 0;
+	}
+}
+
+contract ERC165 is Dummy {
+	function supportsInterface(uint32 interfaceId) public view returns (bool) {
+		require(false, stub_error);
+		interfaceId;
+		dummy;
+		return false;
+	}
+}
+
+contract ERC20 is Dummy, InlineNameSymbol, InlineTotalSupply, ERC20Events {
+	function decimals() public view returns (uint8) {
+		require(false, stub_error);
+		dummy;
+		return 0;
+	}
+
+	function balanceOf(address owner) public view returns (uint256) {
+		require(false, stub_error);
+		owner;
+		dummy;
+		return 0;
+	}
+
+	function transfer(address to, uint256 amount) public returns (bool) {
+		require(false, stub_error);
+		to;
+		amount;
+		dummy = 0;
+		return false;
+	}
+
+	function transferFrom(
+		address from,
+		address to,
+		uint256 amount
+	) public returns (bool) {
+		require(false, stub_error);
+		from;
+		to;
+		amount;
+		dummy = 0;
+		return false;
+	}
+
+	function approve(address spender, uint256 amount) public returns (bool) {
+		require(false, stub_error);
+		spender;
+		amount;
+		dummy = 0;
+		return false;
+	}
+
+	function allowance(address owner, address spender)
+		public
+		view
+		returns (uint256)
+	{
+		require(false, stub_error);
+		owner;
+		spender;
+		dummy;
+		return 0;
+	}
+}
+
+contract UniqueFungible is Dummy, ERC165, ERC20 {}
addedpallets/nft/src/eth/stubs/UniqueInvalid.rawdiffbeforeafterboth
--- /dev/null
+++ b/pallets/nft/src/eth/stubs/UniqueInvalid.raw
@@ -0,0 +1 @@
+TODO
\ No newline at end of file
addedpallets/nft/src/eth/stubs/UniqueNFT.rawdiffbeforeafterboth

binary blob — no preview

addedpallets/nft/src/eth/stubs/UniqueNFT.soldiffbeforeafterboth
--- /dev/null
+++ b/pallets/nft/src/eth/stubs/UniqueNFT.sol
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: OTHER
+// This code is automatically generated
+
+pragma solidity >=0.8.0 <0.9.0;
+
+// Common stubs holder
+contract Dummy {
+	uint8 dummy;
+	string stub_error = "this contract is implemented in native";
+}
+
+// Inline
+contract ERC721Events {
+	event Transfer(
+		address indexed from,
+		address indexed to,
+		uint256 indexed tokenId
+	);
+	event Approval(
+		address indexed owner,
+		address indexed approved,
+		uint256 indexed tokenId
+	);
+	event ApprovalForAll(
+		address indexed owner,
+		address indexed operator,
+		bool approved
+	);
+}
+
+// Inline
+contract ERC721MintableEvents {
+	event MintingFinished();
+}
+
+// Inline
+contract InlineNameSymbol is Dummy {
+	function name() public view returns (string memory) {
+		require(false, stub_error);
+		dummy;
+		return "";
+	}
+
+	function symbol() public view returns (string memory) {
+		require(false, stub_error);
+		dummy;
+		return "";
+	}
+}
+
+// Inline
+contract InlineTotalSupply is Dummy {
+	function totalSupply() public view returns (uint256) {
+		require(false, stub_error);
+		dummy;
+		return 0;
+	}
+}
+
+contract ERC165 is Dummy {
+	function supportsInterface(uint32 interfaceId) public view returns (bool) {
+		require(false, stub_error);
+		interfaceId;
+		dummy;
+		return false;
+	}
+}
+
+contract ERC721 is Dummy, ERC165, ERC721Events {
+	function balanceOf(address owner) public view returns (uint256) {
+		require(false, stub_error);
+		owner;
+		dummy;
+		return 0;
+	}
+
+	function ownerOf(uint256 tokenId) public view returns (address) {
+		require(false, stub_error);
+		tokenId;
+		dummy;
+		return 0x0000000000000000000000000000000000000000;
+	}
+
+	function safeTransferFromWithData(
+		address from,
+		address to,
+		uint256 tokenId,
+		bytes memory data
+	) public {
+		require(false, stub_error);
+		from;
+		to;
+		tokenId;
+		data;
+		dummy = 0;
+	}
+
+	function safeTransferFrom(
+		address from,
+		address to,
+		uint256 tokenId
+	) public {
+		require(false, stub_error);
+		from;
+		to;
+		tokenId;
+		dummy = 0;
+	}
+
+	function transferFrom(
+		address from,
+		address to,
+		uint256 tokenId
+	) public {
+		require(false, stub_error);
+		from;
+		to;
+		tokenId;
+		dummy = 0;
+	}
+
+	function approve(address approved, uint256 tokenId) public {
+		require(false, stub_error);
+		approved;
+		tokenId;
+		dummy = 0;
+	}
+
+	function setApprovalForAll(address operator, bool approved) public {
+		require(false, stub_error);
+		operator;
+		approved;
+		dummy = 0;
+	}
+
+	function getApproved(uint256 tokenId) public view returns (address) {
+		require(false, stub_error);
+		tokenId;
+		dummy;
+		return 0x0000000000000000000000000000000000000000;
+	}
+
+	function isApprovedForAll(address owner, address operator)
+		public
+		view
+		returns (address)
+	{
+		require(false, stub_error);
+		owner;
+		operator;
+		dummy;
+		return 0x0000000000000000000000000000000000000000;
+	}
+}
+
+contract ERC721Burnable is Dummy {
+	function burn(uint256 tokenId) public {
+		require(false, stub_error);
+		tokenId;
+		dummy = 0;
+	}
+}
+
+contract ERC721Enumerable is Dummy, InlineTotalSupply {
+	function tokenByIndex(uint256 index) public view returns (uint256) {
+		require(false, stub_error);
+		index;
+		dummy;
+		return 0;
+	}
+
+	function tokenOfOwnerByIndex(address owner, uint256 index)
+		public
+		view
+		returns (uint256)
+	{
+		require(false, stub_error);
+		owner;
+		index;
+		dummy;
+		return 0;
+	}
+}
+
+contract ERC721Metadata is Dummy, InlineNameSymbol {
+	function tokenURI(uint256 tokenId) public view returns (string memory) {
+		require(false, stub_error);
+		tokenId;
+		dummy;
+		return "";
+	}
+}
+
+contract ERC721Mintable is Dummy, ERC721MintableEvents {
+	function mintingFinished() public view returns (bool) {
+		require(false, stub_error);
+		dummy;
+		return false;
+	}
+
+	function mint(address to, uint256 tokenId) public returns (bool) {
+		require(false, stub_error);
+		to;
+		tokenId;
+		dummy = 0;
+		return false;
+	}
+
+	function mintWithTokenURI(
+		address to,
+		uint256 tokenId,
+		string memory tokenUri
+	) public returns (bool) {
+		require(false, stub_error);
+		to;
+		tokenId;
+		tokenUri;
+		dummy = 0;
+		return false;
+	}
+
+	function finishMinting() public returns (bool) {
+		require(false, stub_error);
+		dummy = 0;
+		return false;
+	}
+}
+
+contract ERC721UniqueExtensions is Dummy {
+	function transfer(address to, uint256 tokenId) public {
+		require(false, stub_error);
+		to;
+		tokenId;
+		dummy = 0;
+	}
+
+	function nextTokenId() public view returns (uint256) {
+		require(false, stub_error);
+		dummy;
+		return 0;
+	}
+}
+
+contract UniqueNFT is
+	Dummy,
+	ERC165,
+	ERC721,
+	ERC721Metadata,
+	ERC721Enumerable,
+	ERC721UniqueExtensions,
+	ERC721Mintable,
+	ERC721Burnable
+{}
addedpallets/nft/src/eth/stubs/UniqueRefungible.rawdiffbeforeafterboth
--- /dev/null
+++ b/pallets/nft/src/eth/stubs/UniqueRefungible.raw
@@ -0,0 +1 @@
+TODO
\ No newline at end of file
modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -31,19 +31,20 @@
 	StorageValue, transactional,
 };
 
-use frame_system::{self as system, ensure_signed, ensure_root};
+use frame_system::{self as system, ensure_signed};
 use sp_core::H160;
 use sp_std::vec;
-use sp_runtime::sp_std::prelude::Vec;
+use sp_runtime::{DispatchError, sp_std::prelude::Vec};
 use core::ops::{Deref, DerefMut};
-use core::cell::RefCell;
 use nft_data_structs::{
 	MAX_DECIMAL_POINTS, MAX_SPONSOR_TIMEOUT, MAX_TOKEN_OWNERSHIP, MAX_REFUNGIBLE_PIECES,
-	AccessMode, ChainLimits, Collection, CreateItemData, CollectionLimits, CollectionId,
-	CollectionMode, TokenId, SchemaVersion, SponsorshipState, Ownership, NftItemType,
-	FungibleItemType, ReFungibleItemType, MetaUpdatePermission,
+	CUSTOM_DATA_LIMIT, COLLECTION_NUMBER_LIMIT, ACCOUNT_TOKEN_OWNERSHIP_LIMIT,
+	VARIABLE_ON_CHAIN_SCHEMA_LIMIT, CONST_ON_CHAIN_SCHEMA_LIMIT, COLLECTION_ADMINS_LIMIT,
+	OFFCHAIN_SCHEMA_LIMIT, MAX_TOKEN_PREFIX_LENGTH, MAX_COLLECTION_NAME_LENGTH,
+	MAX_COLLECTION_DESCRIPTION_LENGTH, AccessMode, Collection, CreateItemData, CollectionLimits,
+	CollectionId, CollectionMode, TokenId, SchemaVersion, SponsorshipState, Ownership, NftItemType,
+	FungibleItemType, ReFungibleItemType,
 };
-use pallet_ethereum::EthereumTransactionSender;
 
 #[cfg(test)]
 mod mock;
@@ -51,10 +52,10 @@
 #[cfg(test)]
 mod tests;
 
-mod default_weights;
 mod eth;
 mod sponsorship;
 pub use sponsorship::NftSponsorshipHandler;
+pub use eth::sponsoring::NftEthSponsorshipHandler;
 
 pub use eth::NftErcSupport;
 pub use eth::account::*;
@@ -62,39 +63,8 @@
 
 #[cfg(feature = "runtime-benchmarks")]
 mod benchmarking;
-
-pub trait WeightInfo {
-	fn create_collection() -> Weight;
-	fn destroy_collection() -> Weight;
-	fn add_to_white_list() -> Weight;
-	fn remove_from_white_list() -> Weight;
-	fn set_public_access_mode() -> Weight;
-	fn set_mint_permission() -> Weight;
-	fn change_collection_owner() -> Weight;
-	fn add_collection_admin() -> Weight;
-	fn remove_collection_admin() -> Weight;
-	fn set_collection_sponsor() -> Weight;
-	fn confirm_sponsorship() -> Weight;
-	fn remove_collection_sponsor() -> Weight;
-	fn create_item(s: usize) -> Weight;
-	fn burn_item() -> Weight;
-	fn transfer() -> Weight;
-	fn approve() -> Weight;
-	fn transfer_from() -> Weight;
-	fn set_offchain_schema() -> Weight;
-	fn set_const_on_chain_schema() -> Weight;
-	fn set_variable_on_chain_schema() -> Weight;
-	fn set_variable_meta_data() -> Weight;
-	fn enable_contract_sponsoring() -> Weight;
-	fn set_schema_version() -> Weight;
-	fn set_chain_limits() -> Weight;
-	fn set_contract_sponsoring_rate_limit() -> Weight;
-	fn set_variable_meta_data_sponsoring_rate_limit() -> Weight;
-	fn toggle_contract_white_list() -> Weight;
-	fn add_to_contract_white_list() -> Weight;
-	fn remove_from_contract_white_list() -> Weight;
-	fn set_collection_limits() -> Weight;
-}
+pub mod weights;
+use weights::WeightInfo;
 
 decl_error! {
 	/// Error for non-fungible-token module.
@@ -179,45 +149,53 @@
 		MetadataUpdateDenied,
 		/// Metadata update flag become unmutable with None option
 		MetadataFlagFrozen,
+		/// Collection settings not allowing items transferring
+		TransferNotAllowed,
+		/// Can't transfer tokens to ethereum zero address
+		AddressIsZero,
 	}
 }
 
+#[must_use = "Should call submit_logs or save, otherwise some data will be lost for evm side"]
 pub struct CollectionHandle<T: Config> {
 	pub id: CollectionId,
 	collection: Collection<T>,
-	logs: eth::log::LogRecorder,
-	evm_address: H160,
-	gas_limit: RefCell<u64>,
+	recorder: pallet_evm_coder_substrate::SubstrateRecorder<T>,
 }
 impl<T: Config> CollectionHandle<T> {
 	pub fn get_with_gas_limit(id: CollectionId, gas_limit: u64) -> Option<Self> {
 		<CollectionById<T>>::get(id).map(|collection| Self {
 			id,
 			collection,
-			logs: eth::log::LogRecorder::default(),
-			evm_address: eth::collection_id_to_address(id),
-			gas_limit: RefCell::new(gas_limit),
+			recorder: pallet_evm_coder_substrate::SubstrateRecorder::new(
+				eth::collection_id_to_address(id),
+				gas_limit,
+			),
 		})
 	}
 	pub fn get(id: CollectionId) -> Option<Self> {
 		Self::get_with_gas_limit(id, u64::MAX)
 	}
-	pub fn gas_left(&self) -> u64 {
-		*self.gas_limit.borrow()
+	pub fn log(&self, log: impl evm_coder::ToLog) -> DispatchResult {
+		self.recorder.log_sub(log)
 	}
-	pub fn consume_gas(&self, gas: u64) -> DispatchResult {
-		let mut gas_limit = self.gas_limit.borrow_mut();
-		if *gas_limit < gas {
-			fail!(Error::<T>::OutOfGas);
-		}
-		*gas_limit -= gas;
-		Ok(())
+	#[allow(dead_code)]
+	fn consume_gas(&self, gas: u64) -> DispatchResult {
+		self.recorder.consume_gas_sub(gas)
+	}
+	fn consume_sload(&self) -> DispatchResult {
+		self.recorder.consume_sload_sub()
+	}
+	fn consume_sstore(&self) -> DispatchResult {
+		self.recorder.consume_sstore_sub()
 	}
-	pub fn log(&self, log: impl evm_coder::ToLog) {
-		self.logs.log(log.to_log(self.evm_address))
+	pub fn submit_logs(self) -> DispatchResult {
+		self.recorder.submit_logs()
 	}
-	pub fn into_inner(self) -> Collection<T> {
-		self.collection
+	pub fn save(self) -> DispatchResult {
+		self.recorder.submit_logs()?;
+		<CollectionById<T>>::insert(self.id, self.collection);
+		Ok(())
 	}
 }
 impl<T: Config> Deref for CollectionHandle<T> {
@@ -234,7 +212,7 @@
 	}
 }
 
-pub trait Config: system::Config + Sized {
+pub trait Config: system::Config + pallet_evm_coder_substrate::Config + Sized {
 	type Event: From<Event<Self>> + Into<<Self as system::Config>::Event>;
 
 	/// Weight information for extrinsics in this pallet.
@@ -249,10 +227,40 @@
 		<<Self as Config>::Currency as Currency<Self::AccountId>>::Balance,
 	>;
 	type TreasuryAccountId: Get<Self::AccountId>;
+}
+
+type SelfWeightOf<T> = <T as Config>::WeightInfo;
 
-	type EthereumChainId: Get<u64>;
-	type EthereumTransactionSender: pallet_ethereum::EthereumTransactionSender;
+trait WeightInfoHelpers: WeightInfo {
+	fn transfer() -> Weight {
+		Self::transfer_nft()
+			.max(Self::transfer_fungible())
+			.max(Self::transfer_refungible())
+	}
+	fn transfer_from() -> Weight {
+		Self::transfer_from_nft()
+			.max(Self::transfer_from_fungible())
+			.max(Self::transfer_from_refungible())
+	}
+	fn approve() -> Weight {
+		// TODO: refungible, fungible
+		Self::approve_nft()
+	}
+	fn set_variable_meta_data(data: u32) -> Weight {
+		// TODO: refungible
+		Self::set_variable_meta_data_nft(data)
+	}
+	fn create_item(data: u32) -> Weight {
+		Self::create_item_nft(data)
+			.max(Self::create_item_fungible())
+			.max(Self::create_item_refungible(data))
+	}
+	fn burn_item() -> Weight {
+		// TODO: refungible, fungible
+		Self::burn_item_nft()
+	}
 }
+impl<T: WeightInfo> WeightInfoHelpers for T {}
 
 // # Used definitions
 //
@@ -287,10 +295,6 @@
 		/// Id of last collection token
 		/// Collection id (controlled?1)
 		ItemListIndex: map hasher(blake2_128_concat) CollectionId => TokenId;
-		//#endregion
-
-		//#region Chain limits struct
-		pub ChainLimit get(fn chain_limit) config(): ChainLimits;
 		//#endregion
 
 		//#region Bound counters
@@ -444,6 +448,7 @@
 		origin: T::Origin
 	{
 		fn deposit_event() = default;
+		const CollectionAdminsLimit: u64 = COLLECTION_ADMINS_LIMIT;
 		type Error = Error<T>;
 
 		fn on_initialize(_now: T::BlockNumber) -> Weight {
@@ -466,7 +471,7 @@
 		///
 		/// * mode: [CollectionMode] collection type and type dependent data.
 		// returns collection ID
-		#[weight = <T as Config>::WeightInfo::create_collection()]
+		#[weight = <SelfWeightOf<T>>::create_collection()]
 		#[transactional]
 		pub fn create_collection(origin,
 								 collection_name: Vec<u16>,
@@ -495,19 +500,17 @@
 				_ => 0
 			};
 
-			let chain_limit = ChainLimit::get();
-
 			let created_count = CreatedCollectionCount::get();
 			let destroyed_count = DestroyedCollectionCount::get();
 
 			// bound Total number of collections
-			ensure!(created_count - destroyed_count < chain_limit.collection_numbers_limit, Error::<T>::TotalCollectionsLimitExceeded);
+			ensure!(created_count - destroyed_count < COLLECTION_NUMBER_LIMIT, Error::<T>::TotalCollectionsLimitExceeded);
 
 			// check params
 			ensure!(decimal_points <= MAX_DECIMAL_POINTS, Error::<T>::CollectionDecimalPointLimitExceeded);
-			ensure!(collection_name.len() <= 64, Error::<T>::CollectionNameLimitExceeded);
-			ensure!(collection_description.len() <= 256, Error::<T>::CollectionDescriptionLimitExceeded);
-			ensure!(token_prefix.len() <= 16, Error::<T>::CollectionTokenPrefixLimitExceeded);
+			ensure!(collection_name.len() <= MAX_COLLECTION_NAME_LENGTH, Error::<T>::CollectionNameLimitExceeded);
+			ensure!(collection_description.len() <= MAX_COLLECTION_DESCRIPTION_LENGTH, Error::<T>::CollectionDescriptionLimitExceeded);
+			ensure!(token_prefix.len() <= MAX_TOKEN_PREFIX_LENGTH, Error::<T>::CollectionTokenPrefixLimitExceeded);
 
 			// Generate next collection ID
 			let next_id = created_count
@@ -517,7 +520,7 @@
 			CreatedCollectionCount::put(next_id);
 
 			let limits = CollectionLimits {
-				sponsored_data_size: chain_limit.custom_data_limit,
+				sponsored_data_size: CUSTOM_DATA_LIMIT,
 				..Default::default()
 			};
 
@@ -538,6 +541,7 @@
 				const_on_chain_schema: Vec::new(),
 				limits,
 				meta_update_permission: MetaUpdatePermission::default(),
+				transfers_enabled: true,
 			};
 
 			// Add new collection to map
@@ -558,7 +562,7 @@
 		/// # Arguments
 		///
 		/// * collection_id: collection to destroy.
-		#[weight = <T as Config>::WeightInfo::destroy_collection()]
+		#[weight = <SelfWeightOf<T>>::destroy_collection()]
 		#[transactional]
 		pub fn destroy_collection(origin, collection_id: CollectionId) -> DispatchResult {
 
@@ -569,23 +573,23 @@
 				fail!(Error::<T>::NoPermission);
 			}
 
-			<AddressTokens<T>>::remove_prefix(collection_id);
-			<Allowances<T>>::remove_prefix(collection_id);
-			<Balance<T>>::remove_prefix(collection_id);
+			<AddressTokens<T>>::remove_prefix(collection_id, None);
+			<Allowances<T>>::remove_prefix(collection_id, None);
+			<Balance<T>>::remove_prefix(collection_id, None);
 			<ItemListIndex>::remove(collection_id);
 			<AdminList<T>>::remove(collection_id);
 			<CollectionById<T>>::remove(collection_id);
-			<WhiteList<T>>::remove_prefix(collection_id);
+			<WhiteList<T>>::remove_prefix(collection_id, None);
 
-			<NftItemList<T>>::remove_prefix(collection_id);
-			<FungibleItemList<T>>::remove_prefix(collection_id);
-			<ReFungibleItemList<T>>::remove_prefix(collection_id);
+			<NftItemList<T>>::remove_prefix(collection_id, None);
+			<FungibleItemList<T>>::remove_prefix(collection_id, None);
+			<ReFungibleItemList<T>>::remove_prefix(collection_id, None);
 
-			<NftTransferBasket<T>>::remove_prefix(collection_id);
-			<FungibleTransferBasket<T>>::remove_prefix(collection_id);
-			<ReFungibleTransferBasket<T>>::remove_prefix(collection_id);
+			<NftTransferBasket<T>>::remove_prefix(collection_id, None);
+			<FungibleTransferBasket<T>>::remove_prefix(collection_id, None);
+			<ReFungibleTransferBasket<T>>::remove_prefix(collection_id, None);
 
-			<VariableMetaDataBasket<T>>::remove_prefix(collection_id);
+			<VariableMetaDataBasket<T>>::remove_prefix(collection_id, None);
 
 			DestroyedCollectionCount::put(DestroyedCollectionCount::get()
 				.checked_add(1)
@@ -606,7 +610,7 @@
 		/// * collection_id.
 		///
 		/// * address.
-		#[weight = <T as Config>::WeightInfo::add_to_white_list()]
+		#[weight = <SelfWeightOf<T>>::add_to_white_list()]
 		#[transactional]
 		pub fn add_to_white_list(origin, collection_id: CollectionId, address: T::CrossAccountId) -> DispatchResult{
 
@@ -635,7 +639,7 @@
 		/// * collection_id.
 		///
 		/// * address.
-		#[weight = <T as Config>::WeightInfo::remove_from_white_list()]
+		#[weight = <SelfWeightOf<T>>::remove_from_white_list()]
 		#[transactional]
 		pub fn remove_from_white_list(origin, collection_id: CollectionId, address: T::CrossAccountId) -> DispatchResult{
 
@@ -663,7 +667,7 @@
 		/// * collection_id.
 		///
 		/// * mode: [AccessMode]
-		#[weight = <T as Config>::WeightInfo::set_public_access_mode()]
+		#[weight = <SelfWeightOf<T>>::set_public_access_mode()]
 		#[transactional]
 		pub fn set_public_access_mode(origin, collection_id: CollectionId, mode: AccessMode) -> DispatchResult
 		{
@@ -672,9 +676,7 @@
 			let mut target_collection = Self::get_collection(collection_id)?;
 			Self::check_owner_permissions(&target_collection, &sender)?;
 			target_collection.access = mode;
-			Self::save_collection(target_collection);
-
-			Ok(())
+			target_collection.save()
 		}
 
 		/// Allows Anyone to create tokens if:
@@ -690,7 +692,7 @@
 		/// * collection_id.
 		///
 		/// * mint_permission: Boolean parameter. If True, allows minting to Anyone with conditions above.
-		#[weight = <T as Config>::WeightInfo::set_mint_permission()]
+		#[weight = <SelfWeightOf<T>>::set_mint_permission()]
 		#[transactional]
 		pub fn set_mint_permission(origin, collection_id: CollectionId, mint_permission: bool) -> DispatchResult
 		{
@@ -699,9 +701,7 @@
 			let mut target_collection = Self::get_collection(collection_id)?;
 			Self::check_owner_permissions(&target_collection, &sender)?;
 			target_collection.mint_mode = mint_permission;
-			Self::save_collection(target_collection);
-
-			Ok(())
+			target_collection.save()
 		}
 
 		/// Change the owner of the collection.
@@ -715,7 +715,7 @@
 		/// * collection_id.
 		///
 		/// * new_owner.
-		#[weight = <T as Config>::WeightInfo::change_collection_owner()]
+		#[weight = <SelfWeightOf<T>>::change_collection_owner()]
 		#[transactional]
 		pub fn change_collection_owner(origin, collection_id: CollectionId, new_owner: T::AccountId) -> DispatchResult {
 
@@ -723,9 +723,7 @@
 			let mut target_collection = Self::get_collection(collection_id)?;
 			Self::check_owner_permissions(&target_collection, &sender)?;
 			target_collection.owner = new_owner;
-			Self::save_collection(target_collection);
-
-			Ok(())
+			target_collection.save()
 		}
 
 		/// Adds an admin of the Collection.
@@ -741,7 +739,7 @@
 		/// * collection_id: ID of the Collection to add admin for.
 		///
 		/// * new_admin_id: Address of new admin to add.
-		#[weight = <T as Config>::WeightInfo::add_collection_admin()]
+		#[weight = <SelfWeightOf<T>>::add_collection_admin()]
 		#[transactional]
 		pub fn add_collection_admin(origin, collection_id: CollectionId, new_admin_id: T::CrossAccountId) -> DispatchResult {
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
@@ -752,8 +750,7 @@
 			match admin_arr.binary_search(&new_admin_id) {
 				Ok(_) => {},
 				Err(idx) => {
-					let limits = ChainLimit::get();
-					ensure!(admin_arr.len() < limits.collections_admins_limit as usize, Error::<T>::CollectionAdminsLimitExceeded);
+					ensure!(admin_arr.len() < COLLECTION_ADMINS_LIMIT as usize, Error::<T>::CollectionAdminsLimitExceeded);
 					admin_arr.insert(idx, new_admin_id);
 					<AdminList<T>>::insert(collection_id, admin_arr);
 				}
@@ -773,7 +770,7 @@
 		/// * collection_id: ID of the Collection to remove admin for.
 		///
 		/// * account_id: Address of admin to remove.
-		#[weight = <T as Config>::WeightInfo::remove_collection_admin()]
+		#[weight = <SelfWeightOf<T>>::remove_collection_admin()]
 		#[transactional]
 		pub fn remove_collection_admin(origin, collection_id: CollectionId, account_id: T::CrossAccountId) -> DispatchResult {
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
@@ -797,7 +794,7 @@
 		/// * collection_id.
 		///
 		/// * new_sponsor.
-		#[weight = <T as Config>::WeightInfo::set_collection_sponsor()]
+		#[weight = <SelfWeightOf<T>>::set_collection_sponsor()]
 		#[transactional]
 		pub fn set_collection_sponsor(origin, collection_id: CollectionId, new_sponsor: T::AccountId) -> DispatchResult {
 			let sender = ensure_signed(origin)?;
@@ -805,9 +802,7 @@
 			Self::check_owner_permissions(&target_collection, &sender)?;
 
 			target_collection.sponsorship = SponsorshipState::Unconfirmed(new_sponsor);
-			Self::save_collection(target_collection);
-
-			Ok(())
+			target_collection.save()
 		}
 
 		/// # Permissions
@@ -817,7 +812,7 @@
 		/// # Arguments
 		///
 		/// * collection_id.
-		#[weight = <T as Config>::WeightInfo::confirm_sponsorship()]
+		#[weight = <SelfWeightOf<T>>::confirm_sponsorship()]
 		#[transactional]
 		pub fn confirm_sponsorship(origin, collection_id: CollectionId) -> DispatchResult {
 			let sender = ensure_signed(origin)?;
@@ -829,9 +824,7 @@
 			);
 
 			target_collection.sponsorship = SponsorshipState::Confirmed(sender);
-			Self::save_collection(target_collection);
-
-			Ok(())
+			target_collection.save()
 		}
 
 		/// Switch back to pay-per-own-transaction model.
@@ -843,7 +836,7 @@
 		/// # Arguments
 		///
 		/// * collection_id.
-		#[weight = <T as Config>::WeightInfo::remove_collection_sponsor()]
+		#[weight = <SelfWeightOf<T>>::remove_collection_sponsor()]
 		#[transactional]
 		pub fn remove_collection_sponsor(origin, collection_id: CollectionId) -> DispatchResult {
 			let sender = ensure_signed(origin)?;
@@ -852,9 +845,7 @@
 			Self::check_owner_permissions(&target_collection, &sender)?;
 
 			target_collection.sponsorship = SponsorshipState::Disabled;
-			Self::save_collection(target_collection);
-
-			Ok(())
+			target_collection.save()
 		}
 
 		/// This method creates a concrete instance of NFT Collection created with CreateCollection method.
@@ -881,7 +872,7 @@
 		// .saturating_add(RocksDbWeight::get().reads(10 as Weight))
 		// .saturating_add(RocksDbWeight::get().writes(8 as Weight))]
 
-		#[weight = <T as Config>::WeightInfo::create_item(data.data_size())]
+		#[weight = <SelfWeightOf<T>>::create_item(data.data_size() as u32)]
 		#[transactional]
 		pub fn create_item(origin, collection_id: CollectionId, owner: T::CrossAccountId, data: CreateItemData) -> DispatchResult {
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
@@ -889,8 +880,7 @@
 
 			Self::create_item_internal(&sender, &collection, &owner, data)?;
 
-			// Self::submit_logs(collection)?;
-			Ok(())
+			collection.submit_logs()
 		}
 
 		/// This method creates multiple items in a collection created with CreateCollection method.
@@ -911,8 +901,8 @@
 		/// * itemsData: Array items properties. Each property is an array of bytes itself, see [create_item].
 		///
 		/// * owner: Address, initial owner of the NFT.
-		#[weight = <T as Config>::WeightInfo::create_item(items_data.iter()
-							   .map(|data| { data.data_size() })
+		#[weight = <SelfWeightOf<T>>::create_item(items_data.iter()
+							   .map(|data| { data.data_size() as u32 })
 							   .sum())]
 		#[transactional]
 		pub fn create_multiple_items(origin, collection_id: CollectionId, owner: T::CrossAccountId, items_data: Vec<CreateItemData>) -> DispatchResult {
@@ -923,11 +913,36 @@
 
 			Self::create_multiple_items_internal(&sender, &collection, &owner, items_data)?;
 
-			// Self::submit_logs(collection)?;
-			Ok(())
+			collection.submit_logs()
 		}
 
 		// TODO! transaction weight
+
+		/// Set transfers_enabled value for particular collection
+		///
+		/// # Permissions
+		///
+		/// * Collection Owner.
+		///
+		/// # Arguments
+		///
+		/// * collection_id: ID of the collection.
+		///
+		/// * value: New flag value.
+		#[weight = <SelfWeightOf<T>>::burn_item()]
+		#[transactional]
+		pub fn set_transfers_enabled_flag(origin, collection_id: CollectionId, value: bool) -> DispatchResult {
+
+			let sender = ensure_signed(origin)?;
+			let mut target_collection = Self::get_collection(collection_id)?;
+
+			Self::check_owner_permissions(&target_collection, &sender)?;
+
+			target_collection.transfers_enabled = value;
+			target_collection.save()
+		}
+
+		// TODO! transaction weight
 		/// Set meta_update_permission value for particular collection
 		///
 		/// # Permissions
@@ -971,7 +986,7 @@
 		/// * collection_id: ID of the collection.
 		///
 		/// * item_id: ID of NFT to burn.
-		#[weight = <T as Config>::WeightInfo::burn_item()]
+		#[weight = <SelfWeightOf<T>>::burn_item()]
 		#[transactional]
 		pub fn burn_item(origin, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResult {
 
@@ -980,8 +995,7 @@
 
 			Self::burn_item_internal(&sender, &target_collection, item_id, value)?;
 
-			// Self::submit_logs(target_collection)?;
-			Ok(())
+			target_collection.submit_logs()
 		}
 
 		/// Change ownership of the token.
@@ -1007,7 +1021,7 @@
 		///     * Non-Fungible Mode: Ignored
 		///     * Fungible Mode: Must specify transferred amount
 		///     * Re-Fungible Mode: Must specify transferred portion (between 0 and 1)
-		#[weight = <T as Config>::WeightInfo::transfer()]
+		#[weight = <SelfWeightOf<T>>::transfer()]
 		#[transactional]
 		pub fn transfer(origin, recipient: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResult {
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
@@ -1015,8 +1029,7 @@
 
 			Self::transfer_internal(&sender, &recipient, &collection, item_id, value)?;
 
-			// Self::submit_logs(collection)?;
-			Ok(())
+			collection.submit_logs()
 		}
 
 		/// Set, change, or remove approved address to transfer the ownership of the NFT.
@@ -1034,7 +1047,7 @@
 		/// * collection_id.
 		///
 		/// * item_id: ID of the item.
-		#[weight = <T as Config>::WeightInfo::approve()]
+		#[weight = <SelfWeightOf<T>>::approve()]
 		#[transactional]
 		pub fn approve(origin, spender: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, amount: u128) -> DispatchResult {
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
@@ -1042,8 +1055,7 @@
 
 			Self::approve_internal(&sender, &spender, &collection, item_id, amount)?;
 
-			// Self::submit_logs(collection)?;
-			Ok(())
+			collection.submit_logs()
 		}
 
 		/// Change ownership of a NFT on behalf of the owner. See Approve method for additional information. After this method executes, the approval is removed so that the approved address will not be able to transfer this NFT again from this owner.
@@ -1065,7 +1077,7 @@
 		/// * item_id: ID of the item.
 		///
 		/// * value: Amount to transfer.
-		#[weight = <T as Config>::WeightInfo::transfer_from()]
+		#[weight = <SelfWeightOf<T>>::transfer_from()]
 		#[transactional]
 		pub fn transfer_from(origin, from: T::CrossAccountId, recipient: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, value: u128 ) -> DispatchResult {
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
@@ -1073,8 +1085,7 @@
 
 			Self::transfer_from_internal(&sender, &from, &recipient, &collection, item_id, value)?;
 
-			// Self::submit_logs(collection)?;
-			Ok(())
+			collection.submit_logs()
 		}
 		// #[weight = 0]
 		//     // let no_perm_mes = "You do not have permissions to modify this collection";
@@ -1101,7 +1112,7 @@
 		/// * collection_id.
 		///
 		/// * schema: String representing the offchain data schema.
-		#[weight = <T as Config>::WeightInfo::set_variable_meta_data()]
+		#[weight = <SelfWeightOf<T>>::set_variable_meta_data(data.len() as u32)]
 		#[transactional]
 		pub fn set_variable_meta_data (
 			origin,
@@ -1132,7 +1143,7 @@
 		/// * collection_id.
 		///
 		/// * schema: SchemaVersion: enum
-		#[weight = <T as Config>::WeightInfo::set_schema_version()]
+		#[weight = <SelfWeightOf<T>>::set_schema_version()]
 		#[transactional]
 		pub fn set_schema_version(
 			origin,
@@ -1143,9 +1154,7 @@
 			let mut target_collection = Self::get_collection(collection_id)?;
 			Self::check_owner_or_admin_permissions(&target_collection, &sender)?;
 			target_collection.schema_version = version;
-			Self::save_collection(target_collection);
-
-			Ok(())
+			target_collection.save()
 		}
 
 		/// Set off-chain data schema.
@@ -1160,7 +1169,7 @@
 		/// * collection_id.
 		///
 		/// * schema: String representing the offchain data schema.
-		#[weight = <T as Config>::WeightInfo::set_offchain_schema()]
+		#[weight = <SelfWeightOf<T>>::set_offchain_schema(schema.len() as u32)]
 		#[transactional]
 		pub fn set_offchain_schema(
 			origin,
@@ -1172,12 +1181,10 @@
 			Self::check_owner_or_admin_permissions(&target_collection, &sender)?;
 
 			// check schema limit
-			ensure!(schema.len() as u32 <= ChainLimit::get().offchain_schema_limit, "");
+			ensure!(schema.len() as u32 <= OFFCHAIN_SCHEMA_LIMIT, "");
 
 			target_collection.offchain_schema = schema;
-			Self::save_collection(target_collection);
-
-			Ok(())
+			target_collection.save()
 		}
 
 		/// Set const on-chain data schema.
@@ -1192,7 +1199,7 @@
 		/// * collection_id.
 		///
 		/// * schema: String representing the const on-chain data schema.
-		#[weight = <T as Config>::WeightInfo::set_const_on_chain_schema()]
+		#[weight = <SelfWeightOf<T>>::set_const_on_chain_schema(schema.len() as u32)]
 		#[transactional]
 		pub fn set_const_on_chain_schema (
 			origin,
@@ -1204,12 +1211,10 @@
 			Self::check_owner_or_admin_permissions(&target_collection, &sender)?;
 
 			// check schema limit
-			ensure!(schema.len() as u32 <= ChainLimit::get().const_on_chain_schema_limit, "");
+			ensure!(schema.len() as u32 <= CONST_ON_CHAIN_SCHEMA_LIMIT, "");
 
 			target_collection.const_on_chain_schema = schema;
-			Self::save_collection(target_collection);
-
-			Ok(())
+			target_collection.save()
 		}
 
 		/// Set variable on-chain data schema.
@@ -1224,7 +1229,7 @@
 		/// * collection_id.
 		///
 		/// * schema: String representing the variable on-chain data schema.
-		#[weight = <T as Config>::WeightInfo::set_const_on_chain_schema()]
+		#[weight = <SelfWeightOf<T>>::set_const_on_chain_schema(schema.len() as u32)]
 		#[transactional]
 		pub fn set_variable_on_chain_schema (
 			origin,
@@ -1236,30 +1241,13 @@
 			Self::check_owner_or_admin_permissions(&target_collection, &sender)?;
 
 			// check schema limit
-			ensure!(schema.len() as u32 <= ChainLimit::get().variable_on_chain_schema_limit, "");
+			ensure!(schema.len() as u32 <= VARIABLE_ON_CHAIN_SCHEMA_LIMIT, "");
 
 			target_collection.variable_on_chain_schema = schema;
-			Self::save_collection(target_collection);
-
-			Ok(())
-		}
-
-		// Sudo permissions function
-		#[weight = <T as Config>::WeightInfo::set_chain_limits()]
-		#[transactional]
-		pub fn set_chain_limits(
-			origin,
-			limits: ChainLimits
-		) -> DispatchResult {
-
-			#[cfg(not(feature = "runtime-benchmarks"))]
-			ensure_root(origin)?;
-
-			<ChainLimit>::put(limits);
-			Ok(())
+			target_collection.save()
 		}
 
-		#[weight = <T as Config>::WeightInfo::set_collection_limits()]
+		#[weight = <SelfWeightOf<T>>::set_collection_limits()]
 		#[transactional]
 		pub fn set_collection_limits(
 			origin,
@@ -1270,12 +1258,11 @@
 			let mut target_collection = Self::get_collection(collection_id)?;
 			Self::check_owner_permissions(&target_collection, sender.as_sub())?;
 			let old_limits = &target_collection.limits;
-			let chain_limits = ChainLimit::get();
 
 			// collection bounds
 			ensure!(new_limits.sponsor_transfer_timeout <= MAX_SPONSOR_TIMEOUT &&
 				new_limits.account_token_ownership_limit <= MAX_TOKEN_OWNERSHIP &&
-				new_limits.sponsored_data_size <= chain_limits.custom_data_limit,
+				new_limits.sponsored_data_size <= CUSTOM_DATA_LIMIT,
 				Error::<T>::CollectionLimitBoundsExceeded);
 
 			// token_limit   check  prev
@@ -1289,9 +1276,8 @@
 			);
 
 			target_collection.limits = new_limits;
-			Self::save_collection(target_collection);
 
-			Ok(())
+			target_collection.save()
 		}
 	}
 }
@@ -1303,6 +1289,11 @@
 		owner: &T::CrossAccountId,
 		data: CreateItemData,
 	) -> DispatchResult {
+		ensure!(
+			owner != &T::CrossAccountId::from_eth(H160([0; 20])),
+			Error::<T>::AddressIsZero
+		);
+
 		Self::can_create_items_in_collection(collection, sender, owner, 1)?;
 		Self::validate_create_item_args(collection, &data)?;
 		Self::create_item_no_validation(collection, owner, data)?;
@@ -1317,14 +1308,18 @@
 		item_id: TokenId,
 		value: u128,
 	) -> DispatchResult {
-		target_collection.consume_gas(2000000)?;
+		ensure!(
+			recipient != &T::CrossAccountId::from_eth(H160([0; 20])),
+			Error::<T>::AddressIsZero
+		);
+
 		// Limits check
 		Self::is_correct_transfer(target_collection, recipient)?;
 
 		// Transfer permissions check
 		ensure!(
-			Self::is_item_owner(sender, target_collection, item_id)
-				|| Self::is_owner_or_admin_permissions(target_collection, sender),
+			Self::is_item_owner(sender, target_collection, item_id)?
+				|| Self::is_owner_or_admin_permissions(target_collection, sender)?,
 			Error::<T>::NoPermission
 		);
 
@@ -1371,16 +1366,15 @@
 		item_id: TokenId,
 		amount: u128,
 	) -> DispatchResult {
-		collection.consume_gas(2000000)?;
 		Self::token_exists(collection, item_id)?;
 
 		// Transfer permissions check
 		let bypasses_limits = collection.limits.owner_can_transfer
-			&& Self::is_owner_or_admin_permissions(collection, sender);
+			&& Self::is_owner_or_admin_permissions(collection, sender)?;
 
 		let allowance_limit = if bypasses_limits {
 			None
-		} else if let Some(amount) = Self::owned_amount(sender, collection, item_id) {
+		} else if let Some(amount) = Self::owned_amount(sender, collection, item_id)? {
 			Some(amount)
 		} else {
 			fail!(Error::<T>::NoPermission);
@@ -1391,6 +1385,7 @@
 			Self::check_white_list(collection, spender)?;
 		}
 
+		collection.consume_sload()?;
 		let allowance: u128 = amount
 			.checked_add(<Allowances<T>>::get(
 				collection.id,
@@ -1400,6 +1395,7 @@
 		if let Some(limit) = allowance_limit {
 			ensure!(limit >= allowance, Error::<T>::TokenValueTooLow);
 		}
+		collection.consume_sstore()?;
 		<Allowances<T>>::insert(
 			collection.id,
 			(item_id, sender.as_sub(), spender.as_sub()),
@@ -1412,7 +1408,7 @@
 				owner: *sender.as_eth(),
 				approved: *spender.as_eth(),
 				token_id: item_id.into(),
-			});
+			})?;
 		}
 
 		if matches!(collection.mode, CollectionMode::Fungible(_)) {
@@ -1421,7 +1417,7 @@
 				owner: *sender.as_eth(),
 				spender: *spender.as_eth(),
 				value: allowance.into(),
-			});
+			})?;
 		}
 
 		Self::deposit_event(RawEvent::Approved(
@@ -1442,8 +1438,13 @@
 		item_id: TokenId,
 		amount: u128,
 	) -> DispatchResult {
-		collection.consume_gas(2000000)?;
+		if sender == from {
+			// Transfer by `from`, because it is either equal to sender, or derived from him
+			return Self::transfer_internal(from, recipient, collection, item_id, amount);
+		}
+
 		// Check approval
+		collection.consume_sload()?;
 		let approval: u128 =
 			<Allowances<T>>::get(collection.id, (item_id, from.as_sub(), sender.as_sub()));
 
@@ -1454,7 +1455,7 @@
 		ensure!(
 			approval >= amount
 				|| (collection.limits.owner_can_transfer
-					&& Self::is_owner_or_admin_permissions(collection, sender)),
+					&& Self::is_owner_or_admin_permissions(collection, sender)?),
 			Error::<T>::NoPermission
 		);
 
@@ -1465,6 +1466,7 @@
 
 		// Reduce approval by transferred amount or remove if remaining approval drops to 0
 		let allowance = approval.saturating_sub(amount);
+		collection.consume_sstore()?;
 		if allowance > 0 {
 			<Allowances<T>>::insert(
 				collection.id,
@@ -1497,7 +1499,7 @@
 				owner: *from.as_eth(),
 				spender: *sender.as_eth(),
 				value: allowance.into(),
-			});
+			})?;
 		}
 
 		Ok(())
@@ -1512,12 +1514,16 @@
 		Self::token_exists(collection, item_id)?;
 
 		ensure!(
-			ChainLimit::get().custom_data_limit >= data.len() as u32,
+			CUSTOM_DATA_LIMIT >= data.len() as u32,
 			Error::<T>::TokenVariableDataLimitExceeded
 		);
 
 		// Modify permissions check
-		Self::meta_update_check(sender, collection, item_id)?;
+		ensure!(
+			Self::is_item_owner(sender, collection, item_id)?
+				|| Self::is_owner_or_admin_permissions(collection, sender)?,
+			Error::<T>::NoPermission
+		);
 
 		match collection.mode {
 			CollectionMode::NFT => Self::set_nft_variable_data(collection, item_id, data)?,
@@ -1582,9 +1588,9 @@
 		value: u128,
 	) -> DispatchResult {
 		ensure!(
-			Self::is_item_owner(sender, collection, item_id)
+			Self::is_item_owner(sender, collection, item_id)?
 				|| (collection.limits.owner_can_transfer
-					&& Self::is_owner_or_admin_permissions(collection, sender)),
+					&& Self::is_owner_or_admin_permissions(collection, sender)?),
 			Error::<T>::NoPermission
 		);
 
@@ -1626,6 +1632,7 @@
 		let collection_id = collection.id;
 
 		// check token limit and account token limit
+		collection.consume_sload()?;
 		let account_items: u32 =
 			<AddressTokens<T>>::get(collection_id, recipient.as_sub()).len() as u32;
 		ensure!(
@@ -1633,6 +1640,9 @@
 			Error::<T>::AccountTokenLimitExceeded
 		);
 
+		// preliminary transfer check
+		ensure!(collection.transfers_enabled, Error::<T>::TransferNotAllowed);
+
 		Ok(())
 	}
 
@@ -1661,7 +1671,7 @@
 			Error::<T>::AccountTokenLimitExceeded
 		);
 
-		if !Self::is_owner_or_admin_permissions(collection, sender) {
+		if !Self::is_owner_or_admin_permissions(collection, sender)? {
 			ensure!(collection.mint_mode, Error::<T>::PublicMintingNotAllowed);
 			Self::check_white_list(collection, owner)?;
 			Self::check_white_list(collection, sender)?;
@@ -1676,38 +1686,17 @@
 	) -> DispatchResult {
 		match target_collection.mode {
 			CollectionMode::NFT => {
-				if let CreateItemData::NFT(data) = data {
-					// check sizes
-					ensure!(
-						ChainLimit::get().custom_data_limit >= data.const_data.len() as u32,
-						Error::<T>::TokenConstDataLimitExceeded
-					);
-					ensure!(
-						ChainLimit::get().custom_data_limit >= data.variable_data.len() as u32,
-						Error::<T>::TokenVariableDataLimitExceeded
-					);
-				} else {
+				if !matches!(data, CreateItemData::NFT(_)) {
 					fail!(Error::<T>::NotNftDataUsedToMintNftCollectionToken);
 				}
 			}
 			CollectionMode::Fungible(_) => {
-				if let CreateItemData::Fungible(_) = data {
-				} else {
+				if !matches!(data, CreateItemData::Fungible(_)) {
 					fail!(Error::<T>::NotFungibleDataUsedToMintFungibleCollectionToken);
 				}
 			}
 			CollectionMode::ReFungible => {
 				if let CreateItemData::ReFungible(data) = data {
-					// check sizes
-					ensure!(
-						ChainLimit::get().custom_data_limit >= data.const_data.len() as u32,
-						Error::<T>::TokenConstDataLimitExceeded
-					);
-					ensure!(
-						ChainLimit::get().custom_data_limit >= data.variable_data.len() as u32,
-						Error::<T>::TokenVariableDataLimitExceeded
-					);
-
 					// Check refungibility limits
 					ensure!(
 						data.pieces <= MAX_REFUNGIBLE_PIECES,
@@ -1735,8 +1724,8 @@
 			CreateItemData::NFT(data) => {
 				let item = NftItemType {
 					owner: owner.clone(),
-					const_data: data.const_data,
-					variable_data: data.variable_data,
+					const_data: data.const_data.into_inner(),
+					variable_data: data.variable_data.into_inner(),
 				};
 
 				Self::add_nft_item(collection, item)?;
@@ -1752,8 +1741,8 @@
 
 				let item = ReFungibleItemType {
 					owner: owner_list,
-					const_data: data.const_data,
-					variable_data: data.variable_data,
+					const_data: data.const_data.into_inner(),
+					variable_data: data.variable_data.into_inner(),
 				};
 
 				Self::add_refungible_item(collection, item)?;
@@ -1771,20 +1760,29 @@
 		let collection_id = collection.id;
 
 		// Does new owner already have an account?
+		collection.consume_sload()?;
 		let balance: u128 = <FungibleItemList<T>>::get(collection_id, owner.as_sub()).value;
 
 		// Mint
 		let item = FungibleItemType {
 			value: balance.checked_add(value).ok_or(Error::<T>::NumOverflow)?,
 		};
+		collection.consume_sstore()?;
 		<FungibleItemList<T>>::insert(collection_id, owner.as_sub(), item);
 
 		// Update balance
+		collection.consume_sload()?;
 		let new_balance = <Balance<T>>::get(collection_id, owner.as_sub())
 			.checked_add(value)
 			.ok_or(Error::<T>::NumOverflow)?;
+		collection.consume_sstore()?;
 		<Balance<T>>::insert(collection_id, owner.as_sub(), new_balance);
 
+		collection.log(ERC20Events::Transfer {
+			from: H160::default(),
+			to: *owner.as_eth(),
+			value: value.into(),
+		})?;
 		Self::deposit_event(RawEvent::ItemCreated(collection_id, 0, owner.clone()));
 		Ok(())
 	}
@@ -1806,7 +1804,7 @@
 		let value = item_owner.fraction;
 		let owner = item_owner.owner.clone();
 
-		Self::add_token_index(collection_id, current_index, &owner)?;
+		Self::add_token_index(collection, current_index, &owner)?;
 
 		<ItemListIndex>::insert(collection_id, current_index);
 		<ReFungibleItemList<T>>::insert(collection_id, current_index, itemcopy);
@@ -1832,7 +1830,7 @@
 			.ok_or(Error::<T>::NumOverflow)?;
 
 		let item_owner = item.owner.clone();
-		Self::add_token_index(collection_id, current_index, &item.owner)?;
+		Self::add_token_index(collection, current_index, &item.owner)?;
 
 		<ItemListIndex>::insert(collection_id, current_index);
 		<NftItemList<T>>::insert(collection_id, current_index, item);
@@ -1847,7 +1845,7 @@
 			from: H160::default(),
 			to: *item_owner.as_eth(),
 			token_id: current_index.into(),
-		});
+		})?;
 		Self::deposit_event(RawEvent::ItemCreated(
 			collection_id,
 			current_index,
@@ -1870,7 +1868,7 @@
 			.iter()
 			.find(|&i| i.owner == *owner)
 			.ok_or(Error::<T>::TokenNotFound)?;
-		Self::remove_token_index(collection_id, item_id, owner)?;
+		Self::remove_token_index(collection, item_id, owner)?;
 
 		// update balance
 		let new_balance = <Balance<T>>::get(collection_id, rft_balance.owner.as_sub())
@@ -1903,7 +1901,7 @@
 
 		let item =
 			<NftItemList<T>>::get(collection_id, item_id).ok_or(Error::<T>::TokenNotFound)?;
-		Self::remove_token_index(collection_id, item_id, &item.owner)?;
+		Self::remove_token_index(collection, item_id, &item.owner)?;
 
 		// update balance
 		let new_balance = <Balance<T>>::get(collection_id, item.owner.as_sub())
@@ -1913,6 +1911,11 @@
 		<NftItemList<T>>::remove(collection_id, item_id);
 		<VariableMetaDataBasket<T>>::remove(collection_id, item_id);
 
+		collection.log(ERC721Events::Transfer {
+			from: *item.owner.as_eth(),
+			to: H160::default(),
+			token_id: item_id.into(),
+		})?;
 		Self::deposit_event(RawEvent::ItemDestroyed(collection.id, item_id));
 		Ok(())
 	}
@@ -1944,7 +1947,7 @@
 			from: *owner.as_eth(),
 			to: H160::default(),
 			value: value.into(),
-		});
+		})?;
 		Ok(())
 	}
 
@@ -1952,20 +1955,6 @@
 		collection_id: CollectionId,
 	) -> Result<CollectionHandle<T>, sp_runtime::DispatchError> {
 		Ok(<CollectionHandle<T>>::get(collection_id).ok_or(Error::<T>::CollectionNotFound)?)
-	}
-
-	fn save_collection(collection: CollectionHandle<T>) {
-		<CollectionById<T>>::insert(collection.id, collection.into_inner());
-	}
-
-	pub fn submit_logs(collection: CollectionHandle<T>) -> DispatchResult {
-		if collection.logs.is_empty() {
-			return Ok(());
-		}
-		T::EthereumTransactionSender::submit_logs_transaction(
-			eth::generate_transaction(collection.id, T::EthereumChainId::get()),
-			collection.logs.retrieve_logs(),
-		)
 	}
 
 	fn check_owner_permissions(
@@ -1983,9 +1972,10 @@
 	fn is_owner_or_admin_permissions(
 		collection: &CollectionHandle<T>,
 		subject: &T::CrossAccountId,
-	) -> bool {
-		*subject.as_sub() == collection.owner
-			|| <AdminList<T>>::get(collection.id).contains(subject)
+	) -> Result<bool, DispatchError> {
+		collection.consume_sload()?;
+		Ok(*subject.as_sub() == collection.owner
+			|| <AdminList<T>>::get(collection.id).contains(subject))
 	}
 
 	fn check_owner_or_admin_permissions(
@@ -1993,7 +1983,7 @@
 		subject: &T::CrossAccountId,
 	) -> DispatchResult {
 		ensure!(
-			Self::is_owner_or_admin_permissions(collection, subject),
+			Self::is_owner_or_admin_permissions(collection, subject)?,
 			Error::<T>::NoPermission
 		);
 
@@ -2002,6 +1992,15 @@
 
 	fn owned_amount(
 		subject: &T::CrossAccountId,
+		collection: &CollectionHandle<T>,
+		item_id: TokenId,
+	) -> Result<Option<u128>, DispatchError> {
+		collection.consume_sload()?;
+		Ok(Self::owned_amount_unchecked(subject, collection, item_id))
+	}
+
+	fn owned_amount_unchecked(
+		subject: &T::CrossAccountId,
 		target_collection: &CollectionHandle<T>,
 		item_id: TokenId,
 	) -> Option<u128> {
@@ -2027,25 +2026,22 @@
 		subject: &T::CrossAccountId,
 		target_collection: &CollectionHandle<T>,
 		item_id: TokenId,
-	) -> bool {
-		match target_collection.mode {
+	) -> Result<bool, DispatchError> {
+		Ok(match target_collection.mode {
 			CollectionMode::Fungible(_) => true,
-			_ => Self::owned_amount(subject, target_collection, item_id).is_some(),
-		}
+			_ => Self::owned_amount(subject, target_collection, item_id)?.is_some(),
+		})
 	}
 
 	fn check_white_list(
 		collection: &CollectionHandle<T>,
 		address: &T::CrossAccountId,
 	) -> DispatchResult {
-		let collection_id = collection.id;
-
-		let mes = Error::<T>::AddresNotInWhiteList;
+		collection.consume_sload()?;
 		ensure!(
-			<WhiteList<T>>::contains_key(collection_id, address.as_sub()),
-			mes
+			<WhiteList<T>>::contains_key(collection.id, address.as_sub()),
+			Error::<T>::AddresNotInWhiteList,
 		);
-
 		Ok(())
 	}
 
@@ -2074,28 +2070,45 @@
 	) -> DispatchResult {
 		let collection_id = collection.id;
 
+		collection.consume_sload()?;
+		collection.consume_sload()?;
+		let mut recipient_balance = <FungibleItemList<T>>::get(collection_id, recipient.as_sub());
 		let mut balance = <FungibleItemList<T>>::get(collection_id, owner.as_sub());
-		ensure!(balance.value >= value, Error::<T>::TokenValueTooLow);
 
-		// Send balance to recipient (updates balanceOf of recipient)
-		Self::add_fungible_item(collection, recipient, value)?;
+		recipient_balance.value = recipient_balance
+			.value
+			.checked_add(value)
+			.ok_or(Error::<T>::NumOverflow)?;
+		balance.value = balance
+			.value
+			.checked_sub(value)
+			.ok_or(Error::<T>::TokenValueTooLow)?;
 
-		// update balanceOf of sender
-		<Balance<T>>::insert(collection_id, owner.as_sub(), balance.value - value);
+		// update balanceOf
+		collection.consume_sstore()?;
+		collection.consume_sstore()?;
+		if balance.value != 0 {
+			<Balance<T>>::insert(collection_id, owner.as_sub(), balance.value);
+		} else {
+			<Balance<T>>::remove(collection_id, owner.as_sub());
+		}
+		<Balance<T>>::insert(collection_id, recipient.as_sub(), recipient_balance.value);
 
 		// Reduce or remove sender
-		if balance.value == value {
-			<FungibleItemList<T>>::remove(collection_id, owner.as_sub());
-		} else {
-			balance.value -= value;
+		collection.consume_sstore()?;
+		collection.consume_sstore()?;
+		if balance.value != 0 {
 			<FungibleItemList<T>>::insert(collection_id, owner.as_sub(), balance);
+		} else {
+			<FungibleItemList<T>>::remove(collection_id, owner.as_sub());
 		}
+		<FungibleItemList<T>>::insert(collection_id, recipient.as_sub(), recipient_balance);
 
 		collection.log(ERC20Events::Transfer {
 			from: *owner.as_eth(),
 			to: *recipient.as_eth(),
 			value: value.into(),
-		});
+		})?;
 		Self::deposit_event(RawEvent::Transfer(
 			collection.id,
 			1,
@@ -2115,6 +2128,7 @@
 		new_owner: T::CrossAccountId,
 	) -> DispatchResult {
 		let collection_id = collection.id;
+		collection.consume_sload()?;
 		let full_item = <ReFungibleItemList<T>>::get(collection_id, item_id)
 			.ok_or(Error::<T>::TokenNotFound)?;
 
@@ -2127,15 +2141,19 @@
 
 		ensure!(amount >= value, Error::<T>::TokenValueTooLow);
 
+		collection.consume_sload()?;
 		// update balance
 		let balance_old_owner = <Balance<T>>::get(collection_id, item.owner.as_sub())
 			.checked_sub(value)
 			.ok_or(Error::<T>::NumOverflow)?;
+		collection.consume_sstore()?;
 		<Balance<T>>::insert(collection_id, item.owner.as_sub(), balance_old_owner);
 
+		collection.consume_sload()?;
 		let balance_new_owner = <Balance<T>>::get(collection_id, new_owner.as_sub())
 			.checked_add(value)
 			.ok_or(Error::<T>::NumOverflow)?;
+		collection.consume_sstore()?;
 		<Balance<T>>::insert(collection_id, new_owner.as_sub(), balance_new_owner);
 
 		let old_owner = item.owner.clone();
@@ -2152,10 +2170,11 @@
 				.find(|i| i.owner == owner)
 				.expect("old owner does present in refungible")
 				.owner = new_owner.clone();
+			collection.consume_sstore()?;
 			<ReFungibleItemList<T>>::insert(collection_id, item_id, new_full_item);
 
 			// update index collection
-			Self::move_token_index(collection_id, item_id, &old_owner, &new_owner)?;
+			Self::move_token_index(collection, item_id, &old_owner, &new_owner)?;
 		} else {
 			new_full_item
 				.owner
@@ -2179,9 +2198,10 @@
 					owner: new_owner.clone(),
 					fraction: value,
 				});
-				Self::add_token_index(collection_id, item_id, &new_owner)?;
+				Self::add_token_index(collection, item_id, &new_owner)?;
 			}
 
+			collection.consume_sstore()?;
 			<ReFungibleItemList<T>>::insert(collection_id, item_id, new_full_item);
 		}
 
@@ -2203,35 +2223,41 @@
 		new_owner: T::CrossAccountId,
 	) -> DispatchResult {
 		let collection_id = collection.id;
+		collection.consume_sload()?;
 		let mut item =
 			<NftItemList<T>>::get(collection_id, item_id).ok_or(Error::<T>::TokenNotFound)?;
 
 		ensure!(sender == item.owner, Error::<T>::MustBeTokenOwner);
 
+		collection.consume_sload()?;
 		// update balance
 		let balance_old_owner = <Balance<T>>::get(collection_id, item.owner.as_sub())
 			.checked_sub(1)
 			.ok_or(Error::<T>::NumOverflow)?;
+		collection.consume_sstore()?;
 		<Balance<T>>::insert(collection_id, item.owner.as_sub(), balance_old_owner);
 
+		collection.consume_sload()?;
 		let balance_new_owner = <Balance<T>>::get(collection_id, new_owner.as_sub())
 			.checked_add(1)
 			.ok_or(Error::<T>::NumOverflow)?;
+		collection.consume_sstore()?;
 		<Balance<T>>::insert(collection_id, new_owner.as_sub(), balance_new_owner);
 
 		// change owner
 		let old_owner = item.owner.clone();
 		item.owner = new_owner.clone();
+		collection.consume_sstore()?;
 		<NftItemList<T>>::insert(collection_id, item_id, item);
 
 		// update index collection
-		Self::move_token_index(collection_id, item_id, &old_owner, &new_owner)?;
+		Self::move_token_index(collection, item_id, &old_owner, &new_owner)?;
 
 		collection.log(ERC721Events::Transfer {
 			from: *sender.as_eth(),
 			to: *new_owner.as_eth(),
 			token_id: item_id.into(),
-		});
+		})?;
 		Self::deposit_event(RawEvent::Transfer(
 			collection.id,
 			item_id,
@@ -2305,7 +2331,12 @@
 	fn init_nft_token(collection_id: CollectionId, item: &NftItemType<T::CrossAccountId>) {
 		let current_index = <ItemListIndex>::get(collection_id).checked_add(1).unwrap();
 
-		Self::add_token_index(collection_id, current_index, &item.owner).unwrap();
+		Self::add_token_index(
+			&CollectionHandle::get(collection_id).unwrap(),
+			current_index,
+			&item.owner,
+		)
+		.unwrap();
 
 		<ItemListIndex>::insert(collection_id, current_index);
 
@@ -2324,7 +2355,12 @@
 	) {
 		let current_index = <ItemListIndex>::get(collection_id).checked_add(1).unwrap();
 
-		Self::add_token_index(collection_id, current_index, owner).unwrap();
+		Self::add_token_index(
+			&CollectionHandle::get(collection_id).unwrap(),
+			current_index,
+			owner,
+		)
+		.unwrap();
 
 		<ItemListIndex>::insert(collection_id, current_index);
 
@@ -2345,7 +2381,12 @@
 		let value = item.owner.first().unwrap().fraction;
 		let owner = item.owner.first().unwrap().owner.clone();
 
-		Self::add_token_index(collection_id, current_index, &owner).unwrap();
+		Self::add_token_index(
+			&CollectionHandle::get(collection_id).unwrap(),
+			current_index,
+			&owner,
+		)
+		.unwrap();
 
 		<ItemListIndex>::insert(collection_id, current_index);
 
@@ -2357,51 +2398,61 @@
 	}
 
 	fn add_token_index(
-		collection_id: CollectionId,
+		collection: &CollectionHandle<T>,
 		item_index: TokenId,
 		owner: &T::CrossAccountId,
 	) -> DispatchResult {
 		// add to account limit
+		collection.consume_sload()?;
 		if <AccountItemCount<T>>::contains_key(owner.as_sub()) {
 			// bound Owned tokens by a single address
+			collection.consume_sload()?;
 			let count = <AccountItemCount<T>>::get(owner.as_sub());
 			ensure!(
-				count < ChainLimit::get().account_token_ownership_limit,
+				count < ACCOUNT_TOKEN_OWNERSHIP_LIMIT,
 				Error::<T>::AddressOwnershipLimitExceeded
 			);
 
+			collection.consume_sstore()?;
 			<AccountItemCount<T>>::insert(
 				owner.as_sub(),
 				count.checked_add(1).ok_or(Error::<T>::NumOverflow)?,
 			);
 		} else {
+			collection.consume_sstore()?;
 			<AccountItemCount<T>>::insert(owner.as_sub(), 1);
 		}
 
-		let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner.as_sub());
+		collection.consume_sload()?;
+		let list_exists = <AddressTokens<T>>::contains_key(collection.id, owner.as_sub());
 		if list_exists {
-			let mut list = <AddressTokens<T>>::get(collection_id, owner.as_sub());
+			collection.consume_sload()?;
+			let mut list = <AddressTokens<T>>::get(collection.id, owner.as_sub());
 			let item_contains = list.contains(&item_index.clone());
 
 			if !item_contains {
 				list.push(item_index);
 			}
 
-			<AddressTokens<T>>::insert(collection_id, owner.as_sub(), list);
+			collection.consume_sstore()?;
+			<AddressTokens<T>>::insert(collection.id, owner.as_sub(), list);
 		} else {
 			let itm = vec![item_index];
-			<AddressTokens<T>>::insert(collection_id, owner.as_sub(), itm);
+			collection.consume_sstore()?;
+			<AddressTokens<T>>::insert(collection.id, owner.as_sub(), itm);
 		}
 
 		Ok(())
 	}
 
 	fn remove_token_index(
-		collection_id: CollectionId,
+		collection: &CollectionHandle<T>,
 		item_index: TokenId,
 		owner: &T::CrossAccountId,
 	) -> DispatchResult {
 		// update counter
+		collection.consume_sload()?;
+		collection.consume_sstore()?;
 		<AccountItemCount<T>>::insert(
 			owner.as_sub(),
 			<AccountItemCount<T>>::get(owner.as_sub())
@@ -2409,14 +2460,17 @@
 				.ok_or(Error::<T>::NumOverflow)?,
 		);
 
-		let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner.as_sub());
+		collection.consume_sload()?;
+		let list_exists = <AddressTokens<T>>::contains_key(collection.id, owner.as_sub());
 		if list_exists {
-			let mut list = <AddressTokens<T>>::get(collection_id, owner.as_sub());
+			collection.consume_sload()?;
+			let mut list = <AddressTokens<T>>::get(collection.id, owner.as_sub());
 			let item_contains = list.contains(&item_index.clone());
 
 			if item_contains {
 				list.retain(|&item| item != item_index);
-				<AddressTokens<T>>::insert(collection_id, owner.as_sub(), list);
+				collection.consume_sstore()?;
+				<AddressTokens<T>>::insert(collection.id, owner.as_sub(), list);
 			}
 		}
 
@@ -2424,13 +2478,13 @@
 	}
 
 	fn move_token_index(
-		collection_id: CollectionId,
+		collection: &CollectionHandle<T>,
 		item_index: TokenId,
 		old_owner: &T::CrossAccountId,
 		new_owner: &T::CrossAccountId,
 	) -> DispatchResult {
-		Self::remove_token_index(collection_id, item_index, old_owner)?;
-		Self::add_token_index(collection_id, item_index, new_owner)?;
+		Self::remove_token_index(collection, item_index, old_owner)?;
+		Self::add_token_index(collection, item_index, new_owner)?;
 
 		Ok(())
 	}
modifiedpallets/nft/src/mock.rsdiffbeforeafterboth
--- a/pallets/nft/src/mock.rs
+++ b/pallets/nft/src/mock.rs
@@ -6,7 +6,6 @@
 use sp_runtime::{
 	traits::{BlakeTwo256, IdentityLookup},
 	testing::Header,
-	Perbill,
 };
 use pallet_transaction_payment::{CurrencyAdapter};
 use frame_system as system;
@@ -99,9 +98,12 @@
 	type WeightInfo = ();
 }
 
+<<<<<<< HEAD
 type Timestamp = pallet_timestamp::Pallet<Test>;
 type Randomness = pallet_randomness_collective_flip::Pallet<Test>;
 
+=======
+>>>>>>> origin/develop
 parameter_types! {
 	pub const CollectionCreationPrice: u32 = 0;
 	pub TreasuryAccountId: u64 = 1234;
@@ -133,8 +135,11 @@
 	fn as_sub(&self) -> &u64 {
 		&self.0
 	}
-	fn from_eth(_eth: sp_core::H160) -> Self {
-		unimplemented!()
+	fn from_eth(eth: sp_core::H160) -> Self {
+		let mut sub_raw = [0; 8];
+		sub_raw.copy_from_slice(&eth.0[0..8]);
+		let sub = u64::from_be_bytes(sub_raw);
+		Self(sub, eth)
 	}
 	fn as_eth(&self) -> &sp_core::H160 {
 		&self.1
@@ -151,6 +156,10 @@
 	}
 }
 
+impl pallet_evm_coder_substrate::Config for Test {
+	type EthereumTransactionSender = TestEtheremTransactionSender;
+}
+
 impl pallet_template::Config for Test {
 	type Event = ();
 	type WeightInfo = ();
@@ -160,8 +169,6 @@
 	type EvmAddressMapping = TestEvmAddressMapping;
 	type EvmBackwardsAddressMapping = TestEvmBackwardsAddressMapping;
 	type CrossAccountId = TestCrossAccountId;
-	type EthereumChainId = EthereumChainId;
-	type EthereumTransactionSender = TestEtheremTransactionSender;
 }
 
 // Build genesis storage according to the mock runtime.
modifiedpallets/nft/src/sponsorship.rsdiffbeforeafterboth
--- a/pallets/nft/src/sponsorship.rs
+++ b/pallets/nft/src/sponsorship.rs
@@ -1,15 +1,18 @@
 use crate::{
 	Config, Call, CollectionById, CreateItemBasket, VariableMetaDataBasket,
-	ReFungibleTransferBasket, FungibleTransferBasket, NftTransferBasket, ChainLimit,
-	CreateItemData, CollectionMode,
+	ReFungibleTransferBasket, FungibleTransferBasket, NftTransferBasket, CreateItemData,
+	CollectionMode,
 };
 use core::marker::PhantomData;
 use up_sponsorship::SponsorshipHandler;
 use frame_support::{
-	traits::IsSubType,
-	storage::{StorageMap, StorageDoubleMap, StorageValue},
+	traits::{IsSubType},
+	storage::{StorageMap, StorageDoubleMap},
+};
+use nft_data_structs::{
+	TokenId, CollectionId, NFT_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+	FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
 };
-use nft_data_structs::{TokenId, CollectionId};
 
 pub struct NftSponsorshipHandler<T>(PhantomData<T>);
 impl<T: Config> NftSponsorshipHandler<T> {
@@ -47,7 +50,6 @@
 		item_id: &TokenId,
 	) -> Option<T::AccountId> {
 		let collection = CollectionById::<T>::get(collection_id)?;
-		let limits = ChainLimit::get();
 
 		let mut sponsor_transfer = false;
 		if collection.sponsorship.confirmed() {
@@ -62,7 +64,7 @@
 					let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {
 						collection_limits.sponsor_transfer_timeout
 					} else {
-						limits.nft_sponsor_transfer_timeout
+						NFT_SPONSOR_TRANSFER_TIMEOUT
 					};
 
 					let mut sponsored = true;
@@ -84,7 +86,7 @@
 					let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {
 						collection_limits.sponsor_transfer_timeout
 					} else {
-						limits.fungible_sponsor_transfer_timeout
+						FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT
 					};
 
 					let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
@@ -107,7 +109,7 @@
 					let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {
 						collection_limits.sponsor_transfer_timeout
 					} else {
-						limits.refungible_sponsor_transfer_timeout
+						REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT
 					};
 
 					let mut sponsored = true;
modifiedpallets/nft/src/tests.rsdiffbeforeafterboth
--- a/pallets/nft/src/tests.rs
+++ b/pallets/nft/src/tests.rs
@@ -1,40 +1,18 @@
 // Tests to be written here
 use super::*;
 use crate::mock::*;
-use crate::{AccessMode, CollectionMode, Ownership, ChainLimits, CreateItemData};
+use crate::{AccessMode, CollectionMode, Ownership, CreateItemData};
 use nft_data_structs::{
 	CreateNftData, CreateFungibleData, CreateReFungibleData, CollectionId, TokenId,
 	MAX_DECIMAL_POINTS,
 };
 use frame_support::{assert_noop, assert_ok};
-use frame_system::{RawOrigin};
-
-fn default_collection_numbers_limit() -> u32 {
-	10
-}
-
-fn default_limits() {
-	assert_ok!(TemplateModule::set_chain_limits(
-		RawOrigin::Root.into(),
-		ChainLimits {
-			collection_numbers_limit: default_collection_numbers_limit(),
-			account_token_ownership_limit: 10,
-			collections_admins_limit: 5,
-			custom_data_limit: 2048,
-			nft_sponsor_transfer_timeout: 15,
-			fungible_sponsor_transfer_timeout: 15,
-			refungible_sponsor_transfer_timeout: 15,
-			const_on_chain_schema_limit: 1024,
-			offchain_schema_limit: 1024,
-			variable_on_chain_schema_limit: 1024,
-		}
-	));
-}
+use sp_std::convert::TryInto;
 
 fn default_nft_data() -> CreateNftData {
 	CreateNftData {
-		const_data: vec![1, 2, 3],
-		variable_data: vec![3, 2, 1],
+		const_data: vec![1, 2, 3].try_into().unwrap(),
+		variable_data: vec![3, 2, 1].try_into().unwrap(),
 	}
 }
 
@@ -44,8 +22,8 @@
 
 fn default_re_fungible_data() -> CreateReFungibleData {
 	CreateReFungibleData {
-		const_data: vec![1, 2, 3],
-		variable_data: vec![3, 2, 1],
+		const_data: vec![1, 2, 3].try_into().unwrap(),
+		variable_data: vec![3, 2, 1].try_into().unwrap(),
 		pieces: 1023,
 	}
 }
@@ -112,7 +90,6 @@
 #[test]
 fn set_version_schema() {
 	new_test_ext().execute_with(|| {
-		default_limits();
 		let origin1 = Origin::signed(1);
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
@@ -133,8 +110,6 @@
 #[test]
 fn create_fungible_collection_fails_with_large_decimal_numbers() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();
 		let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();
 		let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();
@@ -156,14 +131,13 @@
 #[test]
 fn create_nft_item() {
 	new_test_ext().execute_with(|| {
-		default_limits();
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let data = default_nft_data();
 		create_test_item(collection_id, &data.clone().into());
 		let item = TemplateModule::nft_item_id(collection_id, 1).unwrap();
-		assert_eq!(item.const_data, data.const_data);
-		assert_eq!(item.variable_data, data.variable_data);
+		assert_eq!(item.const_data, data.const_data.into_inner());
+		assert_eq!(item.variable_data, data.variable_data.into_inner());
 	});
 }
 
@@ -172,8 +146,6 @@
 #[test]
 fn create_nft_multiple_items() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -190,10 +162,10 @@
 				.map(|d| { d.into() })
 				.collect()
 		));
-		for (index, data) in items_data.iter().enumerate() {
+		for (index, data) in items_data.into_iter().enumerate() {
 			let item = TemplateModule::nft_item_id(1, (index + 1) as TokenId).unwrap();
-			assert_eq!(item.const_data.to_vec(), data.const_data);
-			assert_eq!(item.variable_data.to_vec(), data.variable_data);
+			assert_eq!(item.const_data.to_vec(), data.const_data.into_inner());
+			assert_eq!(item.variable_data.to_vec(), data.variable_data.into_inner());
 		}
 	});
 }
@@ -201,14 +173,13 @@
 #[test]
 fn create_refungible_item() {
 	new_test_ext().execute_with(|| {
-		default_limits();
 		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);
 
 		let data = default_re_fungible_data();
 		create_test_item(collection_id, &data.clone().into());
 		let item = TemplateModule::refungible_item_id(collection_id, 1).unwrap();
-		assert_eq!(item.const_data, data.const_data);
-		assert_eq!(item.variable_data, data.variable_data);
+		assert_eq!(item.const_data, data.const_data.into_inner());
+		assert_eq!(item.variable_data, data.variable_data.into_inner());
 		assert_eq!(
 			item.owner[0],
 			Ownership {
@@ -222,8 +193,6 @@
 #[test]
 fn create_multiple_refungible_items() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		create_test_collection(&CollectionMode::ReFungible, 1);
 
 		let origin1 = Origin::signed(1);
@@ -244,10 +213,10 @@
 				.map(|d| { d.into() })
 				.collect()
 		));
-		for (index, data) in items_data.iter().enumerate() {
+		for (index, data) in items_data.into_iter().enumerate() {
 			let item = TemplateModule::refungible_item_id(1, (index + 1) as TokenId).unwrap();
-			assert_eq!(item.const_data.to_vec(), data.const_data);
-			assert_eq!(item.variable_data.to_vec(), data.variable_data);
+			assert_eq!(item.const_data.to_vec(), data.const_data.into_inner());
+			assert_eq!(item.variable_data.to_vec(), data.variable_data.into_inner());
 			assert_eq!(
 				item.owner[0],
 				Ownership {
@@ -262,8 +231,6 @@
 #[test]
 fn create_fungible_item() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);
 
 		let data = default_fungible_data();
@@ -302,8 +269,6 @@
 #[test]
 fn transfer_fungible_item() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);
 
 		let origin1 = Origin::signed(1);
@@ -344,8 +309,6 @@
 #[test]
 fn transfer_refungible_item() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);
 
 		let data = default_re_fungible_data();
@@ -355,8 +318,8 @@
 		let origin2 = Origin::signed(2);
 		{
 			let item = TemplateModule::refungible_item_id(collection_id, 1).unwrap();
-			assert_eq!(item.const_data, data.const_data);
-			assert_eq!(item.variable_data, data.variable_data);
+			assert_eq!(item.const_data, data.const_data.into_inner());
+			assert_eq!(item.variable_data, data.variable_data.into_inner());
 			assert_eq!(
 				item.owner[0],
 				Ownership {
@@ -441,8 +404,6 @@
 #[test]
 fn transfer_nft_item() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let data = default_nft_data();
@@ -464,8 +425,6 @@
 #[test]
 fn nft_approve_and_transfer_from() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let data = default_nft_data();
@@ -503,8 +462,6 @@
 #[test]
 fn nft_approve_and_transfer_from_white_list() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -514,8 +471,8 @@
 		create_test_item(collection_id, &data.clone().into());
 
 		assert_eq!(
-			TemplateModule::nft_item_id(1, 1).unwrap().const_data,
-			data.const_data
+			&TemplateModule::nft_item_id(1, 1).unwrap().const_data,
+			&data.const_data.into_inner()
 		);
 		assert_eq!(TemplateModule::balance_count(1, 1), 1);
 		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
@@ -573,8 +530,6 @@
 #[test]
 fn refungible_approve_and_transfer_from() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);
 
 		let origin1 = Origin::signed(1);
@@ -636,8 +591,6 @@
 #[test]
 fn fungible_approve_and_transfer_from() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);
 
 		let data = default_fungible_data();
@@ -710,8 +663,6 @@
 #[test]
 fn change_collection_owner() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -730,8 +681,6 @@
 #[test]
 fn destroy_collection() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -742,8 +691,6 @@
 #[test]
 fn burn_nft_item() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -773,8 +720,6 @@
 #[test]
 fn burn_fungible_item() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);
 
 		let origin1 = Origin::signed(1);
@@ -804,8 +749,6 @@
 #[test]
 fn burn_refungible_item() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);
 		let origin1 = Origin::signed(1);
 
@@ -851,8 +794,6 @@
 #[test]
 fn add_collection_admin() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);
 		create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);
 		create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);
@@ -879,8 +820,6 @@
 #[test]
 fn remove_collection_admin() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);
 		create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);
 		create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);
@@ -916,8 +855,6 @@
 #[test]
 fn balance_of() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let nft_collection_id = create_test_collection(&CollectionMode::NFT, 1);
 		let fungible_collection_id = create_test_collection(&CollectionMode::Fungible(3), 2);
 		let re_fungible_collection_id = create_test_collection(&CollectionMode::ReFungible, 3);
@@ -969,8 +906,6 @@
 #[test]
 fn approve() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let data = default_nft_data();
@@ -987,8 +922,6 @@
 #[test]
 fn transfer_from() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
@@ -1051,8 +984,6 @@
 #[test]
 fn owner_can_add_address_to_white_list() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -1068,8 +999,6 @@
 #[test]
 fn admin_can_add_address_to_white_list() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
@@ -1091,8 +1020,6 @@
 #[test]
 fn nonprivileged_user_cannot_add_address_to_white_list() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin2 = Origin::signed(2);
@@ -1106,8 +1033,6 @@
 #[test]
 fn nobody_can_add_address_to_white_list_of_nonexisting_collection() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let origin1 = Origin::signed(1);
 
 		assert_noop!(
@@ -1120,8 +1045,6 @@
 #[test]
 fn nobody_can_add_address_to_white_list_of_deleted_collection() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -1140,8 +1063,6 @@
 #[test]
 fn address_is_already_added_to_white_list() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 		let origin1 = Origin::signed(1);
 
@@ -1162,8 +1083,6 @@
 #[test]
 fn owner_can_remove_address_from_white_list() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -1184,8 +1103,6 @@
 #[test]
 fn admin_can_remove_address_from_white_list() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
@@ -1213,8 +1130,6 @@
 #[test]
 fn nonprivileged_user_cannot_remove_address_from_white_list() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
@@ -1235,7 +1150,6 @@
 #[test]
 fn nobody_can_remove_address_from_white_list_of_nonexisting_collection() {
 	new_test_ext().execute_with(|| {
-		default_limits();
 		let origin1 = Origin::signed(1);
 
 		assert_noop!(
@@ -1248,8 +1162,6 @@
 #[test]
 fn nobody_can_remove_address_from_white_list_of_deleted_collection() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
@@ -1272,8 +1184,6 @@
 #[test]
 fn address_is_already_removed_from_white_list() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 		let origin1 = Origin::signed(1);
 
@@ -1300,8 +1210,6 @@
 #[test]
 fn white_list_test_1() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -1330,8 +1238,6 @@
 #[test]
 fn white_list_test_2() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 		let origin1 = Origin::signed(1);
 
@@ -1381,8 +1287,6 @@
 #[test]
 fn white_list_test_3() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -1411,8 +1315,6 @@
 #[test]
 fn white_list_test_4() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -1463,8 +1365,6 @@
 #[test]
 fn white_list_test_5() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -1488,8 +1388,6 @@
 #[test]
 fn white_list_test_6() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -1516,8 +1414,6 @@
 #[test]
 fn white_list_test_7() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let data = default_nft_data();
@@ -1548,8 +1444,6 @@
 #[test]
 fn white_list_test_8() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let data = default_nft_data();
@@ -1598,8 +1492,6 @@
 #[test]
 fn white_list_test_9() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 		let origin1 = Origin::signed(1);
 
@@ -1623,8 +1515,6 @@
 #[test]
 fn white_list_test_10() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -1660,8 +1550,6 @@
 #[test]
 fn white_list_test_11() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -1694,8 +1582,6 @@
 #[test]
 fn white_list_test_12() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -1723,8 +1609,6 @@
 #[test]
 fn white_list_test_13() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -1749,8 +1633,6 @@
 #[test]
 fn white_list_test_14() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -1786,8 +1668,6 @@
 #[test]
 fn white_list_test_15() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -1815,8 +1695,6 @@
 #[test]
 fn white_list_test_16() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -1851,8 +1729,6 @@
 #[test]
 fn total_number_collections_bound() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		create_test_collection(&CollectionMode::NFT, 1);
 	});
 }
@@ -1861,11 +1737,9 @@
 #[test]
 fn total_number_collections_bound_neg() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let origin1 = Origin::signed(1);
 
-		for i in 0..default_collection_numbers_limit() {
+		for i in 0..COLLECTION_NUMBER_LIMIT {
 			create_test_collection(&CollectionMode::NFT, i + 1);
 		}
 
@@ -1891,8 +1765,6 @@
 #[test]
 fn owned_tokens_bound() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let data = default_nft_data();
@@ -1905,28 +1777,16 @@
 #[test]
 fn owned_tokens_bound_neg() {
 	new_test_ext().execute_with(|| {
-		assert_ok!(TemplateModule::set_chain_limits(
-			RawOrigin::Root.into(),
-			ChainLimits {
-				collection_numbers_limit: 10,
-				account_token_ownership_limit: 1,
-				collections_admins_limit: 5,
-				custom_data_limit: 2048,
-				nft_sponsor_transfer_timeout: 15,
-				fungible_sponsor_transfer_timeout: 15,
-				refungible_sponsor_transfer_timeout: 15,
-				const_on_chain_schema_limit: 1024,
-				offchain_schema_limit: 1024,
-				variable_on_chain_schema_limit: 1024,
-			}
-		));
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
-		let data = default_nft_data();
-		create_test_item(collection_id, &data.clone().into());
 
+		for _ in 0..ACCOUNT_TOKEN_OWNERSHIP_LIMIT {
+			let data = default_nft_data();
+			create_test_item(collection_id, &data.clone().into());
+		}
+
+		let data = default_nft_data();
 		assert_noop!(
 			TemplateModule::create_item(origin1, 1, account(1), data.into()),
 			Error::<Test>::AddressOwnershipLimitExceeded
@@ -1938,22 +1798,6 @@
 #[test]
 fn collection_admins_bound() {
 	new_test_ext().execute_with(|| {
-		assert_ok!(TemplateModule::set_chain_limits(
-			RawOrigin::Root.into(),
-			ChainLimits {
-				collection_numbers_limit: 10,
-				account_token_ownership_limit: 10,
-				collections_admins_limit: 2,
-				custom_data_limit: 2048,
-				nft_sponsor_transfer_timeout: 15,
-				fungible_sponsor_transfer_timeout: 15,
-				refungible_sponsor_transfer_timeout: 15,
-				const_on_chain_schema_limit: 1024,
-				offchain_schema_limit: 1024,
-				variable_on_chain_schema_limit: 1024,
-			}
-		));
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -1975,184 +1819,32 @@
 #[test]
 fn collection_admins_bound_neg() {
 	new_test_ext().execute_with(|| {
-		assert_ok!(TemplateModule::set_chain_limits(
-			RawOrigin::Root.into(),
-			ChainLimits {
-				collection_numbers_limit: 10,
-				account_token_ownership_limit: 1,
-				collections_admins_limit: 1,
-				custom_data_limit: 2048,
-				nft_sponsor_transfer_timeout: 15,
-				fungible_sponsor_transfer_timeout: 15,
-				refungible_sponsor_transfer_timeout: 15,
-				const_on_chain_schema_limit: 1024,
-				offchain_schema_limit: 1024,
-				variable_on_chain_schema_limit: 1024,
-			}
-		));
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
 
-		assert_ok!(TemplateModule::add_collection_admin(
-			origin1.clone(),
-			collection_id,
-			account(2)
-		));
+		for i in 0..COLLECTION_ADMINS_LIMIT {
+			assert_ok!(TemplateModule::add_collection_admin(
+				origin1.clone(),
+				collection_id,
+				account(2 + i)
+			));
+		}
 		assert_noop!(
-			TemplateModule::add_collection_admin(origin1, collection_id, account(3)),
+			TemplateModule::add_collection_admin(
+				origin1,
+				collection_id,
+				account(3 + COLLECTION_ADMINS_LIMIT)
+			),
 			Error::<Test>::CollectionAdminsLimitExceeded
 		);
 	});
 }
-
-// NFT custom data size. Negative test const_data.
-#[test]
-fn custom_data_size_nft_const_data_bound_neg() {
-	new_test_ext().execute_with(|| {
-		assert_ok!(TemplateModule::set_chain_limits(
-			RawOrigin::Root.into(),
-			ChainLimits {
-				collection_numbers_limit: 10,
-				account_token_ownership_limit: 10,
-				collections_admins_limit: 5,
-				custom_data_limit: 2,
-				nft_sponsor_transfer_timeout: 15,
-				fungible_sponsor_transfer_timeout: 15,
-				refungible_sponsor_transfer_timeout: 15,
-				const_on_chain_schema_limit: 1024,
-				offchain_schema_limit: 1024,
-				variable_on_chain_schema_limit: 1024,
-			}
-		));
-
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
-
-		let origin1 = Origin::signed(1);
-		let too_big_const_data = CreateItemData::NFT(CreateNftData {
-			const_data: vec![1, 2, 3, 4],
-			variable_data: vec![],
-		});
-
-		assert_noop!(
-			TemplateModule::create_item(origin1, collection_id, account(1), too_big_const_data),
-			Error::<Test>::TokenConstDataLimitExceeded
-		);
-	});
-}
-
-// NFT custom data size. Negative test variable_data.
-#[test]
-fn custom_data_size_nft_variable_data_bound_neg() {
-	new_test_ext().execute_with(|| {
-		assert_ok!(TemplateModule::set_chain_limits(
-			RawOrigin::Root.into(),
-			ChainLimits {
-				collection_numbers_limit: 10,
-				account_token_ownership_limit: 10,
-				collections_admins_limit: 5,
-				custom_data_limit: 2,
-				nft_sponsor_transfer_timeout: 15,
-				fungible_sponsor_transfer_timeout: 15,
-				refungible_sponsor_transfer_timeout: 15,
-				const_on_chain_schema_limit: 1024,
-				offchain_schema_limit: 1024,
-				variable_on_chain_schema_limit: 1024,
-			}
-		));
-
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
-
-		let origin1 = Origin::signed(1);
-		let too_big_const_data = CreateItemData::NFT(CreateNftData {
-			const_data: vec![],
-			variable_data: vec![1, 2, 3, 4],
-		});
-
-		assert_noop!(
-			TemplateModule::create_item(origin1, collection_id, account(1), too_big_const_data),
-			Error::<Test>::TokenVariableDataLimitExceeded
-		);
-	});
-}
-
-// Re fungible custom data size. Negative test const_data.
-#[test]
-fn custom_data_size_re_fungible_const_data_bound_neg() {
-	new_test_ext().execute_with(|| {
-		assert_ok!(TemplateModule::set_chain_limits(
-			RawOrigin::Root.into(),
-			ChainLimits {
-				collection_numbers_limit: 10,
-				account_token_ownership_limit: 10,
-				collections_admins_limit: 5,
-				custom_data_limit: 2,
-				nft_sponsor_transfer_timeout: 15,
-				fungible_sponsor_transfer_timeout: 15,
-				refungible_sponsor_transfer_timeout: 15,
-				const_on_chain_schema_limit: 1024,
-				offchain_schema_limit: 1024,
-				variable_on_chain_schema_limit: 1024,
-			}
-		));
-
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
-
-		let origin1 = Origin::signed(1);
-		let too_big_const_data = CreateItemData::NFT(CreateNftData {
-			const_data: vec![1, 2, 3, 4],
-			variable_data: vec![],
-		});
-
-		assert_noop!(
-			TemplateModule::create_item(origin1, collection_id, account(1), too_big_const_data),
-			Error::<Test>::TokenConstDataLimitExceeded
-		);
-	});
-}
-
-// Re fungible custom data size. Negative test variable_data.
-#[test]
-fn custom_data_size_re_fungible_variable_data_bound_neg() {
-	new_test_ext().execute_with(|| {
-		assert_ok!(TemplateModule::set_chain_limits(
-			RawOrigin::Root.into(),
-			ChainLimits {
-				collection_numbers_limit: 10,
-				account_token_ownership_limit: 10,
-				collections_admins_limit: 5,
-				custom_data_limit: 2,
-				nft_sponsor_transfer_timeout: 15,
-				fungible_sponsor_transfer_timeout: 15,
-				refungible_sponsor_transfer_timeout: 15,
-				const_on_chain_schema_limit: 1024,
-				offchain_schema_limit: 1024,
-				variable_on_chain_schema_limit: 1024,
-			}
-		));
-
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
-
-		let origin1 = Origin::signed(1);
-		let too_big_const_data = CreateItemData::NFT(CreateNftData {
-			const_data: vec![],
-			variable_data: vec![1, 2, 3, 4],
-		});
-
-		assert_noop!(
-			TemplateModule::create_item(origin1, collection_id, account(1), too_big_const_data),
-			Error::<Test>::TokenVariableDataLimitExceeded
-		);
-	});
-}
 // #endregion
 
 #[test]
 fn set_const_on_chain_schema() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -2180,8 +1872,6 @@
 #[test]
 fn set_variable_on_chain_schema() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -2209,8 +1899,6 @@
 #[test]
 fn set_variable_meta_data_on_nft_token_stores_variable_meta_data() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -2218,7 +1906,7 @@
 		let data = default_nft_data();
 		create_test_item(1, &data.into());
 
-		let variable_data = b"test set_variable_meta_data method.".to_vec();
+		let variable_data = b"test data".to_vec();
 		assert_ok!(TemplateModule::set_variable_meta_data(
 			origin1,
 			collection_id,
@@ -2238,8 +1926,6 @@
 #[test]
 fn set_variable_meta_data_on_re_fungible_token_stores_variable_meta_data() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);
 
 		let origin1 = Origin::signed(1);
@@ -2247,7 +1933,7 @@
 		let data = default_re_fungible_data();
 		create_test_item(1, &data.into());
 
-		let variable_data = b"test set_variable_meta_data method.".to_vec();
+		let variable_data = b"test data".to_vec();
 		assert_ok!(TemplateModule::set_variable_meta_data(
 			origin1,
 			collection_id,
@@ -2267,8 +1953,6 @@
 #[test]
 fn set_variable_meta_data_on_fungible_token_fails() {
 	new_test_ext().execute_with(|| {
-		default_limits();
-
 		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);
 
 		let origin1 = Origin::signed(1);
@@ -2276,7 +1960,7 @@
 		let data = default_fungible_data();
 		create_test_item(1, &data.into());
 
-		let variable_data = b"test set_variable_meta_data method.".to_vec();
+		let variable_data = b"test data".to_vec();
 		assert_noop!(
 			TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data),
 			Error::<Test>::CantStoreMetadataInFungibleTokens
@@ -2287,22 +1971,6 @@
 #[test]
 fn set_variable_meta_data_on_nft_token_fails_for_big_data() {
 	new_test_ext().execute_with(|| {
-		assert_ok!(TemplateModule::set_chain_limits(
-			RawOrigin::Root.into(),
-			ChainLimits {
-				collection_numbers_limit: default_collection_numbers_limit(),
-				account_token_ownership_limit: 10,
-				collections_admins_limit: 5,
-				custom_data_limit: 10,
-				nft_sponsor_transfer_timeout: 15,
-				fungible_sponsor_transfer_timeout: 15,
-				refungible_sponsor_transfer_timeout: 15,
-				const_on_chain_schema_limit: 1024,
-				offchain_schema_limit: 1024,
-				variable_on_chain_schema_limit: 1024,
-			}
-		));
-
 		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
 
 		let origin1 = Origin::signed(1);
@@ -2321,22 +1989,6 @@
 #[test]
 fn set_variable_meta_data_on_re_fungible_token_fails_for_big_data() {
 	new_test_ext().execute_with(|| {
-		assert_ok!(TemplateModule::set_chain_limits(
-			RawOrigin::Root.into(),
-			ChainLimits {
-				collection_numbers_limit: default_collection_numbers_limit(),
-				account_token_ownership_limit: 10,
-				collections_admins_limit: 5,
-				custom_data_limit: 10,
-				nft_sponsor_transfer_timeout: 15,
-				fungible_sponsor_transfer_timeout: 15,
-				refungible_sponsor_transfer_timeout: 15,
-				const_on_chain_schema_limit: 1024,
-				offchain_schema_limit: 1024,
-				variable_on_chain_schema_limit: 1024,
-			}
-		));
-
 		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);
 
 		let origin1 = Origin::signed(1);
@@ -2427,6 +2079,29 @@
 			),
 			Error::<Test>::NoPermission
 		);
+
+#[test]
+fn collection_transfer_flag_works() {
+	new_test_ext().execute_with(|| {
+		let origin1 = Origin::signed(1);
+
+		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		assert_ok!(TemplateModule::set_transfers_enabled_flag(origin1, 1, true));
+
+		let data = default_nft_data();
+		create_test_item(collection_id, &data.into());
+		assert_eq!(TemplateModule::balance_count(1, 1), 1);
+		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+
+		let origin1 = Origin::signed(1);
+
+		// default scenario
+		assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 1000));
+		assert_eq!(TemplateModule::nft_item_id(1, 1).unwrap().owner, account(2));
+		assert_eq!(TemplateModule::balance_count(1, 1), 0);
+		assert_eq!(TemplateModule::balance_count(1, 2), 1);
+
+		assert_eq!(TemplateModule::address_tokens(1, 2), [1]);
 	});
 }
 
@@ -2578,5 +2253,33 @@
 			),
 			Error::<Test>::MetadataUpdateDenied
 		);
+
+#[test]
+fn collection_transfer_flag_works_neg() {
+	new_test_ext().execute_with(|| {
+		let origin1 = Origin::signed(1);
+
+		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		assert_ok!(TemplateModule::set_transfers_enabled_flag(
+			origin1, 1, false
+		));
+
+		let data = default_nft_data();
+		create_test_item(collection_id, &data.into());
+		assert_eq!(TemplateModule::balance_count(1, 1), 1);
+		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+
+		let origin1 = Origin::signed(1);
+
+		// default scenario
+		assert_noop!(
+			TemplateModule::transfer(origin1, account(2), 1, 1, 1000),
+			Error::<Test>::TransferNotAllowed
+		);
+		assert_eq!(TemplateModule::nft_item_id(1, 1).unwrap().owner, account(1));
+		assert_eq!(TemplateModule::balance_count(1, 1), 1);
+		assert_eq!(TemplateModule::balance_count(1, 2), 0);
+
+		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
 	});
 }
addedpallets/nft/src/weights.rsdiffbeforeafterboth
--- /dev/null
+++ b/pallets/nft/src/weights.rs
@@ -0,0 +1,424 @@
+// Template adopted from https://github.com/paritytech/substrate/blob/master/.maintain/frame-weight-template.hbs
+
+//! Autogenerated weights for pallet_nft
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
+//! DATE: 2021-08-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 128
+
+// Executed Command:
+// target/release/nft
+// benchmark
+// --pallet
+// pallet-nft
+// --wasm-execution
+// compiled
+// --extrinsic
+// *
+// --template
+// .maintain/frame-weight-template.hbs
+// --steps=50
+// --repeat=20
+// --output=./pallets/nft/src/weights.rs
+
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+
+use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
+use sp_std::marker::PhantomData;
+
+/// Weight functions needed for pallet_nft.
+pub trait WeightInfo {
+	fn create_collection() -> Weight;
+	fn destroy_collection() -> Weight;
+	fn add_to_white_list() -> Weight;
+	fn remove_from_white_list() -> Weight;
+	fn set_public_access_mode() -> Weight;
+	fn set_mint_permission() -> Weight;
+	fn change_collection_owner() -> Weight;
+	fn add_collection_admin() -> Weight;
+	fn remove_collection_admin() -> Weight;
+	fn set_collection_sponsor() -> Weight;
+	fn confirm_sponsorship() -> Weight;
+	fn remove_collection_sponsor() -> Weight;
+	fn create_item_nft(b: u32, ) -> Weight;
+	fn create_multiple_items_nft(b: u32, ) -> Weight;
+	fn create_item_fungible() -> Weight;
+	fn create_multiple_items_fungible(b: u32, ) -> Weight;
+	fn create_item_refungible(b: u32, ) -> Weight;
+	fn create_multiple_items_refungible(b: u32, ) -> Weight;
+	fn burn_item_nft() -> Weight;
+	fn transfer_nft() -> Weight;
+	fn transfer_fungible() -> Weight;
+	fn transfer_refungible() -> Weight;
+	fn set_transfers_enabled_flag() -> Weight;
+	fn approve_nft() -> Weight;
+	fn transfer_from_nft() -> Weight;
+	fn transfer_from_fungible() -> Weight;
+	fn transfer_from_refungible() -> Weight;
+	fn set_offchain_schema(b: u32, ) -> Weight;
+	fn set_const_on_chain_schema(b: u32, ) -> Weight;
+	fn set_variable_on_chain_schema(b: u32, ) -> Weight;
+	fn set_variable_meta_data_nft(b: u32, ) -> Weight;
+	fn set_schema_version() -> Weight;
+	fn set_collection_limits() -> Weight;
+}
+
+/// Weights for pallet_nft using the Substrate node and recommended hardware.
+pub struct SubstrateWeight<T>(PhantomData<T>);
+impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
+	fn create_collection() -> Weight {
+		(25_851_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(8 as Weight))
+			.saturating_add(T::DbWeight::get().writes(6 as Weight))
+	}
+	fn destroy_collection() -> Weight {
+		(28_737_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(2 as Weight))
+			.saturating_add(T::DbWeight::get().writes(4 as Weight))
+	}
+	fn add_to_white_list() -> Weight {
+		(6_237_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn remove_from_white_list() -> Weight {
+		(6_252_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn set_public_access_mode() -> Weight {
+		(6_691_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn set_mint_permission() -> Weight {
+		(6_630_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn change_collection_owner() -> Weight {
+		(6_521_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn add_collection_admin() -> Weight {
+		(8_057_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(2 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn remove_collection_admin() -> Weight {
+		(8_307_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(2 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn set_collection_sponsor() -> Weight {
+		(6_484_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn confirm_sponsorship() -> Weight {
+		(6_530_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn remove_collection_sponsor() -> Weight {
+		(6_733_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn create_item_nft(_b: u32, ) -> Weight {
+		(167_909_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(11 as Weight))
+			.saturating_add(T::DbWeight::get().writes(8 as Weight))
+	}
+	fn create_multiple_items_nft(b: u32, ) -> Weight {
+		(336_830_000 as Weight)
+			// Standard Error: 42_000
+			.saturating_add((11_627_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(T::DbWeight::get().reads(11 as Weight))
+			.saturating_add(T::DbWeight::get().writes(7 as Weight))
+			.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(b as Weight)))
+	}
+	fn create_item_fungible() -> Weight {
+		(24_123_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(9 as Weight))
+			.saturating_add(T::DbWeight::get().writes(4 as Weight))
+	}
+	fn create_multiple_items_fungible(b: u32, ) -> Weight {
+		(48_227_000 as Weight)
+			// Standard Error: 13_000
+			.saturating_add((2_918_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(T::DbWeight::get().reads(9 as Weight))
+			.saturating_add(T::DbWeight::get().writes(4 as Weight))
+	}
+	fn create_item_refungible(_b: u32, ) -> Weight {
+		(26_293_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(9 as Weight))
+			.saturating_add(T::DbWeight::get().writes(7 as Weight))
+	}
+	fn create_multiple_items_refungible(b: u32, ) -> Weight {
+		(0 as Weight)
+			// Standard Error: 16_000
+			.saturating_add((8_374_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(T::DbWeight::get().reads(9 as Weight))
+			.saturating_add(T::DbWeight::get().writes(6 as Weight))
+			.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(b as Weight)))
+	}
+	fn burn_item_nft() -> Weight {
+		(32_237_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(9 as Weight))
+			.saturating_add(T::DbWeight::get().writes(7 as Weight))
+	}
+	fn transfer_nft() -> Weight {
+		(192_578_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(14 as Weight))
+			.saturating_add(T::DbWeight::get().writes(10 as Weight))
+	}
+	fn transfer_fungible() -> Weight {
+		(170_749_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(11 as Weight))
+			.saturating_add(T::DbWeight::get().writes(7 as Weight))
+	}
+	fn transfer_refungible() -> Weight {
+		(35_949_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(10 as Weight))
+			.saturating_add(T::DbWeight::get().writes(7 as Weight))
+	}
+	fn set_transfers_enabled_flag() -> Weight {
+		(6_376_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn approve_nft() -> Weight {
+		(169_825_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(9 as Weight))
+			.saturating_add(T::DbWeight::get().writes(4 as Weight))
+	}
+	fn transfer_from_nft() -> Weight {
+		(197_912_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(15 as Weight))
+			.saturating_add(T::DbWeight::get().writes(11 as Weight))
+	}
+	fn transfer_from_fungible() -> Weight {
+		(183_789_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(12 as Weight))
+			.saturating_add(T::DbWeight::get().writes(8 as Weight))
+	}
+	fn transfer_from_refungible() -> Weight {
+		(37_149_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(11 as Weight))
+			.saturating_add(T::DbWeight::get().writes(8 as Weight))
+	}
+	fn set_offchain_schema(_b: u32, ) -> Weight {
+		(6_435_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn set_const_on_chain_schema(_b: u32, ) -> Weight {
+		(6_646_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn set_variable_on_chain_schema(_b: u32, ) -> Weight {
+		(6_542_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn set_variable_meta_data_nft(_b: u32, ) -> Weight {
+		(14_697_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(2 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn set_schema_version() -> Weight {
+		(6_566_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn set_collection_limits() -> Weight {
+		(6_349_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+}
+
+// For backwards compatibility and tests
+impl WeightInfo for () {
+	fn create_collection() -> Weight {
+		(25_851_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(8 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(6 as Weight))
+	}
+	fn destroy_collection() -> Weight {
+		(28_737_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(2 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(4 as Weight))
+	}
+	fn add_to_white_list() -> Weight {
+		(6_237_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn remove_from_white_list() -> Weight {
+		(6_252_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn set_public_access_mode() -> Weight {
+		(6_691_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn set_mint_permission() -> Weight {
+		(6_630_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn change_collection_owner() -> Weight {
+		(6_521_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn add_collection_admin() -> Weight {
+		(8_057_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(2 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn remove_collection_admin() -> Weight {
+		(8_307_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(2 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn set_collection_sponsor() -> Weight {
+		(6_484_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn confirm_sponsorship() -> Weight {
+		(6_530_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn remove_collection_sponsor() -> Weight {
+		(6_733_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn create_item_nft(b: u32, ) -> Weight {
+		(167_180_000 as Weight)
+			// Standard Error: 1_000
+			.saturating_add((10_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(RocksDbWeight::get().reads(11 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(8 as Weight))
+	}
+	fn create_multiple_items_nft(b: u32, ) -> Weight {
+		(336_830_000 as Weight)
+			// Standard Error: 42_000
+			.saturating_add((11_627_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(RocksDbWeight::get().reads(11 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(7 as Weight))
+			.saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(b as Weight)))
+	}
+	fn create_item_fungible() -> Weight {
+		(24_123_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(9 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(4 as Weight))
+	}
+	fn create_multiple_items_fungible(b: u32, ) -> Weight {
+		(13_217_000 as Weight)
+			// Standard Error: 4_000
+			.saturating_add((2_971_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(RocksDbWeight::get().reads(9 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(4 as Weight))
+	}
+	fn create_item_refungible(_b: u32, ) -> Weight {
+		(26_293_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(9 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(7 as Weight))
+	}
+	fn create_multiple_items_refungible(b: u32, ) -> Weight {
+		(0 as Weight)
+			// Standard Error: 16_000
+			.saturating_add((8_374_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(RocksDbWeight::get().reads(9 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(6 as Weight))
+			.saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(b as Weight)))
+	}
+	fn burn_item_nft() -> Weight {
+		(32_237_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(9 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(7 as Weight))
+	}
+	fn transfer_nft() -> Weight {
+		(192_578_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(14 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(10 as Weight))
+	}
+	fn transfer_fungible() -> Weight {
+		(170_749_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(11 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(7 as Weight))
+	}
+	fn transfer_refungible() -> Weight {
+		(35_949_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(10 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(7 as Weight))
+	}
+	fn set_transfers_enabled_flag() -> Weight {
+		(6_376_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn approve_nft() -> Weight {
+		(169_825_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(9 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(4 as Weight))
+	}
+	fn transfer_from_nft() -> Weight {
+		(197_912_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(15 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(11 as Weight))
+	}
+	fn transfer_from_fungible() -> Weight {
+		(183_789_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(12 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(8 as Weight))
+	}
+	fn transfer_from_refungible() -> Weight {
+		(37_149_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(11 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(8 as Weight))
+	}
+	fn set_offchain_schema(_b: u32, ) -> Weight {
+		(6_435_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn set_const_on_chain_schema(_b: u32, ) -> Weight {
+		(6_646_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn set_variable_on_chain_schema(_b: u32, ) -> Weight {
+		(6_542_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn set_variable_meta_data_nft(_b: u32, ) -> Weight {
+		(14_697_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(2 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn set_schema_version() -> Weight {
+		(6_566_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn set_collection_limits() -> Weight {
+		(6_349_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+}
\ No newline at end of file
modifiedpallets/scheduler/Cargo.tomldiffbeforeafterboth
--- a/pallets/scheduler/Cargo.toml
+++ b/pallets/scheduler/Cargo.toml
@@ -12,19 +12,19 @@
 [dependencies]
 serde = { version = "1.0.119", default-features = false }
 codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false }
-frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-io = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-frame-benchmarking = { default-features = false, version = '3.0.0', optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
+frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-io = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+frame-benchmarking = { default-features = false, version = '3.0.0', optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
 
 up-sponsorship = { default-features = false, path = "../../primitives/sponsorship", version = "0.1.0" }
 log = { version = "0.4.14", default-features = false }
 
 [dev-dependencies]
-sp-core = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-substrate-test-utils = { version = "3.0.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
+sp-core = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+substrate-test-utils = { version = "3.0.0", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
 
 [features]
 default = ["std"]
modifiedprimitives/nft/Cargo.tomldiffbeforeafterboth
--- a/primitives/nft/Cargo.toml
+++ b/primitives/nft/Cargo.toml
@@ -9,20 +9,28 @@
 version = '0.9.0'
 
 [dependencies]
-codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ['derive'] }
-serde = { version = "1.0.119", features = ['derive'], default-features = false }
-frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-core = { version = "3.0.0", default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
-sp-runtime = { version = "3.0.0", default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.7' }
+codec = { package = "parity-scale-codec", version = "2.2.0", default-features = false, features = ['derive'] }
+serde = { version = "1.0.119", features = ['derive'], default-features = false, optional = true }
+max-encoded-len = { default-features = false, features = ['derive'], version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-core = { version = "3.0.0", default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-std = { version = "3.0.0", default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-runtime = { version = "3.0.0", default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+derivative = "2.2.0"
 
 [features]
 default = ["std"]
 std = [
+  "serde1",
   "serde/std",
   "codec/std",
+  "max-encoded-len/std",
   "frame-system/std",
   "frame-support/std",
   "sp-runtime/std",
   "sp-core/std",
-]
\ No newline at end of file
+  "sp-std/std",
+]
+serde1 = ["serde"]
+limit-testing = []
\ No newline at end of file
modifiedprimitives/nft/src/lib.rsdiffbeforeafterboth
--- a/primitives/nft/src/lib.rs
+++ b/primitives/nft/src/lib.rs
@@ -1,11 +1,13 @@
 #![cfg_attr(not(feature = "std"), no_std)]
 
+#[cfg(feature = "serde")]
 pub use serde::{Serialize, Deserialize};
 
 use sp_runtime::sp_std::prelude::Vec;
 use codec::{Decode, Encode};
+use max_encoded_len::MaxEncodedLen;
 pub use frame_support::{
-	construct_runtime, decl_event, decl_module, decl_storage, decl_error,
+	BoundedVec, construct_runtime, decl_event, decl_module, decl_storage, decl_error,
 	dispatch::DispatchResult,
 	ensure, fail, parameter_types,
 	traits::{
@@ -19,18 +21,58 @@
 	},
 	StorageValue, transactional,
 };
+use derivative::Derivative;
 
 pub const MAX_DECIMAL_POINTS: DecimalPoints = 30;
 pub const MAX_REFUNGIBLE_PIECES: u128 = 1_000_000_000_000_000_000_000;
 pub const MAX_SPONSOR_TIMEOUT: u32 = 10_368_000;
 pub const MAX_TOKEN_OWNERSHIP: u32 = 10_000_000;
 
+pub const COLLECTION_NUMBER_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {
+	100000
+} else {
+	10
+};
+pub const CUSTOM_DATA_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {
+	2048
+} else {
+	10
+};
+pub const COLLECTION_ADMINS_LIMIT: u64 = 5;
+pub const ACCOUNT_TOKEN_OWNERSHIP_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {
+	1000000
+} else {
+	10
+};
+
+// Timeouts for item types in passed blocks
+pub const NFT_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;
+pub const FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;
+pub const REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;
+
+// Schema limits
+pub const OFFCHAIN_SCHEMA_LIMIT: u32 = 1024;
+pub const VARIABLE_ON_CHAIN_SCHEMA_LIMIT: u32 = 1024;
+pub const CONST_ON_CHAIN_SCHEMA_LIMIT: u32 = 1024;
+
+pub const MAX_COLLECTION_NAME_LENGTH: usize = 64;
+pub const MAX_COLLECTION_DESCRIPTION_LENGTH: usize = 256;
+pub const MAX_TOKEN_PREFIX_LENGTH: usize = 16;
+
+/// How much items can be created per single
+/// create_many call
+pub const MAX_ITEMS_PER_BATCH: u32 = 200;
+
+parameter_types! {
+	pub const CustomDataLimit: u32 = CUSTOM_DATA_LIMIT;
+}
+
 pub type CollectionId = u32;
 pub type TokenId = u32;
 pub type DecimalPoints = u8;
 
 #[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub enum CollectionMode {
 	Invalid,
 	NFT,
@@ -61,7 +103,7 @@
 }
 
 #[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub enum AccessMode {
 	Normal,
 	WhiteList,
@@ -73,7 +115,7 @@
 }
 
 #[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub enum SchemaVersion {
 	ImageURL,
 	Unique,
@@ -85,14 +127,14 @@
 }
 
 #[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub struct Ownership<AccountId> {
 	pub owner: AccountId,
 	pub fraction: u128,
 }
 
 #[derive(Encode, Decode, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub enum SponsorshipState<AccountId> {
 	/// The fees are applied to the transaction sender
 	Disabled,
@@ -128,7 +170,7 @@
 }
 
 #[derive(Encode, Decode, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub struct Collection<T: frame_system::Config> {
 	pub owner: T::AccountId,
 	pub mode: CollectionMode,
@@ -145,10 +187,11 @@
 	pub variable_on_chain_schema: Vec<u8>,        //
 	pub const_on_chain_schema: Vec<u8>,           //
 	pub meta_update_permission: MetaUpdatePermission,
+	pub transfers_enabled: bool,
 }
 
 #[derive(Encode, Decode, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub struct NftItemType<AccountId> {
 	pub owner: AccountId,
 	pub const_data: Vec<u8>,
@@ -156,13 +199,13 @@
 }
 
 #[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub struct FungibleItemType {
 	pub value: u128,
 }
 
 #[derive(Encode, Decode, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub struct ReFungibleItemType<AccountId> {
 	pub owner: Vec<Ownership<AccountId>>,
 	pub const_data: Vec<u8>,
@@ -170,7 +213,7 @@
 }
 
 #[derive(Encode, Decode, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub struct CollectionLimits<BlockNumber: Encode + Decode> {
 	pub account_token_ownership_limit: u32,
 	pub sponsored_data_size: u32,
@@ -200,43 +243,67 @@
 	}
 }
 
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-pub struct ChainLimits {
-	pub collection_numbers_limit: u32,
-	pub account_token_ownership_limit: u32,
-	pub collections_admins_limit: u64,
-	pub custom_data_limit: u32,
+/// BoundedVec doesn't supports serde
+#[cfg(feature = "serde1")]
+mod bounded_serde {
+	use core::convert::TryFrom;
+	use frame_support::{BoundedVec, traits::Get};
+	use serde::{
+		ser::{self, Serialize},
+		de::{self, Deserialize, Error},
+	};
+	use sp_std::vec::Vec;
 
-	// Timeouts for item types in passed blocks
-	pub nft_sponsor_transfer_timeout: u32,
-	pub fungible_sponsor_transfer_timeout: u32,
-	pub refungible_sponsor_transfer_timeout: u32,
+	pub fn serialize<D, V, S>(value: &BoundedVec<V, S>, serializer: D) -> Result<D::Ok, D::Error>
+	where
+		D: ser::Serializer,
+		V: Serialize,
+	{
+		let vec: &Vec<_> = &value;
+		vec.serialize(serializer)
+	}
 
-	// Schema limits
-	pub offchain_schema_limit: u32,
-	pub variable_on_chain_schema_limit: u32,
-	pub const_on_chain_schema_limit: u32,
+	pub fn deserialize<'de, D, V, S>(deserializer: D) -> Result<BoundedVec<V, S>, D::Error>
+	where
+		D: de::Deserializer<'de>,
+		V: de::Deserialize<'de>,
+		S: Get<u32>,
+	{
+		// TODO: Implement custom visitor, which will limit vec size at parse time? Will serde only be used by chainspec?
+		let vec = <Vec<V>>::deserialize(deserializer)?;
+		let len = vec.len();
+		TryFrom::try_from(vec).map_err(|_| D::Error::invalid_length(len, &"lesser size"))
+	}
 }
 
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative)]
+#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
+#[derivative(Debug)]
 pub struct CreateNftData {
-	pub const_data: Vec<u8>,
-	pub variable_data: Vec<u8>,
+	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]
+	#[derivative(Debug = "ignore")]
+	pub const_data: BoundedVec<u8, CustomDataLimit>,
+	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]
+	#[derivative(Debug = "ignore")]
+	pub variable_data: BoundedVec<u8, CustomDataLimit>,
 }
 
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, MaxEncodedLen, Default, Debug, Clone, PartialEq)]
+#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub struct CreateFungibleData {
 	pub value: u128,
 }
 
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative)]
+#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
+#[derivative(Debug)]
 pub struct CreateReFungibleData {
-	pub const_data: Vec<u8>,
-	pub variable_data: Vec<u8>,
+	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]
+	#[derivative(Debug = "ignore")]
+	pub const_data: BoundedVec<u8, CustomDataLimit>,
+	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]
+	#[derivative(Debug = "ignore")]
+	pub variable_data: BoundedVec<u8, CustomDataLimit>,
 	pub pieces: u128,
 }
 
@@ -254,8 +321,8 @@
 	}
 }
 
-#[derive(Encode, Decode, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug)]
+#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub enum CreateItemData {
 	NFT(CreateNftData),
 	Fungible(CreateFungibleData),
modifiedruntime/Cargo.tomldiffbeforeafterboth
--- a/runtime/Cargo.toml
+++ b/runtime/Cargo.toml
@@ -23,25 +23,29 @@
     'frame-support/runtime-benchmarks',
     'frame-system-benchmarking',
     'frame-system/runtime-benchmarks',
+    'pallet-evm-migration/runtime-benchmarks',
     'pallet-balances/runtime-benchmarks',
     'pallet-timestamp/runtime-benchmarks',
     'pallet-nft/runtime-benchmarks',
     'pallet-inflation/runtime-benchmarks',
+    'pallet-xcm/runtime-benchmarks',
     'sp-runtime/runtime-benchmarks',
+    'xcm-builder/runtime-benchmarks',
 ]
 std = [
     'codec/std',
-	'cumulus-pallet-aura-ext/std',
-	'cumulus-pallet-parachain-system/std',
-	'cumulus-pallet-xcm/std',
-	'cumulus-pallet-xcmp-queue/std',
-	'cumulus-primitives-core/std',
-	'cumulus-primitives-utility/std',
+    'max-encoded-len/std',
+    'cumulus-pallet-aura-ext/std',
+    'cumulus-pallet-parachain-system/std',
+    'cumulus-pallet-xcm/std',
+    'cumulus-pallet-xcmp-queue/std',
+    'cumulus-primitives-core/std',
+    'cumulus-primitives-utility/std',
     'frame-executive/std',
     'frame-support/std',
     'frame-system/std',
     'frame-system-rpc-runtime-api/std',
-	'pallet-aura/std',
+    'pallet-aura/std',
     'pallet-balances/std',
     # 'pallet-contracts/std',
     # 'pallet-contracts-primitives/std',
@@ -55,31 +59,39 @@
     'pallet-treasury/std',
     'pallet-vesting/std',
     'pallet-evm/std',
+    'pallet-evm-migration/std',
+    'pallet-evm-contract-helpers/std',
+    'pallet-evm-transaction-payment/std',
+    'pallet-evm-coder-substrate/std',
     'pallet-ethereum/std',
     'fp-rpc/std',
-	'parachain-info/std',
+    'parachain-info/std',
     'serde',
     'pallet-inflation/std',
     'pallet-nft/std',
     'pallet-scheduler/std',
     'pallet-nft-charge-transaction/std',
-    'pallet-nft-transaction-payment/std', 
+    'pallet-nft-transaction-payment/std',
     'nft-data-structs/std',
     'sp-api/std',
     'sp-block-builder/std',
-	"sp-consensus-aura/std",
+    "sp-consensus-aura/std",
     'sp-core/std',
     'sp-inherents/std',
-	'sp-io/std',
+    'sp-io/std',
     'sp-offchain/std',
     'sp-runtime/std',
     'sp-session/std',
     'sp-std/std',
     'sp-transaction-pool/std',
     'sp-version/std',
-	'xcm/std',
-	'xcm-builder/std',
-	'xcm-executor/std',
+    'xcm/std',
+    'xcm-builder/std',
+    'xcm-executor/std',
+]
+limit-testing = [
+    'pallet-nft/limit-testing',
+    'nft-data-structs/limit-testing',
 ]
 
 ################################################################################
@@ -95,38 +107,38 @@
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
 optional = true
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.frame-executive]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.frame-support]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.frame-system]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.frame-system-benchmarking]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
 optional = true
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.frame-system-rpc-runtime-api]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.hex-literal]
@@ -142,152 +154,152 @@
 [dependencies.pallet-aura]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.pallet-balances]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 # Contracts specific packages
 # [dependencies.pallet-contracts]
 # git = 'https://github.com/paritytech/substrate.git'
 # default-features = false
-# branch = 'polkadot-v0.9.7'
+# branch = 'polkadot-v0.9.8'
 # version = '3.0.0'
 
 # [dependencies.pallet-contracts-primitives]
 # git = 'https://github.com/paritytech/substrate.git'
 # default-features = false
-# branch = 'polkadot-v0.9.7'
+# branch = 'polkadot-v0.9.8'
 # version = '3.0.0'
 
 # [dependencies.pallet-contracts-rpc-runtime-api]
 # git = 'https://github.com/paritytech/substrate.git'
 # default-features = false
-# branch = 'polkadot-v0.9.7'
+# branch = 'polkadot-v0.9.8'
 # version = '3.0.0'
 
 [dependencies.pallet-randomness-collective-flip]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.pallet-sudo]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.pallet-timestamp]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.pallet-transaction-payment]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.pallet-transaction-payment-rpc-runtime-api]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.pallet-treasury]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.pallet-vesting]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-arithmetic]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-api]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-block-builder]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-core]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-consensus-aura]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '0.9.0'
 
 [dependencies.sp-inherents]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-io]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-offchain]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-runtime]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-session]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-std]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-transaction-pool]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.sp-version]
 default-features = false
 git = 'https://github.com/paritytech/substrate.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '3.0.0'
 
 [dependencies.smallvec]
@@ -299,47 +311,47 @@
 [dependencies.parachain-info]
 default-features = false
 git = 'https://github.com/paritytech/cumulus.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 version = '0.1.0'
 
 [dependencies.cumulus-pallet-aura-ext]
 git = 'https://github.com/paritytech/cumulus.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 default-features = false
 
 [dependencies.cumulus-pallet-parachain-system]
 git = 'https://github.com/paritytech/cumulus.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 default-features = false
 
 [dependencies.cumulus-primitives-core]
 git = 'https://github.com/paritytech/cumulus.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 default-features = false
 
 [dependencies.cumulus-pallet-xcm]
 git = 'https://github.com/paritytech/cumulus.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 default-features = false
 
 [dependencies.cumulus-pallet-dmp-queue]
 git = 'https://github.com/paritytech/cumulus.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 default-features = false
 
 [dependencies.cumulus-pallet-xcmp-queue]
 git = 'https://github.com/paritytech/cumulus.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 default-features = false
 
 [dependencies.cumulus-primitives-utility]
 git = 'https://github.com/paritytech/cumulus.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 default-features = false
 
 [dependencies.cumulus-primitives-timestamp]
 git = 'https://github.com/paritytech/cumulus.git'
-branch = 'polkadot-v0.9.7'
+branch = 'polkadot-v0.9.8'
 default-features = false
 
 ################################################################################
@@ -347,49 +359,54 @@
 
 [dependencies.polkadot-parachain]
 git = 'https://github.com/paritytech/polkadot'
-branch = 'release-v0.9.7'
+branch = 'release-v0.9.8'
 default-features = false
 
 [dependencies.xcm]
 git = 'https://github.com/paritytech/polkadot'
-branch = 'release-v0.9.7'
+branch = 'release-v0.9.8'
 default-features = false
 
 [dependencies.xcm-builder]
 git = 'https://github.com/paritytech/polkadot'
-branch = 'release-v0.9.7'
+branch = 'release-v0.9.8'
 default-features = false
 
 [dependencies.xcm-executor]
 git = 'https://github.com/paritytech/polkadot'
-branch = 'release-v0.9.7'
+branch = 'release-v0.9.8'
 default-features = false
 
 [dependencies.pallet-xcm]
 git = 'https://github.com/paritytech/polkadot'
-branch = 'release-v0.9.7'
+branch = 'release-v0.9.8'
 default-features = false
-
 
 
 ################################################################################
 # local dependencies
 
 [dependencies]
+max-encoded-len = { default-features = false, features = ['derive'], version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+derivative = "2.2.0"
 pallet-nft = { path = '../pallets/nft', default-features = false, version = '3.0.0' }
 pallet-inflation = { path = '../pallets/inflation', default-features = false, version = '3.0.0' }
-nft-data-structs = { path = '../primitives/nft', default-features = false,  version = '0.9.0' }
+nft-data-structs = { path = '../primitives/nft', default-features = false, version = '0.9.0' }
 pallet-scheduler = { path = '../pallets/scheduler', default-features = false, version = '3.0.0' }
 # pallet-contract-helpers = { path = '../pallets/contract-helpers', default-features = false, version = '0.1.0' }
 pallet-nft-transaction-payment = { path = '../pallets/nft-transaction-payment', default-features = false, version = '3.0.0' }
 pallet-nft-charge-transaction = { path = '../pallets/nft-charge-transaction', default-features = false, version = '3.0.0' }
+pallet-evm-migration = { path = '../pallets/evm-migration', default-features = false }
+pallet-evm-contract-helpers = { path = '../pallets/evm-contract-helpers', default-features = false }
+pallet-evm-transaction-payment = { path = '../pallets/evm-transaction-payment', default-features = false }
+pallet-evm-coder-substrate = { default-features = false, path = "../pallets/evm-coder-substrate" }
 
-pallet-evm = { default-features = false, version = "5.0.0-dev", git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
-pallet-ethereum = { default-features = false, version = "3.0.0-dev", git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
-fp-rpc = { default-features = false, version = "2.0.0", git = "https://github.com/usetech-llc/frontier.git", branch = "injected-transactions-parachain" }
+pallet-evm = { default-features = false, version = "5.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+pallet-ethereum = { default-features = false, version = "3.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+fp-rpc = { default-features = false, version = "2.0.0", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
 
 ################################################################################
 # Build Dependencies
 
 [build-dependencies]
-substrate-wasm-builder = '4.0.0'
\ No newline at end of file
+substrate-wasm-builder = '4.0.0'
modifiedruntime/src/chain_extension.rsdiffbeforeafterboth
--- a/runtime/src/chain_extension.rs
+++ b/runtime/src/chain_extension.rs
@@ -6,6 +6,8 @@
 //
 
 use codec::{Decode, Encode};
+use max_encoded_len::MaxEncodedLen;
+use derivative::Derivative;
 
 pub use pallet_contracts::chain_extension::RetVal;
 use pallet_contracts::chain_extension::{
@@ -19,61 +21,63 @@
 pub use pallet_nft::*;
 use pallet_nft::CrossAccountId;
 use nft_data_structs::*;
-
-use crate::Vec;
 
 /// Create item parameters
-#[derive(Debug, PartialEq, Encode, Decode)]
-pub struct NFTExtCreateItem<E: Ext> {
-	pub owner: <E::T as SysConfig>::AccountId,
+#[derive(Debug, PartialEq, Encode, Decode, MaxEncodedLen)]
+pub struct NFTExtCreateItem<AccountId> {
+	pub owner: AccountId,
 	pub collection_id: u32,
 	pub data: CreateItemData,
 }
 
 /// Transfer parameters
-#[derive(Debug, PartialEq, Encode, Decode)]
-pub struct NFTExtTransfer<E: Ext> {
-	pub recipient: <E::T as SysConfig>::AccountId,
+#[derive(Debug, PartialEq, Encode, Decode, MaxEncodedLen)]
+pub struct NFTExtTransfer<AccountId> {
+	pub recipient: AccountId,
 	pub collection_id: u32,
 	pub token_id: u32,
 	pub amount: u128,
 }
 
-#[derive(Debug, PartialEq, Encode, Decode)]
-pub struct NFTExtCreateMultipleItems<E: Ext> {
-	pub owner: <E::T as SysConfig>::AccountId,
+#[derive(Derivative, PartialEq, Encode, Decode, MaxEncodedLen)]
+#[derivative(Debug)]
+pub struct NFTExtCreateMultipleItems<AccountId> {
+	pub owner: AccountId,
 	pub collection_id: u32,
-	pub data: Vec<CreateItemData>,
+	#[derivative(Debug = "ignore")]
+	pub data: BoundedVec<CreateItemData, MaxItemsPerBatch>,
 }
 
-#[derive(Debug, PartialEq, Encode, Decode)]
-pub struct NFTExtApprove<E: Ext> {
-	pub spender: <E::T as SysConfig>::AccountId,
+#[derive(Debug, PartialEq, Encode, Decode, MaxEncodedLen)]
+pub struct NFTExtApprove<AccountId> {
+	pub spender: AccountId,
 	pub collection_id: u32,
 	pub item_id: u32,
 	pub amount: u128,
 }
 
-#[derive(Debug, PartialEq, Encode, Decode)]
-pub struct NFTExtTransferFrom<E: Ext> {
-	pub owner: <E::T as SysConfig>::AccountId,
-	pub recipient: <E::T as SysConfig>::AccountId,
+#[derive(Debug, PartialEq, Encode, Decode, MaxEncodedLen)]
+pub struct NFTExtTransferFrom<AccountId> {
+	pub owner: AccountId,
+	pub recipient: AccountId,
 	pub collection_id: u32,
 	pub item_id: u32,
 	pub amount: u128,
 }
 
-#[derive(Debug, PartialEq, Encode, Decode)]
+#[derive(Derivative, PartialEq, Encode, Decode, MaxEncodedLen)]
+#[derivative(Debug)]
 pub struct NFTExtSetVariableMetaData {
 	pub collection_id: u32,
 	pub item_id: u32,
-	pub data: Vec<u8>,
+	#[derivative(Debug = "ignore")]
+	pub data: BoundedVec<u8, MaxDataSize>,
 }
 
-#[derive(Debug, PartialEq, Encode, Decode)]
-pub struct NFTExtToggleWhiteList<E: Ext> {
+#[derive(Debug, PartialEq, Encode, Decode, MaxEncodedLen)]
+pub struct NFTExtToggleWhiteList<AccountId> {
 	pub collection_id: u32,
-	pub address: <E::T as SysConfig>::AccountId,
+	pub address: AccountId,
 	pub whitelisted: bool,
 }
 
@@ -82,6 +86,8 @@
 
 pub type NftWeightInfoOf<C> = <C as pallet_nft::Config>::WeightInfo;
 
+pub type AccountIdOf<C> = <C as SysConfig>::AccountId;
+
 impl<C: Config + pallet_contracts::Config> ChainExtension<C> for NFTExtension {
 	fn call<E: Ext>(func_id: u32, env: Environment<E, InitState>) -> Result<RetVal, DispatchError>
 	where
@@ -93,7 +99,7 @@
 		match func_id {
 			0 => {
 				let mut env = env.buf_in_buf_out();
-				let input: NFTExtTransfer<E> = env.read_as()?;
+				let input: NFTExtTransfer<AccountIdOf<C>> = env.read_as()?;
 				env.charge_weight(NftWeightInfoOf::<C>::transfer())?;
 
 				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;
@@ -106,13 +112,13 @@
 					input.amount,
 				)?;
 
-				pallet_nft::Module::<C>::submit_logs(collection)?;
+				collection.submit_logs()?;
 				Ok(RetVal::Converging(0))
 			}
 			1 => {
 				// Create Item
 				let mut env = env.buf_in_buf_out();
-				let input: NFTExtCreateItem<E> = env.read_as()?;
+				let input: NFTExtCreateItem<AccountIdOf<C>> = env.read_as()?;
 				env.charge_weight(NftWeightInfoOf::<C>::create_item(input.data.data_size()))?;
 
 				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;
@@ -124,13 +130,13 @@
 					input.data,
 				)?;
 
-				pallet_nft::Module::<C>::submit_logs(collection)?;
+				collection.submit_logs()?;
 				Ok(RetVal::Converging(0))
 			}
 			2 => {
 				// Create multiple items
 				let mut env = env.buf_in_buf_out();
-				let input: NFTExtCreateMultipleItems<E> = env.read_as()?;
+				let input: NFTExtCreateMultipleItems<AccountIdOf<C>> = env.read_as()?;
 				env.charge_weight(NftWeightInfoOf::<C>::create_item(
 					input.data.iter().map(|i| i.data_size()).sum(),
 				))?;
@@ -141,16 +147,16 @@
 					&C::CrossAccountId::from_sub(env.ext().address().clone()),
 					&collection,
 					&C::CrossAccountId::from_sub(input.owner),
-					input.data,
+					input.data.into_inner(),
 				)?;
 
-				pallet_nft::Module::<C>::submit_logs(collection)?;
+				collection.submit_logs()?;
 				Ok(RetVal::Converging(0))
 			}
 			3 => {
 				// Approve
 				let mut env = env.buf_in_buf_out();
-				let input: NFTExtApprove<E> = env.read_as()?;
+				let input: NFTExtApprove<AccountIdOf<C>> = env.read_as()?;
 				env.charge_weight(NftWeightInfoOf::<C>::approve())?;
 
 				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;
@@ -163,13 +169,13 @@
 					input.amount,
 				)?;
 
-				pallet_nft::Module::<C>::submit_logs(collection)?;
+				collection.submit_logs()?;
 				Ok(RetVal::Converging(0))
 			}
 			4 => {
 				// Transfer from
 				let mut env = env.buf_in_buf_out();
-				let input: NFTExtTransferFrom<E> = env.read_as()?;
+				let input: NFTExtTransferFrom<AccountIdOf<C>> = env.read_as()?;
 				env.charge_weight(NftWeightInfoOf::<C>::transfer_from())?;
 
 				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;
@@ -183,7 +189,7 @@
 					input.amount,
 				)?;
 
-				pallet_nft::Module::<C>::submit_logs(collection)?;
+				collection.submit_logs()?;
 				Ok(RetVal::Converging(0))
 			}
 			5 => {
@@ -198,16 +204,16 @@
 					&C::CrossAccountId::from_sub(env.ext().address().clone()),
 					&collection,
 					input.item_id,
-					input.data,
+					input.data.into_inner(),
 				)?;
 
-				pallet_nft::Module::<C>::submit_logs(collection)?;
+				collection.submit_logs()?;
 				Ok(RetVal::Converging(0))
 			}
 			6 => {
 				// Toggle whitelist
 				let mut env = env.buf_in_buf_out();
-				let input: NFTExtToggleWhiteList<E> = env.read_as()?;
+				let input: NFTExtToggleWhiteList<AccountIdOf<C>> = env.read_as()?;
 				env.charge_weight(NftWeightInfoOf::<C>::add_to_white_list())?;
 
 				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;
@@ -219,7 +225,7 @@
 					input.whitelisted,
 				)?;
 
-				pallet_nft::Module::<C>::submit_logs(collection)?;
+				collection.submit_logs()?;
 				Ok(RetVal::Converging(0))
 			}
 			_ => Err(DispatchError::Other("unknown chain_extension func_id")),
modifiedruntime/src/lib.rsdiffbeforeafterboth
--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -72,7 +72,6 @@
 use sp_runtime::{
 	traits::{Dispatchable},
 };
-// use pallet_contracts::chain_extension::UncheckedFrom;
 
 // pub use pallet_timestamp::Call as TimestampCall;
 pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
@@ -119,8 +118,6 @@
 
 /// Digest item type.
 pub type DigestItem = generic::DigestItem<Hash>;
-
-mod nft_weights;
 
 /// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
 /// the specifics of the runtime. They can then be made to be agnostic over specific formats
@@ -163,6 +160,10 @@
 pub const HOURS: BlockNumber = MINUTES * 60;
 pub const DAYS: BlockNumber = HOURS * 24;
 
+parameter_types! {
+	pub const DefaultSponsoringRateLimit: BlockNumber = 1 * DAYS;
+}
+
 #[derive(codec::Encode, codec::Decode)]
 pub enum XCMPMessage<XAccountId, XBalance> {
 	/// Transfer tokens to the given account from the Parachain account.
@@ -248,10 +249,21 @@
 	type Precompiles = ();
 	type Currency = Balances;
 	type Event = Event;
-	type OnMethodCall = pallet_nft::NftErcSupport<Self>;
+	type OnMethodCall = (
+		pallet_evm_migration::OnMethodCall<Self>,
+		pallet_nft::NftErcSupport<Self>,
+		pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,
+	);
+	type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;
 	type ChainId = ChainId;
 	type Runner = pallet_evm::runner::stack::Runner<Self>;
-	type OnChargeTransaction = ();
+	type OnChargeTransaction = pallet_evm_transaction_payment::OnChargeTransaction<Self>;
+	type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack<Self>;
+	type FindAuthor = EthereumFindAuthor<Aura>;
+}
+
+impl pallet_evm_migration::Config for Runtime {
+	type WeightInfo = pallet_evm_migration::weights::SubstrateWeight<Self>;
 }
 
 pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);
@@ -274,9 +286,8 @@
 
 impl pallet_ethereum::Config for Runtime {
 	type Event = Event;
-	type FindAuthor = EthereumFindAuthor<Aura>;
 	type StateRoot = pallet_ethereum::IntermediateStateRoot;
-	type EvmSubmitLog = pallet_evm::Pallet<Runtime>;
+	type EvmSubmitLog = pallet_evm::Pallet<Self>;
 }
 
 impl pallet_randomness_collective_flip::Config for Runtime {}
@@ -324,7 +335,7 @@
 	/// This is used as an identifier of the chain. 42 is the generic substrate prefix.
 	type SS58Prefix = SS58Prefix;
 	/// Weight information for the extrinsics of this pallet.
-	type SystemWeightInfo = system::weights::SubstrateWeight<Runtime>;
+	type SystemWeightInfo = system::weights::SubstrateWeight<Self>;
 	/// Version of the runtime.
 	type Version = Version;
 }
@@ -358,7 +369,7 @@
 	type DustRemoval = Treasury;
 	type ExistentialDeposit = ExistentialDeposit;
 	type AccountStore = System;
-	type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
+	type WeightInfo = pallet_balances::weights::SubstrateWeight<Self>;
 }
 
 pub const MICROUNIQUE: Balance = 1_000_000_000;
@@ -410,7 +421,7 @@
 	type DepositPerStorageItem = DepositPerStorageItem;
 	type RentFraction = RentFraction;
 	type SurchargeReward = SurchargeReward;
-	type WeightPrice = pallet_transaction_payment::Module<Self>;
+	type WeightPrice = pallet_transaction_payment::Pallet<Self>;
 	type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
 	type ChainExtension = NFTExtension;
 	type DeletionQueueDepth = DeletionQueueDepth;
@@ -482,7 +493,7 @@
 	type Burn = Burn;
 	type BurnDestination = ();
 	type SpendFunds = ();
-	type WeightInfo = pallet_treasury::weights::SubstrateWeight<Runtime>;
+	type WeightInfo = pallet_treasury::weights::SubstrateWeight<Self>;
 	type MaxApprovals = MaxApprovals;
 }
 
@@ -511,7 +522,7 @@
 impl cumulus_pallet_parachain_system::Config for Runtime {
 	type Event = Event;
 	type OnValidationData = ();
-	type SelfParaId = parachain_info::Pallet<Runtime>;
+	type SelfParaId = parachain_info::Pallet<Self>;
 	// type DownwardMessageHandlers = cumulus_primitives_utility::UnqueuedDmpAsParent<
 	// 	MaxDownwardMessageWeight,
 	// 	XcmExecutor<XcmConfig>,
@@ -637,6 +648,10 @@
 	XcmpQueue,
 );
 
+impl pallet_evm_coder_substrate::Config for Runtime {
+	type EthereumTransactionSender = pallet_ethereum::Module<Self>;
+}
+
 impl pallet_xcm::Config for Runtime {
 	type Event = Event;
 	type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
@@ -678,7 +693,7 @@
 /// Used for the pallet nft in `./nft.rs`
 impl pallet_nft::Config for Runtime {
 	type Event = Event;
-	type WeightInfo = nft_weights::WeightInfo;
+	type WeightInfo = pallet_nft::weights::SubstrateWeight<Self>;
 
 	type EvmBackwardsAddressMapping = pallet_nft::MapBackwardsAddressTruncated;
 	type EvmAddressMapping = HashedAddressMapping<Self::Hashing>;
@@ -687,9 +702,6 @@
 	type Currency = Balances;
 	type CollectionCreationPrice = CollectionCreationPrice;
 	type TreasuryAccountId = TreasuryAccountId;
-
-	type EthereumChainId = ChainId;
-	type EthereumTransactionSender = pallet_ethereum::Module<Runtime>;
 }
 
 parameter_types! {
@@ -741,50 +753,76 @@
 	type SponsorshipHandler = SponsorshipHandler;
 }
 
+impl pallet_evm_transaction_payment::Config for Runtime {
+	type SponsorshipHandler = (
+		pallet_nft::NftEthSponsorshipHandler<Self>,
+		pallet_evm_contract_helpers::HelpersContractSponsoring<Self>,
+	);
+	type Currency = Balances;
+}
+
 impl pallet_nft_charge_transaction::Config for Runtime {}
 
-// impl pallet_contract_helpers::Config for Runtime {}
+// impl pallet_contract_helpers::Config for Runtime {
+//	 type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
+// }
+
+parameter_types! {
+	// 0x842899ECF380553E8a4de75bF534cdf6fBF64049
+	pub const HelpersContractAddress: H160 = H160([
+		0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,
+	]);
+}
 
+impl pallet_evm_contract_helpers::Config for Runtime {
+	type ContractAddress = HelpersContractAddress;
+	type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
+}
+
 construct_runtime!(
 	pub enum Runtime where
 		Block = Block,
 		NodeBlock = opaque::Block,
 		UncheckedExtrinsic = UncheckedExtrinsic
 	{
-		Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 30,
-		// Contracts: pallet_contracts::{Pallet, Call, Storage, Event<T>},
-		RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Call, Storage},
-		Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent},
-		TransactionPayment: pallet_transaction_payment::{Pallet, Storage},
-		Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event<T>},
-		Sudo: pallet_sudo::{Pallet, Call, Storage, Config<T>, Event<T>},
-		System: system::{Pallet, Call, Storage, Config, Event<T>},
-		Vesting: pallet_vesting::{Pallet, Call, Config<T>, Storage, Event<T>},
-
-		ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Storage, Inherent, Event<T>, ValidateUnsigned} = 20,
+		ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Storage, Inherent, Event<T>} = 20,
 		ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21,
 
-		Aura: pallet_aura::{Pallet, Config<T>},
-		AuraExt: cumulus_pallet_aura_ext::{Pallet, Config},
+		Aura: pallet_aura::{Pallet, Config<T>} = 22,
+		AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23,
 
-		// Frontier
-		EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>},
-		Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, ValidateUnsigned},
+		Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 30,
+		RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 31,
+		Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 32,
+		TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 33,
+		Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event<T>} = 34,
+		Sudo: pallet_sudo::{Pallet, Call, Storage, Config<T>, Event<T>} = 35,
+		System: system::{Pallet, Call, Storage, Config, Event<T>} = 36,
+		Vesting: pallet_vesting::{Pallet, Call, Config<T>, Storage, Event<T>} = 37,
+		// Contracts: pallet_contracts::{Pallet, Call, Storage, Event<T>} = 38,
 
 		// XCM helpers.
 		XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 50,
 		PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 51,
 		CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event<T>, Origin} = 52,
 		DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 53,
-
 
 		// Unique Pallets
-		Inflation: pallet_inflation::{Pallet, Call, Storage},
-		Nft: pallet_nft::{Pallet, Call, Config<T>, Storage, Event<T>},
-		Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event<T>},
-		NftPayment: pallet_nft_transaction_payment::{Pallet, Call, Storage},
-		Charging: pallet_nft_charge_transaction::{Pallet, Call, Storage },
-		// ContractHelpers: pallet_contract_helpers::{Pallet, Call, Storage},
+		Inflation: pallet_inflation::{Pallet, Call, Storage} = 60,
+		Nft: pallet_nft::{Pallet, Call, Config<T>, Storage, Event<T>} = 61,
+		Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event<T>} = 62,
+		NftPayment: pallet_nft_transaction_payment::{Pallet, Call, Storage} = 63,
+		Charging: pallet_nft_charge_transaction::{Pallet, Call, Storage } = 64,
+		// ContractHelpers: pallet_contract_helpers::{Pallet, Call, Storage} = 65,
+
+		// Frontier
+		EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>} = 100,
+		Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, ValidateUnsigned} = 101,
+
+		EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150,
+		EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,
+		EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,
+		EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,
 	}
 );
 
@@ -910,8 +948,9 @@
 		fn validate_transaction(
 			source: TransactionSource,
 			tx: <Block as BlockT>::Extrinsic,
+			hash: <Block as BlockT>::Hash,
 		) -> TransactionValidity {
-			Executive::validate_transaction(source, tx)
+			Executive::validate_transaction(source, tx, hash)
 		}
 	}
 
@@ -939,7 +978,7 @@
 		}
 
 		fn author() -> H160 {
-			<pallet_ethereum::Module<Runtime>>::find_author()
+			<pallet_evm::Module<Runtime>>::find_author()
 		}
 
 		fn storage_at(address: H160, index: U256) -> H256 {
@@ -1029,6 +1068,13 @@
 				Ethereum::current_transaction_statuses()
 			)
 		}
+
+		fn extrinsic_filter(xts: Vec<<Block as sp_api::BlockT>::Extrinsic>) -> Vec<pallet_ethereum::Transaction> {
+			xts.into_iter().filter_map(|xt| match xt.function {
+				Call::Ethereum(pallet_ethereum::Call::transact(t)) => Some(t),
+				_ => None
+			}).collect()
+		}
 	}
 
 	impl sp_session::SessionKeys<Block> for Runtime {
@@ -1138,6 +1184,7 @@
 			let mut batches = Vec::<BenchmarkBatch>::new();
 			let params = (&config, &whitelist);
 
+			add_benchmark!(params, batches, pallet_evm_migration, EvmMigration);
 			add_benchmark!(params, batches, pallet_nft, Nft);
 			add_benchmark!(params, batches, pallet_inflation, Inflation);
 
deletedruntime/src/nft_weights.rsdiffbeforeafterboth
--- a/runtime/src/nft_weights.rs
+++ /dev/null
@@ -1,161 +0,0 @@
-//
-// This file is subject to the terms and conditions defined in
-// file 'LICENSE', which is part of this source code package.
-//
-
-use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight};
-
-pub struct WeightInfo;
-impl pallet_nft::WeightInfo for WeightInfo {
-	fn create_collection() -> Weight {
-		70_000_000_u64
-			.saturating_add(DbWeight::get().reads(7_u64))
-			.saturating_add(DbWeight::get().writes(5_u64))
-	}
-	fn destroy_collection() -> Weight {
-		90_000_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(5_u64))
-	}
-	fn add_to_white_list() -> Weight {
-		30_000_000_u64
-			.saturating_add(DbWeight::get().reads(3_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn remove_from_white_list() -> Weight {
-		35_000_000_u64
-			.saturating_add(DbWeight::get().reads(3_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn set_public_access_mode() -> Weight {
-		27_000_000_u64
-			.saturating_add(DbWeight::get().reads(1_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn set_mint_permission() -> Weight {
-		27_000_000_u64
-			.saturating_add(DbWeight::get().reads(1_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn change_collection_owner() -> Weight {
-		27_000_000_u64
-			.saturating_add(DbWeight::get().reads(1_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn add_collection_admin() -> Weight {
-		32_000_000_u64
-			.saturating_add(DbWeight::get().reads(3_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn remove_collection_admin() -> Weight {
-		50_000_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn set_collection_sponsor() -> Weight {
-		32_000_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn confirm_sponsorship() -> Weight {
-		22_000_000_u64
-			.saturating_add(DbWeight::get().reads(1_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn remove_collection_sponsor() -> Weight {
-		24_000_000_u64
-			.saturating_add(DbWeight::get().reads(1_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn create_item(s: usize) -> Weight {
-		130_000_000_u64
-			.saturating_add(2135_u64.saturating_mul(s as Weight).saturating_mul(500_u64)) // 500 is temparary multiplier, fee for storage
-			.saturating_add(DbWeight::get().reads(10_u64))
-			.saturating_add(DbWeight::get().writes(8_u64))
-	}
-	fn burn_item() -> Weight {
-		170_000_000_u64
-			.saturating_add(DbWeight::get().reads(9_u64))
-			.saturating_add(DbWeight::get().writes(7_u64))
-	}
-	fn transfer() -> Weight {
-		125_000_000_u64
-			.saturating_add(DbWeight::get().reads(7_u64))
-			.saturating_add(DbWeight::get().writes(7_u64))
-	}
-	fn approve() -> Weight {
-		45_000_000_u64
-			.saturating_add(DbWeight::get().reads(3_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn transfer_from() -> Weight {
-		150_000_000_u64
-			.saturating_add(DbWeight::get().reads(9_u64))
-			.saturating_add(DbWeight::get().writes(8_u64))
-	}
-	fn set_offchain_schema() -> Weight {
-		33_000_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn set_const_on_chain_schema() -> Weight {
-		11_100_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn set_variable_on_chain_schema() -> Weight {
-		11_100_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn set_variable_meta_data() -> Weight {
-		17_500_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn enable_contract_sponsoring() -> Weight {
-		13_000_000_u64
-			.saturating_add(DbWeight::get().reads(1_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn set_schema_version() -> Weight {
-		8_500_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn set_chain_limits() -> Weight {
-		1_300_000_u64
-			.saturating_add(DbWeight::get().reads(0_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-	fn set_contract_sponsoring_rate_limit() -> Weight {
-		3_500_000_u64
-			.saturating_add(DbWeight::get().reads(0_u64))
-			.saturating_add(DbWeight::get().writes(2_u64))
-	}
-	fn set_variable_meta_data_sponsoring_rate_limit() -> Weight {
-		3_500_000_u64
-			.saturating_add(DbWeight::get().reads(1_u64))
-			.saturating_add(DbWeight::get().writes(2_u64))
-	}
-	fn toggle_contract_white_list() -> Weight {
-		3_000_000_u64
-			.saturating_add(DbWeight::get().reads(0_u64))
-			.saturating_add(DbWeight::get().writes(2_u64))
-	}
-	fn add_to_contract_white_list() -> Weight {
-		3_000_000_u64
-			.saturating_add(DbWeight::get().reads(0_u64))
-			.saturating_add(DbWeight::get().writes(2_u64))
-	}
-	fn remove_from_contract_white_list() -> Weight {
-		3_200_000_u64
-			.saturating_add(DbWeight::get().reads(0_u64))
-			.saturating_add(DbWeight::get().writes(2_u64))
-	}
-	fn set_collection_limits() -> Weight {
-		8_900_000_u64
-			.saturating_add(DbWeight::get().reads(2_u64))
-			.saturating_add(DbWeight::get().writes(1_u64))
-	}
-}
modifiedruntime_types.jsondiffbeforeafterboth
--- a/runtime_types.json
+++ b/runtime_types.json
@@ -63,7 +63,8 @@
       "Limits": "CollectionLimits",
       "VariableOnChainSchema": "Vec<u8>",
       "ConstOnChainSchema": "Vec<u8>",
-      "MetaUpdatePermission": "MetaUpdatePermission"
+      "MetaUpdatePermission": "MetaUpdatePermission",
+      "TransfersEnabled": "bool"
     },
     "RawData": "Vec<u8>",
     "Address": "MultiAddress",
modifiedtests/package.jsondiffbeforeafterboth
--- a/tests/package.json
+++ b/tests/package.json
@@ -4,28 +4,28 @@
   "description": "Substrate Nft tests",
   "main": "",
   "devDependencies": {
-    "@polkadot/dev": "0.62.43",
-    "@polkadot/ts": "0.3.89",
-    "@polkadot/typegen": "5.0.1",
+    "@polkadot/dev": "0.62.60",
+    "@polkadot/ts": "0.4.4",
+    "@polkadot/typegen": "5.5.1",
     "@types/chai": "^4.2.17",
     "@types/chai-as-promised": "^7.1.3",
     "@types/mocha": "^8.2.2",
+    "@types/node": "^14.14.12",
+    "@typescript-eslint/eslint-plugin": "^4.28.5",
+    "@typescript-eslint/parser": "^4.28.5",
     "chai": "^4.3.4",
+    "eslint": "^7.31.0",
     "mocha": "^8.3.2",
     "ts-node": "^9.1.1",
     "tslint": "^6.1.3",
-    "typescript": "^4.2.4",
-    "eslint": "^7.28.0",
-    "@types/node": "^14.14.12",
-    "@typescript-eslint/eslint-plugin": "^3.4.0",
-    "@typescript-eslint/parser": "^3.4.0"
+    "typescript": "^4.2.4"
   },
   "scripts": {
     "lint": "eslint --ext .ts,.js src/",
     "fix": "eslint --ext .ts,.js src/ --fix",
-    "test": "mocha --timeout 9999999 -r ts-node/register ./**/*.test.ts",
-    "testEth": "mocha --timeout 9999999 -r ts-node/register ./**/eth/**/*.test.ts",
-    "load": "mocha --timeout 9999999 -r ts-node/register ./**/*.load.ts",
+    "test": "mocha --timeout 9999999 -r ts-node/register './**/*.test.ts'",
+    "testEth": "mocha --timeout 9999999 -r ts-node/register './**/eth/**/*.test.ts'",
+    "load": "mocha --timeout 9999999 -r ts-node/register './**/*.load.ts'",
     "loadTransfer": "ts-node src/transfer.nload.ts",
     "testCollision": "mocha --timeout 9999999 -r ts-node/register ./src/collision-tests/*.test.ts",
     "testAddCollectionAdmin": "mocha --timeout 9999999 -r ts-node/register ./**/addCollectionAdmin.test.ts",
@@ -59,16 +59,19 @@
     "testSetVariableMetadataSponsoringRateLimit": "mocha --timeout 9999999 -r ts-node/register ./**/setVariableMetadataSponsoringRateLimit.test.ts",
     "testInflation": "mocha --timeout 9999999 -r ts-node/register ./**/inflation.test.ts",
     "testPalletPresence": "mocha --timeout 9999999 -r ts-node/register ./**/pallet-presence.test.ts",
-    "testBlockProduction": "mocha --timeout 9999999 -r ts-node/register ./**/block-production.test.ts"
+    "testBlockProduction": "mocha --timeout 9999999 -r ts-node/register ./**/block-production.test.ts",
+    "testEnableDisableTransfers": "mocha --timeout 9999999 -r ts-node/register ./**/enableDisableTransfer.test.ts"
   },
   "author": "",
   "license": "SEE LICENSE IN ../LICENSE",
   "homepage": "",
   "dependencies": {
-    "@polkadot/api": "5.0.1",
-    "@polkadot/api-contract": "5.0.1",
+    "@polkadot/api": "5.5.1",
+    "@polkadot/api-contract": "5.5.1",
+    "@polkadot/util-crypto": "^7.2.1",
     "bignumber.js": "^9.0.1",
     "chai-as-promised": "^7.1.1",
+    "solc": "^0.8.6",
     "web3": "^1.3.5"
   },
   "standard": {
modifiedtests/src/addCollectionAdmin.test.tsdiffbeforeafterboth
--- a/tests/src/addCollectionAdmin.test.ts
+++ b/tests/src/addCollectionAdmin.test.ts
@@ -117,8 +117,7 @@
       ];
       const collectionId = await createCollectionExpectSuccess();
 
-      const chainLimit = await api.query.nft.chainLimit() as unknown as { CollectionAdminsLimit: BN };
-      const chainAdminLimit = chainLimit.CollectionAdminsLimit.toNumber();
+      const chainAdminLimit = (api.consts.nft.collectionAdminsLimit as any).toNumber();
       expect(chainAdminLimit).to.be.equal(5);
 
       for (let i = 0; i < chainAdminLimit; i++) {
modifiedtests/src/addToWhiteList.test.tsdiffbeforeafterboth
--- a/tests/src/addToWhiteList.test.ts
+++ b/tests/src/addToWhiteList.test.ts
@@ -16,6 +16,8 @@
   enablePublicMintingExpectSuccess,
   enableWhiteListExpectSuccess,
   normalizeAccountId,
+  addCollectionAdminExpectSuccess,
+  addToWhiteListExpectFail,
 } from './util/helpers';
 
 chai.use(chaiAsPromised);
@@ -23,6 +25,7 @@
 
 let Alice: IKeyringPair;
 let Bob: IKeyringPair;
+let Charlie: IKeyringPair;
 
 describe('Integration Test ext. addToWhiteList()', () => {
 
@@ -85,3 +88,37 @@
   });
 
 });
+
+describe('Integration Test ext. addToWhiteList() with collection admin permissions:', () => {
+
+  before(async () => {
+    await usingApi(async () => {
+      Alice = privateKey('//Alice');
+      Bob = privateKey('//Bob');
+      Charlie = privateKey('//Charlie');
+    });
+  });
+
+  it('Negative. Add to the white list by regular user', async () => {
+    const collectionId = await createCollectionExpectSuccess();
+    await addToWhiteListExpectFail(Bob, collectionId, Charlie.address);
+  });
+
+  it('Execute the extrinsic with parameters: Collection ID and address to add to the white list', async () => {
+    const collectionId = await createCollectionExpectSuccess();
+    await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);
+    await addToWhiteListExpectSuccess(Bob, collectionId, Charlie.address);
+  });
+
+  it('Whitelisted minting: list restrictions', async () => {
+    const collectionId = await createCollectionExpectSuccess();
+    await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);
+    await addToWhiteListExpectSuccess(Bob, collectionId, Charlie.address);
+
+    // allowed only for collection owner
+    await enableWhiteListExpectSuccess(Alice, collectionId);
+    await enablePublicMintingExpectSuccess(Alice, collectionId);
+
+    await createItemExpectSuccess(Charlie, collectionId, 'NFT', Charlie.address);
+  });
+});
\ No newline at end of file
modifiedtests/src/approve.test.tsdiffbeforeafterboth
--- a/tests/src/approve.test.ts
+++ b/tests/src/approve.test.ts
@@ -16,6 +16,7 @@
   destroyCollectionExpectSuccess,
   setCollectionLimitsExpectSuccess,
   transferExpectSuccess,
+  addCollectionAdminExpectSuccess,
 } from './util/helpers';
 
 chai.use(chaiAsPromised);
@@ -177,3 +178,25 @@
     await approveExpectFail(collectionId, itemId, Alice, Charlie);
   });
 });
+
+describe('Integration Test approve(spender, collection_id, item_id, amount) with collection admin permissions:', () => {
+  let Alice: IKeyringPair;
+  let Bob: IKeyringPair;
+  let Charlie: IKeyringPair;
+
+  before(async () => {
+    await usingApi(async () => {
+      Alice = privateKey('//Alice');
+      Bob = privateKey('//Bob');
+      Charlie = privateKey('//Charlie');
+    });
+  });
+
+  it('can be called by collection admin on non-owned item', async () => {
+    const collectionId = await createCollectionExpectSuccess();
+    const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Alice.address);
+
+    await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);
+    await approveExpectSuccess(collectionId, itemId, Bob, Charlie);
+  });
+});
modifiedtests/src/burnItem.test.tsdiffbeforeafterboth
--- a/tests/src/burnItem.test.ts
+++ b/tests/src/burnItem.test.ts
@@ -12,6 +12,7 @@
   getGenericResult,
   destroyCollectionExpectSuccess,
   normalizeAccountId,
+  addCollectionAdminExpectSuccess,
 } from './util/helpers';
 
 import chai from 'chai';
@@ -48,8 +49,8 @@
       // tslint:disable-next-line:no-unused-expression
       expect(item).to.be.null;
     });
-
   });
+
   it('Burn item in Fungible collection', async () => {
     const createMode = 'Fungible';
     const collectionId = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0 }});
@@ -70,8 +71,8 @@
       expect(balance).to.be.not.null;
       expect(balance.Value).to.be.equal(9);
     });
+  });
 
-  });
   it('Burn item in ReFungible collection', async () => {
     const createMode = 'ReFungible';
     const collectionId = await createCollectionExpectSuccess({mode: {type: createMode }});
@@ -89,7 +90,6 @@
       expect(result.success).to.be.true;
       expect(balance).to.be.null;
     });
-
   });
 
   it('Burn owned portion of item in ReFungible collection', async () => {
@@ -136,6 +136,36 @@
 
 });
 
+describe('integration test: ext. burnItem() with admin permissions:', () => {
+  before(async () => {
+    await usingApi(async () => {
+      const keyring = new Keyring({ type: 'sr25519' });
+      alice = keyring.addFromUri('//Alice');
+      bob = keyring.addFromUri('//Bob');
+    });
+  });
+
+  it('Burn item in NFT collection', async () => {
+    const createMode = 'NFT';
+    const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
+    const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
+    await addCollectionAdminExpectSuccess(alice, collectionId, bob);
+
+    await usingApi(async (api) => {
+      const tx = api.tx.nft.burnItem(collectionId, tokenId, 0);
+      const events = await submitTransactionAsync(bob, tx);
+      const result = getGenericResult(events);
+      // Get the item
+      const item: any = (await api.query.nft.nftItemList(collectionId, tokenId)).toJSON();
+      // What to expect
+      // tslint:disable-next-line:no-unused-expression
+      expect(result.success).to.be.true;
+      // tslint:disable-next-line:no-unused-expression
+      expect(item).to.be.null;
+    });
+  });
+});
+
 describe('Negative integration test: ext. burnItem():', () => {
   before(async () => {
     await usingApi(async () => {
modifiedtests/src/change-collection-owner.test.tsdiffbeforeafterboth
--- a/tests/src/change-collection-owner.test.ts
+++ b/tests/src/change-collection-owner.test.ts
@@ -7,7 +7,22 @@
 import chaiAsPromised from 'chai-as-promised';
 import privateKey from './substrate/privateKey';
 import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from './substrate/substrate-api';
-import { createCollectionExpectSuccess } from './util/helpers';
+import { createCollectionExpectSuccess, 
+  addCollectionAdminExpectSuccess,
+  setCollectionSponsorExpectSuccess,
+  confirmSponsorshipExpectSuccess,
+  removeCollectionSponsorExpectSuccess,
+  enableWhiteListExpectSuccess,
+  setMintPermissionExpectSuccess,
+  destroyCollectionExpectSuccess,
+  setCollectionSponsorExpectFailure,
+  confirmSponsorshipExpectFailure,
+  removeCollectionSponsorExpectFailure,
+  enableWhiteListExpectFail,
+  setMintPermissionExpectFailure,
+  destroyCollectionExpectFailure,
+  setPublicAccessModeExpectSuccess,
+} from './util/helpers';
 
 chai.use(chaiAsPromised);
 const expect = chai.expect;
@@ -31,6 +46,97 @@
   });
 });
 
+describe('Integration Test changeCollectionOwner(collection_id, new_owner) special checks for exOwner:', () => {
+  it('Changing the owner of the collection is not allowed for the former owner', async () => {
+    await usingApi(async api => {
+      const collectionId = await createCollectionExpectSuccess();
+      const alice = privateKey('//Alice');
+      const bob = privateKey('//Bob');
+
+      const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();
+      expect(collection.Owner).to.be.deep.eq(alice.address);
+
+      const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);
+      await submitTransactionAsync(alice, changeOwnerTx);
+
+      const badChangeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, alice.address);
+      await expect(submitTransactionExpectFailAsync(alice, badChangeOwnerTx)).to.be.rejected;
+
+      const collectionAfterOwnerChange: any = (await api.query.nft.collectionById(collectionId)).toJSON();
+      expect(collectionAfterOwnerChange.Owner).to.be.deep.eq(bob.address);
+    });
+  });
+
+  it('New collectionOwner has access to sponsorship management operations in the collection', async () => {
+    await usingApi(async api => {
+      const collectionId = await createCollectionExpectSuccess();
+      const alice = privateKey('//Alice');
+      const bob = privateKey('//Bob');
+      const charlie = privateKey('//Charlie');
+
+      const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();
+      expect(collection.Owner).to.be.deep.eq(alice.address);
+
+      const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);
+      await submitTransactionAsync(alice, changeOwnerTx);
+
+      const collectionAfterOwnerChange: any = (await api.query.nft.collectionById(collectionId)).toJSON();
+      expect(collectionAfterOwnerChange.Owner).to.be.deep.eq(bob.address);
+
+      // After changing the owner of the collection, all privileged methods are available to the new owner
+      // The new owner of the collection has access to sponsorship management operations in the collection
+      await setCollectionSponsorExpectSuccess(collectionId, charlie.address, '//Bob');
+      await confirmSponsorshipExpectSuccess(collectionId, '//Charlie');
+      await removeCollectionSponsorExpectSuccess(collectionId, '//Bob');
+
+      // The new owner of the collection has access to operations for managing the collection parameters
+      const collectionLimits = {
+        AccountTokenOwnershipLimit: 1,
+        SponsoredMintSize: 1,
+        TokenLimit: 1,
+        SponsorTimeout: 1,
+        OwnerCanTransfer: true,
+        OwnerCanDestroy: true,
+      };
+      const tx1 = api.tx.nft.setCollectionLimits(
+        collectionId,
+        collectionLimits,
+      );
+      await submitTransactionAsync(bob, tx1);
+
+      await setPublicAccessModeExpectSuccess(bob, collectionId, 'WhiteList');
+      await enableWhiteListExpectSuccess(bob, collectionId);
+      await setMintPermissionExpectSuccess(bob, collectionId, true);
+      await destroyCollectionExpectSuccess(collectionId, '//Bob');
+    });
+  });
+
+  it('New collectionOwner has access to changeCollectionOwner', async () => {
+    await usingApi(async api => {
+      const collectionId = await createCollectionExpectSuccess();
+      const alice = privateKey('//Alice');
+      const bob = privateKey('//Bob');
+      const charlie = privateKey('//Charlie');
+  
+      const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();
+      expect(collection.Owner).to.be.deep.eq(alice.address);
+  
+      const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);
+      await submitTransactionAsync(alice, changeOwnerTx);
+  
+      const collectionAfterOwnerChange: any = (await api.query.nft.collectionById(collectionId)).toJSON();
+      expect(collectionAfterOwnerChange.Owner).to.be.deep.eq(bob.address);
+
+      const changeOwnerTx2 = api.tx.nft.changeCollectionOwner(collectionId, charlie.address);
+      await submitTransactionAsync(bob, changeOwnerTx2);
+  
+      // ownership lost
+      const collectionAfterOwnerChange2: any = (await api.query.nft.collectionById(collectionId)).toJSON();
+      expect(collectionAfterOwnerChange2.Owner).to.be.deep.eq(charlie.address);
+    });
+  });
+});
+
 describe('Negative Integration Test changeCollectionOwner(collection_id, new_owner):', () => {
   it('Not owner can\'t change owner.', async () => {
     await usingApi(async api => {
@@ -48,6 +154,26 @@
       await createCollectionExpectSuccess();
     });
   });
+
+  it('Collection admin can\'t change owner.', async () => {
+    await usingApi(async api => {
+      const collectionId = await createCollectionExpectSuccess();
+      const alice = privateKey('//Alice');
+      const bob = privateKey('//Bob');
+
+      await addCollectionAdminExpectSuccess(alice, collectionId, bob);
+
+      const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);
+      await expect(submitTransactionExpectFailAsync(bob, changeOwnerTx)).to.be.rejected;
+
+      const collectionAfterOwnerChange: any = (await api.query.nft.collectionById(collectionId)).toJSON();
+      expect(collectionAfterOwnerChange.Owner).to.be.deep.eq(alice.address);
+
+      // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
+      await createCollectionExpectSuccess();
+    });
+  });
+
   it('Can\'t change owner of a non-existing collection.', async () => {
     await usingApi(async api => {
       const collectionId = (1<<32) - 1;
@@ -61,4 +187,47 @@
       await createCollectionExpectSuccess();
     });
   });
+
+  it('Former collectionOwner not allowed to sponsorship management operations in the collection', async () => {
+    await usingApi(async api => {
+      const collectionId = await createCollectionExpectSuccess();
+      const alice = privateKey('//Alice');
+      const bob = privateKey('//Bob');
+      const charlie = privateKey('//Charlie');
+
+      const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();
+      expect(collection.Owner).to.be.deep.eq(alice.address);
+
+      const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address);
+      await submitTransactionAsync(alice, changeOwnerTx);
+
+      const badChangeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, alice.address);
+      await expect(submitTransactionExpectFailAsync(alice, badChangeOwnerTx)).to.be.rejected;
+
+      const collectionAfterOwnerChange: any = (await api.query.nft.collectionById(collectionId)).toJSON();
+      expect(collectionAfterOwnerChange.Owner).to.be.deep.eq(bob.address);
+
+      await setCollectionSponsorExpectFailure(collectionId, charlie.address, '//Alice');
+      await confirmSponsorshipExpectFailure(collectionId, '//Alice');
+      await removeCollectionSponsorExpectFailure(collectionId, '//Alice');
+
+      const collectionLimits = {
+        AccountTokenOwnershipLimit: 1,
+        SponsoredMintSize: 1,
+        TokenLimit: 1,
+        SponsorTimeout: 1,
+        OwnerCanTransfer: true,
+        OwnerCanDestroy: true,
+      };
+      const tx1 = api.tx.nft.setCollectionLimits(
+        collectionId,
+        collectionLimits,
+      );
+      await expect(submitTransactionExpectFailAsync(alice, tx1)).to.be.rejected;
+
+      await enableWhiteListExpectFail(alice, collectionId);
+      await setMintPermissionExpectFailure(alice, collectionId, true);
+      await destroyCollectionExpectFailure(collectionId, '//Alice');
+    });
+  });
 });
modifiedtests/src/collision-tests/adminLimitsOff.test.tsdiffbeforeafterboth
--- a/tests/src/collision-tests/adminLimitsOff.test.ts
+++ b/tests/src/collision-tests/adminLimitsOff.test.ts
@@ -34,8 +34,7 @@
     await usingApi(async (api) => {
       const collectionId = await createCollectionExpectSuccess();
 
-      const chainLimit = await api.query.nft.chainLimit() as unknown as { CollectionAdminsLimit: BN };
-      const chainAdminLimit = chainLimit.CollectionAdminsLimit.toNumber();
+      const chainAdminLimit = (api.consts.nft.collectionAdminsLimit as any).toNumber();
       expect(chainAdminLimit).to.be.equal(5);
 
       const changeAdminTx1 = api.tx.nft.addCollectionAdmin(collectionId, Eve.address);
modifiedtests/src/config.tsdiffbeforeafterboth
--- a/tests/src/config.ts
+++ b/tests/src/config.ts
@@ -7,6 +7,7 @@
 
 const config = {
   substrateUrl: process.env.substrateUrl || 'ws://127.0.0.1:9944',
+  frontierUrl: process.env.frontierUrl || 'http://127.0.0.1:9933',
 };
 
 export default config;
\ No newline at end of file
modifiedtests/src/confirmSponsorship.test.tsdiffbeforeafterboth
--- a/tests/src/confirmSponsorship.test.ts
+++ b/tests/src/confirmSponsorship.test.ts
@@ -19,6 +19,7 @@
   enablePublicMintingExpectSuccess,
   addToWhiteListExpectSuccess,
   normalizeAccountId,
+  addCollectionAdminExpectSuccess,
 } from './util/helpers';
 import { Keyring } from '@polkadot/api';
 import { IKeyringPair } from '@polkadot/types/types';
@@ -365,6 +366,13 @@
     await confirmSponsorshipExpectFailure(collectionId, '//Alice');
   });
 
+  it('(!negative test!) Confirm sponsorship by collection admin', async () => {
+    const collectionId = await createCollectionExpectSuccess();
+    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+    await addCollectionAdminExpectSuccess(alice, collectionId, charlie);
+    await confirmSponsorshipExpectFailure(collectionId, '//Charlie');
+  });
+
   it('(!negative test!) Confirm sponsorship without sponsor being set with setCollectionSponsor', async () => {
     const collectionId = await createCollectionExpectSuccess();
     await confirmSponsorshipExpectFailure(collectionId, '//Bob');
modifiedtests/src/createItem.test.tsdiffbeforeafterboth
--- a/tests/src/createItem.test.ts
+++ b/tests/src/createItem.test.ts
@@ -4,20 +4,25 @@
 //
 
 import { default as usingApi } from './substrate/substrate-api';
+import chai from 'chai';
 import { Keyring } from '@polkadot/api';
 import { IKeyringPair } from '@polkadot/types/types';
 import { 
   createCollectionExpectSuccess, 
   createItemExpectSuccess,
+  addCollectionAdminExpectSuccess,
 } from './util/helpers';
 
+const expect = chai.expect;
 let alice: IKeyringPair;
+let bob: IKeyringPair;
 
 describe('integration test: ext. createItem():', () => {
   before(async () => {
     await usingApi(async () => {
       const keyring = new Keyring({ type: 'sr25519' });
       alice = keyring.addFromUri('//Alice');
+      bob = keyring.addFromUri('//Bob');
     });
   });
 
@@ -36,4 +41,48 @@
     const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
     await createItemExpectSuccess(alice, newCollectionID, createMode);
   });
+  it('Create new item in NFT collection with collection admin permissions', async () => {
+    const createMode = 'NFT';
+    const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
+    await addCollectionAdminExpectSuccess(alice, newCollectionID, bob);
+    await createItemExpectSuccess(bob, newCollectionID, createMode);
+  });
+  it('Create new item in Fungible collection with collection admin permissions', async () => {
+    const createMode = 'Fungible';
+    const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});
+    await addCollectionAdminExpectSuccess(alice, newCollectionID, bob);
+    await createItemExpectSuccess(bob, newCollectionID, createMode);
+  });
+  it('Create new item in ReFungible collection with collection admin permissions', async () => {
+    const createMode = 'ReFungible';
+    const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
+    await addCollectionAdminExpectSuccess(alice, newCollectionID, bob);
+    await createItemExpectSuccess(bob, newCollectionID, createMode);
+  });
+});
+
+describe('Negative integration test: ext. createItem():', () => {
+  before(async () => {
+    await usingApi(async () => {
+      const keyring = new Keyring({ type: 'sr25519' });
+      alice = keyring.addFromUri('//Alice');
+      bob = keyring.addFromUri('//Bob');
+    });
+  });
+
+  it('Regular user cannot create new item in NFT collection', async () => {
+    const createMode = 'NFT';
+    const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
+    await expect(createItemExpectSuccess(bob, newCollectionID, createMode)).to.be.rejected;
+  });
+  it('Regular user cannot create new item in Fungible collection', async () => {
+    const createMode = 'Fungible';
+    const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});
+    await expect(createItemExpectSuccess(bob, newCollectionID, createMode)).to.be.rejected;
+  });
+  it('Regular user cannot create new item in ReFungible collection', async () => {
+    const createMode = 'ReFungible';
+    const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
+    await expect(createItemExpectSuccess(bob, newCollectionID, createMode)).to.be.rejected;
+  });
 });
modifiedtests/src/createMultipleItems.test.tsdiffbeforeafterboth
--- a/tests/src/createMultipleItems.test.ts
+++ b/tests/src/createMultipleItems.test.ts
@@ -3,6 +3,7 @@
 // file 'LICENSE', which is part of this source code package.
 //
 import { ApiPromise } from '@polkadot/api';
+import { IKeyringPair } from '@polkadot/types/types';
 import BN from 'bn.js';
 import chai from 'chai';
 import chaiAsPromised from 'chai-as-promised';
@@ -12,9 +13,11 @@
   createCollectionExpectSuccess,
   destroyCollectionExpectSuccess,
   getGenericResult,
+  IFungibleTokenDataType,
   IReFungibleTokenDataType,
   normalizeAccountId,
   setCollectionLimitsExpectSuccess,
+  addCollectionAdminExpectSuccess,
 } from './util/helpers';
 
 chai.use(chaiAsPromised);
@@ -57,6 +60,26 @@
     });
   });
 
+  it('Create  0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {
+    await usingApi(async (api: ApiPromise) => {
+      const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+      const itemsListIndexBefore = await api.query.nft.itemListIndex(collectionId) as unknown as BN;
+      expect(itemsListIndexBefore.toNumber()).to.be.equal(0);
+      const Alice = privateKey('//Alice');
+      const args = [
+        {fungible: { value: 1 }},
+        {fungible: { value: 2 }},
+        {fungible: { value: 3 }},
+      ];
+      const createMultipleItemsTx = api.tx.nft
+        .createMultipleItems(collectionId, normalizeAccountId(Alice.address), args);
+      await submitTransactionAsync(Alice, createMultipleItemsTx);
+      const token1Data = (await api.query.nft.fungibleItemList(collectionId, Alice.address) as any).toJSON() as unknown as IFungibleTokenDataType;
+
+      expect(token1Data.Value).to.be.equal(6); // 1 + 2 + 3
+    });
+  });
+
   it('Create  0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {
     await usingApi(async (api: ApiPromise) => {
       const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
@@ -116,11 +139,167 @@
   });
 });
 
+describe('Integration Test createMultipleItems(collection_id, owner, items_data) with collection admin permissions:', () => {
+
+  let Alice: IKeyringPair;
+  let Bob: IKeyringPair;
+
+  before(async () => {
+    await usingApi(async () => {
+      Alice = privateKey('//Alice');
+      Bob = privateKey('//Bob');
+    });
+  });
+
+  it('Create  0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {
+    await usingApi(async (api: ApiPromise) => {
+      const collectionId = await createCollectionExpectSuccess();
+      const itemsListIndexBefore = await api.query.nft.itemListIndex(collectionId) as unknown as BN;
+      expect(itemsListIndexBefore.toNumber()).to.be.equal(0);
+      await addCollectionAdminExpectSuccess(Alice, collectionId, Bob); 
+      const args = [{ nft: ['0x31', '0x31'] }, { nft: ['0x32', '0x32'] }, { nft: ['0x33', '0x33'] }];
+      const createMultipleItemsTx = api.tx.nft
+        .createMultipleItems(collectionId, normalizeAccountId(Bob.address), args);
+      await submitTransactionAsync(Bob, createMultipleItemsTx);
+      const itemsListIndexAfter = await api.query.nft.itemListIndex(collectionId) as unknown as BN;
+      expect(itemsListIndexAfter.toNumber()).to.be.equal(3);
+      const token1Data = (await api.query.nft.nftItemList(collectionId, 1)).toJSON() as unknown as ITokenDataType;
+      const token2Data = (await api.query.nft.nftItemList(collectionId, 2)).toJSON() as unknown as ITokenDataType;
+      const token3Data = (await api.query.nft.nftItemList(collectionId, 3)).toJSON() as unknown as ITokenDataType;
+
+      expect(token1Data.Owner).to.be.deep.equal(normalizeAccountId(Bob.address));
+      expect(token2Data.Owner).to.be.deep.equal(normalizeAccountId(Bob.address));
+      expect(token3Data.Owner).to.be.deep.equal(normalizeAccountId(Bob.address));
+
+      expect(token1Data.ConstData.toString()).to.be.equal('0x31');
+      expect(token2Data.ConstData.toString()).to.be.equal('0x32');
+      expect(token3Data.ConstData.toString()).to.be.equal('0x33');
+
+      expect(token1Data.VariableData.toString()).to.be.equal('0x31');
+      expect(token2Data.VariableData.toString()).to.be.equal('0x32');
+      expect(token3Data.VariableData.toString()).to.be.equal('0x33');
+    });
+  });
+
+  it('Create  0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {
+    await usingApi(async (api: ApiPromise) => {
+      const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+      const itemsListIndexBefore = await api.query.nft.itemListIndex(collectionId) as unknown as BN;
+      expect(itemsListIndexBefore.toNumber()).to.be.equal(0);
+      await addCollectionAdminExpectSuccess(Alice, collectionId, Bob); 
+      const args = [
+        {fungible: { value: 1 }},
+        {fungible: { value: 2 }},
+        {fungible: { value: 3 }},
+      ];
+      const createMultipleItemsTx = api.tx.nft
+        .createMultipleItems(collectionId, normalizeAccountId(Bob.address), args);
+      await submitTransactionAsync(Bob, createMultipleItemsTx);
+      const token1Data = (await api.query.nft.fungibleItemList(collectionId, Bob.address) as any).toJSON() as unknown as IFungibleTokenDataType;
+
+      expect(token1Data.Value).to.be.equal(6); // 1 + 2 + 3
+    });
+  });
+
+  it('Create  0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {
+    await usingApi(async (api: ApiPromise) => {
+      const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+      const itemsListIndexBefore = await api.query.nft.itemListIndex(collectionId) as unknown as BN;
+      expect(itemsListIndexBefore.toNumber()).to.be.equal(0);
+      await addCollectionAdminExpectSuccess(Alice, collectionId, Bob); 
+      const args = [
+        {refungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},
+        {refungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},
+        {refungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},
+      ];
+      const createMultipleItemsTx = api.tx.nft
+        .createMultipleItems(collectionId, normalizeAccountId(Bob.address), args);
+      await submitTransactionAsync(Bob, createMultipleItemsTx);
+      const itemsListIndexAfter = await api.query.nft.itemListIndex(collectionId) as unknown as BN;
+      expect(itemsListIndexAfter.toNumber()).to.be.equal(3);
+      const token1Data = (await api.query.nft.reFungibleItemList(collectionId, 1) as any).toJSON() as unknown as IReFungibleTokenDataType;
+      const token2Data = (await api.query.nft.reFungibleItemList(collectionId, 2) as any).toJSON() as unknown as IReFungibleTokenDataType;
+      const token3Data = (await api.query.nft.reFungibleItemList(collectionId, 3) as any).toJSON() as unknown as IReFungibleTokenDataType;
+
+      expect(token1Data.Owner[0].Owner).to.be.deep.equal(normalizeAccountId(Bob.address));
+      expect(token1Data.Owner[0].Fraction).to.be.equal(1);
+
+      expect(token2Data.Owner[0].Owner).to.be.deep.equal(normalizeAccountId(Bob.address));
+      expect(token2Data.Owner[0].Fraction).to.be.equal(1);
+
+      expect(token3Data.Owner[0].Owner).to.be.deep.equal(normalizeAccountId(Bob.address));
+      expect(token3Data.Owner[0].Fraction).to.be.equal(1);
+
+      expect(token1Data.ConstData.toString()).to.be.equal('0x31');
+      expect(token2Data.ConstData.toString()).to.be.equal('0x32');
+      expect(token3Data.ConstData.toString()).to.be.equal('0x33');
+
+      expect(token1Data.VariableData.toString()).to.be.equal('0x31');
+      expect(token2Data.VariableData.toString()).to.be.equal('0x32');
+      expect(token3Data.VariableData.toString()).to.be.equal('0x33');
+    });
+  });
+});
+
 describe('Negative Integration Test createMultipleItems(collection_id, owner, items_data):', () => {
+
+  let Alice: IKeyringPair;
+  let Bob: IKeyringPair;
+
+  before(async () => {
+    await usingApi(async () => {
+      Alice = privateKey('//Alice');
+      Bob = privateKey('//Bob');
+    });
+  });
+
+  it('Regular user cannot create items in active NFT collection', async () => {
+    await usingApi(async (api: ApiPromise) => {
+      const collectionId = await createCollectionExpectSuccess();
+      const itemsListIndexBefore = await api.query.nft.itemListIndex(collectionId) as unknown as BN;
+      expect(itemsListIndexBefore.toNumber()).to.be.equal(0);
+      const args = [{ nft: ['0x31', '0x31'] }, { nft: ['0x32', '0x32'] }, { nft: ['0x33', '0x33'] }];
+      const createMultipleItemsTx = api.tx.nft
+        .createMultipleItems(collectionId, normalizeAccountId(Alice.address), args);
+      await expect(submitTransactionAsync(Bob, createMultipleItemsTx)).to.be.rejected;
+    });
+  });
+
+  it('Regular user cannot create items in active Fungible collection', async () => {
+    await usingApi(async (api: ApiPromise) => {
+      const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+      const itemsListIndexBefore = await api.query.nft.itemListIndex(collectionId) as unknown as BN;
+      expect(itemsListIndexBefore.toNumber()).to.be.equal(0);
+      const args = [
+        {fungible: { value: 1 }},
+        {fungible: { value: 2 }},
+        {fungible: { value: 3 }},
+      ];
+      const createMultipleItemsTx = api.tx.nft
+        .createMultipleItems(collectionId, normalizeAccountId(Alice.address), args);
+      await expect(submitTransactionAsync(Bob, createMultipleItemsTx)).to.be.rejected;
+    });
+  });
+
+  it('Regular user cannot create items in active ReFungible collection', async () => {
+    await usingApi(async (api: ApiPromise) => {
+      const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+      const itemsListIndexBefore = await api.query.nft.itemListIndex(collectionId) as unknown as BN;
+      expect(itemsListIndexBefore.toNumber()).to.be.equal(0);
+      const args = [
+        {refungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},
+        {refungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},
+        {refungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},
+      ];
+      const createMultipleItemsTx = api.tx.nft
+        .createMultipleItems(collectionId, normalizeAccountId(Alice.address), args);
+      await expect(submitTransactionAsync(Bob, createMultipleItemsTx)).to.be.rejected;
+    });
+  });
+
   it('Create token with not existing type', async () => {
     await usingApi(async (api: ApiPromise) => {
       const collectionId = await createCollectionExpectSuccess();
-      const Alice = privateKey('//Alice');
       try {
         const args = [{ invalid: null }, { invalid: null }, { invalid: null }];
         const createMultipleItemsTx = await api.tx.nft
@@ -136,7 +315,6 @@
   it('Create token in not existing collection', async () => {
     await usingApi(async (api: ApiPromise) => {
       const collectionId = parseInt((await api.query.nft.createdCollectionCount()).toString()) + 1;
-      const Alice = privateKey('//Alice');
       const createMultipleItemsTx = api.tx.nft
         .createMultipleItems(collectionId, normalizeAccountId(Alice.address), ['NFT', 'NFT', 'NFT']);
       await expect(submitTransactionExpectFailAsync(Alice, createMultipleItemsTx)).to.be.rejected;
@@ -174,7 +352,6 @@
   it('Create tokens with different types', async () => {
     await usingApi(async (api: ApiPromise) => {
       const collectionId = await createCollectionExpectSuccess();
-      const Alice = privateKey('//Alice');
       const createMultipleItemsTx = api.tx.nft
         .createMultipleItems(collectionId, normalizeAccountId(Alice.address), ['NFT', 'Fungible', 'ReFungible']);
       await expect(submitTransactionExpectFailAsync(Alice, createMultipleItemsTx)).to.be.rejected;
@@ -186,7 +363,6 @@
   it('Create tokens with different data limits <> maximum data limit', async () => {
     await usingApi(async (api: ApiPromise) => {
       const collectionId = await createCollectionExpectSuccess();
-      const Alice = privateKey('//Alice');
       const args = [
         { nft: ['A', 'A'] },
         { nft: ['B', 'B'.repeat(2049)] },
@@ -200,18 +376,17 @@
 
   it('Fails when minting tokens exceeds collectionLimits amount', async () => {
     await usingApi(async (api) => {
-      const alice = privateKey('//Alice');
 
       const collectionId = await createCollectionExpectSuccess();
-      await setCollectionLimitsExpectSuccess(alice, collectionId, {
+      await setCollectionLimitsExpectSuccess(Alice, collectionId, {
         TokenLimit: 1,
       });
       const args = [
         { nft: ['A', 'A'] },
         { nft: ['B', 'B'] },
       ];
-      const createMultipleItemsTx = api.tx.nft.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
-      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
+      const createMultipleItemsTx = api.tx.nft.createMultipleItems(collectionId, normalizeAccountId(Alice.address), args);
+      await expect(submitTransactionExpectFailAsync(Alice, createMultipleItemsTx)).to.be.rejected;
     });
   });
 });
modifiedtests/src/destroyCollection.test.tsdiffbeforeafterboth
--- a/tests/src/destroyCollection.test.ts
+++ b/tests/src/destroyCollection.test.ts
@@ -8,7 +8,12 @@
 import chaiAsPromised from 'chai-as-promised';
 import privateKey from './substrate/privateKey';
 import { default as usingApi } from './substrate/substrate-api';
-import { createCollectionExpectSuccess, destroyCollectionExpectSuccess, destroyCollectionExpectFailure, setCollectionLimitsExpectSuccess } from './util/helpers';
+import { createCollectionExpectSuccess, 
+  destroyCollectionExpectSuccess, 
+  destroyCollectionExpectFailure, 
+  setCollectionLimitsExpectSuccess,
+  addCollectionAdminExpectSuccess,
+} from './util/helpers';
 
 chai.use(chaiAsPromised);
 
@@ -29,10 +34,12 @@
 
 describe('(!negative test!) integration test: ext. destroyCollection():', () => {
   let alice: IKeyringPair;
+  let bob: IKeyringPair;
 
   before(async () => {
     await usingApi(async () => {
       alice = privateKey('//Alice');
+      bob = privateKey('//Bob');
     });
   });
 
@@ -53,6 +60,11 @@
     await destroyCollectionExpectFailure(collectionId, '//Bob');
     await destroyCollectionExpectSuccess(collectionId, '//Alice');
   });
+  it('(!negative test!) Destroy a collection using collection admin account', async () => {
+    const collectionId = await createCollectionExpectSuccess();
+    await addCollectionAdminExpectSuccess(alice, collectionId, bob);
+    await destroyCollectionExpectFailure(collectionId, '//Bob');
+  });
   it('fails when OwnerCanDestroy == false', async () => {
     const collectionId = await createCollectionExpectSuccess();
     await setCollectionLimitsExpectSuccess(alice, collectionId, { OwnerCanDestroy: false });
addedtests/src/enableDisableTransfer.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/enableDisableTransfer.test.ts
@@ -0,0 +1,64 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
+import chai from 'chai';
+import chaiAsPromised from 'chai-as-promised';
+import privateKey from './substrate/privateKey';
+import usingApi from './substrate/substrate-api';
+import {
+  createItemExpectSuccess,
+  createCollectionExpectSuccess,
+  transferExpectSuccess,
+  transferExpectFailure,
+  setTransferFlagExpectSuccess,
+  setTransferFlagExpectFailure,
+} from './util/helpers';
+
+chai.use(chaiAsPromised);
+
+describe('Enable/Disable Transfers', () => {
+  it('User can transfer token with enabled transfer flag', async () => {
+    await usingApi(async () => {
+      const Alice = privateKey('//Alice');
+      const Bob = privateKey('//Bob');
+      // nft
+      const nftCollectionId = await createCollectionExpectSuccess();
+      const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');
+
+      // explicitely set transfer flag
+      await setTransferFlagExpectSuccess(Alice, nftCollectionId, true);
+
+      await transferExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob, 1);
+    });
+  });
+
+  it('User can\'n transfer token with disabled transfer flag', async () => {
+    await usingApi(async () => {
+      const Alice = privateKey('//Alice');
+      const Bob = privateKey('//Bob');
+      // nft
+      const nftCollectionId = await createCollectionExpectSuccess();
+      const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');
+
+      // explicitely set transfer flag
+      await setTransferFlagExpectSuccess(Alice, nftCollectionId, false);
+
+      await transferExpectFailure(nftCollectionId, newNftTokenId, Alice, Bob, 1);
+    });
+  });
+});
+
+describe('Negative Enable/Disable Transfers', () => {
+  it('Non-owner cannot change transfer flag', async () => {
+    await usingApi(async () => {
+      const Bob = privateKey('//Bob');
+      // nft
+      const nftCollectionId = await createCollectionExpectSuccess();
+
+      // Change transfer flag
+      await setTransferFlagExpectFailure(Bob, nftCollectionId, false);
+    });
+  });
+});
addedtests/src/eth/allowlist.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/allowlist.test.ts
@@ -0,0 +1,61 @@
+import { expect } from 'chai';
+import waitNewBlocks from '../substrate/wait-new-blocks';
+import { contractHelpers, createEthAccount, createEthAccountWithBalance, deployFlipper, itWeb3, usingWeb3Http } from './util/helpers';
+
+describe('EVM allowlist', () => {
+  itWeb3('Contract allowlist can be toggled', async ({ api }) => {
+    await usingWeb3Http(async web3Http => {
+      const owner = await createEthAccountWithBalance(api, web3Http);
+      const flipper = await deployFlipper(web3Http, owner);
+      await waitNewBlocks(api, 1);
+      const randomUser = createEthAccount(web3Http);
+
+      const helpers = contractHelpers(web3Http, owner);
+
+      // Any user is allowed by default
+      expect(await helpers.methods.allowlistEnabled(flipper.options.address).call()).to.be.false;
+      expect(await helpers.methods.allowed(flipper.options.address, randomUser).call()).to.be.true;
+      await waitNewBlocks(api, 1);
+
+      // Enable
+      await helpers.methods.toggleAllowlist(flipper.options.address, true).send({ from: owner });
+      await waitNewBlocks(api, 1);
+      expect(await helpers.methods.allowlistEnabled(flipper.options.address).call()).to.be.true;
+      expect(await helpers.methods.allowed(flipper.options.address, randomUser).call()).to.be.false;
+
+      // Disable
+      await helpers.methods.toggleAllowlist(flipper.options.address, false).send({ from: owner });
+      await waitNewBlocks(api, 1);
+      expect(await helpers.methods.allowlistEnabled(flipper.options.address).call()).to.be.false;
+      expect(await helpers.methods.allowed(flipper.options.address, randomUser).call()).to.be.true;
+    });
+  });
+
+  itWeb3('Non-whitelisted user can\'t call contract with allowlist enabled', async ({ api }) => {
+    await usingWeb3Http(async web3Http => {
+      const owner = await createEthAccountWithBalance(api, web3Http);
+      const flipper = await deployFlipper(web3Http, owner);
+      await waitNewBlocks(api, 1);
+      const caller = await createEthAccountWithBalance(api, web3Http);
+
+      const helpers = contractHelpers(web3Http, owner);
+
+      // User can flip with allowlist disabled
+      await flipper.methods.flip().send({ from: caller });
+      await waitNewBlocks(api, 1);
+      expect(await flipper.methods.getValue().call()).to.be.true;
+
+      // Tx will be reverted if user is not in whitelist
+      await helpers.methods.toggleAllowlist(flipper.options.address, true).send({ from: owner });
+      await expect(flipper.methods.flip().send({ from: caller })).to.rejected;
+      await waitNewBlocks(api, 1);
+      expect(await flipper.methods.getValue().call()).to.be.true;
+
+      // Adding caller to allowlist will make contract callable again
+      await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});
+      await flipper.methods.flip().send({ from: caller });
+      await waitNewBlocks(api, 1);
+      expect(await flipper.methods.getValue().call()).to.be.false;
+    });
+  });
+});
\ No newline at end of file
addedtests/src/eth/api/ContractHelpers.soldiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/api/ContractHelpers.sol
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: OTHER
+// This code is automatically generated
+
+pragma solidity >=0.8.0 <0.9.0;
+
+// Common stubs holder
+interface Dummy {
+
+}
+
+interface ContractHelpers is Dummy {
+	function contractOwner(address contractAddress)
+		external
+		view
+		returns (address);
+
+	function sponsoringEnabled(address contractAddress)
+		external
+		view
+		returns (bool);
+
+	function toggleSponsoring(address contractAddress, bool enabled) external;
+
+	function setSponsoringRateLimit(address contractAddress, uint32 rateLimit)
+		external;
+
+	function allowed(address contractAddress, address user)
+		external
+		view
+		returns (bool);
+
+	function allowlistEnabled(address contractAddress)
+		external
+		view
+		returns (bool);
+
+	function toggleAllowlist(address contractAddress, bool enabled) external;
+
+	function toggleAllowed(
+		address contractAddress,
+		address user,
+		bool allowed
+	) external;
+}
addedtests/src/eth/api/UniqueFungible.soldiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/api/UniqueFungible.sol
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: OTHER
+// This code is automatically generated
+
+pragma solidity >=0.8.0 <0.9.0;
+
+// Common stubs holder
+interface Dummy {
+
+}
+
+// Inline
+interface ERC20Events {
+	event Transfer(address indexed from, address indexed to, uint256 value);
+	event Approval(
+		address indexed owner,
+		address indexed spender,
+		uint256 value
+	);
+}
+
+// Inline
+interface InlineNameSymbol is Dummy {
+	function name() external view returns (string memory);
+
+	function symbol() external view returns (string memory);
+}
+
+// Inline
+interface InlineTotalSupply is Dummy {
+	function totalSupply() external view returns (uint256);
+}
+
+interface ERC165 is Dummy {
+	function supportsInterface(uint32 interfaceId) external view returns (bool);
+}
+
+interface ERC20 is Dummy, InlineNameSymbol, InlineTotalSupply, ERC20Events {
+	function decimals() external view returns (uint8);
+
+	function balanceOf(address owner) external view returns (uint256);
+
+	function transfer(address to, uint256 amount) external returns (bool);
+
+	function transferFrom(
+		address from,
+		address to,
+		uint256 amount
+	) external returns (bool);
+
+	function approve(address spender, uint256 amount) external returns (bool);
+
+	function allowance(address owner, address spender)
+		external
+		view
+		returns (uint256);
+}
+
+interface UniqueFungible is Dummy, ERC165, ERC20 {}
addedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: OTHER
+// This code is automatically generated
+
+pragma solidity >=0.8.0 <0.9.0;
+
+// Common stubs holder
+interface Dummy {
+
+}
+
+// Inline
+interface ERC721Events {
+	event Transfer(
+		address indexed from,
+		address indexed to,
+		uint256 indexed tokenId
+	);
+	event Approval(
+		address indexed owner,
+		address indexed approved,
+		uint256 indexed tokenId
+	);
+	event ApprovalForAll(
+		address indexed owner,
+		address indexed operator,
+		bool approved
+	);
+}
+
+// Inline
+interface ERC721MintableEvents {
+	event MintingFinished();
+}
+
+// Inline
+interface InlineNameSymbol is Dummy {
+	function name() external view returns (string memory);
+
+	function symbol() external view returns (string memory);
+}
+
+// Inline
+interface InlineTotalSupply is Dummy {
+	function totalSupply() external view returns (uint256);
+}
+
+interface ERC165 is Dummy {
+	function supportsInterface(uint32 interfaceId) external view returns (bool);
+}
+
+interface ERC721 is Dummy, ERC165, ERC721Events {
+	function balanceOf(address owner) external view returns (uint256);
+
+	function ownerOf(uint256 tokenId) external view returns (address);
+
+	function safeTransferFromWithData(
+		address from,
+		address to,
+		uint256 tokenId,
+		bytes memory data
+	) external;
+
+	function safeTransferFrom(
+		address from,
+		address to,
+		uint256 tokenId
+	) external;
+
+	function transferFrom(
+		address from,
+		address to,
+		uint256 tokenId
+	) external;
+
+	function approve(address approved, uint256 tokenId) external;
+
+	function setApprovalForAll(address operator, bool approved) external;
+
+	function getApproved(uint256 tokenId) external view returns (address);
+
+	function isApprovedForAll(address owner, address operator)
+		external
+		view
+		returns (address);
+}
+
+interface ERC721Burnable is Dummy {
+	function burn(uint256 tokenId) external;
+}
+
+interface ERC721Enumerable is Dummy, InlineTotalSupply {
+	function tokenByIndex(uint256 index) external view returns (uint256);
+
+	function tokenOfOwnerByIndex(address owner, uint256 index)
+		external
+		view
+		returns (uint256);
+}
+
+interface ERC721Metadata is Dummy, InlineNameSymbol {
+	function tokenURI(uint256 tokenId) external view returns (string memory);
+}
+
+interface ERC721Mintable is Dummy, ERC721MintableEvents {
+	function mintingFinished() external view returns (bool);
+
+	function mint(address to, uint256 tokenId) external returns (bool);
+
+	function mintWithTokenURI(
+		address to,
+		uint256 tokenId,
+		string memory tokenUri
+	) external returns (bool);
+
+	function finishMinting() external returns (bool);
+}
+
+interface ERC721UniqueExtensions is Dummy {
+	function transfer(address to, uint256 tokenId) external;
+
+	function nextTokenId() external view returns (uint256);
+}
+
+interface UniqueNFT is
+	Dummy,
+	ERC165,
+	ERC721,
+	ERC721Metadata,
+	ERC721Enumerable,
+	ERC721UniqueExtensions,
+	ERC721Mintable,
+	ERC721Burnable
+{}
addedtests/src/eth/base.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/base.test.ts
@@ -0,0 +1,22 @@
+
+import { createEthAccount, createEthAccountWithBalance, deployFlipper, ethBalanceViaSub, GAS_ARGS, itWeb3, recordEthFee } from './util/helpers';
+import { expect } from 'chai';
+import { UNIQUE } from '../util/helpers';
+
+describe('Contract calls', () => {
+  itWeb3('Call of simple contract fee is less than 0.2 UNQ', async ({ web3, api }) => {
+    const deployer = await createEthAccountWithBalance(api, web3);
+    const flipper = await deployFlipper(web3 as any, deployer);
+
+    const cost = await recordEthFee(api, deployer, () => flipper.methods.flip().send({from: deployer}));
+    expect(cost < BigInt(0.2 * Number(UNIQUE))).to.be.true;
+  });
+
+  itWeb3('Balance transfer fee is less than 0.2 UNQ', async ({ web3, api }) => {
+    const userA = await createEthAccountWithBalance(api, web3);
+    const userB = createEthAccount(web3);
+
+    const cost = await recordEthFee(api, userA, () => web3.eth.sendTransaction({ from: userA, to: userB, value: '1000000', ...GAS_ARGS }));
+    expect(cost - await ethBalanceViaSub(api, userB) < BigInt(0.2 * Number(UNIQUE))).to.be.true;
+  });
+});
\ No newline at end of file
addedtests/src/eth/crossTransfer.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/crossTransfer.test.ts
@@ -0,0 +1,88 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
+import privateKey from '../substrate/privateKey';
+import { createCollectionExpectSuccess, 
+  createFungibleItemExpectSuccess, 
+  transferExpectSuccess, 
+  transferFromExpectSuccess, 
+  createItemExpectSuccess } from '../util/helpers';
+import { collectionIdToAddress, 
+  createEthAccountWithBalance, 
+  subToEth,
+  GAS_ARGS, itWeb3 } from './util/helpers';
+import fungibleAbi from './fungibleAbi.json';
+import nonFungibleAbi from './nonFungibleAbi.json';
+
+describe('Token transfer between substrate address and EVM address. Fungible', () => {
+  itWeb3('The private key X create a substrate address. Alice sends a token to the corresponding EVM address, and X can send it to Bob in the substrate', async () => {
+    const collection = await createCollectionExpectSuccess({
+      name: 'token name',
+      mode: { type: 'Fungible', decimalPoints: 0 },
+    });
+    const alice = privateKey('//Alice');
+    const bob = privateKey('//Bob');
+    const charlie = privateKey('//Charlie');
+    await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { substrate: alice.address });
+    await transferExpectSuccess(collection, 0, alice, {ethereum: subToEth(charlie.address)} , 200, 'Fungible');
+    await transferFromExpectSuccess(collection, 0, alice, {ethereum: subToEth(charlie.address)}, charlie, 50, 'Fungible');
+    await transferExpectSuccess(collection, 0, charlie, bob, 50, 'Fungible');
+  });
+
+  itWeb3('The private key X create a EVM address. Alice sends a token to the substrate address corresponding to this EVM address, and X can send it to Bob in the EVM', async ({ api, web3 }) => {
+    const collection = await createCollectionExpectSuccess({
+      name: 'token name',
+      mode: { type: 'Fungible', decimalPoints: 0 },
+    });
+    const alice = privateKey('//Alice');
+    const bob = privateKey('//Bob');
+    const bobProxy = await createEthAccountWithBalance(api, web3);
+    const aliceProxy = await createEthAccountWithBalance(api, web3);
+
+    await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, alice.address);
+    await transferExpectSuccess(collection, 0, alice, { ethereum: aliceProxy } , 200, 'Fungible');
+    const address = collectionIdToAddress(collection);
+    const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: aliceProxy, ...GAS_ARGS});
+
+    await contract.methods.transfer(bobProxy, 50).send({ from: aliceProxy });
+    await transferFromExpectSuccess(collection, 0, alice, {ethereum: bobProxy}, bob, 50, 'Fungible');
+    await transferExpectSuccess(collection, 0, bob, alice, 50, 'Fungible');
+  });
+});
+
+describe('Token transfer between substrate address and EVM address. NFT', () => {
+  itWeb3('The private key X create a substrate address. Alice sends a token to the corresponding EVM address, and X can send it to Bob in the substrate', async () => {
+    const collection = await createCollectionExpectSuccess({
+      name: 'token name',
+      mode: { type: 'NFT' },
+    });
+    const alice = privateKey('//Alice');
+    const bob = privateKey('//Bob');
+    const charlie = privateKey('//Charlie');
+    const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { substrate: alice.address });
+    await transferExpectSuccess(collection, tokenId, alice, { ethereum: subToEth(charlie.address) }, 1, 'NFT');
+    await transferFromExpectSuccess(collection, tokenId, alice, {ethereum: subToEth(charlie.address)}, charlie, 1, 'NFT');
+    await transferExpectSuccess(collection, tokenId, charlie, bob, 1, 'NFT');
+  });
+
+  itWeb3('The private key X create a EVM address. Alice sends a token to the substrate address corresponding to this EVM address, and X can send it to Bob in the EVM', async ({ api, web3 }) => {
+    const collection = await createCollectionExpectSuccess({
+      name: 'token name',
+      mode: { type: 'NFT' },
+    });
+    const alice = privateKey('//Alice');
+    const bob = privateKey('//Bob');
+    const charlie = privateKey('//Charlie');
+    const bobProxy = await createEthAccountWithBalance(api, web3);
+    const aliceProxy = await createEthAccountWithBalance(api, web3);
+    const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { substrate: alice.address });
+    await transferExpectSuccess(collection, tokenId, alice, { ethereum: aliceProxy } , 1, 'NFT');
+    const address = collectionIdToAddress(collection);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: aliceProxy, ...GAS_ARGS});
+    await contract.methods.transfer(bobProxy, 1).send({ from: aliceProxy });
+    await transferFromExpectSuccess(collection, tokenId, alice, {ethereum: bobProxy}, bob, 1, 'NFT');
+    await transferExpectSuccess(collection, tokenId, bob, charlie, 1, 'NFT');
+  });
+});
\ No newline at end of file
modifiedtests/src/eth/fungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/fungible.test.ts
+++ b/tests/src/eth/fungible.test.ts
@@ -4,48 +4,51 @@
 //
 
 import privateKey from '../substrate/privateKey';
-import { approveExpectSuccess, createCollectionExpectSuccess, createFungibleItemExpectSuccess, transferExpectSuccess, transferFromExpectSuccess } from '../util/helpers';
-import { collectionIdToAddress, createEthAccount, itWeb3, normalizeEvents, recordEvents, subToEth, transferBalanceToEth } from './util/helpers';
+import { approveExpectSuccess, createCollectionExpectSuccess, createFungibleItemExpectSuccess, transferExpectSuccess, transferFromExpectSuccess, UNIQUE } from '../util/helpers';
+import { collectionIdToAddress, createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, transferBalanceToEth } from './util/helpers';
 import fungibleAbi from './fungibleAbi.json';
 import { expect } from 'chai';
 
-describe('Information getting', () => {
-  itWeb3('totalSupply', async ({ web3 }) => {
+describe('Fungible: Information getting', () => {
+  itWeb3('totalSupply', async ({ api, web3 }) => {
     const collection = await createCollectionExpectSuccess({
       name: 'token name',
       mode: { type: 'Fungible', decimalPoints: 0 },
     });
     const alice = privateKey('//Alice');
 
+    const caller = await createEthAccountWithBalance(api, web3);
+  
     await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { substrate: alice.address });
 
     const address = collectionIdToAddress(collection);
-    const contract = new web3.eth.Contract(fungibleAbi as any, address);
+    const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS});
     const totalSupply = await contract.methods.totalSupply().call();
 
     // FIXME: always equals to 0, because this method is not implemented
     expect(totalSupply).to.equal('0');
   });
 
-  itWeb3('balanceOf', async ({ web3 }) => {
+  itWeb3('balanceOf', async ({ api, web3 }) => {
     const collection = await createCollectionExpectSuccess({
       name: 'token name',
       mode: { type: 'Fungible', decimalPoints: 0 },
     });
     const alice = privateKey('//Alice');
 
-    const caller = createEthAccount(web3);
+    const caller = await createEthAccountWithBalance(api, web3);
+
     await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: caller });
 
     const address = collectionIdToAddress(collection);
-    const contract = new web3.eth.Contract(fungibleAbi as any, address);
+    const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS});
     const balance = await contract.methods.balanceOf(caller).call();
 
     expect(balance).to.equal('200');
   });
 });
 
-describe('Plain calls', () => {
+describe('Fungible: Plain calls', () => {
   itWeb3('Can perform approve()', async ({ web3, api }) => {
     const collection = await createCollectionExpectSuccess({
       name: 'token name',
@@ -53,18 +56,17 @@
     });
     const alice = privateKey('//Alice');
 
-    const owner = createEthAccount(web3);
-    await transferBalanceToEth(api, alice, owner, 999999999999999);
+    const owner = await createEthAccountWithBalance(api, web3);
 
     await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: owner });
 
     const spender = createEthAccount(web3);
 
     const address = collectionIdToAddress(collection);
-    const contract = new web3.eth.Contract(fungibleAbi as any, address);
+    const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});
 
     {
-      const result = await contract.methods.approve(spender, 100).send({ from: owner, gas: '0x1000000', gasPrice: '0x01' });
+      const result = await contract.methods.approve(spender, 100).send({from: owner});
       const events = normalizeEvents(result.events);
 
       expect(events).to.be.deep.equal([
@@ -104,12 +106,12 @@
     const receiver = createEthAccount(web3);
 
     const address = collectionIdToAddress(collection);
-    const contract = new web3.eth.Contract(fungibleAbi as any, address);
+    const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});
 
-    await contract.methods.approve(spender, 100).send({ from: owner, gas: '0x1000000', gasPrice: '0x01' });
+    await contract.methods.approve(spender, 100).send();
 
     {
-      const result = await contract.methods.transferFrom(owner, receiver, 49).send({ from: spender, gas: '0x1000000', gasPrice: '0x01' });
+      const result = await contract.methods.transferFrom(owner, receiver, 49).send({from: spender});
       const events = normalizeEvents(result.events);
       expect(events).to.be.deep.equal([
         {
@@ -160,10 +162,10 @@
     await transferBalanceToEth(api, alice, receiver, 999999999999999);
 
     const address = collectionIdToAddress(collection);
-    const contract = new web3.eth.Contract(fungibleAbi as any, address);
+    const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});
 
     {
-      const result = await contract.methods.transfer(receiver, 50).send({ from: owner, gas: '0x1000000', gasPrice: '0x01' });
+      const result = await contract.methods.transfer(receiver, 50).send({ from: owner});
       const events = normalizeEvents(result.events);
       expect(events).to.be.deep.equal([
         {
@@ -190,7 +192,65 @@
   });
 });
 
-describe('Substrate calls', () => {
+describe('Fungible: Fees', () => {
+  itWeb3('approve() call fee is less than 0.2UNQ', async ({ web3, api }) => {
+    const collection = await createCollectionExpectSuccess({
+      mode: { type: 'Fungible', decimalPoints: 0 },
+    });
+    const alice = privateKey('//Alice');
+
+    const owner = await createEthAccountWithBalance(api, web3);
+    const spender = createEthAccount(web3);
+
+    await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: owner });
+
+    const address = collectionIdToAddress(collection);
+    const contract = new web3.eth.Contract(fungibleAbi as any, address, { from: owner, ...GAS_ARGS });
+
+    const cost = await recordEthFee(api, owner, () => contract.methods.approve(spender, 100).send({ from: owner }));
+    expect(cost < BigInt(0.2 * Number(UNIQUE)));
+  });
+
+  itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({ web3, api }) => {
+    const collection = await createCollectionExpectSuccess({
+      mode: {type: 'Fungible', decimalPoints: 0},
+    });
+    const alice = privateKey('//Alice');
+  
+    const owner = await createEthAccountWithBalance(api, web3);
+    const spender = await createEthAccountWithBalance(api, web3);
+
+    await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: owner });
+
+    const address = collectionIdToAddress(collection);
+    const contract = new web3.eth.Contract(fungibleAbi as any, address, { from: owner, ...GAS_ARGS });
+
+    await contract.methods.approve(spender, 100).send({ from: owner });
+
+    const cost = await recordEthFee(api, spender, () => contract.methods.transferFrom(owner, spender, 100).send({ from: spender }));
+    expect(cost < BigInt(0.2 * Number(UNIQUE)));
+  });
+
+  itWeb3('transfer() call fee is less than 0.2UNQ', async ({ web3, api }) => {
+    const collection = await createCollectionExpectSuccess({
+      mode: { type: 'Fungible', decimalPoints: 0 },
+    });
+    const alice = privateKey('//Alice');
+
+    const owner = await createEthAccountWithBalance(api, web3);
+    const receiver = createEthAccount(web3);
+
+    await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: owner });
+
+    const address = collectionIdToAddress(collection);
+    const contract = new web3.eth.Contract(fungibleAbi as any, address, { from: owner, ...GAS_ARGS });
+
+    const cost = await recordEthFee(api, owner, () => contract.methods.transfer(receiver, 100).send({ from: owner }));
+    expect(cost < BigInt(0.2 * Number(UNIQUE)));
+  });
+});
+
+describe('Fungible: Substrate calls', () => {
   itWeb3('Events emitted for approve()', async ({ web3 }) => {
     const collection = await createCollectionExpectSuccess({
       mode: { type: 'Fungible', decimalPoints: 0 },
addedtests/src/eth/helpersSmoke.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/helpersSmoke.test.ts
@@ -0,0 +1,25 @@
+import { expect } from 'chai';
+import waitNewBlocks from '../substrate/wait-new-blocks';
+import { createEthAccountWithBalance, deployFlipper, itWeb3, contractHelpers } from './util/helpers';
+
+describe('Helpers sanity check', () => {
+  itWeb3('Contract owner is recorded', async ({ api, web3 }) => {
+    const owner = await createEthAccountWithBalance(api, web3);
+
+    const flipper = await deployFlipper(web3, owner);
+    await waitNewBlocks(api, 1);
+
+    expect(await contractHelpers(web3, owner).methods.contractOwner(flipper.options.address).call()).to.be.equal(owner);
+  });
+
+  itWeb3('Flipper is working', async ({ api, web3 }) => {
+    const owner = await createEthAccountWithBalance(api, web3);
+    const flipper = await deployFlipper(web3, owner);
+    await waitNewBlocks(api, 1);
+
+    expect(await flipper.methods.getValue().call()).to.be.false;
+    await flipper.methods.flip().send({ from: owner });
+    await waitNewBlocks(api, 1);
+    expect(await flipper.methods.getValue().call()).to.be.true;
+  });
+});
\ No newline at end of file
addedtests/src/eth/marketplace/MarketPlaceKSM.abidiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/marketplace/MarketPlaceKSM.abi
@@ -0,0 +1 @@
+[{"inputs":[{"internalType":"address","name":"_escrow","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"asks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"asksbySeller","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"balanceKSM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_idCollection","type":"address"},{"internalType":"uint256","name":"_idNFT","type":"uint256"}],"name":"buy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_currencyCode","type":"uint256"},{"internalType":"address","name":"_sender","type":"address"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_currencyCode","type":"uint256"},{"internalType":"address","name":"_sender","type":"address"}],"name":"escrowBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"offers","outputs":[{"internalType":"uint256","name":"idNFT","type":"uint256"},{"internalType":"uint256","name":"currencyCode","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"time","type":"uint256"},{"internalType":"address","name":"idCollection","type":"address"},{"internalType":"address","name":"userAddr","type":"address"},{"internalType":"uint8","name":"flagActive","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_currencyCode","type":"uint256"},{"internalType":"address","name":"_idCollection","type":"address"},{"internalType":"uint256","name":"_idNFT","type":"uint256"},{"internalType":"uint8","name":"_active","type":"uint8"}],"name":"setAsk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newEscrow","type":"address"}],"name":"setEscrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newEscrow","type":"address"}],"name":"setowner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_currencyCode","type":"uint256"},{"internalType":"address","name":"_sender","type":"address"}],"name":"withdraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
\ No newline at end of file
addedtests/src/eth/marketplace/MarketPlaceKSM.bindiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/marketplace/MarketPlaceKSM.bin
@@ -0,0 +1 @@
+608060405234801561001057600080fd5b50604051610e27380380610e2783398101604081905261002f9161005d565b600480546001600160a01b039092166001600160a01b0319928316179055600580549091163317905561008d565b60006020828403121561006f57600080fd5b81516001600160a01b038116811461008657600080fd5b9392505050565b610d8b8061009c6000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c806399f2d4eb1161007157806399f2d4eb1461018e5780639df55f52146101a1578063c10c35461461010f578063cce7ec13146101b4578063db87db52146101c7578063e22d4f7d146101fa57600080fd5b80630ad58d2f146100ae57806310a5ff17146100d6578063592bd7051461010f5780638a72ea6a146101245780638dbdbe6d1461017b575b600080fd5b6100c16100bc366004610c4d565b610225565b60405190151581526020015b60405180910390f35b6101016100e4366004610bd8565b600160209081526000928352604080842090915290825290205481565b6040519081526020016100cd565b61012261011d366004610b97565b6102d8565b005b610137610132366004610c04565b610345565b6040805197885260208801969096529486019390935260608501919091526001600160a01b0390811660808501521660a083015260ff1660c082015260e0016100cd565b610122610189366004610c4d565b6103a4565b61010161019c366004610bd8565b610449565b6101226101af366004610c86565b61047a565b6101226101c2366004610bd8565b610984565b6101016101d5366004610c1d565b6001600160a01b03166000908152600160209081526040808320938352929052205490565b610101610208366004610bd8565b600260209081526000928352604080842090915290825290205481565b6004546000906001600160a01b031633146102795760405162461bcd60e51b815260206004820152600f60248201526e27b7363c9032b9b1b937bb9031b0b760891b60448201526064015b60405180910390fd5b6001600160a01b03821660009081526001602090815260408083208684529091529020546102a8908590610cfa565b6001600160a01b039290921660009081526001602081815260408084209684529590529390209190915550919050565b6005546001600160a01b031633146103235760405162461bcd60e51b815260206004820152600e60248201526d27b7363c9037bbb732b91031b0b760911b6044820152606401610270565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6000818154811061035557600080fd5b6000918252602090912060069091020180546001820154600283015460038401546004850154600590950154939550919390926001600160a01b0391821691811690600160a01b900460ff1687565b6004546001600160a01b031633146103f05760405162461bcd60e51b815260206004820152600f60248201526e27b7363c9032b9b1b937bb9031b0b760891b6044820152606401610270565b6001600160a01b038116600090815260016020908152604080832085845290915290205461041f908490610ce2565b6001600160a01b039091166000908152600160209081526040808320948352939052919091205550565b6003602052816000526040600020818154811061046557600080fd5b90600052602060002001600091509150505481565b6040516331a9108f60e11b81526004810183905233906001600160a01b03851690636352211e9060240160206040518083038186803b1580156104bc57600080fd5b505afa1580156104d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f49190610bbb565b6001600160a01b0316146105425760405162461bcd60e51b81526020600482015260156024820152742737ba103934b3b43a103a37b5b2b71037bbb732b960591b6044820152606401610270565b6001600160a01b0383166000908152600260209081526040808320858452909152812054905415806105ac575060006001600160a01b03166000828154811061058d5761058d610d27565b60009182526020909120600460069092020101546001600160a01b0316145b15610793576040805160e0810182528481526020810187815291810188815242606083019081526001600160a01b03808916608085019081523360a0860190815260ff808a1660c088019081526000805460018181018355828052995160069091027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56381019190915599517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5648b015596517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5658a015594517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56689015591517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e567880180549185166001600160a01b0319909216919091179055517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56890960180549351909116600160a01b026001600160a81b031990931695909116949094171790925590546107399190610cfa565b6001600160a01b038516600090815260026020908152604080832087845282528083209390935533825260039052908120905461077890600190610cfa565b81546001810183556000928352602090922090910155610916565b6040805160e0810182526001600160a01b03861660009081526002602090815283822087835290529182205482549192839290919081106107d6576107d6610d27565b60009182526020808320600690920290910154835282810189905260408084018b90524260608501526001600160a01b0389168352600282528083208884529091528120548154608090930192811061083157610831610d27565b60009182526020808320600460069093020191909101546001600160a01b039081168452338483015260ff871660409485015288168252600281528282208783529052908120548154811061088857610888610d27565b60009182526020918290208351600690920201908155908201516001820155604082015160028201556060820151600382015560808201516004820180546001600160a01b039283166001600160a01b031990911617905560a08301516005909201805460c09094015160ff16600160a01b026001600160a81b031990941692909116919091179190911790555b6040516323b872dd60e01b8152336004820152306024820152604481018490526001600160a01b038516906323b872dd90606401600060405180830381600087803b15801561096457600080fd5b505af1158015610978573d6000803e3d6000fd5b50505050505050505050565b6001600160a01b0382166000908152600260209081526040808320848452909152812054815482919081106109bb576109bb610d27565b600091825260208083206040805160e0810182526006949094029091018054845260018082015485850190815260028301548685018190526003840154606088015260048401546001600160a01b03908116608089015260059094015493841660a0880152600160a01b90930460ff1660c08701523387529084528286209051865290925290922054909250610a519190610cfa565b33600090815260016020818152604080842086830180518652908352818520959095558581015160a08701516001600160a01b031685529282528084209451845293905291902054610aa39190610ce2565b60a08201516001600160a01b0390811660009081526001602090815260408083208287015184528252808320949094559186168152600282528281208582529091529081205481548291908110610afc57610afc610d27565b60009182526020909120600560069092020101805460ff92909216600160a01b0260ff60a01b199092169190911790556040516323b872dd60e01b8152306004820152336024820152604481018390526001600160a01b038416906323b872dd90606401600060405180830381600087803b158015610b7a57600080fd5b505af1158015610b8e573d6000803e3d6000fd5b50505050505050565b600060208284031215610ba957600080fd5b8135610bb481610d3d565b9392505050565b600060208284031215610bcd57600080fd5b8151610bb481610d3d565b60008060408385031215610beb57600080fd5b8235610bf681610d3d565b946020939093013593505050565b600060208284031215610c1657600080fd5b5035919050565b60008060408385031215610c3057600080fd5b823591506020830135610c4281610d3d565b809150509250929050565b600080600060608486031215610c6257600080fd5b83359250602084013591506040840135610c7b81610d3d565b809150509250925092565b600080600080600060a08688031215610c9e57600080fd5b85359450602086013593506040860135610cb781610d3d565b925060608601359150608086013560ff81168114610cd457600080fd5b809150509295509295909350565b60008219821115610cf557610cf5610d11565b500190565b600082821015610d0c57610d0c610d11565b500390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0381168114610d5257600080fd5b5056fea2646970667358221220d098ae4e0cc7bdbb7de1061c03402a667836f903122c1c606ca2c65db1ab78e964736f6c63430008070033
\ No newline at end of file
addedtests/src/eth/marketplace/MarketPlaceKSM.soldiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/marketplace/MarketPlaceKSM.sol
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier:  Apache License
+pragma solidity >=0.8.0;
+
+interface IERC721 {
+    event Transfer(
+        address indexed from,
+        address indexed to,
+        uint256 indexed tokenId
+    );
+    event Approval(
+        address indexed owner,
+        address indexed approved,
+        uint256 indexed tokenId
+    );
+
+    function ownerOf(uint256 tokenId) external view returns (address owner);
+
+    function transferFrom(
+        address from,
+        address to,
+        uint256 tokenId
+    ) external;
+
+    function debug(string memory value) external;
+}
+
+interface IERC20 {
+    event Transfer(address indexed from, address indexed to, uint256 value);
+    event Approval(
+        address indexed owner,
+        address indexed spender,
+        uint256 value
+    );
+
+    function transfer(address recipient, uint256 amount)
+        external
+        returns (bool);
+
+    function transferFrom(
+        address sender,
+        address recipient,
+        uint256 amount
+    ) external returns (bool);
+}
+
+contract MarketPlaceKSM {
+    struct Offer {
+        uint256 idNFT;
+        uint256 currencyCode;
+        uint256 price;
+        uint256 time;
+        address idCollection;
+        address userAddr;
+        uint8 flagActive;
+    }
+    Offer[] public offers;
+
+    mapping(address => mapping(uint256 => uint256)) public balanceKSM; //  [userAddr] => [KSMs]
+    mapping(address => mapping(uint256 => uint256)) public asks; // [buyer][idCollection][idNFT] => idOffer
+
+    mapping(address => uint256[]) public asksbySeller; // [addressSeller] =>idOffer
+
+    address escrow;
+    address owner;
+
+    constructor(address _escrow) {
+        escrow = _escrow;
+        owner = msg.sender;
+    }
+
+    function setowner(address _newEscrow) public onlyOwner {
+        escrow = _newEscrow;
+    }
+
+    function setEscrow(address _newEscrow) public onlyOwner {
+        escrow = _newEscrow;
+    }
+
+    modifier onlyEscrow() {
+        require(msg.sender == escrow, "Only escrow can");
+        _;
+    }
+
+    modifier onlyOwner() {
+        require(msg.sender == owner, "Only owner can");
+        _;
+    }
+
+    /**
+     * Make bids (offers) to sell NFTs
+     */
+    function setAsk(
+        uint256 _price,
+        uint256 _currencyCode,
+        address _idCollection,
+        uint256 _idNFT,
+        uint8 _active
+    ) public {
+        require(
+            IERC721(_idCollection).ownerOf(_idNFT) == msg.sender,
+            "Not right token owner"
+        );
+        uint256 offerID = asks[_idCollection][_idNFT];
+        if (offers.length == 0 || offers[offerID].idCollection == address(0)) {
+            offers.push(
+                Offer(
+                    _idNFT,
+                    _currencyCode,
+                    _price,
+                    block.timestamp,
+                    _idCollection,
+                    msg.sender,
+                    _active
+                )
+            );
+            asks[_idCollection][_idNFT] = offers.length - 1;
+            asksbySeller[msg.sender].push(offers.length - 1);
+        }
+        //edit existing offer
+        else {
+            offers[asks[_idCollection][_idNFT]] = Offer(
+                offers[asks[_idCollection][_idNFT]].idNFT,
+                _currencyCode,
+                _price,
+                block.timestamp,
+                offers[asks[_idCollection][_idNFT]].idCollection,
+                msg.sender,
+                _active
+            );
+        }
+
+        IERC721(_idCollection).transferFrom(msg.sender, address(this), _idNFT);
+    }
+
+    function deposit(
+        uint256 _amount,
+        uint256 _currencyCode,
+        address _sender
+    ) public onlyEscrow {
+        balanceKSM[_sender][_currencyCode] =
+            balanceKSM[_sender][_currencyCode] +
+            _amount;
+    }
+
+    function buy(address _idCollection, uint256 _idNFT) public {
+        Offer memory offer = offers[asks[_idCollection][_idNFT]];
+        // 1. reduce balance
+        balanceKSM[msg.sender][offer.currencyCode] =
+            balanceKSM[msg.sender][offer.currencyCode] -
+            offer.price;
+        // 2. increase balance
+        balanceKSM[offer.userAddr][offer.currencyCode] =
+            balanceKSM[offer.userAddr][offer.currencyCode] +
+            offer.price;
+        // 3. close offer
+        offers[asks[_idCollection][_idNFT]].flagActive = 0;
+        // 4. transfer NFT to buyer
+        IERC721(_idCollection).transferFrom(address(this), msg.sender, _idNFT);
+    }
+
+    function withdraw(
+        uint256 _amount,
+        uint256 _currencyCode,
+        address _sender
+    ) public onlyEscrow returns (bool) {
+        balanceKSM[_sender][_currencyCode] =
+            balanceKSM[_sender][_currencyCode] -
+            _amount;
+        return true;
+    }
+
+    function escrowBalance(uint256 _currencyCode, address _sender)
+        public
+        view
+        returns (uint256)
+    {
+        return balanceKSM[_sender][_currencyCode];
+    }
+}
addedtests/src/eth/marketplace/MarketPlaceUNQ.abidiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/marketplace/MarketPlaceUNQ.abi
@@ -0,0 +1 @@
+[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"asks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"asksbySeller","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_idCollection","type":"address"},{"internalType":"uint256","name":"_idNFT","type":"uint256"},{"internalType":"address","name":"_currencyCode","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"buy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_idCollection","type":"address"},{"internalType":"uint256","name":"_idNFT","type":"uint256"}],"name":"buy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"offers","outputs":[{"internalType":"uint256","name":"idNFT","type":"uint256"},{"internalType":"address","name":"currencyCode","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"time","type":"uint256"},{"internalType":"address","name":"idCollection","type":"address"},{"internalType":"address","name":"userAddr","type":"address"},{"internalType":"uint8","name":"flagActive","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"address","name":"_currencyCode","type":"address"},{"internalType":"address","name":"_idCollection","type":"address"},{"internalType":"uint256","name":"_idNFT","type":"uint256"},{"internalType":"uint8","name":"_active","type":"uint8"}],"name":"setAsk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"setowner","outputs":[],"stateMutability":"nonpayable","type":"function"}]
\ No newline at end of file
addedtests/src/eth/marketplace/MarketPlaceUNQ.bindiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/marketplace/MarketPlaceUNQ.bin
@@ -0,0 +1 @@
+608060405234801561001057600080fd5b50600380546001600160a01b03191633179055610f2d806100326000396000f3fe6080604052600436106100705760003560e01c806399f2d4eb1161004e57806399f2d4eb14610120578063b3ffb7601461014e578063cce7ec1314610161578063e22d4f7d1461017457600080fd5b8063592bd705146100755780637b1d6001146100975780638a72ea6a146100b7575b600080fd5b34801561008157600080fd5b50610095610090366004610d2b565b6101ac565b005b3480156100a357600080fd5b506100956100b2366004610e1b565b61021e565b3480156100c357600080fd5b506100d76100d2366004610e02565b61073d565b604080519788526001600160a01b03968716602089015287019490945260608601929092528316608085015290911660a083015260ff1660c082015260e0015b60405180910390f35b34801561012c57600080fd5b5061014061013b366004610d6c565b6107a0565b604051908152602001610117565b61009561015c366004610d98565b6107d1565b61009561016f366004610d6c565b610b0b565b34801561018057600080fd5b5061014061018f366004610d6c565b600160209081526000928352604080842090915290825290205481565b6003546001600160a01b031633146101fc5760405162461bcd60e51b815260206004820152600e60248201526d27b7363c9037bbb732b91031b0b760911b60448201526064015b60405180910390fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6040516331a9108f60e11b81526004810183905233906001600160a01b03851690636352211e9060240160206040518083038186803b15801561026057600080fd5b505afa158015610274573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102989190610d4f565b6001600160a01b0316146102e65760405162461bcd60e51b81526020600482015260156024820152742737ba103934b3b43a103a37b5b2b71037bbb732b960591b60448201526064016101f3565b6001600160a01b038316600090815260016020908152604080832085845290915281205490541580610350575060006001600160a01b03166000828154811061033157610331610ec9565b60009182526020909120600460069092020101546001600160a01b0316145b15610542576040805160e0810182528481526001600160a01b03878116602083019081529282018981524260608401908152888316608085019081523360a0860190815260ff89811660c08801908152600080546001808201835582805299517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56360069092029182015599517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5648b0180546001600160a01b0319908116928b1692909217905596517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5658b015594517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5668a015592517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5678901805490961690871617909455517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56890960180549151969094166001600160a81b031990911617600160a01b959092169490940217905590546104e99190610ea4565b6001600160a01b0385166000908152600160208181526040808420888552825280842094909455338352600290529181209054909161052791610ea4565b815460018101835560009283526020909220909101556106d3565b6040805160e0810182526001600160a01b038616600090815260016020908152838220878352905291822054825491928392909190811061058557610585610ec9565b6000918252602080832060069092029091015483526001600160a01b03808a168483015260408085018c9052426060860152908916835260018252808320888452909152812054815460809093019281106105e2576105e2610ec9565b60009182526020808320600460069093020191909101546001600160a01b039081168452338483015260ff871660409485015288168252600181528282208783529052908120548154811061063957610639610ec9565b60009182526020918290208351600690920201908155908201516001820180546001600160a01b039283166001600160a01b031991821617909155604084015160028401556060840151600384015560808401516004840180549184169190921617905560a08301516005909201805460c09094015160ff16600160a01b026001600160a81b031990941692909116919091179190911790555b6040516323b872dd60e01b81526001600160a01b038516906323b872dd9061070390339030908890600401610e80565b600060405180830381600087803b15801561071d57600080fd5b505af1158015610731573d6000803e3d6000fd5b50505050505050505050565b6000818154811061074d57600080fd5b60009182526020909120600690910201805460018201546002830154600384015460048501546005909501549395506001600160a01b03928316949193909291821691811690600160a01b900460ff1687565b600260205281600052604060002081815481106107bc57600080fd5b90600052602060002001600091509150505481565b6001600160a01b03841660009081526001602090815260408083208684529091528120548154829190811061080857610808610ec9565b60009182526020918290206040805160e0810182526006939093029091018054835260018101546001600160a01b03908116948401949094526002810154918301829052600381015460608401526004810154841660808401526005015492831660a0830152600160a01b90920460ff1660c08201529150821480156108a35750826001600160a01b031681602001516001600160a01b0316145b6109245760405162461bcd60e51b815260206004820152604660248201527f4e6f7420726967687420616d6f756e74206f722063757272656e63792073656e60448201527f742c206861766520746f20626520657175616c2063757272656e637920616e6460648201526520707269636560d01b608482015260a4016101f3565b80602001516001600160a01b03166323b872dd333084604001516040518463ffffffff1660e01b815260040161095c93929190610e80565b602060405180830381600087803b15801561097657600080fd5b505af115801561098a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ae9190610de0565b50602081015160a0820151604080840151905163a9059cbb60e01b81526001600160a01b039283166004820152602481019190915291169063a9059cbb90604401602060405180830381600087803b158015610a0957600080fd5b505af1158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190610de0565b506001600160a01b038516600090815260016020908152604080832087845290915281205481548291908110610a7957610a79610ec9565b906000526020600020906006020160050160146101000a81548160ff021916908360ff160217905550846001600160a01b03166323b872dd3033876040518463ffffffff1660e01b8152600401610ad293929190610e80565b600060405180830381600087803b158015610aec57600080fd5b505af1158015610b00573d6000803e3d6000fd5b505050505050505050565b6001600160a01b038216600090815260016020908152604080832084845290915281205481548291908110610b4257610b42610ec9565b60009182526020918290206040805160e0810182526006939093029091018054835260018101546001600160a01b03908116948401949094526002810154918301829052600381015460608401526004810154841660808401526005015492831660a0830152600160a01b90920460ff1660c082015291503414610c225760405162461bcd60e51b815260206004820152603160248201527f4e6f7420726967687420616d6f756e7420554e512073656e742c206861766520604482015270746f20626520657175616c20707269636560781b60648201526084016101f3565b8060a001516001600160a01b03166108fc82604001519081150290604051600060405180830381858888f19350505050158015610c63573d6000803e3d6000fd5b506001600160a01b038316600090815260016020908152604080832085845290915281205481548291908110610c9b57610c9b610ec9565b906000526020600020906006020160050160146101000a81548160ff021916908360ff160217905550826001600160a01b03166323b872dd3033856040518463ffffffff1660e01b8152600401610cf493929190610e80565b600060405180830381600087803b158015610d0e57600080fd5b505af1158015610d22573d6000803e3d6000fd5b50505050505050565b600060208284031215610d3d57600080fd5b8135610d4881610edf565b9392505050565b600060208284031215610d6157600080fd5b8151610d4881610edf565b60008060408385031215610d7f57600080fd5b8235610d8a81610edf565b946020939093013593505050565b60008060008060808587031215610dae57600080fd5b8435610db981610edf565b9350602085013592506040850135610dd081610edf565b9396929550929360600135925050565b600060208284031215610df257600080fd5b81518015158114610d4857600080fd5b600060208284031215610e1457600080fd5b5035919050565b600080600080600060a08688031215610e3357600080fd5b853594506020860135610e4581610edf565b93506040860135610e5581610edf565b925060608601359150608086013560ff81168114610e7257600080fd5b809150509295509295909350565b6001600160a01b039384168152919092166020820152604081019190915260600190565b600082821015610ec457634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0381168114610ef457600080fd5b5056fea2646970667358221220fbf33eb1e471c428b86ad6d948b8699fd08a127b923d5fe27ec1e1ec5f59627564736f6c63430008070033
\ No newline at end of file
addedtests/src/eth/marketplace/MarketPlaceUNQ.soldiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/marketplace/MarketPlaceUNQ.sol
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier:  Apache License
+pragma solidity >=0.8.0;
+
+interface IERC721 {
+    event Transfer(
+        address indexed from,
+        address indexed to,
+        uint256 indexed tokenId
+    );
+    event Approval(
+        address indexed owner,
+        address indexed approved,
+        uint256 indexed tokenId
+    );
+
+    function ownerOf(uint256 tokenId) external view returns (address owner);
+
+    function transferFrom(
+        address from,
+        address to,
+        uint256 tokenId
+    ) external;
+
+    function debug(string memory value) external;
+}
+
+interface IERC20 {
+    event Transfer(address indexed from, address indexed to, uint256 value);
+    event Approval(
+        address indexed owner,
+        address indexed spender,
+        uint256 value
+    );
+
+    function transfer(address recipient, uint256 amount)
+        external
+        returns (bool);
+
+    function transferFrom(
+        address sender,
+        address recipient,
+        uint256 amount
+    ) external returns (bool);
+}
+
+contract MarketPlaceUNQ {
+    struct Offer {
+        uint256 idNFT;
+        address currencyCode; //address of currency  token, = address(0) for UNQ
+        uint256 price;
+        uint256 time;
+        address idCollection;
+        address userAddr;
+        uint8 flagActive;
+    }
+    Offer[] public offers;
+
+    mapping(address => mapping(uint256 => uint256)) public asks; // [idCollection][idNFT] => idOffer
+
+    mapping(address => uint256[]) public asksbySeller; // [addressSeller] =>idOffer
+
+    address owner;
+
+    constructor() {
+        owner = msg.sender;
+    }
+
+    function setowner(address _newOwner) public onlyOwner {
+        owner = _newOwner;
+    }
+
+    modifier onlyOwner() {
+        require(msg.sender == owner, "Only owner can");
+        _;
+    }
+
+    /**
+     * Make bids (offers) to sell NFTs
+     */
+    function setAsk(
+        uint256 _price,
+        address _currencyCode,
+        address _idCollection,
+        uint256 _idNFT,
+        uint8 _active
+    ) public {
+        require(
+            IERC721(_idCollection).ownerOf(_idNFT) == msg.sender,
+            "Not right token owner"
+        );
+        uint256 offerID = asks[_idCollection][_idNFT];
+        if (offers.length == 0 || offers[offerID].idCollection == address(0)) {
+            offers.push(
+                Offer(
+                    _idNFT,
+                    _currencyCode,
+                    _price,
+                    block.timestamp,
+                    _idCollection,
+                    msg.sender,
+                    _active
+                )
+            );
+            asks[_idCollection][_idNFT] = offers.length - 1;
+            asksbySeller[msg.sender].push(offers.length - 1);
+        }
+        //edit existing offer
+        else {
+            offers[asks[_idCollection][_idNFT]] = Offer(
+                offers[asks[_idCollection][_idNFT]].idNFT,
+                _currencyCode,
+                _price,
+                block.timestamp,
+                offers[asks[_idCollection][_idNFT]].idCollection,
+                msg.sender,
+                _active
+            );
+        }
+
+        IERC721(_idCollection).transferFrom(msg.sender, address(this), _idNFT);
+    }
+
+    function buy(address _idCollection, uint256 _idNFT) public payable {
+        //buing for UNQ like as ethers
+        Offer memory offer = offers[asks[_idCollection][_idNFT]];
+        //1. check sent amount and send to seller
+        require(
+            msg.value == offer.price,
+            "Not right amount UNQ sent, have to be equal price"
+        );
+        payable(offer.userAddr).transfer(offer.price);
+        // 2. close offer
+        offers[asks[_idCollection][_idNFT]].flagActive = 0;
+        // 3. transfer NFT to buyer
+        IERC721(_idCollection).transferFrom(address(this), msg.sender, _idNFT);
+    }
+
+    function buy(
+        address _idCollection,
+        uint256 _idNFT,
+        address _currencyCode,
+        uint256 _amount
+    ) public payable {
+        Offer memory offer = offers[asks[_idCollection][_idNFT]];
+        //1. check sent amount and transfer from buyer to seller
+        require(
+            offer.price == _amount && offer.currencyCode == _currencyCode,
+            "Not right amount or currency sent, have to be equal currency and price"
+        );
+        // !!! transfer have to be approved to marketplace!
+        IERC20(offer.currencyCode).transferFrom(
+            msg.sender,
+            address(this),
+            offer.price
+        );
+        //to not disclojure buyer's address
+        IERC20(offer.currencyCode).transfer(offer.userAddr, offer.price);
+        // 2. close offer
+        offers[asks[_idCollection][_idNFT]].flagActive = 0;
+        // 3. transfer NFT to buyer
+        IERC721(_idCollection).transferFrom(address(this), msg.sender, _idNFT);
+    }
+}
addedtests/src/eth/marketplace/marketplace.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/marketplace/marketplace.test.ts
@@ -0,0 +1,198 @@
+import { readFile } from 'fs/promises';
+import { getBalanceSingle, transferBalanceExpectSuccess } from '../../substrate/get-balance';
+import privateKey from '../../substrate/privateKey';
+import { createCollectionExpectSuccess, createFungibleItemExpectSuccess, createItemExpectSuccess, queryNftOwner, transferExpectSuccess, transferFromExpectSuccess } from '../../util/helpers';
+import { collectionIdToAddress, createEthAccountWithBalance, executeEthTxOnSub, GAS_ARGS, itWeb3, subToEth, subToEthLowercase } from '../util/helpers';
+import { evmToAddress } from '@polkadot/util-crypto';
+import nonFungibleAbi from '../nonFungibleAbi.json';
+import fungibleAbi from '../fungibleAbi.json';
+import waitNewBlocks from '../../substrate/wait-new-blocks';
+import { expect } from 'chai';
+
+const PRICE = 2000n;
+
+describe('Matcher contract usage', () => {
+  itWeb3('With UNQ', async ({api, web3}) => {
+    const matcherOwner = await createEthAccountWithBalance(api, web3);
+    const Matcher = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlaceUNQ.abi`)).toString()), undefined, {
+      from: matcherOwner,
+      ...GAS_ARGS,
+    });
+    const matcher = await Matcher.deploy({ data: (await readFile(`${__dirname}/MarketPlaceUNQ.bin`)).toString() }).send({ from: matcherOwner });
+
+    const alice = privateKey('//Alice');
+    const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
+    const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), { from: matcherOwner });
+
+    const seller = privateKey('//Bob');
+  
+    const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);
+
+    // To transfer item to matcher it first needs to be transfered to EVM account of bob
+    await transferExpectSuccess(collectionId, tokenId, seller, {ethereum: subToEth(seller.address)});
+    // Fees will be paid from EVM account, so we should have some balance here
+    await transferBalanceExpectSuccess(api, seller, evmToAddress(subToEth(seller.address)), 10n ** 18n);
+    await transferBalanceExpectSuccess(api, alice, evmToAddress(subToEth(alice.address)), 10n ** 18n);
+    await waitNewBlocks(api, 1);
+
+    // Token is owned by seller initially
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: subToEthLowercase(seller.address) });
+
+    // Ask
+    {
+      await executeEthTxOnSub(api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));
+      await executeEthTxOnSub(api, seller, matcher, m => m.setAsk(PRICE, '0x0000000000000000000000000000000000000000', evmCollection.options.address, tokenId, 1));
+    }
+      
+    // Token is transferred to matcher
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: matcher.options.address.toLowerCase() });
+
+    // Buy
+    {
+      const sellerBalanceBeforePurchase = await getBalanceSingle(api, seller.address);
+      // There is two functions named 'buy', so we should provide full signature
+      await executeEthTxOnSub(api, alice, matcher, m => m['buy(address,uint256)'](evmCollection.options.address, tokenId), { value: PRICE });
+      expect(await getBalanceSingle(api, seller.address) - sellerBalanceBeforePurchase === PRICE);
+    }
+
+    // Token is transferred to evm account of alice
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: subToEthLowercase(alice.address) });
+
+  
+    // Transfer token to substrate side of alice
+    await transferFromExpectSuccess(collectionId, tokenId, alice, { ethereum: subToEth(alice.address) }, { substrate: alice.address });
+    
+    // Token is transferred to substrate account of alice, seller received funds
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ substrate: alice.address });
+  });
+
+  itWeb3('With custom ERC20', async ({api, web3}) => {
+    const matcherOwner = await createEthAccountWithBalance(api, web3);
+    const Matcher = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlaceUNQ.abi`)).toString()), undefined, {
+      from: matcherOwner,
+      ...GAS_ARGS,
+    });
+    const matcher = await Matcher.deploy({ data: (await readFile(`${__dirname}/MarketPlaceUNQ.bin`)).toString() }).send({ from: matcherOwner });
+
+    const alice = privateKey('//Alice');
+    const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
+    const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), { from: matcherOwner });
+
+    const fungibleId = await createCollectionExpectSuccess({ mode: { type: 'Fungible', decimalPoints: 0 } });
+    const evmFungible = new web3.eth.Contract(fungibleAbi as any, collectionIdToAddress(fungibleId), { from: matcherOwner, ...GAS_ARGS });
+    await createFungibleItemExpectSuccess(alice, fungibleId, { Value: PRICE }, { ethereum: subToEth(alice.address) });
+
+    const seller = privateKey('//Bob');
+  
+    const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);
+
+    // To transfer item to matcher it first needs to be transfered to EVM account of bob
+    await transferExpectSuccess(collectionId, tokenId, seller, {ethereum: subToEth(seller.address)});
+    // Fees will be paid from EVM account, so we should have some balance here
+    await transferBalanceExpectSuccess(api, seller, evmToAddress(subToEth(seller.address)), 10n ** 18n);
+    await transferBalanceExpectSuccess(api, alice, evmToAddress(subToEth(alice.address)), 10n ** 18n);
+    await waitNewBlocks(api, 1);
+
+    // Token is owned by seller initially
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: subToEthLowercase(seller.address) });
+
+    // Ask
+    {
+      await executeEthTxOnSub(api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));
+      await executeEthTxOnSub(api, seller, matcher, m => m.setAsk(PRICE, evmFungible.options.address, evmCollection.options.address, tokenId, 1));
+    }
+      
+    // Token is transferred to matcher
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: matcher.options.address.toLowerCase() });
+
+    // Buy
+    {
+      const sellerBalanceBeforePurchase = BigInt(await evmFungible.methods.balanceOf(subToEth(seller.address)).call());
+      const buyerBalanceBeforePurchase = BigInt(await evmFungible.methods.balanceOf(subToEth(alice.address)).call());
+
+      await executeEthTxOnSub(api, alice, evmFungible, m => m.approve(matcher.options.address, PRICE));
+      // There is two functions named 'buy', so we should provide full signature
+      await executeEthTxOnSub(api, alice, matcher, m =>
+        m['buy(address,uint256,address,uint256)'](evmCollection.options.address, tokenId, evmFungible.options.address, PRICE));
+
+      // Approved price is removed from buyer balance, and added to seller
+      expect(BigInt(await evmFungible.methods.balanceOf(subToEth(seller.address)).call()) - sellerBalanceBeforePurchase === PRICE);
+      expect(buyerBalanceBeforePurchase - BigInt(await evmFungible.methods.balanceOf(subToEth(alice.address)).call()) === PRICE);
+    }
+
+    // Token is transferred to evm account of alice
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: subToEthLowercase(alice.address) });
+
+  
+    // Transfer token to substrate side of alice
+    await transferFromExpectSuccess(collectionId, tokenId, alice, { ethereum: subToEth(alice.address) }, { substrate: alice.address });
+    
+    // Token is transferred to substrate account of alice
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ substrate: alice.address });
+  });
+
+  itWeb3('With escrow', async ({ api, web3 }) => {
+    const matcherOwner = await createEthAccountWithBalance(api, web3);
+    const escrow = await createEthAccountWithBalance(api, web3);
+    const Matcher = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlaceKSM.abi`)).toString()), undefined, {
+      from: matcherOwner,
+      ...GAS_ARGS,
+    });
+    const matcher = await Matcher.deploy({ data: (await readFile(`${__dirname}/MarketPlaceKSM.bin`)).toString(), arguments: [escrow] }).send({ from: matcherOwner });
+    
+    const ksmToken = 11;
+
+    const alice = privateKey('//Alice');
+    const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
+    const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), { from: matcherOwner });
+
+    const seller = privateKey('//Bob');
+  
+    const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);
+
+    // To transfer item to matcher it first needs to be transfered to EVM account of bob
+    await transferExpectSuccess(collectionId, tokenId, seller, {ethereum: subToEth(seller.address)});
+    // Fees will be paid from EVM account, so we should have some balance here
+    await transferBalanceExpectSuccess(api, seller, evmToAddress(subToEth(seller.address)), 10n ** 18n);
+    await transferBalanceExpectSuccess(api, alice, evmToAddress(subToEth(alice.address)), 10n ** 18n);
+    await waitNewBlocks(api, 1);
+
+    // Token is owned by seller initially
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: subToEthLowercase(seller.address) });
+
+    // Ask
+    {
+      await executeEthTxOnSub(api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));
+      await executeEthTxOnSub(api, seller, matcher, m => m.setAsk(PRICE, ksmToken, evmCollection.options.address, tokenId, 1));
+    }
+      
+    // Token is transferred to matcher
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: matcher.options.address.toLowerCase() });
+
+    // Give buyer KSM
+    await matcher.methods.deposit(PRICE, ksmToken, subToEth(alice.address)).send({ from: escrow });
+    await waitNewBlocks(api, 1);
+  
+    // Buy
+    {
+      expect(await matcher.methods.escrowBalance(ksmToken, subToEth(seller.address)).call()).to.be.equal('0');
+      expect(await matcher.methods.escrowBalance(ksmToken, subToEth(alice.address)).call()).to.be.equal(PRICE.toString());
+
+      await executeEthTxOnSub(api, alice, matcher, m => m.buy(evmCollection.options.address, tokenId));
+      await waitNewBlocks(api, 1);
+
+      // Price is removed from buyer balance, and added to seller
+      expect(await matcher.methods.escrowBalance(ksmToken, subToEth(alice.address)).call()).to.be.equal('0');
+      expect(await matcher.methods.escrowBalance(ksmToken, subToEth(seller.address)).call()).to.be.equal(PRICE.toString());
+    }
+
+    // Token is transferred to evm account of alice
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: subToEthLowercase(alice.address) });
+  
+    // Transfer token to substrate side of alice
+    await transferFromExpectSuccess(collectionId, tokenId, alice, { ethereum: subToEth(alice.address) }, { substrate: alice.address });
+    
+    // Token is transferred to substrate account of alice, seller received funds
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ substrate: alice.address });
+  });
+});
modifiedtests/src/eth/metadata.test.tsdiffbeforeafterboth
--- a/tests/src/eth/metadata.test.ts
+++ b/tests/src/eth/metadata.test.ts
@@ -4,9 +4,8 @@
 //
 
 import { expect } from 'chai';
-import privateKey from '../substrate/privateKey';
 import { createCollectionExpectSuccess } from '../util/helpers';
-import { collectionIdToAddress, createEthAccount, itWeb3, transferBalanceToEth } from './util/helpers';
+import { collectionIdToAddress, createEthAccountWithBalance, GAS_ARGS, itWeb3 } from './util/helpers';
 import fungibleMetadataAbi from './fungibleMetadataAbi.json';
 
 describe('Common metadata', () => {
@@ -15,12 +14,11 @@
       name: 'token name',
       mode: { type: 'NFT' },
     });
-    const caller = createEthAccount(web3);
-    await transferBalanceToEth(api, privateKey('//Alice'), caller, 999999);
+    const caller = await createEthAccountWithBalance(api, web3);
 
     const address = collectionIdToAddress(collection);
-    const contract = new web3.eth.Contract(fungibleMetadataAbi as any, address);
-    const name = await contract.methods.name().call({ from: caller });
+    const contract = new web3.eth.Contract(fungibleMetadataAbi as any, address, { from: caller, ...GAS_ARGS });
+    const name = await contract.methods.name().call();
 
     expect(name).to.equal('token name');
   });
@@ -30,12 +28,11 @@
       tokenPrefix: 'TOK',
       mode: { type: 'NFT' },
     });
-    const caller = createEthAccount(web3);
-    await transferBalanceToEth(api, privateKey('//Alice'), caller, 999999);
+    const caller = await createEthAccountWithBalance(api, web3);
 
     const address = collectionIdToAddress(collection);
-    const contract = new web3.eth.Contract(fungibleMetadataAbi as any, address);
-    const symbol = await contract.methods.symbol().call({ from: caller });
+    const contract = new web3.eth.Contract(fungibleMetadataAbi as any, address, { from: caller, ...GAS_ARGS });
+    const symbol = await contract.methods.symbol().call();
 
     expect(symbol).to.equal('TOK');
   });
@@ -46,12 +43,11 @@
     const collection = await createCollectionExpectSuccess({
       mode: { type: 'Fungible', decimalPoints: 6 },
     });
-    const caller = createEthAccount(web3);
-    await transferBalanceToEth(api, privateKey('//Alice'), caller, 999999);
+    const caller = await createEthAccountWithBalance(api, web3);
 
     const address = collectionIdToAddress(collection);
-    const contract = new web3.eth.Contract(fungibleMetadataAbi as any, address);
-    const decimals = await contract.methods.decimals().call({ from: caller });
+    const contract = new web3.eth.Contract(fungibleMetadataAbi as any, address, { from: caller, ...GAS_ARGS });
+    const decimals = await contract.methods.decimals().call();
 
     expect(+decimals).to.equal(6);
   });
addedtests/src/eth/migration.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/migration.test.ts
@@ -0,0 +1,82 @@
+import { expect } from 'chai';
+import privateKey from '../substrate/privateKey';
+import { submitTransactionAsync } from '../substrate/substrate-api';
+import { createEthAccountWithBalance, GAS_ARGS, itWeb3 } from './util/helpers';
+
+describe('EVM Migrations', () => {
+  itWeb3('Deploy contract saved state', async ({ web3, api }) => {
+    /*
+      contract StatefulContract {
+        uint counter;
+        mapping (uint => uint) kv;
+
+        function inc() public {
+          counter = counter + 1;
+        }
+        function counterValue() public view returns (uint) {
+          return counter;
+        }
+
+        function set(uint key, uint value) public {
+          kv[key] = value;
+        }
+
+        function get(uint key) public view returns (uint) {
+          return kv[key];
+        }
+      }
+    */
+    const ADDRESS = '0x4956bf52ef9ed8789f21bc600e915e0d961079f6';
+    const CODE = '0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80631ab06ee514610051578063371303c01461006d5780637bfdec3b146100775780639507d39a14610095575b600080fd5b61006b60048036038101906100669190610160565b6100c5565b005b6100756100e1565b005b61007f6100f8565b60405161008c91906101af565b60405180910390f35b6100af60048036038101906100aa9190610133565b610101565b6040516100bc91906101af565b60405180910390f35b8060016000848152602001908152602001600020819055505050565b60016000546100f091906101ca565b600081905550565b60008054905090565b600060016000838152602001908152602001600020549050919050565b60008135905061012d8161025e565b92915050565b60006020828403121561014957610148610259565b5b60006101578482850161011e565b91505092915050565b6000806040838503121561017757610176610259565b5b60006101858582860161011e565b92505060206101968582860161011e565b9150509250929050565b6101a981610220565b82525050565b60006020820190506101c460008301846101a0565b92915050565b60006101d582610220565b91506101e083610220565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156102155761021461022a565b5b828201905092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b61026781610220565b811461027257600080fd5b5056fea26469706673582212206a02d2fb5c244105ab884961479c1aee3b4c1011e4b5530ab483eb22344a865664736f6c63430008060033';
+    const DATA = [
+      // counter = 10
+      ['0x0000000000000000000000000000000000000000000000000000000000000000', '0x000000000000000000000000000000000000000000000000000000000000000a'],
+      // kv = {1: 1, 2: 2, 3: 3, 4: 4},
+      ['0xcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f', '0x0000000000000000000000000000000000000000000000000000000000000001'],
+      ['0xd9d16d34ffb15ba3a3d852f0d403e2ce1d691fb54de27ac87cd2f993f3ec330f', '0x0000000000000000000000000000000000000000000000000000000000000002'],
+      ['0x7dfe757ecd65cbd7922a9c0161e935dd7fdbcc0e999689c7d31633896b1fc60b', '0x0000000000000000000000000000000000000000000000000000000000000003'],
+      ['0xedc95719e9a3b28dd8e80877cb5880a9be7de1a13fc8b05e7999683b6b567643', '0x0000000000000000000000000000000000000000000000000000000000000004'],
+    ];
+
+    const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
+
+    await submitTransactionAsync(alice, api.tx.sudo.sudo(api.tx.evmMigration.begin(ADDRESS)));
+    await submitTransactionAsync(alice, api.tx.sudo.sudo(api.tx.evmMigration.setData(ADDRESS, DATA)));
+    await submitTransactionAsync(alice, api.tx.sudo.sudo(api.tx.evmMigration.finish(ADDRESS, CODE)));
+
+    const contract = new web3.eth.Contract([
+      {
+        inputs: [],
+        name: 'counterValue',
+        outputs: [{
+          internalType: 'uint256',
+          name: '',
+          type: 'uint256',
+        }],
+        stateMutability: 'view',
+        type: 'function',
+      },
+      {
+        inputs: [{
+          internalType: 'uint256',
+          name: 'key',
+          type: 'uint256',
+        }],
+        name: 'get',
+        outputs: [{
+          internalType: 'uint256',
+          name: '',
+          type: 'uint256',
+        }],
+        stateMutability: 'view',
+        type: 'function',
+      },
+    ], ADDRESS, { from: caller, ...GAS_ARGS });
+    
+    expect(await contract.methods.counterValue().call()).to.be.equal('10');
+    for (let i = 1; i <= 4; i++) {
+      expect(await contract.methods.get(i).call()).to.be.equal(i.toString());
+    }
+  });
+});
\ No newline at end of file
modifiedtests/src/eth/nonFungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/nonFungible.test.ts
+++ b/tests/src/eth/nonFungible.test.ts
@@ -4,64 +4,140 @@
 //
 
 import privateKey from '../substrate/privateKey';
-import { approveExpectSuccess, createCollectionExpectSuccess, createItemExpectSuccess, transferExpectSuccess, transferFromExpectSuccess } from '../util/helpers';
-import { collectionIdToAddress, createEthAccount, itWeb3, normalizeEvents, recordEvents, subToEth, transferBalanceToEth } from './util/helpers';
+import { approveExpectSuccess, burnItemExpectSuccess, createCollectionExpectSuccess, createItemExpectSuccess, transferExpectSuccess, transferFromExpectSuccess, UNIQUE } from '../util/helpers';
+import { collectionIdToAddress, createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, transferBalanceToEth } from './util/helpers';
+import { evmToAddress } from '@polkadot/util-crypto';
 import nonFungibleAbi from './nonFungibleAbi.json';
 import { expect } from 'chai';
+import waitNewBlocks from '../substrate/wait-new-blocks';
+import { submitTransactionAsync } from '../substrate/substrate-api';
 
-describe('Information getting', () => {
-  itWeb3('totalSupply', async ({ web3 }) => {
+describe('NFT: Information getting', () => {
+  itWeb3('totalSupply', async ({ api, web3 }) => {
     const collection = await createCollectionExpectSuccess({
       mode: { type: 'NFT' },
     });
     const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
 
     await createItemExpectSuccess(alice, collection, 'NFT', { substrate: alice.address });
 
     const address = collectionIdToAddress(collection);
-    const contract = new web3.eth.Contract(nonFungibleAbi as any, address);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
     const totalSupply = await contract.methods.totalSupply().call();
 
     // FIXME: always equals to 0, because this method is not implemented
     expect(totalSupply).to.equal('0');
   });
 
-  itWeb3('balanceOf', async ({ web3 }) => {
+  itWeb3('balanceOf', async ({ api, web3 }) => {
     const collection = await createCollectionExpectSuccess({
       mode: { type: 'NFT' },
     });
     const alice = privateKey('//Alice');
 
-    const caller = createEthAccount(web3);
+    const caller = await createEthAccountWithBalance(api, web3);
     await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });
     await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });
     await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });
 
     const address = collectionIdToAddress(collection);
-    const contract = new web3.eth.Contract(nonFungibleAbi as any, address);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
     const balance = await contract.methods.balanceOf(caller).call();
 
     expect(balance).to.equal('3');
   });
 
-  itWeb3('ownerOf', async ({ web3 }) => {
+  itWeb3('ownerOf', async ({ api, web3 }) => {
     const collection = await createCollectionExpectSuccess({
       mode: { type: 'NFT' },
     });
     const alice = privateKey('//Alice');
 
-    const caller = createEthAccount(web3);
+    const caller = await createEthAccountWithBalance(api, web3);
     const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });
 
     const address = collectionIdToAddress(collection);
-    const contract = new web3.eth.Contract(nonFungibleAbi as any, address);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
     const owner = await contract.methods.ownerOf(tokenId).call();
 
     expect(owner).to.equal(caller);
   });
 });
 
-describe('Plain calls', () => {
+describe('NFT: Plain calls', () => {
+  itWeb3('Can perform mint()', async ({ web3, api }) => {
+    const collection = await createCollectionExpectSuccess({
+      mode: { type: 'NFT' },
+    });
+    const alice = privateKey('//Alice');
+
+    const caller = await createEthAccountWithBalance(api, web3);
+    const changeAdminTx = api.tx.nft.addCollectionAdmin(collection, { ethereum: caller });
+    await submitTransactionAsync(alice, changeAdminTx);
+    const receiver = createEthAccount(web3);
+
+    const address = collectionIdToAddress(collection);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
+
+    {
+      const nextTokenId = await contract.methods.nextTokenId().call();
+      expect(nextTokenId).to.be.equal('1');
+      const result = await contract.methods.mintWithTokenURI(
+        receiver,
+        nextTokenId,
+        'Test URI',
+      ).send({from: caller});
+      const events = normalizeEvents(result.events);
+
+      expect(events).to.be.deep.equal([
+        {
+          address,
+          event: 'Transfer',
+          args: {
+            from: '0x0000000000000000000000000000000000000000',
+            to: receiver,
+            tokenId: nextTokenId,
+          },
+        },
+      ]);
+
+      await waitNewBlocks(api, 1);
+      expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
+    }
+  });
+
+  itWeb3('Can perform burn()', async ({ web3, api }) => {
+    const collection = await createCollectionExpectSuccess({
+      mode: {type: 'NFT'},
+    });
+    const alice = privateKey('//Alice');
+
+    const owner = await createEthAccountWithBalance(api, web3);
+
+    const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });
+    
+    const address = collectionIdToAddress(collection);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
+
+    {
+      const result = await contract.methods.burn(tokenId).send({ from: owner });
+      const events = normalizeEvents(result.events);
+      
+      expect(events).to.be.deep.equal([
+        {
+          address,
+          event: 'Transfer',
+          args: {
+            from: owner,
+            to: '0x0000000000000000000000000000000000000000',
+            tokenId: tokenId.toString(),
+          },
+        },
+      ]);
+    }
+  });
+
   itWeb3('Can perform approve()', async ({ web3, api }) => {
     const collection = await createCollectionExpectSuccess({
       mode: { type: 'NFT' },
@@ -113,12 +189,12 @@
     const receiver = createEthAccount(web3);
 
     const address = collectionIdToAddress(collection);
-    const contract = new web3.eth.Contract(nonFungibleAbi as any, address);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
 
-    await contract.methods.approve(spender, tokenId).send({ from: owner, gas: '0x1000000', gasPrice: '0x01' });
+    await contract.methods.approve(spender, tokenId).send({ from: owner });
 
     {
-      const result = await contract.methods.transferFrom(owner, receiver, tokenId).send({ from: spender, gas: '0x1000000', gasPrice: '0x01' });
+      const result = await contract.methods.transferFrom(owner, receiver, tokenId).send({ from: spender });
       const events = normalizeEvents(result.events);
       expect(events).to.be.deep.equal([
         {
@@ -159,11 +235,11 @@
     await transferBalanceToEth(api, alice, receiver, 999999999999999);
 
     const address = collectionIdToAddress(collection);
-    const contract = new web3.eth.Contract(nonFungibleAbi as any, address);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
 
     {
-      const result = await contract.methods.transfer(receiver, tokenId).send({ from: owner, gas: '0x1000000', gasPrice: '0x01' });
-      console.log(result);
+      const result = await contract.methods.transfer(receiver, tokenId).send({ from: owner });
+      await waitNewBlocks(api, 1);
       const events = normalizeEvents(result.events);
       expect(events).to.be.deep.equal([
         {
@@ -190,7 +266,119 @@
   });
 });
 
-describe('Substrate calls', () => {
+describe('NFT: Fees', () => {
+  itWeb3('approve() call fee is less than 0.2UNQ', async ({ web3, api }) => {
+    const collection = await createCollectionExpectSuccess({
+      mode: { type: 'NFT' },
+    });
+    const alice = privateKey('//Alice');
+
+    const owner = await createEthAccountWithBalance(api, web3);
+    const spender = createEthAccount(web3);
+
+    const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });
+
+    const address = collectionIdToAddress(collection);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, { from: owner, ...GAS_ARGS });
+
+    const cost = await recordEthFee(api, owner, () => contract.methods.approve(spender, tokenId).send({ from: owner }));
+    expect(cost < BigInt(0.2 * Number(UNIQUE)));
+  });
+
+  itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({ web3, api }) => {
+    const collection = await createCollectionExpectSuccess({
+      mode: { type: 'NFT' },
+    });
+    const alice = privateKey('//Alice');
+  
+    const owner = await createEthAccountWithBalance(api, web3);
+    const spender = await createEthAccountWithBalance(api, web3);
+
+    const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });
+
+    const address = collectionIdToAddress(collection);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, { from: owner, ...GAS_ARGS });
+
+    await contract.methods.approve(spender, tokenId).send({ from: owner });
+
+    const cost = await recordEthFee(api, spender, () => contract.methods.transferFrom(owner, spender, tokenId).send({ from: spender }));
+    expect(cost < BigInt(0.2 * Number(UNIQUE)));
+  });
+
+  itWeb3('transfer() call fee is less than 0.2UNQ', async ({ web3, api }) => {
+    const collection = await createCollectionExpectSuccess({
+      mode: { type: 'NFT' },
+    });
+    const alice = privateKey('//Alice');
+
+    const owner = await createEthAccountWithBalance(api, web3);
+    const receiver = createEthAccount(web3);
+
+    const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });
+
+    const address = collectionIdToAddress(collection);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, { from: owner, ...GAS_ARGS });
+
+    const cost = await recordEthFee(api, owner, () => contract.methods.transfer(receiver, tokenId).send({ from: owner }));
+    expect(cost < BigInt(0.2 * Number(UNIQUE)));
+  });
+});
+
+describe('NFT: Substrate calls', () => {
+  itWeb3('Events emitted for mint()', async ({ web3 }) => {
+    const collection = await createCollectionExpectSuccess({
+      mode: { type: 'NFT' },
+    });
+    const alice = privateKey('//Alice');
+
+    const address = collectionIdToAddress(collection);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address);
+
+    let tokenId: number;
+    const events = await recordEvents(contract, async () => {
+      tokenId = await createItemExpectSuccess(alice, collection, 'NFT');
+    });
+
+    expect(events).to.be.deep.equal([
+      {
+        address,
+        event: 'Transfer',
+        args: {
+          from: '0x0000000000000000000000000000000000000000',
+          to: subToEth(alice.address),
+          tokenId: tokenId!.toString(),
+        },
+      },
+    ]);
+  });
+
+  itWeb3('Events emitted for burn()', async ({ web3 }) => {
+    const collection = await createCollectionExpectSuccess({
+      mode: { type: 'NFT' },
+    });
+    const alice = privateKey('//Alice');
+
+    const address = collectionIdToAddress(collection);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address);
+
+    const tokenId = await createItemExpectSuccess(alice, collection, 'NFT');
+    const events = await recordEvents(contract, async () => {
+      await burnItemExpectSuccess(alice, collection, tokenId);
+    });
+
+    expect(events).to.be.deep.equal([
+      {
+        address,
+        event: 'Transfer',
+        args: {
+          from: subToEth(alice.address),
+          to: '0x0000000000000000000000000000000000000000',
+          tokenId: tokenId.toString(),
+        },
+      },
+    ]);
+  });
+
   itWeb3('Events emitted for approve()', async ({ web3 }) => {
     const collection = await createCollectionExpectSuccess({
       mode: { type: 'NFT' },
@@ -282,4 +470,4 @@
       },
     ]);
   });
-});
\ No newline at end of file
+});
modifiedtests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth
--- a/tests/src/eth/nonFungibleAbi.json
+++ b/tests/src/eth/nonFungibleAbi.json
@@ -50,6 +50,12 @@
         "type": "event"
     },
     {
+        "anonymous": true,
+        "inputs": [],
+        "name": "MintingFinished",
+        "type": "event"
+    },
+    {
         "anonymous": false,
         "inputs": [
             {
@@ -89,7 +95,7 @@
         ],
         "name": "approve",
         "outputs": [],
-        "stateMutability": "payable",
+        "stateMutability": "nonpayable",
         "type": "function"
     },
     {
@@ -119,6 +125,32 @@
                 "type": "uint256"
             }
         ],
+        "name": "burn",
+        "outputs": [],
+        "stateMutability": "nonpayable",
+        "type": "function"
+    },
+    {
+        "inputs": [],
+        "name": "finishMinting",
+        "outputs": [
+            {
+                "internalType": "bool",
+                "name": "",
+                "type": "bool"
+            }
+        ],
+        "stateMutability": "nonpayable",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "uint256",
+                "name": "tokenId",
+                "type": "uint256"
+            }
+        ],
         "name": "getApproved",
         "outputs": [
             {
@@ -146,11 +178,77 @@
         "name": "isApprovedForAll",
         "outputs": [
             {
+                "internalType": "address",
+                "name": "",
+                "type": "address"
+            }
+        ],
+        "stateMutability": "view",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "to",
+                "type": "address"
+            },
+            {
+                "internalType": "uint256",
+                "name": "tokenId",
+                "type": "uint256"
+            }
+        ],
+        "name": "mint",
+        "outputs": [
+            {
                 "internalType": "bool",
                 "name": "",
                 "type": "bool"
             }
         ],
+        "stateMutability": "nonpayable",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "to",
+                "type": "address"
+            },
+            {
+                "internalType": "uint256",
+                "name": "tokenId",
+                "type": "uint256"
+            },
+            {
+                "internalType": "string",
+                "name": "tokenURI",
+                "type": "string"
+            }
+        ],
+        "name": "mintWithTokenURI",
+        "outputs": [
+            {
+                "internalType": "bool",
+                "name": "",
+                "type": "bool"
+            }
+        ],
+        "stateMutability": "nonpayable",
+        "type": "function"
+    },
+    {
+        "inputs": [],
+        "name": "mintingFinished",
+        "outputs": [
+            {
+                "internalType": "bool",
+                "name": "",
+                "type": "bool"
+            }
+        ],
         "stateMutability": "view",
         "type": "function"
     },
@@ -160,7 +258,7 @@
         "outputs": [
             {
                 "internalType": "string",
-                "name": "res_name",
+                "name": "",
                 "type": "string"
             }
         ],
@@ -168,6 +266,19 @@
         "type": "function"
     },
     {
+        "inputs": [],
+        "name": "nextTokenId",
+        "outputs": [
+            {
+                "internalType": "uint256",
+                "name": "",
+                "type": "uint256"
+            }
+        ],
+        "stateMutability": "view",
+        "type": "function"
+    },
+    {
         "inputs": [
             {
                 "internalType": "uint256",
@@ -206,7 +317,7 @@
         ],
         "name": "safeTransferFrom",
         "outputs": [],
-        "stateMutability": "payable",
+        "stateMutability": "nonpayable",
         "type": "function"
     },
     {
@@ -232,9 +343,9 @@
                 "type": "bytes"
             }
         ],
-        "name": "safeTransferFrom",
+        "name": "safeTransferFromWithData",
         "outputs": [],
-        "stateMutability": "payable",
+        "stateMutability": "nonpayable",
         "type": "function"
     },
     {
@@ -258,9 +369,9 @@
     {
         "inputs": [
             {
-                "internalType": "bytes4",
-                "name": "interfaceID",
-                "type": "bytes4"
+                "internalType": "uint32",
+                "name": "interfaceId",
+                "type": "uint32"
             }
         ],
         "name": "supportsInterface",
@@ -271,7 +382,7 @@
                 "type": "bool"
             }
         ],
-        "stateMutability": "pure",
+        "stateMutability": "view",
         "type": "function"
     },
     {
@@ -280,7 +391,7 @@
         "outputs": [
             {
                 "internalType": "string",
-                "name": "res_symbol",
+                "name": "",
                 "type": "string"
             }
         ],
@@ -366,11 +477,6 @@
         "inputs": [
             {
                 "internalType": "address",
-                "name": "from",
-                "type": "address"
-            },
-            {
-                "internalType": "address",
                 "name": "to",
                 "type": "address"
             },
@@ -380,15 +486,20 @@
                 "type": "uint256"
             }
         ],
-        "name": "transferFrom",
+        "name": "transfer",
         "outputs": [],
-        "stateMutability": "payable",
+        "stateMutability": "nonpayable",
         "type": "function"
     },
     {
         "inputs": [
             {
                 "internalType": "address",
+                "name": "from",
+                "type": "address"
+            },
+            {
+                "internalType": "address",
                 "name": "to",
                 "type": "address"
             },
@@ -398,9 +509,9 @@
                 "type": "uint256"
             }
         ],
-        "name": "transfer",
+        "name": "transferFrom",
         "outputs": [],
-        "stateMutability": "payable",
+        "stateMutability": "nonpayable",
         "type": "function"
     }
 ]
\ No newline at end of file
addedtests/src/eth/payable.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/payable.test.ts
@@ -0,0 +1,98 @@
+import { expect } from 'chai';
+import privateKey from '../substrate/privateKey';
+import { submitTransactionAsync } from '../substrate/substrate-api';
+import waitNewBlocks from '../substrate/wait-new-blocks';
+import { createEthAccountWithBalance, deployCollector, GAS_ARGS, itWeb3, subToEth } from './util/helpers';
+import {evmToAddress} from '@polkadot/util-crypto';
+import { getGenericResult } from '../util/helpers';
+import { getBalanceSingle, transferBalanceExpectSuccess } from '../substrate/get-balance';
+
+describe('EVM payable contracts', ()=>{
+  itWeb3('Evm contract can receive wei from eth account', async ({api, web3}) => {
+    const deployer = await createEthAccountWithBalance(api, web3);
+    const contract = await deployCollector(web3, deployer);
+
+    await web3.eth.sendTransaction({from: deployer, to: contract.options.address, value: '10000', ...GAS_ARGS});
+    await waitNewBlocks(api, 1);
+
+    expect(await contract.methods.getCollected().call()).to.be.equal('10000');
+  });
+
+  itWeb3('Evm contract can receive wei from substrate account', async ({api, web3}) => {
+    const deployer = await createEthAccountWithBalance(api, web3);
+    const contract = await deployCollector(web3, deployer);
+    const alice = privateKey('//Alice');
+
+    // Transaction fee/value will be payed from subToEth(sender) evm balance,
+    // which is backed by evmToAddress(subToEth(sender)) substrate balance
+    await transferBalanceExpectSuccess(api, alice, evmToAddress(subToEth(alice.address)), '1000000000000');
+
+    {
+      const tx = api.tx.evm.call(
+        subToEth(alice.address),
+        contract.options.address,
+        contract.methods.giveMoney().encodeABI(),
+        '10000',
+        GAS_ARGS.gas,
+        GAS_ARGS.gasPrice,
+        null,
+      );
+      const events = await submitTransactionAsync(alice, tx);
+      const result = getGenericResult(events);
+      expect(result.success).to.be.true;
+    }
+
+    expect(await contract.methods.getCollected().call()).to.be.equal('10000');
+  });
+
+  // We can't handle sending balance to backing storage of evm balance, because evmToAddress operation is irreversible
+  itWeb3('Wei sent directly to backing storage of evm contract balance is unaccounted', async({api, web3}) => {
+    const deployer = await createEthAccountWithBalance(api, web3);
+    const contract = await deployCollector(web3, deployer);
+    const alice = privateKey('//Alice');
+
+    await transferBalanceExpectSuccess(api, alice, evmToAddress(contract.options.address), '10000');
+  
+    expect(await contract.methods.getUnaccounted().call()).to.be.equal('10000');
+  });
+
+  itWeb3('Balance can be retrieved from evm contract', async({api, web3}) => {
+    const FEE_BALANCE = 10n ** 18n;
+    const CONTRACT_BALANCE = 10n ** 14n;
+
+    const deployer = await createEthAccountWithBalance(api, web3);
+    const contract = await deployCollector(web3, deployer);
+    const alice = privateKey('//Alice');
+
+    await web3.eth.sendTransaction({from: deployer, to: contract.options.address, value: CONTRACT_BALANCE.toString(), ...GAS_ARGS});
+    await waitNewBlocks(api, 1);
+
+    const receiver = privateKey(`//Receiver${Date.now()}`);
+
+    // First receive balance on eth balance of bob
+    {
+      const ethReceiver = subToEth(receiver.address);
+      expect(await web3.eth.getBalance(ethReceiver)).to.be.equal('0');
+      await contract.methods.withdraw(ethReceiver).send({from: deployer});
+      expect(await web3.eth.getBalance(ethReceiver)).to.be.equal(CONTRACT_BALANCE.toString());
+    }
+
+    // Some balance is required to pay fee for evm.withdraw call
+    await transferBalanceExpectSuccess(api, alice, receiver.address, FEE_BALANCE.toString());
+
+    // Withdraw balance from eth to substrate
+    {
+      const initialReceiverBalance = await getBalanceSingle(api, receiver.address);
+      const tx = api.tx.evm.withdraw(
+        subToEth(receiver.address),
+        CONTRACT_BALANCE.toString(),
+      );
+      const events = await submitTransactionAsync(receiver, tx);
+      const result = getGenericResult(events);
+      expect(result.success).to.be.true;
+      const finalReceiverBalance = await getBalanceSingle(api, receiver.address);
+
+      expect(finalReceiverBalance > initialReceiverBalance).to.be.true;
+    }
+  });
+});
\ No newline at end of file
addedtests/src/eth/proxy/UniqueFungibleProxy.abidiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/proxy/UniqueFungibleProxy.abi
@@ -0,0 +1 @@
+[{"inputs":[{"internalType":"address","name":"_proxied","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"interfaceId","type":"uint32"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
\ No newline at end of file
addedtests/src/eth/proxy/UniqueFungibleProxy.bindiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/proxy/UniqueFungibleProxy.bin
@@ -0,0 +1 @@
+608060405234801561001057600080fd5b5060405161098038038061098083398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610084565b60006020828403121561006657600080fd5b81516001600160a01b038116811461007d57600080fd5b9392505050565b6108ed806100936000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c806370a082311161006657806370a082311461012757806395d89b411461013a578063a9059cbb14610142578063dd62ed3e14610155578063f4f4b5001461016857600080fd5b806306fdde03146100a3578063095ea7b3146100c157806318160ddd146100e457806323b872dd146100fa578063313ce5671461010d575b600080fd5b6100ab61017b565b6040516100b8919061083e565b60405180910390f35b6100d46100cf3660046106e3565b610200565b60405190151581526020016100b8565b6100ec61028f565b6040519081526020016100b8565b6100d46101083660046106a7565b610316565b6101156103ad565b60405160ff90911681526020016100b8565b6100ec610135366004610659565b610434565b6100ab6104b8565b6100d46101503660046106e3565b6104fc565b6100ec610163366004610674565b610536565b6100d46101763660046107f5565b6105bc565b60008054604080516306fdde0360e01b815290516060936001600160a01b03909316926306fdde039260048082019391829003018186803b1580156101bf57600080fd5b505afa1580156101d3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526101fb919081019061072f565b905090565b6000805460405163095ea7b360e01b81526001600160a01b038581166004830152602482018590529091169063095ea7b3906044015b602060405180830381600087803b15801561025057600080fd5b505af1158015610264573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610288919061070d565b9392505050565b60008060009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156102de57600080fd5b505afa1580156102f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101fb91906107dc565b600080546040516323b872dd60e01b81526001600160a01b038681166004830152858116602483015260448201859052909116906323b872dd90606401602060405180830381600087803b15801561036d57600080fd5b505af1158015610381573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a5919061070d565b949350505050565b60008060009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156103fc57600080fd5b505afa158015610410573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101fb919061081b565b600080546040516370a0823160e01b81526001600160a01b038481166004830152909116906370a082319060240160206040518083038186803b15801561047a57600080fd5b505afa15801561048e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b291906107dc565b92915050565b60008054604080516395d89b4160e01b815290516060936001600160a01b03909316926395d89b419260048082019391829003018186803b1580156101bf57600080fd5b6000805460405163a9059cbb60e01b81526001600160a01b038581166004830152602482018590529091169063a9059cbb90604401610236565b60008054604051636eb1769f60e11b81526001600160a01b03858116600483015284811660248301529091169063dd62ed3e9060440160206040518083038186803b15801561058457600080fd5b505afa158015610598573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061028891906107dc565b6000805460405162f4f4b560e81b815263ffffffff841660048201526001600160a01b039091169063f4f4b5009060240160206040518083038186803b15801561060557600080fd5b505afa158015610619573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b2919061070d565b80356001600160a01b038116811461065457600080fd5b919050565b60006020828403121561066b57600080fd5b6102888261063d565b6000806040838503121561068757600080fd5b6106908361063d565b915061069e6020840161063d565b90509250929050565b6000806000606084860312156106bc57600080fd5b6106c58461063d565b92506106d36020850161063d565b9150604084013590509250925092565b600080604083850312156106f657600080fd5b6106ff8361063d565b946020939093013593505050565b60006020828403121561071f57600080fd5b8151801515811461028857600080fd5b60006020828403121561074157600080fd5b815167ffffffffffffffff8082111561075957600080fd5b818401915084601f83011261076d57600080fd5b81518181111561077f5761077f6108a1565b604051601f8201601f19908116603f011681019083821181831017156107a7576107a76108a1565b816040528281528760208487010111156107c057600080fd5b6107d1836020830160208801610871565b979650505050505050565b6000602082840312156107ee57600080fd5b5051919050565b60006020828403121561080757600080fd5b813563ffffffff8116811461028857600080fd5b60006020828403121561082d57600080fd5b815160ff8116811461028857600080fd5b602081526000825180602084015261085d816040850160208701610871565b601f01601f19169190910160400192915050565b60005b8381101561088c578181015183820152602001610874565b8381111561089b576000848401525b50505050565b634e487b7160e01b600052604160045260246000fdfea2646970667358221220c05e4cb7ab439b86c0b6ac8a84eec6a230b592fa63d1ab2e3a7f1474c27338f364736f6c63430008070033
\ No newline at end of file
addedtests/src/eth/proxy/UniqueFungibleProxy.soldiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/proxy/UniqueFungibleProxy.sol
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: OTHER
+
+pragma solidity >=0.8.0 <0.9.0;
+
+import "../api/UniqueFungible.sol";
+
+contract UniqueFungibleProxy is UniqueFungible {
+    UniqueFungible proxied;
+
+    constructor(address _proxied) UniqueFungible() {
+        proxied = UniqueFungible(_proxied);
+    }
+
+    function name() external view override returns (string memory) {
+        return proxied.name();
+    }
+
+    function symbol() external view override returns (string memory) {
+        return proxied.symbol();
+    }
+
+    function totalSupply() external view override returns (uint256) {
+        return proxied.totalSupply();
+    }
+
+    function supportsInterface(uint32 interfaceId)
+        external
+        view
+        override
+        returns (bool)
+    {
+        return proxied.supportsInterface(interfaceId);
+    }
+
+    function decimals() external view override returns (uint8) {
+        return proxied.decimals();
+    }
+
+    function balanceOf(address owner) external view override returns (uint256) {
+        return proxied.balanceOf(owner);
+    }
+
+    function transfer(address to, uint256 amount)
+        external
+        override
+        returns (bool)
+    {
+        return proxied.transfer(to, amount);
+    }
+
+    function transferFrom(
+        address from,
+        address to,
+        uint256 amount
+    ) external override returns (bool) {
+        return proxied.transferFrom(from, to, amount);
+    }
+
+    function approve(address spender, uint256 amount)
+        external
+        override
+        returns (bool)
+    {
+        return proxied.approve(spender, amount);
+    }
+
+    function allowance(address owner, address spender)
+        external
+        view
+        override
+        returns (uint256)
+    {
+        return proxied.allowance(owner, spender);
+    }
+}
addedtests/src/eth/proxy/UniqueNFTProxy.abidiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/proxy/UniqueNFTProxy.abi
@@ -0,0 +1 @@
+[{"inputs":[{"internalType":"address","name":"_proxied","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[],"name":"MintingFinished","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"approved","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finishMinting","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"tokenUri","type":"string"}],"name":"mintWithTokenURI","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintingFinished","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFromWithData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"interfaceId","type":"uint32"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}]
\ No newline at end of file
addedtests/src/eth/proxy/UniqueNFTProxy.bindiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/proxy/UniqueNFTProxy.bin
@@ -0,0 +1 @@
+608060405234801561001057600080fd5b506040516111e03803806111e083398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610084565b60006020828403121561006657600080fd5b81516001600160a01b038116811461007d57600080fd5b9392505050565b61114d806100936000396000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c806350bb4e7f116100c357806395d89b411161007c57806395d89b41146102a8578063a22cb465146102b0578063a9059cbb146102c3578063c87b56dd146102d6578063e985e9c5146102e9578063f4f4b500146102fc57600080fd5b806350bb4e7f1461024c57806360a116721461025f5780636352211e1461027257806370a082311461028557806375794a3c146102985780637d64bcb4146102a057600080fd5b806323b872dd1161011557806323b872dd146101da5780632f745c59146101ed57806340c10f191461020057806342842e0e1461021357806342966c68146102265780634f6ccce71461023957600080fd5b806305d2035b1461015257806306fdde031461016f578063081812fc14610184578063095ea7b3146101af57806318160ddd146101c4575b600080fd5b61015a61030f565b60405190151581526020015b60405180910390f35b61017761039b565b6040516101669190611043565b610197610192366004610f5b565b61041b565b6040516001600160a01b039091168152602001610166565b6101c26101bd366004610e2e565b61049f565b005b6101cc61050a565b604051908152602001610166565b6101c26101e8366004610d3f565b610591565b6101cc6101fb366004610e2e565b610605565b61015a61020e366004610e2e565b610691565b6101c2610221366004610d3f565b610718565b6101c2610234366004610f5b565b610759565b6101cc610247366004610f5b565b6107ba565b61015a61025a366004610e5a565b610838565b6101c261026d366004610d80565b6108c7565b610197610280366004610f5b565b610936565b6101cc610293366004610ccc565b610968565b6101cc61099b565b61015a6109ea565b610177610a4f565b6101c26102be366004610e00565b610a93565b6101c26102d1366004610e2e565b610acd565b6101776102e4366004610f5b565b610b06565b6101976102f7366004610d06565b610b87565b61015a61030a366004610f8d565b610c0d565b60008060009054906101000a90046001600160a01b03166001600160a01b03166305d2035b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561035e57600080fd5b505afa158015610372573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103969190610ec7565b905090565b60008054604080516306fdde0360e01b815290516060936001600160a01b03909316926306fdde039260048082019391829003018186803b1580156103df57600080fd5b505afa1580156103f3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526103969190810190610ee4565b6000805460405163020604bf60e21b8152600481018490526001600160a01b039091169063081812fc906024015b60206040518083038186803b15801561046157600080fd5b505afa158015610475573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104999190610ce9565b92915050565b60005460405163095ea7b360e01b81526001600160a01b038481166004830152602482018490529091169063095ea7b3906044015b600060405180830381600087803b1580156104ee57600080fd5b505af1158015610502573d6000803e3d6000fd5b505050505050565b60008060009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561055957600080fd5b505afa15801561056d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103969190610f74565b6000546040516323b872dd60e01b81526001600160a01b038581166004830152848116602483015260448201849052909116906323b872dd906064015b600060405180830381600087803b1580156105e857600080fd5b505af11580156105fc573d6000803e3d6000fd5b50505050505050565b60008054604051632f745c5960e01b81526001600160a01b0385811660048301526024820185905290911690632f745c599060440160206040518083038186803b15801561065257600080fd5b505afa158015610666573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068a9190610f74565b9392505050565b600080546040516340c10f1960e01b81526001600160a01b03858116600483015260248201859052909116906340c10f1990604401602060405180830381600087803b1580156106e057600080fd5b505af11580156106f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068a9190610ec7565b600054604051632142170760e11b81526001600160a01b038581166004830152848116602483015260448201849052909116906342842e0e906064016105ce565b600054604051630852cd8d60e31b8152600481018390526001600160a01b03909116906342966c6890602401600060405180830381600087803b15801561079f57600080fd5b505af11580156107b3573d6000803e3d6000fd5b5050505050565b60008054604051634f6ccce760e01b8152600481018490526001600160a01b0390911690634f6ccce7906024015b60206040518083038186803b15801561080057600080fd5b505afa158015610814573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104999190610f74565b600080546040516350bb4e7f60e01b81526001600160a01b03909116906350bb4e7f9061086d9087908790879060040161101c565b602060405180830381600087803b15801561088757600080fd5b505af115801561089b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bf9190610ec7565b949350505050565b6000546040516330508b3960e11b81526001600160a01b03909116906360a11672906108fd908790879087908790600401610fdf565b600060405180830381600087803b15801561091757600080fd5b505af115801561092b573d6000803e3d6000fd5b505050505b50505050565b600080546040516331a9108f60e11b8152600481018490526001600160a01b0390911690636352211e90602401610449565b600080546040516370a0823160e01b81526001600160a01b038481166004830152909116906370a08231906024016107e8565b60008060009054906101000a90046001600160a01b03166001600160a01b03166375794a3c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561055957600080fd5b60008060009054906101000a90046001600160a01b03166001600160a01b0316637d64bcb46040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610a3b57600080fd5b505af1158015610372573d6000803e3d6000fd5b60008054604080516395d89b4160e01b815290516060936001600160a01b03909316926395d89b419260048082019391829003018186803b1580156103df57600080fd5b60005460405163a22cb46560e01b81526001600160a01b03848116600483015283151560248301529091169063a22cb465906044016104d4565b60005460405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490529091169063a9059cbb906044016104d4565b60005460405163c87b56dd60e01b8152600481018390526060916001600160a01b03169063c87b56dd9060240160006040518083038186803b158015610b4b57600080fd5b505afa158015610b5f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526104999190810190610ee4565b6000805460405163e985e9c560e01b81526001600160a01b03858116600483015284811660248301529091169063e985e9c59060440160206040518083038186803b158015610bd557600080fd5b505afa158015610be9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068a9190610ce9565b6000805460405162f4f4b560e81b815263ffffffff841660048201526001600160a01b039091169063f4f4b5009060240160206040518083038186803b158015610c5657600080fd5b505afa158015610c6a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104999190610ec7565b6000610ca1610c9c84611087565b611056565b9050828152838383011115610cb557600080fd5b828260208301376000602084830101529392505050565b600060208284031215610cde57600080fd5b813561068a816110f1565b600060208284031215610cfb57600080fd5b815161068a816110f1565b60008060408385031215610d1957600080fd5b8235610d24816110f1565b91506020830135610d34816110f1565b809150509250929050565b600080600060608486031215610d5457600080fd5b8335610d5f816110f1565b92506020840135610d6f816110f1565b929592945050506040919091013590565b60008060008060808587031215610d9657600080fd5b8435610da1816110f1565b93506020850135610db1816110f1565b925060408501359150606085013567ffffffffffffffff811115610dd457600080fd5b8501601f81018713610de557600080fd5b610df487823560208401610c8e565b91505092959194509250565b60008060408385031215610e1357600080fd5b8235610e1e816110f1565b91506020830135610d3481611109565b60008060408385031215610e4157600080fd5b8235610e4c816110f1565b946020939093013593505050565b600080600060608486031215610e6f57600080fd5b8335610e7a816110f1565b925060208401359150604084013567ffffffffffffffff811115610e9d57600080fd5b8401601f81018613610eae57600080fd5b610ebd86823560208401610c8e565b9150509250925092565b600060208284031215610ed957600080fd5b815161068a81611109565b600060208284031215610ef657600080fd5b815167ffffffffffffffff811115610f0d57600080fd5b8201601f81018413610f1e57600080fd5b8051610f2c610c9c82611087565b818152856020838501011115610f4157600080fd5b610f528260208301602086016110af565b95945050505050565b600060208284031215610f6d57600080fd5b5035919050565b600060208284031215610f8657600080fd5b5051919050565b600060208284031215610f9f57600080fd5b813563ffffffff8116811461068a57600080fd5b60008151808452610fcb8160208601602086016110af565b601f01601f19169290920160200192915050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061101290830184610fb3565b9695505050505050565b60018060a01b0384168152826020820152606060408201526000610f526060830184610fb3565b60208152600061068a6020830184610fb3565b604051601f8201601f1916810167ffffffffffffffff8111828210171561107f5761107f6110db565b604052919050565b600067ffffffffffffffff8211156110a1576110a16110db565b50601f01601f191660200190565b60005b838110156110ca5781810151838201526020016110b2565b838111156109305750506000910152565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461110657600080fd5b50565b801515811461110657600080fdfea2646970667358221220cd50bb20b48b73eddb390585af8699a01cd5f49b79ab50aa532df41df639f36764736f6c63430008070033
\ No newline at end of file
addedtests/src/eth/proxy/UniqueNFTProxy.soldiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/proxy/UniqueNFTProxy.sol
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: OTHER
+
+pragma solidity >=0.8.0 <0.9.0;
+
+import "../api/UniqueNFT.sol";
+
+contract UniqueNFTProxy is UniqueNFT {
+    UniqueNFT proxied;
+
+    constructor(address _proxied) UniqueNFT() {
+        proxied = UniqueNFT(_proxied);
+    }
+
+    function name() external view override returns (string memory) {
+        return proxied.name();
+    }
+
+    function symbol() external view override returns (string memory) {
+        return proxied.symbol();
+    }
+
+    function totalSupply() external view override returns (uint256) {
+        return proxied.totalSupply();
+    }
+
+    function balanceOf(address owner) external view override returns (uint256) {
+        return proxied.balanceOf(owner);
+    }
+
+    function ownerOf(uint256 tokenId) external view override returns (address) {
+        return proxied.ownerOf(tokenId);
+    }
+
+    function safeTransferFromWithData(
+        address from,
+        address to,
+        uint256 tokenId,
+        bytes memory data
+    ) external override {
+        return proxied.safeTransferFromWithData(from, to, tokenId, data);
+    }
+
+    function safeTransferFrom(
+        address from,
+        address to,
+        uint256 tokenId
+    ) external override {
+        return proxied.safeTransferFrom(from, to, tokenId);
+    }
+
+    function transferFrom(
+        address from,
+        address to,
+        uint256 tokenId
+    ) external override {
+        return proxied.transferFrom(from, to, tokenId);
+    }
+
+    function approve(address approved, uint256 tokenId) external override {
+        return proxied.approve(approved, tokenId);
+    }
+
+    function setApprovalForAll(address operator, bool approved)
+        external
+        override
+    {
+        return proxied.setApprovalForAll(operator, approved);
+    }
+
+    function getApproved(uint256 tokenId)
+        external
+        view
+        override
+        returns (address)
+    {
+        return proxied.getApproved(tokenId);
+    }
+
+    function isApprovedForAll(address owner, address operator)
+        external
+        view
+        override
+        returns (address)
+    {
+        return proxied.isApprovedForAll(owner, operator);
+    }
+
+    function burn(uint256 tokenId) external override {
+        return proxied.burn(tokenId);
+    }
+
+    function tokenByIndex(uint256 index)
+        external
+        view
+        override
+        returns (uint256)
+    {
+        return proxied.tokenByIndex(index);
+    }
+
+    function tokenOfOwnerByIndex(address owner, uint256 index)
+        external
+        view
+        override
+        returns (uint256)
+    {
+        return proxied.tokenOfOwnerByIndex(owner, index);
+    }
+
+    function tokenURI(uint256 tokenId)
+        external
+        view
+        override
+        returns (string memory)
+    {
+        return proxied.tokenURI(tokenId);
+    }
+
+    function mintingFinished() external view override returns (bool) {
+        return proxied.mintingFinished();
+    }
+
+    function mint(address to, uint256 tokenId)
+        external
+        override
+        returns (bool)
+    {
+        return proxied.mint(to, tokenId);
+    }
+
+    function mintWithTokenURI(
+        address to,
+        uint256 tokenId,
+        string memory tokenUri
+    ) external override returns (bool) {
+        return proxied.mintWithTokenURI(to, tokenId, tokenUri);
+    }
+
+    function finishMinting() external override returns (bool) {
+        return proxied.finishMinting();
+    }
+
+    function transfer(address to, uint256 tokenId) external override {
+        return proxied.transfer(to, tokenId);
+    }
+
+    function nextTokenId() external view override returns (uint256) {
+        return proxied.nextTokenId();
+    }
+
+    function supportsInterface(uint32 interfaceId)
+        external
+        view
+        override
+        returns (bool)
+    {
+        return proxied.supportsInterface(interfaceId);
+    }
+}
addedtests/src/eth/proxy/fungibleProxy.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/proxy/fungibleProxy.test.ts
@@ -0,0 +1,194 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
+import privateKey from '../../substrate/privateKey';
+import { createCollectionExpectSuccess, createFungibleItemExpectSuccess } from '../../util/helpers';
+import { collectionIdToAddress, createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3, normalizeEvents } from '../util/helpers';
+import fungibleAbi from '../fungibleAbi.json';
+import { expect } from 'chai';
+import { ApiPromise } from '@polkadot/api';
+import Web3 from 'web3';
+import { readFile } from 'fs/promises';
+
+async function proxyWrap(api: ApiPromise, web3: Web3, wrapped: any) {
+  // Proxy owner has no special privilegies, we don't need to reuse them
+  const owner = await createEthAccountWithBalance(api, web3);
+  const Proxy = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/UniqueFungibleProxy.abi`)).toString()), undefined, {
+    from: owner,
+    ...GAS_ARGS,
+  });
+  const proxy = await Proxy.deploy({ data: (await readFile(`${__dirname}/UniqueFungibleProxy.bin`)).toString(), arguments: [wrapped.options.address] }).send({ from: owner });
+  return proxy;
+}
+
+describe('Fungible (Via EVM proxy): Information getting', () => {
+  itWeb3('totalSupply', async ({ api, web3 }) => {
+    const collection = await createCollectionExpectSuccess({
+      name: 'token name',
+      mode: { type: 'Fungible', decimalPoints: 0 },
+    });
+    const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
+  
+    await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { substrate: alice.address });
+
+    const address = collectionIdToAddress(collection);
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    const totalSupply = await contract.methods.totalSupply().call();
+
+    // FIXME: always equals to 0, because this method is not implemented
+    expect(totalSupply).to.equal('0');
+  });
+
+  itWeb3('balanceOf', async ({ api, web3 }) => {
+    const collection = await createCollectionExpectSuccess({
+      name: 'token name',
+      mode: { type: 'Fungible', decimalPoints: 0 },
+    });
+    const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
+
+    await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: caller });
+
+    const address = collectionIdToAddress(collection);
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    const balance = await contract.methods.balanceOf(caller).call();
+
+    expect(balance).to.equal('200');
+  });
+});
+
+describe('Fungible (Via EVM proxy): Plain calls', () => {
+  itWeb3('Can perform approve()', async ({ web3, api }) => {
+    const collection = await createCollectionExpectSuccess({
+      name: 'token name',
+      mode: { type: 'Fungible', decimalPoints: 0 },
+    });
+    const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
+    const spender = createEthAccount(web3);
+
+    const address = collectionIdToAddress(collection);
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: contract.options.address });
+
+    {
+      const result = await contract.methods.approve(spender, 100).send({from: caller});
+      const events = normalizeEvents(result.events);
+
+      expect(events).to.be.deep.equal([
+        {
+          address,
+          event: 'Approval',
+          args: {
+            owner: contract.options.address,
+            spender,
+            value: '100',
+          },
+        },
+      ]);
+    }
+
+    {
+      const allowance = await contract.methods.allowance(contract.options.address, spender).call();
+      expect(+allowance).to.equal(100);
+    }
+  });
+
+  itWeb3('Can perform transferFrom()', async ({ web3, api }) => {
+    const collection = await createCollectionExpectSuccess({
+      name: 'token name',
+      mode: { type: 'Fungible', decimalPoints: 0 },
+    });
+    const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
+    const owner = await createEthAccountWithBalance(api, web3);
+
+    await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: owner });
+
+    const receiver = createEthAccount(web3);
+
+    const address = collectionIdToAddress(collection);
+    const evmCollection = new web3.eth.Contract(fungibleAbi as any, address, { from: caller, ...GAS_ARGS });
+    const contract = await proxyWrap(api, web3, evmCollection);
+
+    await evmCollection.methods.approve(contract.options.address, 100).send({from: owner});
+
+    {
+      const result = await contract.methods.transferFrom(owner, receiver, 49).send({from: caller});
+      const events = normalizeEvents(result.events);
+      expect(events).to.be.deep.equal([
+        {
+          address,
+          event: 'Transfer',
+          args: {
+            from: owner,
+            to: receiver,
+            value: '49',
+          },
+        },
+        {
+          address,
+          event: 'Approval',
+          args: {
+            owner,
+            spender: contract.options.address,
+            value: '51',
+          },
+        },
+      ]);
+    }
+
+    {
+      const balance = await contract.methods.balanceOf(receiver).call();
+      expect(+balance).to.equal(49);
+    }
+
+    {
+      const balance = await contract.methods.balanceOf(owner).call();
+      expect(+balance).to.equal(151);
+    }
+  });
+
+  itWeb3('Can perform transfer()', async ({ web3, api }) => {
+    const collection = await createCollectionExpectSuccess({
+      name: 'token name',
+      mode: { type: 'Fungible', decimalPoints: 0 },
+    });
+    const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
+    const receiver = await createEthAccountWithBalance(api, web3);
+
+    const address = collectionIdToAddress(collection);
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    await createFungibleItemExpectSuccess(alice, collection, { Value: 200n }, { ethereum: contract.options.address });
+
+    {
+      const result = await contract.methods.transfer(receiver, 50).send({ from: caller});
+      const events = normalizeEvents(result.events);
+      expect(events).to.be.deep.equal([
+        {
+          address,
+          event: 'Transfer',
+          args: {
+            from: contract.options.address,
+            to: receiver,
+            value: '50',
+          },
+        },
+      ]);
+    }
+
+    {
+      const balance = await contract.methods.balanceOf(contract.options.address).call();
+      expect(+balance).to.equal(150);
+    }
+
+    {
+      const balance = await contract.methods.balanceOf(receiver).call();
+      expect(+balance).to.equal(50);
+    }
+  });
+});
addedtests/src/eth/proxy/nonFungibleProxy.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/proxy/nonFungibleProxy.test.ts
@@ -0,0 +1,270 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
+import privateKey from '../../substrate/privateKey';
+import { createCollectionExpectSuccess, createItemExpectSuccess } from '../../util/helpers';
+import { collectionIdToAddress, createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3, normalizeEvents } from '../util/helpers';
+import nonFungibleAbi from '../nonFungibleAbi.json';
+import { expect } from 'chai';
+import waitNewBlocks from '../../substrate/wait-new-blocks';
+import { submitTransactionAsync } from '../../substrate/substrate-api';
+import Web3 from 'web3';
+import { readFile } from 'fs/promises';
+import { ApiPromise } from '@polkadot/api';
+
+async function proxyWrap(api: ApiPromise, web3: Web3, wrapped: any) {
+  // Proxy owner has no special privilegies, we don't need to reuse them
+  const owner = await createEthAccountWithBalance(api, web3);
+  const Proxy = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/UniqueNFTProxy.abi`)).toString()), undefined, {
+    from: owner,
+    ...GAS_ARGS,
+  });
+  const proxy = await Proxy.deploy({ data: (await readFile(`${__dirname}/UniqueNFTProxy.bin`)).toString(), arguments: [wrapped.options.address] }).send({ from: owner });
+  return proxy;
+}
+
+describe('NFT (Via EVM proxy): Information getting', () => {
+  itWeb3('totalSupply', async ({ api, web3 }) => {
+    const collection = await createCollectionExpectSuccess({
+      mode: { type: 'NFT' },
+    });
+    const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
+
+    await createItemExpectSuccess(alice, collection, 'NFT', { substrate: alice.address });
+
+    const address = collectionIdToAddress(collection);
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    const totalSupply = await contract.methods.totalSupply().call();
+
+    // FIXME: always equals to 0, because this method is not implemented
+    expect(totalSupply).to.equal('0');
+  });
+
+  itWeb3('balanceOf', async ({ api, web3 }) => {
+    const collection = await createCollectionExpectSuccess({
+      mode: { type: 'NFT' },
+    });
+    const alice = privateKey('//Alice');
+
+    const caller = await createEthAccountWithBalance(api, web3);
+    await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });
+    await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });
+    await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });
+
+    const address = collectionIdToAddress(collection);
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    const balance = await contract.methods.balanceOf(caller).call();
+
+    expect(balance).to.equal('3');
+  });
+
+  itWeb3('ownerOf', async ({ api, web3 }) => {
+    const collection = await createCollectionExpectSuccess({
+      mode: { type: 'NFT' },
+    });
+    const alice = privateKey('//Alice');
+
+    const caller = await createEthAccountWithBalance(api, web3);
+    const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });
+
+    const address = collectionIdToAddress(collection);
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    const owner = await contract.methods.ownerOf(tokenId).call();
+
+    expect(owner).to.equal(caller);
+  });
+});
+
+describe('NFT (Via EVM proxy): Plain calls', () => {
+  itWeb3('Can perform mint()', async ({ web3, api }) => {
+    const collection = await createCollectionExpectSuccess({
+      mode: { type: 'NFT' },
+    });
+    const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
+    const receiver = createEthAccount(web3);
+
+    const address = collectionIdToAddress(collection);
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, { from: caller, ...GAS_ARGS }));
+
+    const changeAdminTx = api.tx.nft.addCollectionAdmin(collection, { ethereum: contract.options.address });
+    await submitTransactionAsync(alice, changeAdminTx);
+
+    {
+      const nextTokenId = await contract.methods.nextTokenId().call();
+      expect(nextTokenId).to.be.equal('1');
+      console.log('Before mint');
+      const result = await contract.methods.mintWithTokenURI(
+        receiver,
+        nextTokenId,
+        'Test URI',
+      ).send({ from: caller });
+      console.log('After mint');
+      const events = normalizeEvents(result.events);
+
+      expect(events).to.be.deep.equal([
+        {
+          address,
+          event: 'Transfer',
+          args: {
+            from: '0x0000000000000000000000000000000000000000',
+            to: receiver,
+            tokenId: nextTokenId,
+          },
+        },
+      ]);
+
+      await waitNewBlocks(api, 1);
+      expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
+    }
+  });
+
+  itWeb3('Can perform burn()', async ({ web3, api }) => {
+    const collection = await createCollectionExpectSuccess({
+      mode: {type: 'NFT'},
+    });
+    const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
+    
+    const address = collectionIdToAddress(collection);
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: contract.options.address });
+
+    const changeAdminTx = api.tx.nft.addCollectionAdmin(collection, { ethereum: contract.options.address });
+    await submitTransactionAsync(alice, changeAdminTx);
+
+    {
+      const result = await contract.methods.burn(tokenId).send({ from: caller });
+      const events = normalizeEvents(result.events);
+      
+      expect(events).to.be.deep.equal([
+        {
+          address,
+          event: 'Transfer',
+          args: {
+            from: contract.options.address,
+            to: '0x0000000000000000000000000000000000000000',
+            tokenId: tokenId.toString(),
+          },
+        },
+      ]);
+    }
+  });
+
+  itWeb3('Can perform approve()', async ({ web3, api }) => {
+    const collection = await createCollectionExpectSuccess({
+      mode: { type: 'NFT' },
+    });
+    const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
+    const spender = createEthAccount(web3);
+
+    const address = collectionIdToAddress(collection);
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address));
+    const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: contract.options.address });
+
+    {
+      const result = await contract.methods.approve(spender, tokenId).send({ from: caller, gas: '0x1000000', gasPrice: '0x01' });
+      const events = normalizeEvents(result.events);
+
+      expect(events).to.be.deep.equal([
+        {
+          address,
+          event: 'Approval',
+          args: {
+            owner: contract.options.address,
+            approved: spender,
+            tokenId: tokenId.toString(),
+          },
+        },
+      ]);
+    }
+  });
+
+  itWeb3('Can perform transferFrom()', async ({ web3, api }) => {
+    const collection = await createCollectionExpectSuccess({
+      mode: { type: 'NFT' },
+    });
+    const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
+    const owner = await createEthAccountWithBalance(api, web3);
+
+    const receiver = createEthAccount(web3);
+
+    const address = collectionIdToAddress(collection);
+    const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, address, { from: caller, ...GAS_ARGS });
+    const contract = await proxyWrap(api, web3, evmCollection);
+    const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });
+
+    await evmCollection.methods.approve(contract.options.address, tokenId).send({ from: owner });
+
+    {
+      const result = await contract.methods.transferFrom(owner, receiver, tokenId).send({ from: caller });
+      const events = normalizeEvents(result.events);
+      expect(events).to.be.deep.equal([
+        {
+          address,
+          event: 'Transfer',
+          args: {
+            from: owner,
+            to: receiver,
+            tokenId: tokenId.toString(),
+          },
+        },
+      ]);
+    }
+
+    {
+      const balance = await contract.methods.balanceOf(receiver).call();
+      expect(+balance).to.equal(1);
+    }
+
+    {
+      const balance = await contract.methods.balanceOf(contract.options.address).call();
+      expect(+balance).to.equal(0);
+    }
+  });
+
+  itWeb3('Can perform transfer()', async ({ web3, api }) => {
+    const collection = await createCollectionExpectSuccess({
+      mode: { type: 'NFT' },
+    });
+    const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
+    const receiver = createEthAccount(web3);
+
+    const address = collectionIdToAddress(collection);
+    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
+    const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: contract.options.address });
+
+    {
+      const result = await contract.methods.transfer(receiver, tokenId).send({ from: caller });
+      await waitNewBlocks(api, 1);
+      const events = normalizeEvents(result.events);
+      expect(events).to.be.deep.equal([
+        {
+          address,
+          event: 'Transfer',
+          args: {
+            from: contract.options.address,
+            to: receiver,
+            tokenId: tokenId.toString(),
+          },
+        },
+      ]);
+    }
+
+    {
+      const balance = await contract.methods.balanceOf(contract.options.address).call();
+      expect(+balance).to.equal(0);
+    }
+
+    {
+      const balance = await contract.methods.balanceOf(receiver).call();
+      expect(+balance).to.equal(1);
+    }
+  });
+});
addedtests/src/eth/sponsoring.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/sponsoring.test.ts
@@ -0,0 +1,88 @@
+import { expect } from 'chai';
+import privateKey from '../substrate/privateKey';
+import waitNewBlocks from '../substrate/wait-new-blocks';
+import { contractHelpers, createEthAccount, createEthAccountWithBalance, deployCollector, deployFlipper, itWeb3, transferBalanceToEth, usingWeb3Http } from './util/helpers';
+
+describe('EVM sponsoring', () => {
+  itWeb3('Fee is deducted from contract if sponsoring is enabled', async ({api, web3}) => {
+    await usingWeb3Http(async web3Http => {
+      const alice = privateKey('//Alice');
+
+      const owner = await createEthAccountWithBalance(api, web3Http);
+      const caller = createEthAccount(web3Http);
+      const originalCallerBalance = await web3.eth.getBalance(caller);
+      expect(originalCallerBalance).to.be.equal('0');
+
+      const flipper = await deployFlipper(web3Http, owner);
+      await waitNewBlocks(api, 1);
+      
+      const helpers = contractHelpers(web3Http, owner);
+      await helpers.methods.toggleAllowlist(flipper.options.address, true).send({ from: owner });
+      await waitNewBlocks(api, 1);
+      await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({ from: owner });
+      await waitNewBlocks(api, 1);
+
+      expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;
+      await helpers.methods.toggleSponsoring(flipper.options.address, true).send({from: owner});
+      await waitNewBlocks(api, 1);
+      await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});
+      await waitNewBlocks(api, 1);
+      expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;
+
+      await transferBalanceToEth(api, alice, flipper.options.address);
+      await waitNewBlocks(api, 2);
+
+      const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);
+      expect(originalFlipperBalance).to.be.not.equal('0');
+
+      await flipper.methods.flip().send({ from: caller });
+      await waitNewBlocks(api, 1);
+      expect(await flipper.methods.getValue().call()).to.be.true;
+
+      // Balance should be taken from flipper instead of caller
+      expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance);
+      expect(await web3.eth.getBalance(flipper.options.address)).to.be.not.equals(originalFlipperBalance);
+    });
+  });
+  itWeb3('...but this doesn\'t applies to payable value', async ({api, web3}) => {
+    await usingWeb3Http(async web3Http => {
+      const alice = privateKey('//Alice');
+
+      const owner = await createEthAccountWithBalance(api, web3Http);
+      const caller = await createEthAccountWithBalance(api, web3Http);
+      await waitNewBlocks(api, 1);
+      const originalCallerBalance = await web3.eth.getBalance(caller);
+      expect(originalCallerBalance).to.be.not.equal('0');
+
+      const collector = await deployCollector(web3Http, owner);
+      await waitNewBlocks(api, 1);
+     
+      const helpers = contractHelpers(web3Http, owner);
+      await helpers.methods.toggleAllowlist(collector.options.address, true).send({ from: owner });
+      await waitNewBlocks(api, 1);
+      await helpers.methods.toggleAllowed(collector.options.address, caller, true).send({ from: owner });
+      await waitNewBlocks(api, 1);
+
+      expect(await helpers.methods.sponsoringEnabled(collector.options.address).call()).to.be.false;
+      await helpers.methods.toggleSponsoring(collector.options.address, true).send({ from: owner });
+      await waitNewBlocks(api, 1);
+      await helpers.methods.setSponsoringRateLimit(collector.options.address, 0).send({ from: owner });
+      await waitNewBlocks(api, 1);
+      expect(await helpers.methods.sponsoringEnabled(collector.options.address).call()).to.be.true;
+
+      await transferBalanceToEth(api, alice, collector.options.address);
+      await waitNewBlocks(api, 2);
+
+      const originalCollectorBalance = await web3.eth.getBalance(collector.options.address);
+      expect(originalCollectorBalance).to.be.not.equal('0');
+
+      await collector.methods.giveMoney().send({ from: caller, value: '10000' });
+      await waitNewBlocks(api, 1);
+
+      // Balance will be taken from both caller (value) and from collector (fee)
+      expect(await web3.eth.getBalance(caller)).to.be.equals((BigInt(originalCallerBalance) - 10000n).toString());
+      expect(await web3.eth.getBalance(collector.options.address)).to.be.not.equals(originalCollectorBalance);
+      expect(await collector.methods.getCollected().call()).to.be.equal('10000');
+    });
+  });
+});
\ No newline at end of file
addedtests/src/eth/util/contractHelpersAbi.jsondiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/util/contractHelpersAbi.json
@@ -0,0 +1,160 @@
+[
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "contract",
+                "type": "address"
+            }
+        ],
+        "name": "allowlistEnabled",
+        "outputs": [
+            {
+                "internalType": "bool",
+                "name": "",
+                "type": "bool"
+            }
+        ],
+        "stateMutability": "view",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "target",
+                "type": "address"
+            },
+            {
+                "internalType": "address",
+                "name": "caller",
+                "type": "address"
+            }
+        ],
+        "name": "allowed",
+        "outputs": [
+            {
+                "internalType": "bool",
+                "name": "",
+                "type": "bool"
+            }
+        ],
+        "stateMutability": "view",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "target",
+                "type": "address"
+            }
+        ],
+        "name": "contractOwner",
+        "outputs": [
+            {
+                "internalType": "address",
+                "name": "",
+                "type": "address"
+            }
+        ],
+        "stateMutability": "view",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "target",
+                "type": "address"
+            }
+        ],
+        "name": "sponsoringEnabled",
+        "outputs": [
+            {
+                "internalType": "bool",
+                "name": "",
+                "type": "bool"
+            }
+        ],
+        "stateMutability": "view",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "target",
+                "type": "address"
+            },
+            {
+                "internalType": "address",
+                "name": "user",
+                "type": "address"
+            },
+            {
+                "internalType": "bool",
+                "name": "isAllowed",
+                "type": "bool"
+            }
+        ],
+        "name": "toggleAllowed",
+        "outputs": [],
+        "stateMutability": "nonpayable",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "target",
+                "type": "address"
+            },
+            {
+                "internalType": "bool",
+                "name": "enabled",
+                "type": "bool"
+            }
+        ],
+        "name": "toggleAllowlist",
+        "outputs": [],
+        "stateMutability": "nonpayable",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "target",
+                "type": "address"
+            },
+            {
+                "internalType": "bool",
+                "name": "enabled",
+                "type": "bool"
+            }
+        ],
+        "name": "toggleSponsoring",
+        "outputs": [],
+        "stateMutability": "nonpayable",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "target",
+                "type": "address"
+            },
+            {
+                "internalType": "uint32",
+                "name": "limit",
+                "type": "uint32"
+            }
+        ],
+        "name": "setSponsoringRateLimit",
+        "outputs": [],
+        "stateMutability": "nonpayable",
+        "type": "function"
+    }
+]
\ No newline at end of file
addedtests/src/eth/util/helpers.d.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/util/helpers.d.ts
@@ -0,0 +1 @@
+declare module 'solc';
\ No newline at end of file
modifiedtests/src/eth/util/helpers.tsdiffbeforeafterboth
--- a/tests/src/eth/util/helpers.ts
+++ b/tests/src/eth/util/helpers.ts
@@ -3,6 +3,9 @@
 // file 'LICENSE', which is part of this source code package.
 //
 
+// eslint-disable-next-line @typescript-eslint/triple-slash-reference
+/// <reference path="helpers.d.ts" />
+
 import { ApiPromise } from '@polkadot/api';
 import { addressToEvm, evmToAddress } from '@polkadot/util-crypto';
 import Web3 from 'web3';
@@ -10,13 +13,21 @@
 import { IKeyringPair } from '@polkadot/types/types';
 import { expect } from 'chai';
 import { getGenericResult } from '../../util/helpers';
+import * as solc from 'solc';
+import config from '../../config';
+import privateKey from '../../substrate/privateKey';
+import contractHelpersAbi from './contractHelpersAbi.json';
+import getBalance from '../../substrate/get-balance';
+import waitNewBlocks from '../../substrate/wait-new-blocks';
+
+export const GAS_ARGS = { gas: 0x1000000, gasPrice: '0x01' };
 
 let web3Connected = false;
 export async function usingWeb3<T>(cb: (web3: Web3) => Promise<T> | T): Promise<T> {
   if (web3Connected) throw new Error('do not nest usingWeb3 calls');
   web3Connected = true;
 
-  const provider = new Web3.providers.WebsocketProvider('http://localhost:9944');
+  const provider = new Web3.providers.WebsocketProvider(config.substrateUrl);
   const web3 = new Web3(provider);
 
   try {
@@ -28,6 +39,16 @@
   }
 }
 
+/**
+ * @deprecated Web3 update solved issue with deployment over ws provider
+ */
+export async function usingWeb3Http<T>(cb: (web3: Web3) => Promise<T> | T): Promise<T> {
+  const provider = new Web3.providers.HttpProvider(config.frontierUrl);
+  const web3: Web3 = new Web3(provider);
+
+  return await cb(web3);
+}
+
 export function collectionIdToAddress(address: number): string {
   if (address >= 0xffffffff || address < 0) throw new Error('id overflow');
   const buf = Buffer.from([0x17, 0xc4, 0xe6, 0x45, 0x3c, 0xc4, 0x9a, 0xaa, 0xae, 0xac, 0xa8, 0x94, 0xe6, 0xd9, 0x68, 0x3e,
@@ -45,7 +66,15 @@
   return account.address;
 }
 
-export async function transferBalanceToEth(api: ApiPromise, source: IKeyringPair, target: string, amount: number) {
+export async function createEthAccountWithBalance(api: ApiPromise, web3: Web3) {
+  const alice = privateKey('//Alice');
+  const account = createEthAccount(web3);
+  await transferBalanceToEth(api, alice, account);
+
+  return account;
+}
+
+export async function transferBalanceToEth(api: ApiPromise, source: IKeyringPair, target: string, amount = 999999999999999) {
   const tx = api.tx.balances.transfer(evmToAddress(target), amount);
   const events = await submitTransactionAsync(source, tx);
   const result = getGenericResult(events);
@@ -114,8 +143,130 @@
   return normalizeEvents(out);
 }
 
+export function subToEthLowercase(eth: string): string {
+  const bytes = addressToEvm(eth);
+  return '0x' + Buffer.from(bytes).toString('hex');
+}
+
 export function subToEth(eth: string): string {
-  const bytes = addressToEvm(eth);
-  const string = '0x' + Buffer.from(bytes).toString('hex');
-  return Web3.utils.toChecksumAddress(string);
+  return Web3.utils.toChecksumAddress(subToEthLowercase(eth));
+}
+
+export function compileContract(name: string, src: string) {
+  const out = JSON.parse(solc.compile(JSON.stringify({
+    language: 'Solidity',
+    sources: {
+      [`${name}.sol`]: {
+        content: `
+          // SPDX-License-Identifier: UNLICENSED
+          pragma solidity ^0.8.6;
+
+          ${src}
+        `,
+      },
+    },
+    settings: {
+      outputSelection: {
+        '*': {
+          '*': ['*'],
+        },
+      },
+    },
+  }))).contracts[`${name}.sol`][name];
+
+  return {
+    abi: out.abi,
+    object: '0x' + out.evm.bytecode.object,
+  };
+}
+
+export async function deployFlipper(web3: Web3, deployer: string) {
+  const compiled = compileContract('Flipper', `
+    contract Flipper {
+      bool value = false;
+      function flip() public {
+        value = !value;
+      }
+      function getValue() public view returns (bool) {
+        return value;
+      }
+    }
+  `);
+  const Flipper = new web3.eth.Contract(compiled.abi, undefined, {
+    data: compiled.object,
+    from: deployer,
+    ...GAS_ARGS,
+  });
+  const flipper = await Flipper.deploy({ data: compiled.object }).send({from: deployer});
+
+  return flipper;
+}
+
+export async function deployCollector(web3: Web3, deployer: string) {
+  const compiled = compileContract('Collector', `
+    contract Collector {
+      uint256 collected;
+      fallback() external payable {
+        giveMoney();
+      }
+      function giveMoney() public payable {
+        collected += msg.value;
+      }
+      function getCollected() public view returns (uint256) {
+        return collected;
+      }
+      function getUnaccounted() public view returns (uint256) {
+        return address(this).balance - collected;
+      }
+
+      function withdraw(address payable target) public {
+        target.transfer(collected);
+        collected = 0;
+      }
+    }
+  `);
+  const Collector = new web3.eth.Contract(compiled.abi, undefined, {
+    data: compiled.object,
+    from: deployer,
+    ...GAS_ARGS,
+  });
+  const collector = await Collector.deploy({ data: compiled.object }).send({ from: deployer });
+
+  return collector;
+}
+
+export function contractHelpers(web3: Web3, caller: string) {
+  return new web3.eth.Contract(contractHelpersAbi as any, '0x842899ECF380553E8a4de75bF534cdf6fBF64049', {from: caller, ...GAS_ARGS});
+}
+
+export async function executeEthTxOnSub(api: ApiPromise, from: IKeyringPair, to: any, mkTx: (methods: any) => any, { value = 0 }: {value?: bigint | number} = { }) {
+  const tx = api.tx.evm.call(
+    subToEth(from.address),
+    to.options.address,
+    mkTx(to.methods).encodeABI(),
+    value,
+    GAS_ARGS.gas,
+    GAS_ARGS.gasPrice,
+    null,
+  );
+  const events = await submitTransactionAsync(from, tx);
+  expect(events.find(({ event: {section, method}})=>section === 'evm' && method === 'Executed')).to.be.not.undefined;
+}
+
+export async function ethBalanceViaSub(api: ApiPromise, address: string): Promise<bigint> {
+  return (await getBalance(api, [evmToAddress(address)]))[0];
+}
+
+export async function recordEthFee(api: ApiPromise, user: string, call: () => Promise<any>): Promise<bigint> {
+  const before = await ethBalanceViaSub(api, user);
+
+  await call();
+  await waitNewBlocks(api, 1);
+
+  const after = await ethBalanceViaSub(api, user);
+
+  // Can't use .to.be.less, because chai doesn't supports bigint
+  expect(after < before).to.be.true;
+
+  return before - after;
 }
\ No newline at end of file
modifiedtests/src/pallet-presence.test.tsdiffbeforeafterboth
--- a/tests/src/pallet-presence.test.ts
+++ b/tests/src/pallet-presence.test.ts
@@ -23,6 +23,9 @@
   'parachainsystem',
   'parachaininfo',
   'evm',
+  'evmcodersubstrate',
+  'evmcontracthelpers',
+  'evmtransactionpayment',
   'ethereum',
   'xcmpqueue',
   'polkadotxcm',
@@ -59,7 +62,7 @@
   });
   it('No extra pallets are included', async () => {
     await usingApi(async api => {
-      expect(getModuleNames(api).length).to.be.equal(requiredPallets.length + consensusPallets.length);
+      expect(getModuleNames(api).sort()).to.be.deep.equal([...requiredPallets, ...consensusPallets].sort());
     });
   });
 });
modifiedtests/src/removeCollectionAdmin.test.tsdiffbeforeafterboth
--- a/tests/src/removeCollectionAdmin.test.ts
+++ b/tests/src/removeCollectionAdmin.test.ts
@@ -37,6 +37,33 @@
     });
   });
 
+  it('Remove collection admin by admin.', async () => {
+    await usingApi(async (api: ApiPromise) => {
+      const collectionId = await createCollectionExpectSuccess();
+      const Alice = privateKey('//Alice');
+      const Bob = privateKey('//Bob');
+      const Charlie = privateKey('//Charlie');
+      const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();
+      expect(collection.Owner).to.be.deep.eq(Alice.address);
+      // first - add collection admin Bob
+      const addAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));
+      await submitTransactionAsync(Alice, addAdminTx);
+
+      const addAdminTx2 = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Charlie.address));
+      await submitTransactionAsync(Alice, addAdminTx2);
+
+      const adminListAfterAddAdmin: any = (await api.query.nft.adminList(collectionId)).toJSON();
+      expect(adminListAfterAddAdmin).to.be.deep.contains(normalizeAccountId(Bob.address));
+
+      // then remove bob from admins of collection
+      const removeAdminTx = api.tx.nft.removeCollectionAdmin(collectionId, normalizeAccountId(Bob.address));
+      await submitTransactionAsync(Charlie, removeAdminTx);
+
+      const adminListAfterRemoveAdmin: any = (await api.query.nft.adminList(collectionId)).toJSON;
+      expect(adminListAfterRemoveAdmin).not.to.be.deep.contains(normalizeAccountId(Bob.address));
+    });
+  });
+
   it('Remove admin from collection that has no admins', async () => {
     await usingApi(async (api: ApiPromise) => {
       const Alice = privateKey('//Alice');
@@ -83,4 +110,22 @@
       await createCollectionExpectSuccess();
     });
   });
+
+  it('Regular user Can\'t remove collection admin', async () => {
+    await usingApi(async (api: ApiPromise) => {
+      const collectionId = await createCollectionExpectSuccess();
+      const Alice = privateKey('//Alice');
+      const Bob = privateKey('//Bob');
+      const Charlie = privateKey('//Charlie');
+
+      const addAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(Bob.address));
+      await submitTransactionAsync(Alice, addAdminTx);
+
+      const changeOwnerTx = api.tx.nft.removeCollectionAdmin(collectionId, normalizeAccountId(Bob.address));
+      await expect(submitTransactionExpectFailAsync(Charlie, changeOwnerTx)).to.be.rejected;
+
+      // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
+      await createCollectionExpectSuccess();
+    });
+  });
 });
modifiedtests/src/removeCollectionSponsor.test.tsdiffbeforeafterboth
--- a/tests/src/removeCollectionSponsor.test.ts
+++ b/tests/src/removeCollectionSponsor.test.ts
@@ -17,6 +17,7 @@
   removeCollectionSponsorExpectSuccess,
   removeCollectionSponsorExpectFailure,
   normalizeAccountId,
+  addCollectionAdminExpectSuccess,
 } from './util/helpers';
 import { Keyring } from '@polkadot/api';
 import { IKeyringPair } from '@polkadot/types/types';
@@ -104,6 +105,19 @@
     await removeCollectionSponsorExpectFailure(collectionId);
   });
 
+  it('(!negative test!) Remove sponsor for a collection with collection admin permissions', async () => {
+    const collectionId = await createCollectionExpectSuccess();
+    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+    await addCollectionAdminExpectSuccess(alice, collectionId, bob);
+    await removeCollectionSponsorExpectFailure(collectionId, '//Bob');
+  });
+
+  it('(!negative test!) Remove sponsor for a collection by regular user', async () => {
+    const collectionId = await createCollectionExpectSuccess();
+    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+    await removeCollectionSponsorExpectFailure(collectionId, '//Bob');
+  });
+
   it('(!negative test!) Remove sponsor in a destroyed collection', async () => {
     const collectionId = await createCollectionExpectSuccess();
     await setCollectionSponsorExpectSuccess(collectionId, bob.address);
modifiedtests/src/removeFromWhiteList.test.tsdiffbeforeafterboth
--- a/tests/src/removeFromWhiteList.test.ts
+++ b/tests/src/removeFromWhiteList.test.ts
@@ -17,6 +17,7 @@
   removeFromWhiteListExpectFailure,
   disableWhiteListExpectSuccess,
   normalizeAccountId,
+  addCollectionAdminExpectSuccess,
 } from './util/helpers';
 import { IKeyringPair } from '@polkadot/types/types';
 import privateKey from './substrate/privateKey';
@@ -88,3 +89,48 @@
     });
   });
 });
+
+describe('Integration Test removeFromWhiteList with collection admin permissions', () => {
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+  let charlie: IKeyringPair;
+
+  before(async () => {
+    await usingApi(async () => {
+      alice = privateKey('//Alice');
+      bob = privateKey('//Bob');
+      charlie = privateKey('//Charlie');
+    });
+  });
+
+  it('ensure address is not in whitelist after removal', async () => {
+    await usingApi(async () => {
+      const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });
+      await enableWhiteListExpectSuccess(alice, collectionId);
+      await addCollectionAdminExpectSuccess(alice, collectionId, bob);
+      await addToWhiteListExpectSuccess(alice, collectionId, charlie.address);
+      await removeFromWhiteListExpectSuccess(bob, collectionId, normalizeAccountId(charlie.address));
+      expect(await isWhitelisted(collectionId, charlie.address)).to.be.false;
+    });
+  });
+
+  it('Collection admin allowed to remove from whitelist with unset whitelist status', async () => {
+    await usingApi(async () => {
+      const collectionWithoutWhitelistId = await createCollectionExpectSuccess();
+      await enableWhiteListExpectSuccess(alice, collectionWithoutWhitelistId);
+      await addCollectionAdminExpectSuccess(alice, collectionWithoutWhitelistId, bob);
+      await addToWhiteListExpectSuccess(alice, collectionWithoutWhitelistId, charlie.address);
+      await disableWhiteListExpectSuccess(alice, collectionWithoutWhitelistId);
+      await removeFromWhiteListExpectSuccess(bob, collectionWithoutWhitelistId, normalizeAccountId(charlie.address));
+    });
+  });
+
+  it('Regular user can`t remove from whitelist', async () => {
+    await usingApi(async () => {
+      const collectionWithoutWhitelistId = await createCollectionExpectSuccess();
+      await enableWhiteListExpectSuccess(alice, collectionWithoutWhitelistId);
+      await addToWhiteListExpectSuccess(alice, collectionWithoutWhitelistId, charlie.address);
+      await removeFromWhiteListExpectFailure(bob, collectionWithoutWhitelistId, normalizeAccountId(charlie.address));
+    });
+  });
+});
\ No newline at end of file
addedtests/src/setChainLimits.test.tsdiffbeforeafterboth

no changes

modifiedtests/src/setCollectionLimits.test.tsdiffbeforeafterboth
--- a/tests/src/setCollectionLimits.test.ts
+++ b/tests/src/setCollectionLimits.test.ts
@@ -16,6 +16,7 @@
   getDetailedCollectionInfo,
   setCollectionLimitsExpectFailure,
   setCollectionLimitsExpectSuccess,
+  addCollectionAdminExpectSuccess,
 } from './util/helpers';
 
 chai.use(chaiAsPromised);
@@ -150,6 +151,21 @@
       await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;
     });
   });
+  it('execute setCollectionLimits from admin collection', async () => {
+    await addCollectionAdminExpectSuccess(alice, collectionIdForTesting, bob);
+    await usingApi(async (api: ApiPromise) => {
+      tx = api.tx.nft.setCollectionLimits(
+        collectionIdForTesting,
+        {
+          accountTokenOwnershipLimit,
+          sponsoredDataSize,
+          sponsoredMintSize,
+          tokenLimit,
+        },
+      );
+      await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;
+    });
+  });
   it('execute setCollectionLimits with incorrect limits', async () => {
     await usingApi(async (api: ApiPromise) => {
       tx = api.tx.nft.setCollectionLimits(
modifiedtests/src/setCollectionSponsor.test.tsdiffbeforeafterboth
--- a/tests/src/setCollectionSponsor.test.ts
+++ b/tests/src/setCollectionSponsor.test.ts
@@ -6,19 +6,27 @@
 import chai from 'chai';
 import chaiAsPromised from 'chai-as-promised';
 import { default as usingApi } from './substrate/substrate-api';
-import { createCollectionExpectSuccess, setCollectionSponsorExpectSuccess, destroyCollectionExpectSuccess, setCollectionSponsorExpectFailure } from './util/helpers';
+import { createCollectionExpectSuccess, 
+  setCollectionSponsorExpectSuccess, 
+  destroyCollectionExpectSuccess, 
+  setCollectionSponsorExpectFailure,
+  addCollectionAdminExpectSuccess,
+} from './util/helpers';
 import { Keyring } from '@polkadot/api';
 import { IKeyringPair } from '@polkadot/types/types';
 
 chai.use(chaiAsPromised);
 
+let alice: IKeyringPair;
 let bob: IKeyringPair;
+let charlie: IKeyringPair;
 
 describe('integration test: ext. setCollectionSponsor():', () => {
 
   before(async () => {
     await usingApi(async () => {
       const keyring = new Keyring({ type: 'sr25519' });
+      alice = keyring.addFromUri('//Alice');
       bob = keyring.addFromUri('//Bob');
     });
   });
@@ -55,7 +63,9 @@
   before(async () => {
     await usingApi(async () => {
       const keyring = new Keyring({ type: 'sr25519' });
+      alice = keyring.addFromUri('//Alice');
       bob = keyring.addFromUri('//Bob');
+      charlie = keyring.addFromUri('//Charlie');
     });
   });
 
@@ -77,4 +87,9 @@
     await destroyCollectionExpectSuccess(collectionId);
     await setCollectionSponsorExpectFailure(collectionId, bob.address);
   });
+  it('(!negative test!) Collection admin add sponsor', async () => {
+    const collectionId = await createCollectionExpectSuccess();
+    await addCollectionAdminExpectSuccess(alice, collectionId, bob);
+    await setCollectionSponsorExpectFailure(collectionId, charlie.address, '//Bob');
+  });
 });
modifiedtests/src/setConstOnChainSchema.test.tsdiffbeforeafterboth
--- a/tests/src/setConstOnChainSchema.test.ts
+++ b/tests/src/setConstOnChainSchema.test.ts
@@ -11,6 +11,7 @@
 import {
   createCollectionExpectSuccess,
   destroyCollectionExpectSuccess,
+  addCollectionAdminExpectSuccess,
 } from './util/helpers';
 
 chai.use(chaiAsPromised);
@@ -43,6 +44,17 @@
     });
   });
 
+  it('Collection admin can set the scheme', async () => {
+    await usingApi(async (api) => {
+      const collectionId = await createCollectionExpectSuccess();
+      const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();
+      expect(collection.Owner).to.be.eq(Alice.address);
+      await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);
+      const setShema = api.tx.nft.setConstOnChainSchema(collectionId, Shema);
+      await submitTransactionAsync(Bob, setShema);
+    });
+  });
+
   it('Checking collection data using the ConstOnChainSchema parameter', async () => {
     await usingApi(async (api) => {
       const collectionId = await createCollectionExpectSuccess();
modifiedtests/src/setMintPermission.test.tsdiffbeforeafterboth
--- a/tests/src/setMintPermission.test.ts
+++ b/tests/src/setMintPermission.test.ts
@@ -16,6 +16,7 @@
   findNotExistingCollection,
   setMintPermissionExpectFailure,
   setMintPermissionExpectSuccess,
+  addCollectionAdminExpectSuccess,
 } from './util/helpers';
 
 describe('Integration Test setMintPermission', () => {
@@ -91,6 +92,14 @@
     await setMintPermissionExpectFailure(bob, collectionId, true);
   });
 
+  it('Collection admin fails on set', async () => {
+    await usingApi(async () => {
+      const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });
+      await addCollectionAdminExpectSuccess(alice, collectionId, bob);
+      await setMintPermissionExpectFailure(bob, collectionId, true);
+    });
+  });
+
   it('ensure non-white-listed non-privileged address can\'t mint tokens', async () => {
     await usingApi(async () => {
       const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });
modifiedtests/src/setOffchainSchema.test.tsdiffbeforeafterboth
--- a/tests/src/setOffchainSchema.test.ts
+++ b/tests/src/setOffchainSchema.test.ts
@@ -15,6 +15,7 @@
   queryCollectionExpectSuccess,
   setOffchainSchemaExpectFailure,
   setOffchainSchemaExpectSuccess,
+  addCollectionAdminExpectSuccess,
 } from './util/helpers';
 
 chai.use(chaiAsPromised);
@@ -24,10 +25,12 @@
 
 describe('Integration Test setOffchainSchema', () => {
   let alice: IKeyringPair;
+  let bob: IKeyringPair;
 
   before(async () => {
     await usingApi(async () => {
       alice = privateKey('//Alice');
+      bob = privateKey('//Bob');
     });
   });
 
@@ -38,6 +41,15 @@
 
     expect(collection.OffchainSchema).to.be.equal('0x' + Buffer.from(DATA).toString('hex'));
   });
+
+  it('execute setOffchainSchema (collection admin), verify data was set', async () => {
+    const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });
+    await addCollectionAdminExpectSuccess(alice, collectionId, bob);
+    await setOffchainSchemaExpectSuccess(bob, collectionId, DATA);
+    const collection = await queryCollectionExpectSuccess(collectionId);
+
+    expect(collection.OffchainSchema).to.be.equal('0x' + Buffer.from(DATA).toString('hex'));
+  });
 });
 
 describe('Negative Integration Test setOffchainSchema', () => {
modifiedtests/src/setPublicAccessMode.test.tsdiffbeforeafterboth
--- a/tests/src/setPublicAccessMode.test.ts
+++ b/tests/src/setPublicAccessMode.test.ts
@@ -18,6 +18,7 @@
   enablePublicMintingExpectSuccess,
   enableWhiteListExpectSuccess,
   normalizeAccountId,
+  addCollectionAdminExpectSuccess,
 } from './util/helpers';
 
 chai.use(chaiAsPromised);
@@ -92,3 +93,21 @@
     });
   });
 });
+
+describe('Negative Integration Test ext. collection admin setPublicAccessMode(): ', () => {
+  before(async () => {
+    await usingApi(async () => {
+      Alice = privateKey('//Alice');
+      Bob = privateKey('//Bob');
+    });
+  });
+  it('setPublicAccessMode by collection admin', async () => {
+    await usingApi(async (api: ApiPromise) => {
+      // tslint:disable-next-line: no-bitwise
+      const collectionId = await createCollectionExpectSuccess();
+      await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);
+      const tx = api.tx.nft.setPublicAccessMode(collectionId, 'WhiteList');
+      await expect(submitTransactionExpectFailAsync(Bob, tx)).to.be.rejected;
+    });
+  });
+});
modifiedtests/src/setSchemaVersion.test.tsdiffbeforeafterboth
--- a/tests/src/setSchemaVersion.test.ts
+++ b/tests/src/setSchemaVersion.test.ts
@@ -16,12 +16,15 @@
   getCreatedCollectionCount,
   getCreateItemResult,
   getDetailedCollectionInfo,
+  addCollectionAdminExpectSuccess,
 } from './util/helpers';
 
 chai.use(chaiAsPromised);
 const expect = chai.expect;
 
 let alice: IKeyringPair;
+let bob: IKeyringPair;
+let charlie: IKeyringPair;
 let collectionIdForTesting: number;
 
 /*
@@ -66,11 +69,37 @@
       expect(collectionInfo ? collectionInfo.SchemaVersion.toString() : '').to.be.equal('Unique');
     });
   });
+});
+
+describe('Collection admin setSchemaVersion positive', () => {
+  let tx;
+  before(async () => {
+    await usingApi(async () => {
+      const keyring = new Keyring({ type: 'sr25519' });
+      alice = keyring.addFromUri('//Alice');
+      bob = keyring.addFromUri('//Bob');
+      await addCollectionAdminExpectSuccess(alice, collectionIdForTesting, bob);
+    });
+  });
+  it('execute setSchemaVersion with image url and unique ', async () => {
+    await usingApi(async (api: ApiPromise) => {
+      tx = api.tx.nft.setSchemaVersion(collectionIdForTesting, 'Unique');
+      const events = await submitTransactionAsync(bob, tx);
+      const result = getCreateItemResult(events);
+      const collectionInfo = await getDetailedCollectionInfo(api, collectionIdForTesting) as ICollectionInterface;
+      // tslint:disable-next-line:no-unused-expression
+      expect(result.success).to.be.true;
+      // tslint:disable-next-line:no-unused-expression
+      expect(collectionInfo).to.be.exist;
+      // tslint:disable-next-line:no-unused-expression
+      expect(collectionInfo ? collectionInfo.SchemaVersion.toString() : '').to.be.equal('Unique');
+    });
+  });
 
   it('validate schema version with just entered data', async () => {
     await usingApi(async (api: ApiPromise) => {
       tx = api.tx.nft.setSchemaVersion(collectionIdForTesting, 'ImageURL');
-      const events = await submitTransactionAsync(alice, tx);
+      const events = await submitTransactionAsync(bob, tx);
       const result = getCreateItemResult(events);
       const collectionInfo = await getDetailedCollectionInfo(api, collectionIdForTesting) as ICollectionInterface;
       // tslint:disable-next-line:no-unused-expression
@@ -89,6 +118,7 @@
     await usingApi(async () => {
       const keyring = new Keyring({ type: 'sr25519' });
       alice = keyring.addFromUri('//Alice');
+      charlie = keyring.addFromUri('//Charlie');
     });
   });
   it('execute setSchemaVersion for not exists collection', async () => {
@@ -99,7 +129,6 @@
       await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
     });
   });
-
   it('execute setSchemaVersion with not correct schema version', async () => {
     await usingApi(async (api: ApiPromise) => {
       const consoleError = console.error;
@@ -115,7 +144,6 @@
       }
     });
   });
-
   it('execute setSchemaVersion for deleted collection', async () => {
     await usingApi(async (api: ApiPromise) => {
       await destroyCollectionExpectSuccess(collectionIdForTesting);
@@ -123,4 +151,10 @@
       await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
     });
   });
+  it('Regular user can`t execute setSchemaVersion with image url and unique ', async () => {
+    await usingApi(async (api: ApiPromise) => {
+      tx = api.tx.nft.setSchemaVersion(collectionIdForTesting, 'Unique');
+      await expect(submitTransactionAsync(charlie, tx)).to.be.rejected;
+    });
+  });
 });
modifiedtests/src/setVariableMetaData.test.tsdiffbeforeafterboth
--- a/tests/src/setVariableMetaData.test.ts
+++ b/tests/src/setVariableMetaData.test.ts
@@ -16,6 +16,7 @@
   findNotExistingCollection,
   setVariableMetaDataExpectFailure,
   setVariableMetaDataExpectSuccess,
+  addCollectionAdminExpectSuccess,
 } from './util/helpers';
 
 chai.use(chaiAsPromised);
@@ -48,6 +49,36 @@
   });
 });
 
+describe('Integration Test collection admin setVariableMetaData', () => {
+  const data = [1, 2, 254, 255];
+
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+  let collectionId: number;
+  let tokenId: number;
+  before(async () => {
+    await usingApi(async () => {
+      alice = privateKey('//Alice');
+      bob = privateKey('//Bob');
+      collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });
+      tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
+      await addCollectionAdminExpectSuccess(alice, collectionId, bob);
+    });
+  });
+
+  it('execute setVariableMetaData', async () => {
+    await setVariableMetaDataExpectSuccess(bob, collectionId, tokenId, data);
+  });
+
+  it('verify data was set', async () => {
+    await usingApi(async api => {
+      const item: any = (await api.query.nft.nftItemList(collectionId, tokenId) as any).unwrap();
+
+      expect(Array.from(item.VariableData)).to.deep.equal(Array.from(data));
+    });
+  });
+});
+
 describe('Negative Integration Test setVariableMetaData', () => {
   const data = [1];
 
modifiedtests/src/setVariableOnChainSchema.test.tsdiffbeforeafterboth
--- a/tests/src/setVariableOnChainSchema.test.ts
+++ b/tests/src/setVariableOnChainSchema.test.ts
@@ -11,6 +11,7 @@
 import {
   createCollectionExpectSuccess,
   destroyCollectionExpectSuccess,
+  addCollectionAdminExpectSuccess,
 } from './util/helpers';
 
 chai.use(chaiAsPromised);
@@ -55,6 +56,32 @@
   });
 });
 
+describe('Integration Test ext. collection admin setVariableOnChainSchema()', () => {
+
+  it('Run extrinsic with parameters of the collection id, set the scheme', async () => {
+    await usingApi(async (api) => {
+      const collectionId = await createCollectionExpectSuccess();
+      const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();
+      expect(collection.Owner).to.be.eq(Alice.address);
+      await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);
+      const setSchema = api.tx.nft.setVariableOnChainSchema(collectionId, Schema);
+      await submitTransactionAsync(Bob, setSchema);
+    });
+  });
+
+  it('Checking collection data using the setVariableOnChainSchema parameter', async () => {
+    await usingApi(async (api) => {
+      const collectionId = await createCollectionExpectSuccess();
+      await addCollectionAdminExpectSuccess(Alice, collectionId, Bob);
+      const setSchema = api.tx.nft.setVariableOnChainSchema(collectionId, Schema);
+      await submitTransactionAsync(Bob, setSchema);
+      const collection: any = (await api.query.nft.collectionById(collectionId)).toJSON();
+      expect(collection.VariableOnChainSchema.toString()).to.be.eq(Schema);
+
+    });
+  });
+});
+
 describe('Negative Integration Test ext. setVariableOnChainSchema()', () => {
 
   it('Set a non-existent collection', async () => {
modifiedtests/src/substrate/get-balance.tsdiffbeforeafterboth
--- a/tests/src/substrate/get-balance.ts
+++ b/tests/src/substrate/get-balance.ts
@@ -6,9 +6,24 @@
 import { ApiPromise } from '@polkadot/api';
 import {AccountInfo} from '@polkadot/types/interfaces/system';
 import promisifySubstrate from './promisify-substrate';
+import { IKeyringPair } from '@polkadot/types/types';
+import { submitTransactionAsync } from './substrate-api';
+import { getGenericResult } from '../util/helpers';
+import { expect } from 'chai';
 
 export default async function getBalance(api: ApiPromise, accounts: string[]): Promise<Array<bigint>> {
   const balance = promisifySubstrate(api, (acc: string[]) => api.query.system.account.multi(acc));
   const responce = await balance(accounts) as unknown as AccountInfo[];
   return responce.map((r) => r.data.free.toBigInt().valueOf());
 }
+
+export async function getBalanceSingle(api: ApiPromise, account: string): Promise<bigint> {
+  return (await getBalance(api, [account]))[0];
+}
+
+export async function transferBalanceExpectSuccess(api: ApiPromise, from: IKeyringPair, to: string, amount: bigint | string) {
+  const tx = api.tx.balances.transfer(to, amount);
+  const events = await submitTransactionAsync(from, tx);
+  const result = getGenericResult(events);
+  expect(result.success).to.be.true;
+}
\ No newline at end of file
modifiedtests/src/substrate/substrate-api.tsdiffbeforeafterboth
--- a/tests/src/substrate/substrate-api.ts
+++ b/tests/src/substrate/substrate-api.ts
@@ -37,6 +37,10 @@
   const consoleWarn = console.warn;
 
   const outFn = (message: string) => {
+    if (typeof message !== 'string') {
+      consoleErr(message);
+      return;
+    }
     if (!message.includes('StorageChangeSet:: WebSocket is not connected') && 
         !message.includes('2021-') &&
         !message.includes('StorageChangeSet:: Normal connection closure'))
modifiedtests/src/transfer.test.tsdiffbeforeafterboth
--- a/tests/src/transfer.test.ts
+++ b/tests/src/transfer.test.ts
@@ -18,6 +18,7 @@
   getCreateItemResult,
   transferExpectFailure,
   transferExpectSuccess,
+  addCollectionAdminExpectSuccess,
 } from './util/helpers';
 
 let Alice: IKeyringPair;
@@ -89,6 +90,35 @@
       );
     });
   });
+
+  it('Collection admin can transfer owned token', async () => {
+    await usingApi(async () => {
+      const Alice = privateKey('//Alice');
+      const Bob = privateKey('//Bob');
+      // nft
+      const nftCollectionId = await createCollectionExpectSuccess();
+      await addCollectionAdminExpectSuccess(Alice, nftCollectionId, Bob);
+      const newNftTokenId = await createItemExpectSuccess(Bob, nftCollectionId, 'NFT', Bob.address);
+      await transferExpectSuccess(nftCollectionId, newNftTokenId, Bob, Alice, 1, 'NFT');
+      // fungible
+      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+      await addCollectionAdminExpectSuccess(Alice, fungibleCollectionId, Bob);
+      const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible', Bob.address);
+      await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, Bob, Alice, 1, 'Fungible');
+      // reFungible
+      const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+      await addCollectionAdminExpectSuccess(Alice, reFungibleCollectionId, Bob);
+      const newReFungibleTokenId = await createItemExpectSuccess(Bob, reFungibleCollectionId, 'ReFungible', Bob.address);
+      await transferExpectSuccess(
+        reFungibleCollectionId,
+        newReFungibleTokenId,
+        Bob,
+        Alice,
+        100,
+        'ReFungible',
+      );
+    });
+  });
 });
 
 describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
modifiedtests/src/util/helpers.tsdiffbeforeafterboth
--- a/tests/src/util/helpers.ts
+++ b/tests/src/util/helpers.ts
@@ -53,6 +53,11 @@
 
 export const U128_MAX = (1n << 128n) - 1n;
 
+const MICROUNIQUE = 1_000_000_000n;
+const MILLIUNIQUE = 1_000n * MICROUNIQUE;
+const CENTIUNIQUE = 10n * MILLIUNIQUE;
+export const UNIQUE = 100n * CENTIUNIQUE;
+
 type GenericResult = {
   success: boolean,
 };
@@ -95,6 +100,23 @@
   checkMsgSysMethod: string;
 }
 
+export interface IFungibleTokenDataType {
+  Value: number;
+}
+
+export interface IChainLimits {
+  CollectionNumbersLimit: number;
+	AccountTokenOwnershipLimit: number;
+	CollectionsAdminsLimit: number;
+	CustomDataLimit: number;
+	NftSponsorTransferTimeout: number;
+	FungibleSponsorTransferTimeout: number;
+	RefungibleSponsorTransferTimeout: number;
+	OffchainSchemaLimit: number;
+	VariableOnChainSchemaLimit: number;
+	ConstOnChainSchemaLimit: number;
+}
+
 export interface IReFungibleTokenDataType {
   Owner: IReFungibleOwner[];
   ConstData: number[];
@@ -414,13 +436,13 @@
   });
 }
 
-export async function setCollectionSponsorExpectSuccess(collectionId: number, sponsor: string) {
+export async function setCollectionSponsorExpectSuccess(collectionId: number, sponsor: string, sender = '//Alice') {
   await usingApi(async (api) => {
 
     // Run the transaction
-    const alicePrivateKey = privateKey('//Alice');
+    const senderPrivateKey = privateKey(sender);
     const tx = api.tx.nft.setCollectionSponsor(collectionId, sponsor);
-    const events = await submitTransactionAsync(alicePrivateKey, tx);
+    const events = await submitTransactionAsync(senderPrivateKey, tx);
     const result = getGenericResult(events);
 
     // Get the collection
@@ -434,11 +456,11 @@
   });
 }
 
-export async function removeCollectionSponsorExpectSuccess(collectionId: number) {
+export async function removeCollectionSponsorExpectSuccess(collectionId: number, sender = '//Alice') {
   await usingApi(async (api) => {
 
     // Run the transaction
-    const alicePrivateKey = privateKey('//Alice');
+    const alicePrivateKey = privateKey(sender);
     const tx = api.tx.nft.removeCollectionSponsor(collectionId);
     const events = await submitTransactionAsync(alicePrivateKey, tx);
     const result = getGenericResult(events);
@@ -452,11 +474,11 @@
   });
 }
 
-export async function removeCollectionSponsorExpectFailure(collectionId: number) {
+export async function removeCollectionSponsorExpectFailure(collectionId: number, senderSeed = '//Alice') {
   await usingApi(async (api) => {
 
     // Run the transaction
-    const alicePrivateKey = privateKey('//Alice');
+    const alicePrivateKey = privateKey(senderSeed);
     const tx = api.tx.nft.removeCollectionSponsor(collectionId);
     await expect(submitTransactionExpectFailAsync(alicePrivateKey, tx)).to.be.rejected;
   });
@@ -545,6 +567,30 @@
   });
 }
 
+export async function setTransferFlagExpectSuccess(sender: IKeyringPair, collectionId: number, enabled: boolean) {
+
+  await usingApi(async (api) => {
+
+    const tx = api.tx.nft.setTransfersEnabledFlag (collectionId, enabled);
+    const events = await submitTransactionAsync(sender, tx);
+    const result = getGenericResult(events);
+
+    expect(result.success).to.be.true;
+  }); 
+}
+
+export async function setTransferFlagExpectFailure(sender: IKeyringPair, collectionId: number, enabled: boolean) {
+
+  await usingApi(async (api) => {
+
+    const tx = api.tx.nft.setTransfersEnabledFlag (collectionId, enabled);
+    const events = await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected;
+    const result = getGenericResult(events);
+
+    expect(result.success).to.be.false;
+  }); 
+}
+
 export async function setContractSponsoringRateLimitExpectSuccess(sender: IKeyringPair, contractAddress: AccountId | string, rateLimit: number) {
   await usingApi(async (api) => {
     const tx = api.tx.nft.setContractSponsoringRateLimit(contractAddress, rateLimit);
@@ -763,6 +809,15 @@
   });
 }
 
+export async function addCollectionAdminExpectSuccess(sender: IKeyringPair, collectionId: number, address: IKeyringPair) {
+  await usingApi(async (api) => {
+    const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, normalizeAccountId(address.address));
+    const events = await submitTransactionAsync(sender, changeAdminTx);
+    const result = getCreateCollectionResult(events);
+    expect(result.success).to.be.true;
+  });
+}
+
 export async function
 scheduleTransferExpectSuccess(
   collectionId: number,
@@ -978,10 +1033,31 @@
   });
 }
 
+export async function setPublicAccessModeExpectFail(
+  sender: IKeyringPair, collectionId: number,
+  accessMode: 'Normal' | 'WhiteList',
+) {
+  await usingApi(async (api) => {
+
+    // Run the transaction
+    const tx = api.tx.nft.setPublicAccessMode(collectionId, accessMode);
+    const events = await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected;
+    const result = getGenericResult(events);
+
+    // What to expect
+    // tslint:disable-next-line:no-unused-expression
+    expect(result.success).to.be.false;
+  });
+}
+
 export async function enableWhiteListExpectSuccess(sender: IKeyringPair, collectionId: number) {
   await setPublicAccessModeExpectSuccess(sender, collectionId, 'WhiteList');
 }
 
+export async function enableWhiteListExpectFail(sender: IKeyringPair, collectionId: number) {
+  await setPublicAccessModeExpectFail(sender, collectionId, 'WhiteList');
+}
+
 export async function disableWhiteListExpectSuccess(sender: IKeyringPair, collectionId: number) {
   await setPublicAccessModeExpectSuccess(sender, collectionId, 'Normal');
 }
@@ -1028,6 +1104,17 @@
   });
 }
 
+export async function setChainLimitsExpectFailure(sender: IKeyringPair, limits: IChainLimits) {
+  await usingApi(async (api) => {
+    // Run the transaction
+    const tx = api.tx.nft.setChainLimits(limits);
+    const events = await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected;
+    const result = getCreateCollectionResult(events);
+    // tslint:disable-next-line:no-unused-expression
+    expect(result.success).to.be.false;
+  });
+}
+
 export async function isWhitelisted(collectionId: number, address: string) {
   let whitelisted = false;
   await usingApi(async (api) => {
@@ -1058,6 +1145,19 @@
   });
 }
 
+export async function addToWhiteListExpectFail(sender: IKeyringPair, collectionId: number, address: string | AccountId) {
+  await usingApi(async (api) => {
+    // Run the transaction
+    const tx = api.tx.nft.addToWhiteList(collectionId, normalizeAccountId(address));
+    const events = await expect(submitTransactionAsync(sender, tx)).to.be.rejected;
+    const result = getGenericResult(events);
+
+    // What to expect
+    // tslint:disable-next-line:no-unused-expression
+    expect(result.success).to.be.false;
+  });
+}
+
 export async function removeFromWhiteListExpectSuccess(sender: IKeyringPair, collectionId: number, address: CrossAccountId) {
   await usingApi(async (api) => {
     // Run the transaction
@@ -1099,3 +1199,7 @@
     return (await api.query.nft.collectionById(collectionId)).toJSON() as unknown as ICollectionInterface;
   });
 }
+
+export async function queryNftOwner(api: ApiPromise, collectionId: number, tokenId: number): Promise<CrossAccountId> {
+  return normalizeAccountId((await api.query.nft.nftItemList(collectionId, tokenId) as any).toJSON().Owner);
+}
\ No newline at end of file
modifiedtests/yarn.lockdiffbeforeafterboth
--- a/tests/yarn.lock
+++ b/tests/yarn.lock
@@ -2,10 +2,10 @@
 # yarn lockfile v1
 
 
-"@babel/cli@^7.14.5":
-  version "7.14.5"
-  resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.14.5.tgz#9551b194f02360729de6060785bbdcce52c69f0a"
-  integrity sha512-poegjhRvXHWO0EAsnYajwYZuqcz7gyfxwfaecUESxDujrqOivf3zrjFbub8IJkrqEaz3fvJWh001EzxBub54fg==
+"@babel/cli@^7.14.8":
+  version "7.14.8"
+  resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.14.8.tgz#fac73c0e2328a8af9fd3560c06b096bfa3730933"
+  integrity sha512-lcy6Lymft9Rpfqmrqdd4oTDdUx9ZwaAhAfywVrHG4771Pa6PPT0danJ1kDHBXYqh4HHSmIdA+nlmfxfxSDPtBg==
   dependencies:
     commander "^4.0.1"
     convert-source-map "^1.1.0"
@@ -42,7 +42,12 @@
   resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.7.tgz#7b047d7a3a89a67d2258dc61f604f098f1bc7e08"
   integrity sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==
 
-"@babel/core@^7.1.0", "@babel/core@^7.14.6", "@babel/core@^7.7.2", "@babel/core@^7.7.5":
+"@babel/compat-data@^7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176"
+  integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==
+
+"@babel/core@^7.1.0", "@babel/core@^7.7.2", "@babel/core@^7.7.5":
   version "7.14.6"
   resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.6.tgz#e0814ec1a950032ff16c13a2721de39a8416fcab"
   integrity sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==
@@ -63,6 +68,27 @@
     semver "^6.3.0"
     source-map "^0.5.0"
 
+"@babel/core@^7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.15.0.tgz#749e57c68778b73ad8082775561f67f5196aafa8"
+  integrity sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw==
+  dependencies:
+    "@babel/code-frame" "^7.14.5"
+    "@babel/generator" "^7.15.0"
+    "@babel/helper-compilation-targets" "^7.15.0"
+    "@babel/helper-module-transforms" "^7.15.0"
+    "@babel/helpers" "^7.14.8"
+    "@babel/parser" "^7.15.0"
+    "@babel/template" "^7.14.5"
+    "@babel/traverse" "^7.15.0"
+    "@babel/types" "^7.15.0"
+    convert-source-map "^1.7.0"
+    debug "^4.1.0"
+    gensync "^1.0.0-beta.2"
+    json5 "^2.1.2"
+    semver "^6.3.0"
+    source-map "^0.5.0"
+
 "@babel/generator@^7.14.5", "@babel/generator@^7.7.2":
   version "7.14.5"
   resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.5.tgz#848d7b9f031caca9d0cd0af01b063f226f52d785"
@@ -72,6 +98,15 @@
     jsesc "^2.5.1"
     source-map "^0.5.0"
 
+"@babel/generator@^7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.0.tgz#a7d0c172e0d814974bad5aa77ace543b97917f15"
+  integrity sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ==
+  dependencies:
+    "@babel/types" "^7.15.0"
+    jsesc "^2.5.1"
+    source-map "^0.5.0"
+
 "@babel/helper-annotate-as-pure@^7.0.0", "@babel/helper-annotate-as-pure@^7.14.5":
   version "7.14.5"
   resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz#7bf478ec3b71726d56a8ca5775b046fc29879e61"
@@ -97,7 +132,17 @@
     browserslist "^4.16.6"
     semver "^6.3.0"
 
-"@babel/helper-create-class-features-plugin@^7.14.5", "@babel/helper-create-class-features-plugin@^7.14.6":
+"@babel/helper-compilation-targets@^7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz#973df8cbd025515f3ff25db0c05efc704fa79818"
+  integrity sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A==
+  dependencies:
+    "@babel/compat-data" "^7.15.0"
+    "@babel/helper-validator-option" "^7.14.5"
+    browserslist "^4.16.6"
+    semver "^6.3.0"
+
+"@babel/helper-create-class-features-plugin@^7.14.5":
   version "7.14.6"
   resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.6.tgz#f114469b6c06f8b5c59c6c4e74621f5085362542"
   integrity sha512-Z6gsfGofTxH/+LQXqYEK45kxmcensbzmk/oi8DmaQytlQCgqNZt9XQF8iqlI/SeXWVjaMNxvYvzaYw+kh42mDg==
@@ -109,6 +154,18 @@
     "@babel/helper-replace-supers" "^7.14.5"
     "@babel/helper-split-export-declaration" "^7.14.5"
 
+"@babel/helper-create-class-features-plugin@^7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.0.tgz#c9a137a4d137b2d0e2c649acf536d7ba1a76c0f7"
+  integrity sha512-MdmDXgvTIi4heDVX/e9EFfeGpugqm9fobBVg/iioE8kueXrOHdRDe36FAY7SnE9xXLVeYCoJR/gdrBEIHRC83Q==
+  dependencies:
+    "@babel/helper-annotate-as-pure" "^7.14.5"
+    "@babel/helper-function-name" "^7.14.5"
+    "@babel/helper-member-expression-to-functions" "^7.15.0"
+    "@babel/helper-optimise-call-expression" "^7.14.5"
+    "@babel/helper-replace-supers" "^7.15.0"
+    "@babel/helper-split-export-declaration" "^7.14.5"
+
 "@babel/helper-create-regexp-features-plugin@^7.14.5":
   version "7.14.5"
   resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz#c7d5ac5e9cf621c26057722fb7a8a4c5889358c4"
@@ -168,6 +225,13 @@
   dependencies:
     "@babel/types" "^7.14.5"
 
+"@babel/helper-member-expression-to-functions@^7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz#0ddaf5299c8179f27f37327936553e9bba60990b"
+  integrity sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg==
+  dependencies:
+    "@babel/types" "^7.15.0"
+
 "@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.14.5":
   version "7.14.5"
   resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz#6d1a44df6a38c957aa7c312da076429f11b422f3"
@@ -189,6 +253,20 @@
     "@babel/traverse" "^7.14.5"
     "@babel/types" "^7.14.5"
 
+"@babel/helper-module-transforms@^7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz#679275581ea056373eddbe360e1419ef23783b08"
+  integrity sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg==
+  dependencies:
+    "@babel/helper-module-imports" "^7.14.5"
+    "@babel/helper-replace-supers" "^7.15.0"
+    "@babel/helper-simple-access" "^7.14.8"
+    "@babel/helper-split-export-declaration" "^7.14.5"
+    "@babel/helper-validator-identifier" "^7.14.9"
+    "@babel/template" "^7.14.5"
+    "@babel/traverse" "^7.15.0"
+    "@babel/types" "^7.15.0"
+
 "@babel/helper-optimise-call-expression@^7.14.5":
   version "7.14.5"
   resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz#f27395a8619e0665b3f0364cddb41c25d71b499c"
@@ -220,6 +298,16 @@
     "@babel/traverse" "^7.14.5"
     "@babel/types" "^7.14.5"
 
+"@babel/helper-replace-supers@^7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz#ace07708f5bf746bf2e6ba99572cce79b5d4e7f4"
+  integrity sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA==
+  dependencies:
+    "@babel/helper-member-expression-to-functions" "^7.15.0"
+    "@babel/helper-optimise-call-expression" "^7.14.5"
+    "@babel/traverse" "^7.15.0"
+    "@babel/types" "^7.15.0"
+
 "@babel/helper-simple-access@^7.14.5":
   version "7.14.5"
   resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz#66ea85cf53ba0b4e588ba77fc813f53abcaa41c4"
@@ -227,6 +315,13 @@
   dependencies:
     "@babel/types" "^7.14.5"
 
+"@babel/helper-simple-access@^7.14.8":
+  version "7.14.8"
+  resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz#82e1fec0644a7e775c74d305f212c39f8fe73924"
+  integrity sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg==
+  dependencies:
+    "@babel/types" "^7.14.8"
+
 "@babel/helper-skip-transparent-expression-wrappers@^7.14.5":
   version "7.14.5"
   resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.14.5.tgz#96f486ac050ca9f44b009fbe5b7d394cab3a0ee4"
@@ -246,6 +341,11 @@
   resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8"
   integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==
 
+"@babel/helper-validator-identifier@^7.14.9":
+  version "7.14.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48"
+  integrity sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==
+
 "@babel/helper-validator-option@^7.14.5":
   version "7.14.5"
   resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3"
@@ -270,6 +370,15 @@
     "@babel/traverse" "^7.14.5"
     "@babel/types" "^7.14.5"
 
+"@babel/helpers@^7.14.8":
+  version "7.15.3"
+  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.15.3.tgz#c96838b752b95dcd525b4e741ed40bb1dc2a1357"
+  integrity sha512-HwJiz52XaS96lX+28Tnbu31VeFSQJGOeKHJeaEPQlTl7PnlhFElWPj8tUXtqFIzeN86XxXoBr+WFAyK2PPVz6g==
+  dependencies:
+    "@babel/template" "^7.14.5"
+    "@babel/traverse" "^7.15.0"
+    "@babel/types" "^7.15.0"
+
 "@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5":
   version "7.14.5"
   resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9"
@@ -284,6 +393,11 @@
   resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.6.tgz#d85cc68ca3cac84eae384c06f032921f5227f4b2"
   integrity sha512-oG0ej7efjEXxb4UgE+klVx+3j4MVo+A2vCzm7OUN4CLo6WhQ+vSOD2yJ8m7B+DghObxtLxt3EfgMWpq+AsWehQ==
 
+"@babel/parser@^7.15.0":
+  version "7.15.3"
+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.3.tgz#3416d9bea748052cfcb63dbcc27368105b1ed862"
+  integrity sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==
+
 "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.14.5":
   version "7.14.5"
   resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz#4b467302e1548ed3b1be43beae2cc9cf45e0bb7e"
@@ -293,10 +407,10 @@
     "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5"
     "@babel/plugin-proposal-optional-chaining" "^7.14.5"
 
-"@babel/plugin-proposal-async-generator-functions@^7.14.7":
-  version "7.14.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.7.tgz#784a48c3d8ed073f65adcf30b57bcbf6c8119ace"
-  integrity sha512-RK8Wj7lXLY3bqei69/cc25gwS5puEc3dknoFPFbqfy3XxYQBQFvu4ioWpafMBAB+L9NyptQK4nMOa5Xz16og8Q==
+"@babel/plugin-proposal-async-generator-functions@^7.14.9":
+  version "7.14.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.9.tgz#7028dc4fa21dc199bbacf98b39bab1267d0eaf9a"
+  integrity sha512-d1lnh+ZnKrFKwtTYdw320+sQWCTwgkB9fmUhNXRADA4akR6wLjaruSGnIEUjpt9HCOwTr4ynFTKu19b7rFRpmw==
   dependencies:
     "@babel/helper-plugin-utils" "^7.14.5"
     "@babel/helper-remap-async-to-generator" "^7.14.5"
@@ -577,10 +691,10 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.14.5"
 
-"@babel/plugin-transform-classes@^7.14.5":
-  version "7.14.5"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.5.tgz#0e98e82097b38550b03b483f9b51a78de0acb2cf"
-  integrity sha512-J4VxKAMykM06K/64z9rwiL6xnBHgB1+FVspqvlgCdwD1KUbQNfszeKVVOMh59w3sztHYIZDgnhOC4WbdEfHFDA==
+"@babel/plugin-transform-classes@^7.14.9":
+  version "7.14.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.9.tgz#2a391ffb1e5292710b00f2e2c210e1435e7d449f"
+  integrity sha512-NfZpTcxU3foGWbl4wxmZ35mTsYJy8oQocbeIMoDAGGFarAmSQlL+LWMkDx/tj6pNotpbX3rltIA4dprgAPOq5A==
   dependencies:
     "@babel/helper-annotate-as-pure" "^7.14.5"
     "@babel/helper-function-name" "^7.14.5"
@@ -665,14 +779,14 @@
     "@babel/helper-plugin-utils" "^7.14.5"
     babel-plugin-dynamic-import-node "^2.3.3"
 
-"@babel/plugin-transform-modules-commonjs@^7.14.5":
-  version "7.14.5"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.5.tgz#7aaee0ea98283de94da98b28f8c35701429dad97"
-  integrity sha512-en8GfBtgnydoao2PS+87mKyw62k02k7kJ9ltbKe0fXTHrQmG6QZZflYuGI1VVG7sVpx4E1n7KBpNlPb8m78J+A==
+"@babel/plugin-transform-modules-commonjs@^7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.0.tgz#3305896e5835f953b5cdb363acd9e8c2219a5281"
+  integrity sha512-3H/R9s8cXcOGE8kgMlmjYYC9nqr5ELiPkJn4q0mypBrjhYQoc+5/Maq69vV4xRPWnkzZuwJPf5rArxpB/35Cig==
   dependencies:
-    "@babel/helper-module-transforms" "^7.14.5"
+    "@babel/helper-module-transforms" "^7.15.0"
     "@babel/helper-plugin-utils" "^7.14.5"
-    "@babel/helper-simple-access" "^7.14.5"
+    "@babel/helper-simple-access" "^7.14.8"
     babel-plugin-dynamic-import-node "^2.3.3"
 
 "@babel/plugin-transform-modules-systemjs@^7.14.5":
@@ -694,10 +808,10 @@
     "@babel/helper-module-transforms" "^7.14.5"
     "@babel/helper-plugin-utils" "^7.14.5"
 
-"@babel/plugin-transform-named-capturing-groups-regex@^7.14.7":
-  version "7.14.7"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.7.tgz#60c06892acf9df231e256c24464bfecb0908fd4e"
-  integrity sha512-DTNOTaS7TkW97xsDMrp7nycUVh6sn/eq22VaxWfEdzuEbRsiaOU0pqU7DlyUGHVsbQbSghvjKRpEl+nUCKGQSg==
+"@babel/plugin-transform-named-capturing-groups-regex@^7.14.9":
+  version "7.14.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.9.tgz#c68f5c5d12d2ebaba3762e57c2c4f6347a46e7b2"
+  integrity sha512-l666wCVYO75mlAtGFfyFwnWmIXQm3kSH0C3IRnJqWcZbWkoihyAdDhFm2ZWaxWTqvBvhVFfJjMRQ0ez4oN1yYA==
   dependencies:
     "@babel/helper-create-regexp-features-plugin" "^7.14.5"
 
@@ -777,10 +891,10 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.14.5"
 
-"@babel/plugin-transform-runtime@^7.14.5":
-  version "7.14.5"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.14.5.tgz#30491dad49c6059f8f8fa5ee8896a0089e987523"
-  integrity sha512-fPMBhh1AV8ZyneiCIA+wYYUH1arzlXR1UMcApjvchDhfKxhy2r2lReJv8uHEyihi4IFIGlr1Pdx7S5fkESDQsg==
+"@babel/plugin-transform-runtime@^7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.15.0.tgz#d3aa650d11678ca76ce294071fda53d7804183b3"
+  integrity sha512-sfHYkLGjhzWTq6xsuQ01oEsUYjkHRux9fW1iUA68dC7Qd8BS1Unq4aZ8itmQp95zUzIcyR2EbNMTzAicFj+guw==
   dependencies:
     "@babel/helper-module-imports" "^7.14.5"
     "@babel/helper-plugin-utils" "^7.14.5"
@@ -825,12 +939,12 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.14.5"
 
-"@babel/plugin-transform-typescript@^7.14.5":
-  version "7.14.6"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.14.6.tgz#6e9c2d98da2507ebe0a883b100cde3c7279df36c"
-  integrity sha512-XlTdBq7Awr4FYIzqhmYY80WN0V0azF74DMPyFqVHBvf81ZUgc4X7ZOpx6O8eLDK6iM5cCQzeyJw0ynTaefixRA==
+"@babel/plugin-transform-typescript@^7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.15.0.tgz#553f230b9d5385018716586fc48db10dd228eb7e"
+  integrity sha512-WIIEazmngMEEHDaPTx0IZY48SaAmjVWe3TRSX7cmJXn0bEv9midFzAjxiruOWYIVf5iQ10vFx7ASDpgEO08L5w==
   dependencies:
-    "@babel/helper-create-class-features-plugin" "^7.14.6"
+    "@babel/helper-create-class-features-plugin" "^7.15.0"
     "@babel/helper-plugin-utils" "^7.14.5"
     "@babel/plugin-syntax-typescript" "^7.14.5"
 
@@ -849,17 +963,17 @@
     "@babel/helper-create-regexp-features-plugin" "^7.14.5"
     "@babel/helper-plugin-utils" "^7.14.5"
 
-"@babel/preset-env@^7.14.7":
-  version "7.14.7"
-  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.14.7.tgz#5c70b22d4c2d893b03d8c886a5c17422502b932a"
-  integrity sha512-itOGqCKLsSUl0Y+1nSfhbuuOlTs0MJk2Iv7iSH+XT/mR8U1zRLO7NjWlYXB47yhK4J/7j+HYty/EhFZDYKa/VA==
+"@babel/preset-env@^7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.15.0.tgz#e2165bf16594c9c05e52517a194bf6187d6fe464"
+  integrity sha512-FhEpCNFCcWW3iZLg0L2NPE9UerdtsCR6ZcsGHUX6Om6kbCQeL5QZDqFDmeNHC6/fy6UH3jEge7K4qG5uC9In0Q==
   dependencies:
-    "@babel/compat-data" "^7.14.7"
-    "@babel/helper-compilation-targets" "^7.14.5"
+    "@babel/compat-data" "^7.15.0"
+    "@babel/helper-compilation-targets" "^7.15.0"
     "@babel/helper-plugin-utils" "^7.14.5"
     "@babel/helper-validator-option" "^7.14.5"
     "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.14.5"
-    "@babel/plugin-proposal-async-generator-functions" "^7.14.7"
+    "@babel/plugin-proposal-async-generator-functions" "^7.14.9"
     "@babel/plugin-proposal-class-properties" "^7.14.5"
     "@babel/plugin-proposal-class-static-block" "^7.14.5"
     "@babel/plugin-proposal-dynamic-import" "^7.14.5"
@@ -892,7 +1006,7 @@
     "@babel/plugin-transform-async-to-generator" "^7.14.5"
     "@babel/plugin-transform-block-scoped-functions" "^7.14.5"
     "@babel/plugin-transform-block-scoping" "^7.14.5"
-    "@babel/plugin-transform-classes" "^7.14.5"
+    "@babel/plugin-transform-classes" "^7.14.9"
     "@babel/plugin-transform-computed-properties" "^7.14.5"
     "@babel/plugin-transform-destructuring" "^7.14.7"
     "@babel/plugin-transform-dotall-regex" "^7.14.5"
@@ -903,10 +1017,10 @@
     "@babel/plugin-transform-literals" "^7.14.5"
     "@babel/plugin-transform-member-expression-literals" "^7.14.5"
     "@babel/plugin-transform-modules-amd" "^7.14.5"
-    "@babel/plugin-transform-modules-commonjs" "^7.14.5"
+    "@babel/plugin-transform-modules-commonjs" "^7.15.0"
     "@babel/plugin-transform-modules-systemjs" "^7.14.5"
     "@babel/plugin-transform-modules-umd" "^7.14.5"
-    "@babel/plugin-transform-named-capturing-groups-regex" "^7.14.7"
+    "@babel/plugin-transform-named-capturing-groups-regex" "^7.14.9"
     "@babel/plugin-transform-new-target" "^7.14.5"
     "@babel/plugin-transform-object-super" "^7.14.5"
     "@babel/plugin-transform-parameters" "^7.14.5"
@@ -921,11 +1035,11 @@
     "@babel/plugin-transform-unicode-escapes" "^7.14.5"
     "@babel/plugin-transform-unicode-regex" "^7.14.5"
     "@babel/preset-modules" "^0.1.4"
-    "@babel/types" "^7.14.5"
+    "@babel/types" "^7.15.0"
     babel-plugin-polyfill-corejs2 "^0.2.2"
     babel-plugin-polyfill-corejs3 "^0.2.2"
     babel-plugin-polyfill-regenerator "^0.2.2"
-    core-js-compat "^3.15.0"
+    core-js-compat "^3.16.0"
     semver "^6.3.0"
 
 "@babel/preset-modules@^0.1.4":
@@ -951,19 +1065,19 @@
     "@babel/plugin-transform-react-jsx-development" "^7.14.5"
     "@babel/plugin-transform-react-pure-annotations" "^7.14.5"
 
-"@babel/preset-typescript@^7.14.5":
-  version "7.14.5"
-  resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.14.5.tgz#aa98de119cf9852b79511f19e7f44a2d379bcce0"
-  integrity sha512-u4zO6CdbRKbS9TypMqrlGH7sd2TAJppZwn3c/ZRLeO/wGsbddxgbPDUZVNrie3JWYLQ9vpineKlsrWFvO6Pwkw==
+"@babel/preset-typescript@^7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.15.0.tgz#e8fca638a1a0f64f14e1119f7fe4500277840945"
+  integrity sha512-lt0Y/8V3y06Wq/8H/u0WakrqciZ7Fz7mwPDHWUJAXlABL5hiUG42BNlRXiELNjeWjO5rWmnNKlx+yzJvxezHow==
   dependencies:
     "@babel/helper-plugin-utils" "^7.14.5"
     "@babel/helper-validator-option" "^7.14.5"
-    "@babel/plugin-transform-typescript" "^7.14.5"
+    "@babel/plugin-transform-typescript" "^7.15.0"
 
-"@babel/register@^7.14.5":
-  version "7.14.5"
-  resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.14.5.tgz#d0eac615065d9c2f1995842f85d6e56c345f3233"
-  integrity sha512-TjJpGz/aDjFGWsItRBQMOFTrmTI9tr79CHOK+KIvLeCkbxuOAk2M5QHjvruIMGoo9OuccMh5euplPzc5FjAKGg==
+"@babel/register@^7.15.3":
+  version "7.15.3"
+  resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.15.3.tgz#6b40a549e06ec06c885b2ec42c3dd711f55fe752"
+  integrity sha512-mj4IY1ZJkorClxKTImccn4T81+UKTo4Ux0+OFSV9hME1ooqS9UV+pJ6BjD0qXPK4T3XW/KNa79XByjeEMZz+fw==
   dependencies:
     clone-deep "^4.0.1"
     find-cache-dir "^2.0.0"
@@ -978,6 +1092,13 @@
   dependencies:
     regenerator-runtime "^0.13.4"
 
+"@babel/runtime@^7.15.3":
+  version "7.15.3"
+  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.3.tgz#2e1c2880ca118e5b2f9988322bd8a7656a32502b"
+  integrity sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==
+  dependencies:
+    regenerator-runtime "^0.13.4"
+
 "@babel/template@^7.14.5", "@babel/template@^7.3.3":
   version "7.14.5"
   resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4"
@@ -1002,6 +1123,21 @@
     debug "^4.1.0"
     globals "^11.1.0"
 
+"@babel/traverse@^7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.0.tgz#4cca838fd1b2a03283c1f38e141f639d60b3fc98"
+  integrity sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw==
+  dependencies:
+    "@babel/code-frame" "^7.14.5"
+    "@babel/generator" "^7.15.0"
+    "@babel/helper-function-name" "^7.14.5"
+    "@babel/helper-hoist-variables" "^7.14.5"
+    "@babel/helper-split-export-declaration" "^7.14.5"
+    "@babel/parser" "^7.15.0"
+    "@babel/types" "^7.15.0"
+    debug "^4.1.0"
+    globals "^11.1.0"
+
 "@babel/types@^7.0.0", "@babel/types@^7.14.5", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
   version "7.14.5"
   resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.5.tgz#3bb997ba829a2104cedb20689c4a5b8121d383ff"
@@ -1010,15 +1146,23 @@
     "@babel/helper-validator-identifier" "^7.14.5"
     to-fast-properties "^2.0.0"
 
+"@babel/types@^7.14.8", "@babel/types@^7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.0.tgz#61af11f2286c4e9c69ca8deb5f4375a73c72dcbd"
+  integrity sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==
+  dependencies:
+    "@babel/helper-validator-identifier" "^7.14.9"
+    to-fast-properties "^2.0.0"
+
 "@bcoe/v8-coverage@^0.2.3":
   version "0.2.3"
   resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
   integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
 
-"@eslint/eslintrc@^0.4.2":
-  version "0.4.2"
-  resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.2.tgz#f63d0ef06f5c0c57d76c4ab5f63d3835c51b0179"
-  integrity sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==
+"@eslint/eslintrc@^0.4.3":
+  version "0.4.3"
+  resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
+  integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==
   dependencies:
     ajv "^6.12.4"
     debug "^4.1.1"
@@ -1236,94 +1380,94 @@
   resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98"
   integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==
 
-"@jest/console@^27.0.2":
-  version "27.0.2"
-  resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.0.2.tgz#b8eeff8f21ac51d224c851e1729d2630c18631e6"
-  integrity sha512-/zYigssuHLImGeMAACkjI4VLAiiJznHgAl3xnFT19iWyct2LhrH3KXOjHRmxBGTkiPLZKKAJAgaPpiU9EZ9K+w==
+"@jest/console@^27.0.6":
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.0.6.tgz#3eb72ea80897495c3d73dd97aab7f26770e2260f"
+  integrity sha512-fMlIBocSHPZ3JxgWiDNW/KPj6s+YRd0hicb33IrmelCcjXo/pXPwvuiKFmZz+XuqI/1u7nbUK10zSsWL/1aegg==
   dependencies:
-    "@jest/types" "^27.0.2"
+    "@jest/types" "^27.0.6"
     "@types/node" "*"
     chalk "^4.0.0"
-    jest-message-util "^27.0.2"
-    jest-util "^27.0.2"
+    jest-message-util "^27.0.6"
+    jest-util "^27.0.6"
     slash "^3.0.0"
 
-"@jest/core@^27.0.5":
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.0.5.tgz#59e9e69e7374d65dbb22e3fc1bd52e80991eae72"
-  integrity sha512-g73//jF0VwsOIrWUC9Cqg03lU3QoAMFxVjsm6n6yNmwZcQPN/o8w+gLWODw5VfKNFZT38otXHWxc6b8eGDUpEA==
+"@jest/core@^27.0.6":
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.0.6.tgz#c5f642727a0b3bf0f37c4b46c675372d0978d4a1"
+  integrity sha512-SsYBm3yhqOn5ZLJCtccaBcvD/ccTLCeuDv8U41WJH/V1MW5eKUkeMHT9U+Pw/v1m1AIWlnIW/eM2XzQr0rEmow==
   dependencies:
-    "@jest/console" "^27.0.2"
-    "@jest/reporters" "^27.0.5"
-    "@jest/test-result" "^27.0.2"
-    "@jest/transform" "^27.0.5"
-    "@jest/types" "^27.0.2"
+    "@jest/console" "^27.0.6"
+    "@jest/reporters" "^27.0.6"
+    "@jest/test-result" "^27.0.6"
+    "@jest/transform" "^27.0.6"
+    "@jest/types" "^27.0.6"
     "@types/node" "*"
     ansi-escapes "^4.2.1"
     chalk "^4.0.0"
     emittery "^0.8.1"
     exit "^0.1.2"
     graceful-fs "^4.2.4"
-    jest-changed-files "^27.0.2"
-    jest-config "^27.0.5"
-    jest-haste-map "^27.0.5"
-    jest-message-util "^27.0.2"
-    jest-regex-util "^27.0.1"
-    jest-resolve "^27.0.5"
-    jest-resolve-dependencies "^27.0.5"
-    jest-runner "^27.0.5"
-    jest-runtime "^27.0.5"
-    jest-snapshot "^27.0.5"
-    jest-util "^27.0.2"
-    jest-validate "^27.0.2"
-    jest-watcher "^27.0.2"
+    jest-changed-files "^27.0.6"
+    jest-config "^27.0.6"
+    jest-haste-map "^27.0.6"
+    jest-message-util "^27.0.6"
+    jest-regex-util "^27.0.6"
+    jest-resolve "^27.0.6"
+    jest-resolve-dependencies "^27.0.6"
+    jest-runner "^27.0.6"
+    jest-runtime "^27.0.6"
+    jest-snapshot "^27.0.6"
+    jest-util "^27.0.6"
+    jest-validate "^27.0.6"
+    jest-watcher "^27.0.6"
     micromatch "^4.0.4"
     p-each-series "^2.1.0"
     rimraf "^3.0.0"
     slash "^3.0.0"
     strip-ansi "^6.0.0"
 
-"@jest/environment@^27.0.5":
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.0.5.tgz#a294ad4acda2e250f789fb98dc667aad33d3adc9"
-  integrity sha512-IAkJPOT7bqn0GiX5LPio6/e1YpcmLbrd8O5EFYpAOZ6V+9xJDsXjdgN2vgv9WOKIs/uA1kf5WeD96HhlBYO+FA==
+"@jest/environment@^27.0.6":
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.0.6.tgz#ee293fe996db01d7d663b8108fa0e1ff436219d2"
+  integrity sha512-4XywtdhwZwCpPJ/qfAkqExRsERW+UaoSRStSHCCiQTUpoYdLukj+YJbQSFrZjhlUDRZeNiU9SFH0u7iNimdiIg==
   dependencies:
-    "@jest/fake-timers" "^27.0.5"
-    "@jest/types" "^27.0.2"
+    "@jest/fake-timers" "^27.0.6"
+    "@jest/types" "^27.0.6"
     "@types/node" "*"
-    jest-mock "^27.0.3"
+    jest-mock "^27.0.6"
 
-"@jest/fake-timers@^27.0.5":
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.0.5.tgz#304d5aedadf4c75cff3696995460b39d6c6e72f6"
-  integrity sha512-d6Tyf7iDoKqeUdwUKrOBV/GvEZRF67m7lpuWI0+SCD9D3aaejiOQZxAOxwH2EH/W18gnfYaBPLi0VeTGBHtQBg==
+"@jest/fake-timers@^27.0.6":
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.0.6.tgz#cbad52f3fe6abe30e7acb8cd5fa3466b9588e3df"
+  integrity sha512-sqd+xTWtZ94l3yWDKnRTdvTeZ+A/V7SSKrxsrOKSqdyddb9CeNRF8fbhAU0D7ZJBpTTW2nbp6MftmKJDZfW2LQ==
   dependencies:
-    "@jest/types" "^27.0.2"
+    "@jest/types" "^27.0.6"
     "@sinonjs/fake-timers" "^7.0.2"
     "@types/node" "*"
-    jest-message-util "^27.0.2"
-    jest-mock "^27.0.3"
-    jest-util "^27.0.2"
+    jest-message-util "^27.0.6"
+    jest-mock "^27.0.6"
+    jest-util "^27.0.6"
 
-"@jest/globals@^27.0.5":
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.0.5.tgz#f63b8bfa6ea3716f8df50f6a604b5c15b36ffd20"
-  integrity sha512-qqKyjDXUaZwDuccpbMMKCCMBftvrbXzigtIsikAH/9ca+kaae8InP2MDf+Y/PdCSMuAsSpHS6q6M25irBBUh+Q==
+"@jest/globals@^27.0.6":
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.0.6.tgz#48e3903f99a4650673d8657334d13c9caf0e8f82"
+  integrity sha512-DdTGCP606rh9bjkdQ7VvChV18iS7q0IMJVP1piwTWyWskol4iqcVwthZmoJEf7obE1nc34OpIyoVGPeqLC+ryw==
   dependencies:
-    "@jest/environment" "^27.0.5"
-    "@jest/types" "^27.0.2"
-    expect "^27.0.2"
+    "@jest/environment" "^27.0.6"
+    "@jest/types" "^27.0.6"
+    expect "^27.0.6"
 
-"@jest/reporters@^27.0.5":
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.0.5.tgz#cd730b77d9667b8ff700ad66d4edc293bb09716a"
-  integrity sha512-4uNg5+0eIfRafnpgu3jCZws3NNcFzhu5JdRd1mKQ4/53+vkIqwB6vfZ4gn5BdGqOaLtYhlOsPaL5ATkKzyBrJw==
+"@jest/reporters@^27.0.6":
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.0.6.tgz#91e7f2d98c002ad5df94d5b5167c1eb0b9fd5b00"
+  integrity sha512-TIkBt09Cb2gptji3yJXb3EE+eVltW6BjO7frO7NEfjI9vSIYoISi5R3aI3KpEDXlB1xwB+97NXIqz84qYeYsfA==
   dependencies:
     "@bcoe/v8-coverage" "^0.2.3"
-    "@jest/console" "^27.0.2"
-    "@jest/test-result" "^27.0.2"
-    "@jest/transform" "^27.0.5"
-    "@jest/types" "^27.0.2"
+    "@jest/console" "^27.0.6"
+    "@jest/test-result" "^27.0.6"
+    "@jest/transform" "^27.0.6"
+    "@jest/types" "^27.0.6"
     chalk "^4.0.0"
     collect-v8-coverage "^1.0.0"
     exit "^0.1.2"
@@ -1334,70 +1478,70 @@
     istanbul-lib-report "^3.0.0"
     istanbul-lib-source-maps "^4.0.0"
     istanbul-reports "^3.0.2"
-    jest-haste-map "^27.0.5"
-    jest-resolve "^27.0.5"
-    jest-util "^27.0.2"
-    jest-worker "^27.0.2"
+    jest-haste-map "^27.0.6"
+    jest-resolve "^27.0.6"
+    jest-util "^27.0.6"
+    jest-worker "^27.0.6"
     slash "^3.0.0"
     source-map "^0.6.0"
     string-length "^4.0.1"
     terminal-link "^2.0.0"
     v8-to-istanbul "^8.0.0"
 
-"@jest/source-map@^27.0.1":
-  version "27.0.1"
-  resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.0.1.tgz#2afbf73ddbaddcb920a8e62d0238a0a9e0a8d3e4"
-  integrity sha512-yMgkF0f+6WJtDMdDYNavmqvbHtiSpwRN2U/W+6uztgfqgkq/PXdKPqjBTUF1RD/feth4rH5N3NW0T5+wIuln1A==
+"@jest/source-map@^27.0.6":
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.0.6.tgz#be9e9b93565d49b0548b86e232092491fb60551f"
+  integrity sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==
   dependencies:
     callsites "^3.0.0"
     graceful-fs "^4.2.4"
     source-map "^0.6.0"
 
-"@jest/test-result@^27.0.2":
-  version "27.0.2"
-  resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.0.2.tgz#0451049e32ceb609b636004ccc27c8fa22263f10"
-  integrity sha512-gcdWwL3yP5VaIadzwQtbZyZMgpmes8ryBAJp70tuxghiA8qL4imJyZex+i+USQH2H4jeLVVszhwntgdQ97fccA==
+"@jest/test-result@^27.0.6":
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.0.6.tgz#3fa42015a14e4fdede6acd042ce98c7f36627051"
+  integrity sha512-ja/pBOMTufjX4JLEauLxE3LQBPaI2YjGFtXexRAjt1I/MbfNlMx0sytSX3tn5hSLzQsR3Qy2rd0hc1BWojtj9w==
   dependencies:
-    "@jest/console" "^27.0.2"
-    "@jest/types" "^27.0.2"
+    "@jest/console" "^27.0.6"
+    "@jest/types" "^27.0.6"
     "@types/istanbul-lib-coverage" "^2.0.0"
     collect-v8-coverage "^1.0.0"
 
-"@jest/test-sequencer@^27.0.5":
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.0.5.tgz#c58b21db49afc36c0e3921d7ddf1fb7954abfded"
-  integrity sha512-opztnGs+cXzZ5txFG2+omBaV5ge/0yuJNKbhE3DREMiXE0YxBuzyEa6pNv3kk2JuucIlH2Xvgmn9kEEHSNt/SA==
+"@jest/test-sequencer@^27.0.6":
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.0.6.tgz#80a913ed7a1130545b1cd777ff2735dd3af5d34b"
+  integrity sha512-bISzNIApazYOlTHDum9PwW22NOyDa6VI31n6JucpjTVM0jD6JDgqEZ9+yn575nDdPF0+4csYDxNNW13NvFQGZA==
   dependencies:
-    "@jest/test-result" "^27.0.2"
+    "@jest/test-result" "^27.0.6"
     graceful-fs "^4.2.4"
-    jest-haste-map "^27.0.5"
-    jest-runtime "^27.0.5"
+    jest-haste-map "^27.0.6"
+    jest-runtime "^27.0.6"
 
-"@jest/transform@^27.0.5":
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.0.5.tgz#2dcb78953708af713941ac845b06078bc74ed873"
-  integrity sha512-lBD6OwKXSc6JJECBNk4mVxtSVuJSBsQrJ9WCBisfJs7EZuYq4K6vM9HmoB7hmPiLIDGeyaerw3feBV/bC4z8tg==
+"@jest/transform@^27.0.6":
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.0.6.tgz#189ad7107413208f7600f4719f81dd2f7278cc95"
+  integrity sha512-rj5Dw+mtIcntAUnMlW/Vju5mr73u8yg+irnHwzgtgoeI6cCPOvUwQ0D1uQtc/APmWgvRweEb1g05pkUpxH3iCA==
   dependencies:
     "@babel/core" "^7.1.0"
-    "@jest/types" "^27.0.2"
+    "@jest/types" "^27.0.6"
     babel-plugin-istanbul "^6.0.0"
     chalk "^4.0.0"
     convert-source-map "^1.4.0"
     fast-json-stable-stringify "^2.0.0"
     graceful-fs "^4.2.4"
-    jest-haste-map "^27.0.5"
-    jest-regex-util "^27.0.1"
-    jest-util "^27.0.2"
+    jest-haste-map "^27.0.6"
+    jest-regex-util "^27.0.6"
+    jest-util "^27.0.6"
     micromatch "^4.0.4"
     pirates "^4.0.1"
     slash "^3.0.0"
     source-map "^0.6.1"
     write-file-atomic "^3.0.0"
 
-"@jest/types@^27.0.2":
-  version "27.0.2"
-  resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.0.2.tgz#e153d6c46bda0f2589f0702b071f9898c7bbd37e"
-  integrity sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==
+"@jest/types@^27.0.6":
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.0.6.tgz#9a992bc517e0c49f035938b8549719c2de40706b"
+  integrity sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==
   dependencies:
     "@types/istanbul-lib-coverage" "^2.0.0"
     "@types/istanbul-reports" "^3.0.0"
@@ -1544,54 +1688,54 @@
   dependencies:
     "@octokit/openapi-types" "^7.3.2"
 
-"@polkadot/api-contract@5.0.1":
-  version "5.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/api-contract/-/api-contract-5.0.1.tgz#520a7b3cd990a76374b79e12eca5bf629cc565a1"
-  integrity sha512-qZ2wnXHDyU2c1/V9GKpbcZKBfVua4YFsU/LHKevZLkJfnGFBgNRdwAuKgVe5h2FCt2W2/pt618WgxG0UDWwjcw==
+"@polkadot/api-contract@5.5.1":
+  version "5.5.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/api-contract/-/api-contract-5.5.1.tgz#4cdd0d6f4352050c58464d5958bdb779770bd2dc"
+  integrity sha512-/1O1AnpCu+LM2EKhRY83r36blG8KOr0JCVFeSfT0u52tM4wMdLlUy1XV/XTZayuCucdJ6I0pjUudCljm92aiGw==
   dependencies:
-    "@babel/runtime" "^7.14.6"
-    "@polkadot/api" "5.0.1"
-    "@polkadot/types" "5.0.1"
-    "@polkadot/util" "^7.0.1"
-    rxjs "^7.2.0"
+    "@babel/runtime" "^7.15.3"
+    "@polkadot/api" "5.5.1"
+    "@polkadot/types" "5.5.1"
+    "@polkadot/util" "^7.2.1"
+    rxjs "^7.3.0"
 
-"@polkadot/api-derive@5.0.1":
-  version "5.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-5.0.1.tgz#08064c10ed159826ffd07013dcdde1d8b63186a0"
-  integrity sha512-JZpH1JVLu3PvX4+A71iDLtNr6LL103dAFou61DxyJF4obyTmS2lzigG3xXqUFShiPDb19ywxQpsE4gAOP6emuQ==
+"@polkadot/api-derive@5.5.1":
+  version "5.5.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-5.5.1.tgz#6fdba748d90024f2fcdeb7827d178ff8d0ad308e"
+  integrity sha512-dkpl3CnroBYAlLx571KoyjI72TqRweWI61z7tzNeR8qwniNyWDEILTErUfzy5jYAO7XrZpW1Gn4WMMH+kEcqZQ==
   dependencies:
-    "@babel/runtime" "^7.14.6"
-    "@polkadot/api" "5.0.1"
-    "@polkadot/rpc-core" "5.0.1"
-    "@polkadot/types" "5.0.1"
-    "@polkadot/util" "^7.0.1"
-    "@polkadot/util-crypto" "^7.0.1"
-    rxjs "^7.2.0"
+    "@babel/runtime" "^7.15.3"
+    "@polkadot/api" "5.5.1"
+    "@polkadot/rpc-core" "5.5.1"
+    "@polkadot/types" "5.5.1"
+    "@polkadot/util" "^7.2.1"
+    "@polkadot/util-crypto" "^7.2.1"
+    rxjs "^7.3.0"
 
-"@polkadot/api@5.0.1":
-  version "5.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-5.0.1.tgz#9607b53009322f9264f7dcc8705c466bd33aa516"
-  integrity sha512-5JDpM2Fjc80gHBju1B/rMBGDfAvY8UiU4XVlivJRk+mTVD3OTwbtTro4nmwJOub05xQCJvD/bnCuxG8eFSoq+Q==
+"@polkadot/api@5.5.1":
+  version "5.5.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-5.5.1.tgz#0298c6d883c2264a68ae93a3b59b98263aed53d3"
+  integrity sha512-GS/MoRc7NB61jz7TzwX0WAA3JS7DSj3xH4ac39LcuPHXu0VMQw6LgT/5KIzYxTx+79Iwth62bKelW/Mgk23wUg==
   dependencies:
-    "@babel/runtime" "^7.14.6"
-    "@polkadot/api-derive" "5.0.1"
-    "@polkadot/keyring" "^7.0.1"
-    "@polkadot/rpc-core" "5.0.1"
-    "@polkadot/rpc-provider" "5.0.1"
-    "@polkadot/types" "5.0.1"
-    "@polkadot/types-known" "5.0.1"
-    "@polkadot/util" "^7.0.1"
-    "@polkadot/util-crypto" "^7.0.1"
+    "@babel/runtime" "^7.15.3"
+    "@polkadot/api-derive" "5.5.1"
+    "@polkadot/keyring" "^7.2.1"
+    "@polkadot/rpc-core" "5.5.1"
+    "@polkadot/rpc-provider" "5.5.1"
+    "@polkadot/types" "5.5.1"
+    "@polkadot/types-known" "5.5.1"
+    "@polkadot/util" "^7.2.1"
+    "@polkadot/util-crypto" "^7.2.1"
     eventemitter3 "^4.0.7"
-    rxjs "^7.2.0"
+    rxjs "^7.3.0"
 
-"@polkadot/dev@0.62.43":
-  version "0.62.43"
-  resolved "https://registry.yarnpkg.com/@polkadot/dev/-/dev-0.62.43.tgz#567591bf3c38dded4b4c1f3ec8bf3d3198a23b6d"
-  integrity sha512-ZSgYUbC6A+WtRSY5nq7yeGYW+wv3g8cds2zndL4GeClIdVHksgEW6+ch3Hx6LMkE3y4q9Kjvs50oHeemBDut4Q==
+"@polkadot/dev@0.62.60":
+  version "0.62.60"
+  resolved "https://registry.yarnpkg.com/@polkadot/dev/-/dev-0.62.60.tgz#450007c189a8433d8627bcc1fc01d2ffb1becfc3"
+  integrity sha512-VHZ4d/hhRSNFe0RXp3L/ZcAk1t2JQ1/lsznONAz4I9SZ2pn5kAQrWRF6eukgfQscrlqCH5njDAxwgXe6ODNVRw==
   dependencies:
-    "@babel/cli" "^7.14.5"
-    "@babel/core" "^7.14.6"
+    "@babel/cli" "^7.14.8"
+    "@babel/core" "^7.15.0"
     "@babel/plugin-proposal-class-properties" "^7.14.5"
     "@babel/plugin-proposal-nullish-coalescing-operator" "^7.14.5"
     "@babel/plugin-proposal-numeric-separator" "^7.14.5"
@@ -1603,28 +1747,34 @@
     "@babel/plugin-syntax-import-meta" "^7.10.4"
     "@babel/plugin-syntax-top-level-await" "^7.14.5"
     "@babel/plugin-transform-regenerator" "^7.14.5"
-    "@babel/plugin-transform-runtime" "^7.14.5"
-    "@babel/preset-env" "^7.14.7"
+    "@babel/plugin-transform-runtime" "^7.15.0"
+    "@babel/preset-env" "^7.15.0"
     "@babel/preset-react" "^7.14.5"
-    "@babel/preset-typescript" "^7.14.5"
-    "@babel/register" "^7.14.5"
-    "@babel/runtime" "^7.14.6"
+    "@babel/preset-typescript" "^7.15.0"
+    "@babel/register" "^7.15.3"
+    "@babel/runtime" "^7.15.3"
+    "@rollup/plugin-alias" "^3.1.5"
+    "@rollup/plugin-commonjs" "^19.0.2"
+    "@rollup/plugin-inject" "^4.0.2"
+    "@rollup/plugin-json" "^4.1.0"
+    "@rollup/plugin-node-resolve" "^13.0.4"
     "@rushstack/eslint-patch" "^1.0.6"
-    "@typescript-eslint/eslint-plugin" "4.28.0"
-    "@typescript-eslint/parser" "4.28.0"
+    "@typescript-eslint/eslint-plugin" "4.29.2"
+    "@typescript-eslint/parser" "4.29.2"
     "@vue/component-compiler-utils" "^3.2.2"
-    babel-jest "^27.0.5"
+    babel-jest "^27.0.6"
     babel-plugin-module-extension-resolver "^1.0.0-rc.2"
     babel-plugin-module-resolver "^4.1.0"
-    babel-plugin-styled-components "^1.12.0"
-    browserslist "^4.16.6"
-    chalk "^4.1.1"
-    coveralls "^3.1.0"
-    eslint "^7.29.0"
+    babel-plugin-styled-components "^1.13.2"
+    browserslist "^4.16.7"
+    chalk "^4.1.2"
+    coveralls "^3.1.1"
+    eslint "^7.32.0"
     eslint-config-standard "^16.0.3"
-    eslint-import-resolver-node "^0.3.4"
+    eslint-import-resolver-node "^0.3.6"
     eslint-plugin-header "^3.1.1"
-    eslint-plugin-import "^2.23.4"
+    eslint-plugin-import "^2.24.0"
+    eslint-plugin-import-newlines "^1.1.4"
     eslint-plugin-node "^11.1.0"
     eslint-plugin-promise "^5.1.0"
     eslint-plugin-react "^7.24.0"
@@ -1636,118 +1786,129 @@
     gh-release "^6.0.0"
     glob "^7.1.7"
     glob2base "^0.0.12"
-    jest "^27.0.5"
-    jest-cli "^27.0.5"
-    jest-config "^27.0.5"
-    jest-haste-map "^27.0.5"
-    jest-resolve "^27.0.5"
+    jest "^27.0.6"
+    jest-cli "^27.0.6"
+    jest-config "^27.0.6"
+    jest-haste-map "^27.0.6"
+    jest-resolve "^27.0.6"
     madge "^4.0.2"
     minimatch "^3.0.4"
     mkdirp "^1.0.4"
-    prettier "^2.3.1"
+    prettier "^2.3.2"
     rimraf "^3.0.2"
-    typescript "^4.3.4"
-    yargs "^17.0.1"
+    rollup "^2.56.2"
+    typescript "^4.3.5"
+    yargs "^17.1.1"
 
-"@polkadot/keyring@^7.0.1":
-  version "7.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-7.0.1.tgz#666e903661b98279dc16d512be69f5ace4b58d8d"
-  integrity sha512-eSvG8Q4gUTRDFWj2lqTY/9NekGP8dtp+W6WmouKh0DDwHRawaVeDaq6UJYQv6XoBG1i+ZGPvErRQeGMPOn/mUQ==
+"@polkadot/keyring@^7.2.1":
+  version "7.2.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-7.2.1.tgz#5ed8e6c0edc61e3dd99ee647a227b9e3d955e8e6"
+  integrity sha512-WmiTsHKELX16uZWLvebDBckZIAXeJFfbcOM6m/VbMOjSV5C6xIKqiV3232Mn8ZuPKgsOf25Q78/IwJW1Dq53Qg==
   dependencies:
-    "@babel/runtime" "^7.14.6"
-    "@polkadot/util" "7.0.1"
-    "@polkadot/util-crypto" "7.0.1"
+    "@babel/runtime" "^7.15.3"
+    "@polkadot/util" "7.2.1"
+    "@polkadot/util-crypto" "7.2.1"
 
-"@polkadot/networks@7.0.1", "@polkadot/networks@^7.0.1":
-  version "7.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-7.0.1.tgz#e07c4b88e25711433e76d24fce4c7273c25dd38b"
-  integrity sha512-bJSvI7UgEpxmBKS8TMh+I1mfmCMwhClGdSs29kwU+K61IjBTKTt3yQJ/SflYIQV7QftGbz3oMfSkGbQbRHZqvQ==
+"@polkadot/networks@7.2.1", "@polkadot/networks@^7.2.1":
+  version "7.2.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-7.2.1.tgz#20c8d81fba4b48162bf360759d8d54c55d30128b"
+  integrity sha512-YX8oQ7QQ2oq3YowwOiv/C82l849V0ZEzpR26YrPgKSXbYFbasho3Akf0zalndZJZV1Bb8EiOkzGoJ3ffogSPxA==
   dependencies:
-    "@babel/runtime" "^7.14.6"
+    "@babel/runtime" "^7.15.3"
 
-"@polkadot/rpc-core@5.0.1":
-  version "5.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-5.0.1.tgz#8460287532fe61c31505564df53e92ef6feba875"
-  integrity sha512-JMNOVQijjyJZNu9B8CJwIrQzGYzAp03uCBSbqYfzWBFnYVLKh7JmvOlkLnODM8uUYq0gVN4BaDUSPc39GpELAQ==
+"@polkadot/rpc-core@5.5.1":
+  version "5.5.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-5.5.1.tgz#4ce0646becabe7736dfb81eb902e5933158646c8"
+  integrity sha512-hP7a55iSpgZVqxAIpK+v63eV/nD14Tm7C1rUmfKIS6gGJFJf+sQbTmp6d7+fuKxvYfFqBrFLU8IraOhLOQ5W3Q==
   dependencies:
-    "@babel/runtime" "^7.14.6"
-    "@polkadot/rpc-provider" "5.0.1"
-    "@polkadot/types" "5.0.1"
-    "@polkadot/util" "^7.0.1"
-    rxjs "^7.2.0"
+    "@babel/runtime" "^7.15.3"
+    "@polkadot/rpc-provider" "5.5.1"
+    "@polkadot/types" "5.5.1"
+    "@polkadot/util" "^7.2.1"
+    rxjs "^7.3.0"
 
-"@polkadot/rpc-provider@5.0.1":
-  version "5.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-5.0.1.tgz#ef022a123eb9073634b59c6e0f6e1705e96066a5"
-  integrity sha512-t+VKhMtQfQVgkZDqYnP/44KlBDmcCVo1/MvJ+DoNd7RUWUIBJt3v71G5gDSNeGMTyvxn0KK0qL4j+Nqr6c4FUQ==
+"@polkadot/rpc-provider@5.5.1":
+  version "5.5.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-5.5.1.tgz#633f4a48605623092fb9017433f2b3cd70cd96bc"
+  integrity sha512-wOCKeeyUa7Dw3nxKkQntnfOO471icdzqT2V7bwloBOo+G2MX8nHImO0mW3QMfJygn4qoARF1PBo1PLbDUEDgog==
   dependencies:
-    "@babel/runtime" "^7.14.6"
-    "@polkadot/types" "5.0.1"
-    "@polkadot/util" "^7.0.1"
-    "@polkadot/util-crypto" "^7.0.1"
-    "@polkadot/x-fetch" "^7.0.1"
-    "@polkadot/x-global" "^7.0.1"
-    "@polkadot/x-ws" "^7.0.1"
+    "@babel/runtime" "^7.15.3"
+    "@polkadot/types" "5.5.1"
+    "@polkadot/util" "^7.2.1"
+    "@polkadot/util-crypto" "^7.2.1"
+    "@polkadot/x-fetch" "^7.2.1"
+    "@polkadot/x-global" "^7.2.1"
+    "@polkadot/x-ws" "^7.2.1"
     eventemitter3 "^4.0.7"
 
-"@polkadot/ts@0.3.89":
-  version "0.3.89"
-  resolved "https://registry.yarnpkg.com/@polkadot/ts/-/ts-0.3.89.tgz#c7a704ea284d04fcf4d581f5df156d5945480033"
-  integrity sha512-GC0H8wmVKebkieN2MHScjDDonzigIzkjl1Q4V1OhoRcfQbeZZ7vijeiVwP8Hw3wIw4GLKxxXeDrkKPWl/bcaHw==
+"@polkadot/ts@0.4.4":
+  version "0.4.4"
+  resolved "https://registry.yarnpkg.com/@polkadot/ts/-/ts-0.4.4.tgz#e86aa47c2bcbc70ac8385b31014c81927c4b0a88"
+  integrity sha512-lzB8lg8GfdJlA7RdeoOJVFopecN4i++JndbUs6jW7AgRz+joeXQIIRomVgCNE52nW1uWpXMELnlvEP812v7sVw==
   dependencies:
-    "@types/chrome" "^0.0.144"
+    "@types/chrome" "^0.0.145"
 
-"@polkadot/typegen@5.0.1":
-  version "5.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/typegen/-/typegen-5.0.1.tgz#718b517f4f1578441911096603577bd0a2a968e0"
-  integrity sha512-iFLJoWgIkn+J6MDw3AUWveP9qxVn1C+VeLJbpZ21St5WyeE148Tml0BmYnKLSXlaPMhZEwB+/IV3jpQ35dH4bw==
+"@polkadot/typegen@5.5.1":
+  version "5.5.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/typegen/-/typegen-5.5.1.tgz#b31010716a142290d12f48ead6166851599055d0"
+  integrity sha512-ua55CVqT3+Y5fX9stpYUO+UhiJJ1RDTZ6vM2/Lndmsuda4lHQnUDrCnMmxKhM5OcyIlJlY5mF9dyO0kl5mTm+w==
   dependencies:
-    "@babel/core" "^7.14.6"
-    "@babel/register" "^7.14.5"
-    "@babel/runtime" "^7.14.6"
-    "@polkadot/api" "5.0.1"
-    "@polkadot/rpc-provider" "5.0.1"
-    "@polkadot/types" "5.0.1"
-    "@polkadot/util" "^7.0.1"
+    "@babel/core" "^7.15.0"
+    "@babel/register" "^7.15.3"
+    "@babel/runtime" "^7.15.3"
+    "@polkadot/api" "5.5.1"
+    "@polkadot/rpc-provider" "5.5.1"
+    "@polkadot/types" "5.5.1"
+    "@polkadot/types-support" "5.5.1"
+    "@polkadot/util" "^7.2.1"
     handlebars "^4.7.7"
     websocket "^1.0.34"
-    yargs "^17.0.1"
+    yargs "^17.1.0"
 
-"@polkadot/types-known@5.0.1":
-  version "5.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-5.0.1.tgz#21feb327fc4323733bf027c8d874a2aa3014b21f"
-  integrity sha512-AIhPlN4r14ZW4wdwHZD2nIe1DE61ZO9PsyrCyAU3ysl6Cw6TI+txDCN3aS/8XYuC7wDLEgLB9vJv2sVWdCzqJg==
+"@polkadot/types-known@5.5.1":
+  version "5.5.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-5.5.1.tgz#b00b0d45cbd07b4e0c3199f8ba00d10a1bd3f63d"
+  integrity sha512-bxBRmZ0a3lwEyWkWOKqmDJfpNKh3cp9xo6IidrQU2S5OPMjFFercB+HwJjkNE1cMtShwBYTvDheUImNkdm+FXA==
   dependencies:
-    "@babel/runtime" "^7.14.6"
-    "@polkadot/networks" "^7.0.1"
-    "@polkadot/types" "5.0.1"
-    "@polkadot/util" "^7.0.1"
+    "@babel/runtime" "^7.15.3"
+    "@polkadot/networks" "^7.2.1"
+    "@polkadot/types" "5.5.1"
+    "@polkadot/util" "^7.2.1"
 
-"@polkadot/types@5.0.1":
-  version "5.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-5.0.1.tgz#2a4e23e452f999eeae175b595470df0e426a930d"
-  integrity sha512-aN6JKeF7ZYi5irYAaUoDqth6qlOlB15C5vhlDOojEorYLfRs/R+GCrO+lPSs+bKmSxh7BSRh500ikI/xD4nx5A==
+"@polkadot/types-support@5.5.1":
+  version "5.5.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/types-support/-/types-support-5.5.1.tgz#15556c2f31e79f0a6a821c7723f702757cb89462"
+  integrity sha512-57i1SdK8B+miGTAlDNdvbBuN6FguTnwzv2UPE2Zv3iQznTSZBkQZN16tIK/yMkQfhtO4ZzPcAnnSPZMncqh/Mg==
   dependencies:
-    "@babel/runtime" "^7.14.6"
-    "@polkadot/util" "^7.0.1"
-    "@polkadot/util-crypto" "^7.0.1"
-    rxjs "^7.2.0"
+    "@babel/runtime" "^7.15.3"
+    "@polkadot/util" "^7.2.1"
 
-"@polkadot/util-crypto@7.0.1", "@polkadot/util-crypto@^7.0.1":
-  version "7.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-7.0.1.tgz#03109dc11323dad174fb2214d395855495def16a"
-  integrity sha512-dbvdsICoyOVw/K45RmHOP7wXE/7vj+NzEKGcKbiDt39nglHm6g2BTJ947PwwyNusTTAx82Q2iJ9vIZ1Kl0xG+g==
+"@polkadot/types@5.5.1":
+  version "5.5.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-5.5.1.tgz#057e8f0fc2369c0741c0f9b0224418e8f25a6938"
+  integrity sha512-+Cm7Y6D/98WqL8ofONyZrVvE2CxzK3/z18bATIQIWhG2w9ir9PdWaFMZ3fLCRw2Ggaq88AknguK6kXeEPcKPrA==
   dependencies:
-    "@babel/runtime" "^7.14.6"
-    "@polkadot/networks" "7.0.1"
-    "@polkadot/util" "7.0.1"
+    "@babel/runtime" "^7.15.3"
+    "@polkadot/util" "^7.2.1"
+    "@polkadot/util-crypto" "^7.2.1"
+    rxjs "^7.3.0"
+
+"@polkadot/util-crypto@7.2.1", "@polkadot/util-crypto@^7.2.1":
+  version "7.2.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-7.2.1.tgz#7f1bbf031dac75090699083fc9e825c22e5d5f61"
+  integrity sha512-X3iGba/1JTL/0MNzMNEIlO9DNyKlwFV839jfGLDKhPbCuDmWp0NdQjF3mBmbvNwkXvn07WmhE7g3q9n5iTzqvQ==
+  dependencies:
+    "@babel/runtime" "^7.15.3"
+    "@polkadot/networks" "7.2.1"
+    "@polkadot/util" "7.2.1"
     "@polkadot/wasm-crypto" "^4.1.2"
-    "@polkadot/x-randomvalues" "7.0.1"
+    "@polkadot/x-randomvalues" "7.2.1"
     base-x "^3.0.8"
     base64-js "^1.5.1"
     blakejs "^1.1.1"
     bn.js "^4.11.9"
     create-hash "^1.2.0"
+    ed2curve "^0.3.0"
     elliptic "^6.5.4"
     hash.js "^1.1.7"
     js-sha3 "^0.8.0"
@@ -1755,14 +1916,14 @@
     tweetnacl "^1.0.3"
     xxhashjs "^0.2.2"
 
-"@polkadot/util@7.0.1", "@polkadot/util@^7.0.1":
-  version "7.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-7.0.1.tgz#79afd40473016876f51d65ebb9900a20108fe0a4"
-  integrity sha512-EtQlZL6ok0Ep+zRz2QHMUoJo/b3kFHVN2qqyD2+9sdqg0FGLmkzNFM+K6dasCMLXieJ1l0HoFsQppSo/leUeaA==
+"@polkadot/util@7.2.1", "@polkadot/util@^7.2.1":
+  version "7.2.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-7.2.1.tgz#abcad49f884534ff042c37480f63b9750c69341d"
+  integrity sha512-GilFg3i5dmu0H6dHEyh5bUw3yywmnFpEHfxFmKghL1ABDEr4qD0d/XAJ9UrzLFCBKbdTZsR0MDjgjVI2N84J1A==
   dependencies:
-    "@babel/runtime" "^7.14.6"
-    "@polkadot/x-textdecoder" "7.0.1"
-    "@polkadot/x-textencoder" "7.0.1"
+    "@babel/runtime" "^7.15.3"
+    "@polkadot/x-textdecoder" "7.2.1"
+    "@polkadot/x-textencoder" "7.2.1"
     "@types/bn.js" "^4.11.6"
     bn.js "^4.11.9"
     camelcase "^5.3.1"
@@ -1791,57 +1952,114 @@
     "@polkadot/wasm-crypto-asmjs" "^4.1.2"
     "@polkadot/wasm-crypto-wasm" "^4.1.2"
 
-"@polkadot/x-fetch@^7.0.1":
-  version "7.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-7.0.1.tgz#2db6fa19f4f4d9b2f4cf50ba78bf3aa947d7b982"
-  integrity sha512-9R38FjtlJcvdpEA7tVGmTmH4aiBCTABuLJdVSn3cYkgWfxDHeFMqjdFzTJ6Asa5cY0Ds3ZKsh9uccTQBQzV/HQ==
+"@polkadot/x-fetch@^7.2.1":
+  version "7.2.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-7.2.1.tgz#c9bee0316d31cd150b2cb6646ccdb77c6dc3d42d"
+  integrity sha512-osdZNPfrB50d7tfjVs4QRjfsb6xqC09JEeYzbUl24hUXPwtkQE8/379jayu1usPe9/JI2wKYGscdf/nRl4pBkA==
   dependencies:
-    "@babel/runtime" "^7.14.6"
-    "@polkadot/x-global" "7.0.1"
-    "@types/node-fetch" "^2.5.11"
+    "@babel/runtime" "^7.15.3"
+    "@polkadot/x-global" "7.2.1"
+    "@types/node-fetch" "^2.5.12"
     node-fetch "^2.6.1"
 
-"@polkadot/x-global@7.0.1", "@polkadot/x-global@^7.0.1":
-  version "7.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-7.0.1.tgz#44fb248d3aaea557753318327149772969e96bff"
-  integrity sha512-gVVACSdRhHYRJejLEAL0mM9BZfY8N50VT2+15A7ALD1tVqwS4tz3P9vRW3Go7ZjfyAc83aEmh0PiQ8Nm1R+2Cg==
+"@polkadot/x-global@7.2.1", "@polkadot/x-global@^7.2.1":
+  version "7.2.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-7.2.1.tgz#32207936b7f939a21da608f82ca20535f9148cda"
+  integrity sha512-VNW+76TxEPqvBy3XMNV05mJRPRGZcYh3k5HjW4+asYeFunMahH4zjmCulhtD9SRI/TqdfHTiqDOqKNKe2xJcVg==
   dependencies:
-    "@babel/runtime" "^7.14.6"
+    "@babel/runtime" "^7.15.3"
 
-"@polkadot/x-randomvalues@7.0.1":
-  version "7.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-7.0.1.tgz#32036ae5d48645a062f6a1c3ebbf227236c806b8"
-  integrity sha512-UNoIFaz1xJPozruT+lo8BTeT8A3NM3PgWuru7Vs8OsIz0Phkg7lUWlpHu9PZHyQCyKlUryvkOA692IlVlNYy2Q==
+"@polkadot/x-randomvalues@7.2.1":
+  version "7.2.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-7.2.1.tgz#708b7a54bd90ec091ab54e125d8b52e0853ea86b"
+  integrity sha512-B4sjwX+gFweZ1YM1Cg/S9hAEx9E/gV/vqLW89PJB6+hyvsPS9eiVvfVpaOsohc7AgmuINm/bSQbNZvtC+BbbKw==
   dependencies:
-    "@babel/runtime" "^7.14.6"
-    "@polkadot/x-global" "7.0.1"
+    "@babel/runtime" "^7.15.3"
+    "@polkadot/x-global" "7.2.1"
 
-"@polkadot/x-textdecoder@7.0.1":
-  version "7.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-7.0.1.tgz#bb9bba94b2eb1612dd35c299f43ab74515db74d9"
-  integrity sha512-CFRnpI0cp1h2N1+ec551BLVLwV6OHG6Gj62EYcIOXR+o/SX/6MXm3Qcehm2YvfTKqktyIUSWmTwbWjGjuqPrpA==
+"@polkadot/x-textdecoder@7.2.1":
+  version "7.2.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-7.2.1.tgz#c52074dba9943a12583f3f8672a49399f10e00f3"
+  integrity sha512-yXSZ0P/D/8HT8gbkdTjw/1AKZIVbX3+mIfiDiN3VqUBzruV7ak5hA+D01I0woBGDqxWISoLQFtGrxPAQ8pwAcg==
   dependencies:
-    "@babel/runtime" "^7.14.6"
-    "@polkadot/x-global" "7.0.1"
+    "@babel/runtime" "^7.15.3"
+    "@polkadot/x-global" "7.2.1"
 
-"@polkadot/x-textencoder@7.0.1":
-  version "7.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-7.0.1.tgz#181d403c5dc1d94fd1e2147fd1c5c528d30d8805"
-  integrity sha512-m+QL1HNiu5GMz6cfr/udSA6fUTv3RyIybJb7v43EQCxqlj/L0J3cUHapFd6tqH9PElD6jPkH1pXcgYN8e7dWTQ==
+"@polkadot/x-textencoder@7.2.1":
+  version "7.2.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-7.2.1.tgz#2326b3b7f9a5e445d7e560c438effbe800e2b1f6"
+  integrity sha512-1aqfxmfKSOWeOxmGBmk+RYrpqGtWywS6t0y/R3FI+k+s8NfIfGdcjMcupKq7khPh92PvVGkur+CnM/y6chn4XA==
   dependencies:
-    "@babel/runtime" "^7.14.6"
-    "@polkadot/x-global" "7.0.1"
+    "@babel/runtime" "^7.15.3"
+    "@polkadot/x-global" "7.2.1"
 
-"@polkadot/x-ws@^7.0.1":
-  version "7.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-7.0.1.tgz#8c22a61c0dd9b82865c7631e22ac147c2b73b118"
-  integrity sha512-VUn/6sCJUpvW9WhUK+DKo1uDrw4yO84twRcy5JSzvSiBTaSplhU9Q4qGFl2Atr3WIzAYYx1jQSm/j6AhPRji1w==
+"@polkadot/x-ws@^7.2.1":
+  version "7.2.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-7.2.1.tgz#5971ab630911cdecd0a46db6fb899e9086954e58"
+  integrity sha512-sYnOF0qNdMuGFiRGWAtpkQQYIP44JFzGywap0CskhNEyCc+zDBi4l/ta3qHjeGta+h9rdVjDeYk2J86EsKlkSw==
   dependencies:
-    "@babel/runtime" "^7.14.6"
-    "@polkadot/x-global" "7.0.1"
-    "@types/websocket" "^1.0.3"
+    "@babel/runtime" "^7.15.3"
+    "@polkadot/x-global" "7.2.1"
+    "@types/websocket" "^1.0.4"
     websocket "^1.0.34"
 
+"@rollup/plugin-alias@^3.1.5":
+  version "3.1.5"
+  resolved "https://registry.yarnpkg.com/@rollup/plugin-alias/-/plugin-alias-3.1.5.tgz#73356a3a1eab2e1e2fd952f9f53cd89fc740d952"
+  integrity sha512-yzUaSvCC/LJPbl9rnzX3HN7vy0tq7EzHoEiQl1ofh4n5r2Rd5bj/+zcJgaGA76xbw95/JjWQyvHg9rOJp2y0oQ==
+  dependencies:
+    slash "^3.0.0"
+
+"@rollup/plugin-commonjs@^19.0.2":
+  version "19.0.2"
+  resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-19.0.2.tgz#1ccc3d63878d1bc9846f8969f09dd3b3e4ecc244"
+  integrity sha512-gBjarfqlC7qs0AutpRW/hrFNm+cd2/QKxhwyFa+srbg1oX7rDsEU3l+W7LAUhsAp9mPJMAkXDhLbQaVwEaE8bA==
+  dependencies:
+    "@rollup/pluginutils" "^3.1.0"
+    commondir "^1.0.1"
+    estree-walker "^2.0.1"
+    glob "^7.1.6"
+    is-reference "^1.2.1"
+    magic-string "^0.25.7"
+    resolve "^1.17.0"
+
+"@rollup/plugin-inject@^4.0.2":
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/@rollup/plugin-inject/-/plugin-inject-4.0.2.tgz#55b21bb244a07675f7fdde577db929c82fc17395"
+  integrity sha512-TSLMA8waJ7Dmgmoc8JfPnwUwVZgLjjIAM6MqeIFqPO2ODK36JqE0Cf2F54UTgCUuW8da93Mvoj75a6KAVWgylw==
+  dependencies:
+    "@rollup/pluginutils" "^3.0.4"
+    estree-walker "^1.0.1"
+    magic-string "^0.25.5"
+
+"@rollup/plugin-json@^4.1.0":
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-4.1.0.tgz#54e09867ae6963c593844d8bd7a9c718294496f3"
+  integrity sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==
+  dependencies:
+    "@rollup/pluginutils" "^3.0.8"
+
+"@rollup/plugin-node-resolve@^13.0.4":
+  version "13.0.4"
+  resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.4.tgz#b10222f4145a019740acb7738402130d848660c0"
+  integrity sha512-eYq4TFy40O8hjeDs+sIxEH/jc9lyuI2k9DM557WN6rO5OpnC2qXMBNj4IKH1oHrnAazL49C5p0tgP0/VpqJ+/w==
+  dependencies:
+    "@rollup/pluginutils" "^3.1.0"
+    "@types/resolve" "1.17.1"
+    builtin-modules "^3.1.0"
+    deepmerge "^4.2.2"
+    is-module "^1.0.0"
+    resolve "^1.19.0"
+
+"@rollup/pluginutils@^3.0.4", "@rollup/pluginutils@^3.0.8", "@rollup/pluginutils@^3.1.0":
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b"
+  integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==
+  dependencies:
+    "@types/estree" "0.0.39"
+    estree-walker "^1.0.1"
+    picomatch "^2.2.2"
+
 "@rushstack/eslint-patch@^1.0.6":
   version "1.0.6"
   resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.0.6.tgz#023d72a5c4531b4ce204528971700a78a85a0c50"
@@ -1930,18 +2148,23 @@
   resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.18.tgz#0c8e298dbff8205e2266606c1ea5fbdba29b46e4"
   integrity sha512-rS27+EkB/RE1Iz3u0XtVL5q36MGDWbgYe7zWiodyKNUnthxY0rukK5V36eiUCtCisB7NN8zKYH6DO2M37qxFEQ==
 
-"@types/chrome@^0.0.144":
-  version "0.0.144"
-  resolved "https://registry.yarnpkg.com/@types/chrome/-/chrome-0.0.144.tgz#7dd9188e355aa17e3ad397f50b5cd3ad12caf788"
-  integrity sha512-BgoiO7/KP9hRNrCR2Wq+aKWT5Dh9bTofuWaRtcqPcj8YKhZojQgb6sSdIqvds2C+eO63BwaR9KHVMYYgZdGGBg==
+"@types/chrome@^0.0.145":
+  version "0.0.145"
+  resolved "https://registry.yarnpkg.com/@types/chrome/-/chrome-0.0.145.tgz#6c53ae0af5f25350b07bfd24cf459b5fe65cd9b8"
+  integrity sha512-vLvTMmfc8mvwOZzkmn2UwlWSNu0t0txBkyuIv8NgihRkvFCe6XJX65YZAgAP/RdBit3enhU2GTxCr+prn4uZmA==
   dependencies:
     "@types/filesystem" "*"
     "@types/har-format" "*"
 
-"@types/eslint-visitor-keys@^1.0.0":
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
-  integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==
+"@types/estree@*":
+  version "0.0.50"
+  resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83"
+  integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==
+
+"@types/estree@0.0.39":
+  version "0.0.39"
+  resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
+  integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
 
 "@types/filesystem@*":
   version "0.0.30"
@@ -1985,11 +2208,6 @@
   integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==
   dependencies:
     "@types/istanbul-lib-report" "*"
-
-"@types/json-schema@^7.0.3":
-  version "7.0.8"
-  resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.8.tgz#edf1bf1dbf4e04413ca8e5b17b3b7d7d54b59818"
-  integrity sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==
 
 "@types/json-schema@^7.0.7":
   version "7.0.7"
@@ -2006,10 +2224,10 @@
   resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.2.tgz#91daa226eb8c2ff261e6a8cbf8c7304641e095e0"
   integrity sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==
 
-"@types/node-fetch@^2.5.11":
-  version "2.5.11"
-  resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.11.tgz#ce22a2e65fc8999f4dbdb7ddbbcf187d755169e4"
-  integrity sha512-2upCKaqVZETDRb8A2VTaRymqFBEgH8u6yr96b/u3+1uQEPDRo3mJLEiPk7vdXBHRtjwkjqzFYMJXrt0Z9QsYjQ==
+"@types/node-fetch@^2.5.12":
+  version "2.5.12"
+  resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.12.tgz#8a6f779b1d4e60b7a57fb6fd48d84fb545b9cc66"
+  integrity sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==
   dependencies:
     "@types/node" "*"
     form-data "^3.0.0"
@@ -2041,6 +2259,13 @@
   resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.0.tgz#2e8332cc7363f887d32ec5496b207d26ba8052bb"
   integrity sha512-hkc1DATxFLQo4VxPDpMH1gCkPpBbpOoJ/4nhuXw4n63/0R6bCpQECj4+K226UJ4JO/eJQz+1mC2I7JsWanAdQw==
 
+"@types/resolve@1.17.1":
+  version "1.17.1"
+  resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6"
+  integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==
+  dependencies:
+    "@types/node" "*"
+
 "@types/secp256k1@^4.0.1":
   version "4.0.2"
   resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.2.tgz#20c29a87149d980f64464e56539bf4810fdb5d1d"
@@ -2053,10 +2278,10 @@
   resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff"
   integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==
 
-"@types/websocket@^1.0.3":
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.3.tgz#49e09f939afd0ccdee4f7108d4712ec9feb0f153"
-  integrity sha512-ZdoTSwmDsKR7l1I8fpfQtmTI/hUwlOvE3q0iyJsp4tXU0MkdrYowimDzwxjhQvxU4qjhHLd3a6ig0OXRbLgIdw==
+"@types/websocket@^1.0.4":
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.4.tgz#1dc497280d8049a5450854dd698ee7e6ea9e60b8"
+  integrity sha512-qn1LkcFEKK8RPp459jkjzsfpbsx36BBt3oC3pITYtkoBw/aVX+EZFa5j3ThCRTNpLFvIMr5dSTD4RaMdilIOpA==
   dependencies:
     "@types/node" "*"
 
@@ -2072,119 +2297,127 @@
   dependencies:
     "@types/yargs-parser" "*"
 
-"@typescript-eslint/eslint-plugin@4.28.0":
-  version "4.28.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.0.tgz#1a66f03b264844387beb7dc85e1f1d403bd1803f"
-  integrity sha512-KcF6p3zWhf1f8xO84tuBailV5cN92vhS+VT7UJsPzGBm9VnQqfI9AsiMUFUCYHTYPg1uCCo+HyiDnpDuvkAMfQ==
+"@typescript-eslint/eslint-plugin@4.29.2":
+  version "4.29.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.2.tgz#f54dc0a32b8f61c6024ab8755da05363b733838d"
+  integrity sha512-x4EMgn4BTfVd9+Z+r+6rmWxoAzBaapt4QFqE+d8L8sUtYZYLDTK6VG/y/SMMWA5t1/BVU5Kf+20rX4PtWzUYZg==
   dependencies:
-    "@typescript-eslint/experimental-utils" "4.28.0"
-    "@typescript-eslint/scope-manager" "4.28.0"
+    "@typescript-eslint/experimental-utils" "4.29.2"
+    "@typescript-eslint/scope-manager" "4.29.2"
     debug "^4.3.1"
     functional-red-black-tree "^1.0.1"
     regexpp "^3.1.0"
     semver "^7.3.5"
     tsutils "^3.21.0"
 
-"@typescript-eslint/eslint-plugin@^3.4.0":
-  version "3.10.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.10.1.tgz#7e061338a1383f59edc204c605899f93dc2e2c8f"
-  integrity sha512-PQg0emRtzZFWq6PxBcdxRH3QIQiyFO3WCVpRL3fgj5oQS3CDs3AeAKfv4DxNhzn8ITdNJGJ4D3Qw8eAJf3lXeQ==
+"@typescript-eslint/eslint-plugin@^4.28.5":
+  version "4.28.5"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.5.tgz#8197f1473e7da8218c6a37ff308d695707835684"
+  integrity sha512-m31cPEnbuCqXtEZQJOXAHsHvtoDi9OVaeL5wZnO2KZTnkvELk+u6J6jHg+NzvWQxk+87Zjbc4lJS4NHmgImz6Q==
   dependencies:
-    "@typescript-eslint/experimental-utils" "3.10.1"
-    debug "^4.1.1"
+    "@typescript-eslint/experimental-utils" "4.28.5"
+    "@typescript-eslint/scope-manager" "4.28.5"
+    debug "^4.3.1"
     functional-red-black-tree "^1.0.1"
-    regexpp "^3.0.0"
-    semver "^7.3.2"
-    tsutils "^3.17.1"
+    regexpp "^3.1.0"
+    semver "^7.3.5"
+    tsutils "^3.21.0"
 
-"@typescript-eslint/experimental-utils@3.10.1":
-  version "3.10.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz#e179ffc81a80ebcae2ea04e0332f8b251345a686"
-  integrity sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw==
+"@typescript-eslint/experimental-utils@4.28.5":
+  version "4.28.5"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.5.tgz#66c28bef115b417cf9d80812a713e0e46bb42a64"
+  integrity sha512-bGPLCOJAa+j49hsynTaAtQIWg6uZd8VLiPcyDe4QPULsvQwLHGLSGKKcBN8/lBxIX14F74UEMK2zNDI8r0okwA==
   dependencies:
-    "@types/json-schema" "^7.0.3"
-    "@typescript-eslint/types" "3.10.1"
-    "@typescript-eslint/typescript-estree" "3.10.1"
-    eslint-scope "^5.0.0"
-    eslint-utils "^2.0.0"
+    "@types/json-schema" "^7.0.7"
+    "@typescript-eslint/scope-manager" "4.28.5"
+    "@typescript-eslint/types" "4.28.5"
+    "@typescript-eslint/typescript-estree" "4.28.5"
+    eslint-scope "^5.1.1"
+    eslint-utils "^3.0.0"
 
-"@typescript-eslint/experimental-utils@4.28.0":
-  version "4.28.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.0.tgz#13167ed991320684bdc23588135ae62115b30ee0"
-  integrity sha512-9XD9s7mt3QWMk82GoyUpc/Ji03vz4T5AYlHF9DcoFNfJ/y3UAclRsfGiE2gLfXtyC+JRA3trR7cR296TEb1oiQ==
+"@typescript-eslint/experimental-utils@4.29.2":
+  version "4.29.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.2.tgz#5f67fb5c5757ef2cb3be64817468ba35c9d4e3b7"
+  integrity sha512-P6mn4pqObhftBBPAv4GQtEK7Yos1fz/MlpT7+YjH9fTxZcALbiiPKuSIfYP/j13CeOjfq8/fr9Thr2glM9ub7A==
   dependencies:
     "@types/json-schema" "^7.0.7"
-    "@typescript-eslint/scope-manager" "4.28.0"
-    "@typescript-eslint/types" "4.28.0"
-    "@typescript-eslint/typescript-estree" "4.28.0"
+    "@typescript-eslint/scope-manager" "4.29.2"
+    "@typescript-eslint/types" "4.29.2"
+    "@typescript-eslint/typescript-estree" "4.29.2"
     eslint-scope "^5.1.1"
     eslint-utils "^3.0.0"
 
-"@typescript-eslint/parser@4.28.0":
-  version "4.28.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.0.tgz#2404c16751a28616ef3abab77c8e51d680a12caa"
-  integrity sha512-7x4D22oPY8fDaOCvkuXtYYTQ6mTMmkivwEzS+7iml9F9VkHGbbZ3x4fHRwxAb5KeuSkLqfnYjs46tGx2Nour4A==
+"@typescript-eslint/parser@4.29.2":
+  version "4.29.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.29.2.tgz#1c7744f4c27aeb74610c955d3dce9250e95c370a"
+  integrity sha512-WQ6BPf+lNuwteUuyk1jD/aHKqMQ9jrdCn7Gxt9vvBnzbpj7aWEf+aZsJ1zvTjx5zFxGCt000lsbD9tQPEL8u6g==
   dependencies:
-    "@typescript-eslint/scope-manager" "4.28.0"
-    "@typescript-eslint/types" "4.28.0"
-    "@typescript-eslint/typescript-estree" "4.28.0"
+    "@typescript-eslint/scope-manager" "4.29.2"
+    "@typescript-eslint/types" "4.29.2"
+    "@typescript-eslint/typescript-estree" "4.29.2"
     debug "^4.3.1"
 
-"@typescript-eslint/parser@^3.4.0":
-  version "3.10.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.10.1.tgz#1883858e83e8b442627e1ac6f408925211155467"
-  integrity sha512-Ug1RcWcrJP02hmtaXVS3axPPTTPnZjupqhgj+NnZ6BCkwSImWk/283347+x9wN+lqOdK9Eo3vsyiyDHgsmiEJw==
+"@typescript-eslint/parser@^4.28.5":
+  version "4.28.5"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.5.tgz#9c971668f86d1b5c552266c47788a87488a47d1c"
+  integrity sha512-NPCOGhTnkXGMqTznqgVbA5LqVsnw+i3+XA1UKLnAb+MG1Y1rP4ZSK9GX0kJBmAZTMIktf+dTwXToT6kFwyimbw==
   dependencies:
-    "@types/eslint-visitor-keys" "^1.0.0"
-    "@typescript-eslint/experimental-utils" "3.10.1"
-    "@typescript-eslint/types" "3.10.1"
-    "@typescript-eslint/typescript-estree" "3.10.1"
-    eslint-visitor-keys "^1.1.0"
+    "@typescript-eslint/scope-manager" "4.28.5"
+    "@typescript-eslint/types" "4.28.5"
+    "@typescript-eslint/typescript-estree" "4.28.5"
+    debug "^4.3.1"
 
-"@typescript-eslint/scope-manager@4.28.0":
-  version "4.28.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.0.tgz#6a3009d2ab64a30fc8a1e257a1a320067f36a0ce"
-  integrity sha512-eCALCeScs5P/EYjwo6se9bdjtrh8ByWjtHzOkC4Tia6QQWtQr3PHovxh3TdYTuFcurkYI4rmFsRFpucADIkseg==
+"@typescript-eslint/scope-manager@4.28.5":
+  version "4.28.5"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.5.tgz#3a1b70c50c1535ac33322786ea99ebe403d3b923"
+  integrity sha512-PHLq6n9nTMrLYcVcIZ7v0VY1X7dK309NM8ya9oL/yG8syFINIMHxyr2GzGoBYUdv3NUfCOqtuqps0ZmcgnZTfQ==
   dependencies:
-    "@typescript-eslint/types" "4.28.0"
-    "@typescript-eslint/visitor-keys" "4.28.0"
+    "@typescript-eslint/types" "4.28.5"
+    "@typescript-eslint/visitor-keys" "4.28.5"
 
-"@typescript-eslint/types@3.10.1":
-  version "3.10.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.10.1.tgz#1d7463fa7c32d8a23ab508a803ca2fe26e758727"
-  integrity sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ==
+"@typescript-eslint/scope-manager@4.29.2":
+  version "4.29.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.29.2.tgz#442b0f029d981fa402942715b1718ac7fcd5aa1b"
+  integrity sha512-mfHmvlQxmfkU8D55CkZO2sQOueTxLqGvzV+mG6S/6fIunDiD2ouwsAoiYCZYDDK73QCibYjIZmGhpvKwAB5BOA==
+  dependencies:
+    "@typescript-eslint/types" "4.29.2"
+    "@typescript-eslint/visitor-keys" "4.29.2"
 
 "@typescript-eslint/types@4.27.0":
   version "4.27.0"
   resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.27.0.tgz#712b408519ed699baff69086bc59cd2fc13df8d8"
   integrity sha512-I4ps3SCPFCKclRcvnsVA/7sWzh7naaM/b4pBO2hVxnM3wrU51Lveybdw5WoIktU/V4KfXrTt94V9b065b/0+wA==
 
-"@typescript-eslint/types@4.28.0":
-  version "4.28.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.0.tgz#a33504e1ce7ac51fc39035f5fe6f15079d4dafb0"
-  integrity sha512-p16xMNKKoiJCVZY5PW/AfILw2xe1LfruTcfAKBj3a+wgNYP5I9ZEKNDOItoRt53p4EiPV6iRSICy8EPanG9ZVA==
+"@typescript-eslint/types@4.28.5":
+  version "4.28.5"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.5.tgz#d33edf8e429f0c0930a7c3d44e9b010354c422e9"
+  integrity sha512-MruOu4ZaDOLOhw4f/6iudyks/obuvvZUAHBDSW80Trnc5+ovmViLT2ZMDXhUV66ozcl6z0LJfKs1Usldgi/WCA==
+
+"@typescript-eslint/types@4.29.2":
+  version "4.29.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.29.2.tgz#fc0489c6b89773f99109fb0aa0aaddff21f52fcd"
+  integrity sha512-K6ApnEXId+WTGxqnda8z4LhNMa/pZmbTFkDxEBLQAbhLZL50DjeY0VIDCml/0Y3FlcbqXZrABqrcKxq+n0LwzQ==
 
-"@typescript-eslint/typescript-estree@3.10.1":
-  version "3.10.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz#fd0061cc38add4fad45136d654408569f365b853"
-  integrity sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w==
+"@typescript-eslint/typescript-estree@4.28.5":
+  version "4.28.5"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.5.tgz#4906d343de693cf3d8dcc301383ed638e0441cd1"
+  integrity sha512-FzJUKsBX8poCCdve7iV7ShirP8V+ys2t1fvamVeD1rWpiAnIm550a+BX/fmTHrjEpQJ7ZAn+Z7ZZwJjytk9rZw==
   dependencies:
-    "@typescript-eslint/types" "3.10.1"
-    "@typescript-eslint/visitor-keys" "3.10.1"
-    debug "^4.1.1"
-    glob "^7.1.6"
+    "@typescript-eslint/types" "4.28.5"
+    "@typescript-eslint/visitor-keys" "4.28.5"
+    debug "^4.3.1"
+    globby "^11.0.3"
     is-glob "^4.0.1"
-    lodash "^4.17.15"
-    semver "^7.3.2"
-    tsutils "^3.17.1"
+    semver "^7.3.5"
+    tsutils "^3.21.0"
 
-"@typescript-eslint/typescript-estree@4.28.0":
-  version "4.28.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.0.tgz#e66d4e5aa2ede66fec8af434898fe61af10c71cf"
-  integrity sha512-m19UQTRtxMzKAm8QxfKpvh6OwQSXaW1CdZPoCaQuLwAq7VZMNuhJmZR4g5281s2ECt658sldnJfdpSZZaxUGMQ==
+"@typescript-eslint/typescript-estree@4.29.2":
+  version "4.29.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.2.tgz#a0ea8b98b274adbb2577100ba545ddf8bf7dc219"
+  integrity sha512-TJ0/hEnYxapYn9SGn3dCnETO0r+MjaxtlWZ2xU+EvytF0g4CqTpZL48SqSNn2hXsPolnewF30pdzR9a5Lj3DNg==
   dependencies:
-    "@typescript-eslint/types" "4.28.0"
-    "@typescript-eslint/visitor-keys" "4.28.0"
+    "@typescript-eslint/types" "4.29.2"
+    "@typescript-eslint/visitor-keys" "4.29.2"
     debug "^4.3.1"
     globby "^11.0.3"
     is-glob "^4.0.1"
@@ -2204,13 +2437,6 @@
     semver "^7.3.5"
     tsutils "^3.21.0"
 
-"@typescript-eslint/visitor-keys@3.10.1":
-  version "3.10.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz#cd4274773e3eb63b2e870ac602274487ecd1e931"
-  integrity sha512-9JgC82AaQeglebjZMgYR5wgmfUdUc+EitGUUMW8u2nDckaeimzW+VsoLV6FoimPv2id3VQzfjwBxEMVz08ameQ==
-  dependencies:
-    eslint-visitor-keys "^1.1.0"
-
 "@typescript-eslint/visitor-keys@4.27.0":
   version "4.27.0"
   resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.27.0.tgz#f56138b993ec822793e7ebcfac6ffdce0a60cb81"
@@ -2219,14 +2445,22 @@
     "@typescript-eslint/types" "4.27.0"
     eslint-visitor-keys "^2.0.0"
 
-"@typescript-eslint/visitor-keys@4.28.0":
-  version "4.28.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.0.tgz#255c67c966ec294104169a6939d96f91c8a89434"
-  integrity sha512-PjJyTWwrlrvM5jazxYF5ZPs/nl0kHDZMVbuIcbpawVXaDPelp3+S9zpOz5RmVUfS/fD5l5+ZXNKnWhNYjPzCvw==
+"@typescript-eslint/visitor-keys@4.28.5":
+  version "4.28.5"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.5.tgz#ffee2c602762ed6893405ee7c1144d9cc0a29675"
+  integrity sha512-dva/7Rr+EkxNWdJWau26xU/0slnFlkh88v3TsyTgRS/IIYFi5iIfpCFM4ikw0vQTFUR9FYSSyqgK4w64gsgxhg==
   dependencies:
-    "@typescript-eslint/types" "4.28.0"
+    "@typescript-eslint/types" "4.28.5"
     eslint-visitor-keys "^2.0.0"
 
+"@typescript-eslint/visitor-keys@4.29.2":
+  version "4.29.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.2.tgz#d2da7341f3519486f50655159f4e5ecdcb2cd1df"
+  integrity sha512-bDgJLQ86oWHJoZ1ai4TZdgXzJxsea3Ee9u9wsTAvjChdj2WLcVsgWYAPeY7RQMn16tKrlQaBnpKv7KBfs4EQag==
+  dependencies:
+    "@typescript-eslint/types" "4.29.2"
+    eslint-visitor-keys "^2.0.0"
+
 "@ungap/promise-all-settled@1.1.2":
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"
@@ -2592,16 +2826,16 @@
   resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
   integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
 
-babel-jest@^27.0.5:
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.0.5.tgz#cd34c033ada05d1362211e5152391fd7a88080c8"
-  integrity sha512-bTMAbpCX7ldtfbca2llYLeSFsDM257aspyAOpsdrdSrBqoLkWCy4HPYTXtXWaSLgFPjrJGACL65rzzr4RFGadw==
+babel-jest@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.0.6.tgz#e99c6e0577da2655118e3608b68761a5a69bd0d8"
+  integrity sha512-iTJyYLNc4wRofASmofpOc5NK9QunwMk+TLFgGXsTFS8uEqmd8wdI7sga0FPe2oVH3b5Agt/EAK1QjPEuKL8VfA==
   dependencies:
-    "@jest/transform" "^27.0.5"
-    "@jest/types" "^27.0.2"
+    "@jest/transform" "^27.0.6"
+    "@jest/types" "^27.0.6"
     "@types/babel__core" "^7.1.14"
     babel-plugin-istanbul "^6.0.0"
-    babel-preset-jest "^27.0.1"
+    babel-preset-jest "^27.0.6"
     chalk "^4.0.0"
     graceful-fs "^4.2.4"
     slash "^3.0.0"
@@ -2624,10 +2858,10 @@
     istanbul-lib-instrument "^4.0.0"
     test-exclude "^6.0.0"
 
-babel-plugin-jest-hoist@^27.0.1:
-  version "27.0.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.1.tgz#a6d10e484c93abff0f4e95f437dad26e5736ea11"
-  integrity sha512-sqBF0owAcCDBVEDtxqfYr2F36eSHdx7lAVGyYuOBRnKdD6gzcy0I0XrAYCZgOA3CRrLhmR+Uae9nogPzmAtOfQ==
+babel-plugin-jest-hoist@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.6.tgz#f7c6b3d764af21cb4a2a1ab6870117dbde15b456"
+  integrity sha512-CewFeM9Vv2gM7Yr9n5eyyLVPRSiBnk6lKZRjgwYnGKSl9M14TMn2vkN02wTF04OGuSDLEzlWiMzvjXuW9mB6Gw==
   dependencies:
     "@babel/template" "^7.3.3"
     "@babel/types" "^7.3.3"
@@ -2674,10 +2908,10 @@
   dependencies:
     "@babel/helper-define-polyfill-provider" "^0.2.2"
 
-babel-plugin-styled-components@^1.12.0:
-  version "1.12.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.12.0.tgz#1dec1676512177de6b827211e9eda5a30db4f9b9"
-  integrity sha512-FEiD7l5ZABdJPpLssKXjBUJMYqzbcNzBowfXDCdJhOpbhWiewapUaY+LZGT8R4Jg2TwOjGjG4RKeyrO5p9sBkA==
+babel-plugin-styled-components@^1.13.2:
+  version "1.13.2"
+  resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.13.2.tgz#ebe0e6deff51d7f93fceda1819e9b96aeb88278d"
+  integrity sha512-Vb1R3d4g+MUfPQPVDMCGjm3cDocJEUTR7Xq7QS95JWWeksN1wdFRYpD2kulDgI3Huuaf1CZd+NK4KQmqUFh5dA==
   dependencies:
     "@babel/helper-annotate-as-pure" "^7.0.0"
     "@babel/helper-module-imports" "^7.0.0"
@@ -2707,12 +2941,12 @@
     "@babel/plugin-syntax-optional-chaining" "^7.8.3"
     "@babel/plugin-syntax-top-level-await" "^7.8.3"
 
-babel-preset-jest@^27.0.1:
-  version "27.0.1"
-  resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.0.1.tgz#7a50c75d16647c23a2cf5158d5bb9eb206b10e20"
-  integrity sha512-nIBIqCEpuiyhvjQs2mVNwTxQQa2xk70p9Dd/0obQGBf8FBzbnI8QhQKzLsWMN2i6q+5B0OcWDtrboBX5gmOLyA==
+babel-preset-jest@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.0.6.tgz#909ef08e9f24a4679768be2f60a3df0856843f9d"
+  integrity sha512-WObA0/Biw2LrVVwZkF/2GqbOdzhKD6Fkdwhoy9ASIrOWr/zodcSpQh72JOkEn6NWyjmnPDjNSqaGN4KnpKzhXw==
   dependencies:
-    babel-plugin-jest-hoist "^27.0.1"
+    babel-plugin-jest-hoist "^27.0.6"
     babel-preset-current-node-syntax "^1.0.0"
 
 balanced-match@^1.0.0:
@@ -2952,6 +3186,17 @@
     escalade "^3.1.1"
     node-releases "^1.1.71"
 
+browserslist@^4.16.7:
+  version "4.16.7"
+  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.7.tgz#108b0d1ef33c4af1b587c54f390e7041178e4335"
+  integrity sha512-7I4qVwqZltJ7j37wObBe3SoTz+nS8APaNcrBOlgoirb6/HbEU2XxW/LpUDTCngM6iauwFqmRTuOMfyKnFGY5JA==
+  dependencies:
+    caniuse-lite "^1.0.30001248"
+    colorette "^1.2.2"
+    electron-to-chromium "^1.3.793"
+    escalade "^3.1.1"
+    node-releases "^1.1.73"
+
 bs58@^4.0.0:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a"
@@ -3010,6 +3255,11 @@
   resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
   integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=
 
+builtin-modules@^3.1.0:
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887"
+  integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==
+
 bytes@3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
@@ -3071,6 +3321,11 @@
   resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001238.tgz#e6a8b45455c5de601718736d0242feef0ecdda15"
   integrity sha512-bZGam2MxEt7YNsa2VwshqWQMwrYs5tR5WZQRYSuFxsBQunWjBuXhN4cS9nV5FFb1Z9y+DoQcQ0COyQbv6A+CKw==
 
+caniuse-lite@^1.0.30001248:
+  version "1.0.30001251"
+  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz#6853a606ec50893115db660f82c094d18f096d85"
+  integrity sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A==
+
 caseless@~0.12.0:
   version "0.12.0"
   resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
@@ -3120,6 +3375,14 @@
     ansi-styles "^4.1.0"
     supports-color "^7.1.0"
 
+chalk@^4.1.2:
+  version "4.1.2"
+  resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
+  integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
+  dependencies:
+    ansi-styles "^4.1.0"
+    supports-color "^7.1.0"
+
 changelog-parser@^2.0.0:
   version "2.8.0"
   resolved "https://registry.yarnpkg.com/changelog-parser/-/changelog-parser-2.8.0.tgz#c14293e3e8fab797913c722de965480198650108"
@@ -3338,6 +3601,16 @@
   dependencies:
     delayed-stream "~1.0.0"
 
+command-exists@^1.2.8:
+  version "1.2.9"
+  resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69"
+  integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==
+
+commander@3.0.2:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e"
+  integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==
+
 commander@^2.12.1, commander@^2.16.0, commander@^2.18.0, commander@^2.20.3, commander@^2.8.1:
   version "2.20.3"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
@@ -3448,12 +3721,12 @@
     browserslist "^4.16.6"
     semver "7.0.0"
 
-core-js-compat@^3.15.0:
-  version "3.15.1"
-  resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.15.1.tgz#1afe233716d37ee021956ef097594071b2b585a7"
-  integrity sha512-xGhzYMX6y7oEGQGAJmP2TmtBLvR4nZmRGEcFa3ubHOq5YEp51gGN9AovVa0AoujGZIq+Wm6dISiYyGNfdflYww==
+core-js-compat@^3.16.0:
+  version "3.16.1"
+  resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.16.1.tgz#c44b7caa2dcb94b673a98f27eee1c8312f55bc2d"
+  integrity sha512-NHXQXvRbd4nxp9TEmooTJLUf94ySUG6+DSsscBpTftN1lQLQ4LjnWvc7AoIo4UjDsFF3hB8Uh5LLCRRdaiT5MQ==
   dependencies:
-    browserslist "^4.16.6"
+    browserslist "^4.16.7"
     semver "7.0.0"
 
 core-util-is@1.0.2, core-util-is@~1.0.0:
@@ -3469,10 +3742,10 @@
     object-assign "^4"
     vary "^1"
 
-coveralls@^3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.1.0.tgz#13c754d5e7a2dd8b44fe5269e21ca394fb4d615b"
-  integrity sha512-sHxOu2ELzW8/NC1UP5XVLbZDzO4S3VxfFye3XYCznopHy02YjNkHcj5bKaVw2O7hVaBdBjEdQGpie4II1mWhuQ==
+coveralls@^3.1.1:
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.1.1.tgz#f5d4431d8b5ae69c5079c8f8ca00d64ac77cf081"
+  integrity sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==
   dependencies:
     js-yaml "^3.13.1"
     lcov-parse "^1.0.0"
@@ -3859,10 +4132,10 @@
     node-source-walk "^4.2.0"
     typescript "^3.9.7"
 
-diff-sequences@^27.0.1:
-  version "27.0.1"
-  resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.0.1.tgz#9c9801d52ed5f576ff0a20e3022a13ee6e297e7c"
-  integrity sha512-XPLijkfJUh/PIBnfkcSHgvD6tlYixmcMAn3osTk6jt+H0v/mgURto1XUiD9DKuGX5NDoVS6dSlA23gd9FUaCFg==
+diff-sequences@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.0.6.tgz#3305cb2e55a033924054695cc66019fd7f8e5723"
+  integrity sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==
 
 diff@5.0.0:
   version "5.0.0"
@@ -3946,6 +4219,13 @@
     jsbn "~0.1.0"
     safer-buffer "^2.1.0"
 
+ed2curve@^0.3.0:
+  version "0.3.0"
+  resolved "https://registry.yarnpkg.com/ed2curve/-/ed2curve-0.3.0.tgz#322b575152a45305429d546b071823a93129a05d"
+  integrity sha512-8w2fmmq3hv9rCrcI7g9hms2pMunQr1JINfcjwR9tAyZqhtyaMN991lF/ZfHfr5tzZQ8c7y7aBgZbjfbd0fjFwQ==
+  dependencies:
+    tweetnacl "1.x.x"
+
 ee-first@1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@@ -3956,6 +4236,11 @@
   resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.752.tgz#0728587f1b9b970ec9ffad932496429aef750d09"
   integrity sha512-2Tg+7jSl3oPxgsBsWKh5H83QazTkmWG/cnNwJplmyZc7KcN61+I10oUgaXSVk/NwfvN3BdkKDR4FYuRBQQ2v0A==
 
+electron-to-chromium@^1.3.793:
+  version "1.3.807"
+  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.807.tgz#c2eb803f4f094869b1a24151184ffbbdbf688b1f"
+  integrity sha512-p8uxxg2a23zRsvQ2uwA/OOI+O4BQxzaR7YKMIGGGQCpYmkFX2CVF5f0/hxLMV7yCr7nnJViCwHLhPfs52rIYCA==
+
 elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4:
   version "6.5.4"
   resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
@@ -4127,18 +4412,18 @@
   resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz#6c8761e544e96c531ff92642eeb87842b8488516"
   integrity sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==
 
-eslint-import-resolver-node@^0.3.4:
-  version "0.3.4"
-  resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717"
-  integrity sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==
+eslint-import-resolver-node@^0.3.5, eslint-import-resolver-node@^0.3.6:
+  version "0.3.6"
+  resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd"
+  integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==
   dependencies:
-    debug "^2.6.9"
-    resolve "^1.13.1"
+    debug "^3.2.7"
+    resolve "^1.20.0"
 
-eslint-module-utils@^2.6.1:
-  version "2.6.1"
-  resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz#b51be1e473dd0de1c5ea638e22429c2490ea8233"
-  integrity sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==
+eslint-module-utils@^2.6.2:
+  version "2.6.2"
+  resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz#94e5540dd15fe1522e8ffa3ec8db3b7fa7e7a534"
+  integrity sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q==
   dependencies:
     debug "^3.2.7"
     pkg-dir "^2.0.0"
@@ -4156,17 +4441,22 @@
   resolved "https://registry.yarnpkg.com/eslint-plugin-header/-/eslint-plugin-header-3.1.1.tgz#6ce512432d57675265fac47292b50d1eff11acd6"
   integrity sha512-9vlKxuJ4qf793CmeeSrZUvVClw6amtpghq3CuWcB5cUNnWHQhgcqy5eF8oVKFk1G3Y/CbchGfEaw3wiIJaNmVg==
 
-eslint-plugin-import@^2.23.4:
-  version "2.23.4"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz#8dceb1ed6b73e46e50ec9a5bb2411b645e7d3d97"
-  integrity sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ==
+eslint-plugin-import-newlines@^1.1.4:
+  version "1.1.4"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-import-newlines/-/eslint-plugin-import-newlines-1.1.4.tgz#d69d03fe512b2f54bc781d1dfc51a4ad99df7a52"
+  integrity sha512-GCIM+524XQOFcEPinEyrvktQHkQq+k+kYCwbRrIioGBVGnk3RGDFWv5BPqBQCDci6SNZCVgIOi3/FmtDetbxvA==
+
+eslint-plugin-import@^2.24.0:
+  version "2.24.0"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.24.0.tgz#697ffd263e24da5e84e03b282f5fb62251777177"
+  integrity sha512-Kc6xqT9hiYi2cgybOc0I2vC9OgAYga5o/rAFinam/yF/t5uBqxQbauNPMC6fgb640T/89P0gFoO27FOilJ/Cqg==
   dependencies:
     array-includes "^3.1.3"
     array.prototype.flat "^1.2.4"
     debug "^2.6.9"
     doctrine "^2.1.0"
-    eslint-import-resolver-node "^0.3.4"
-    eslint-module-utils "^2.6.1"
+    eslint-import-resolver-node "^0.3.5"
+    eslint-module-utils "^2.6.2"
     find-up "^2.0.0"
     has "^1.0.3"
     is-core-module "^2.4.0"
@@ -4229,7 +4519,7 @@
   dependencies:
     natural-compare-lite "^1.4.0"
 
-eslint-scope@^5.0.0, eslint-scope@^5.1.1:
+eslint-scope@^5.1.1:
   version "5.1.1"
   resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
   integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
@@ -4261,13 +4551,13 @@
   resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
   integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
 
-eslint@^7.28.0:
-  version "7.30.0"
-  resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.30.0.tgz#6d34ab51aaa56112fd97166226c9a97f505474f8"
-  integrity sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==
+eslint@^7.31.0:
+  version "7.31.0"
+  resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.31.0.tgz#f972b539424bf2604907a970860732c5d99d3aca"
+  integrity sha512-vafgJpSh2ia8tnTkNUkwxGmnumgckLh5aAbLa1xRmIn9+owi8qBNGKL+B881kNKNTy7FFqTEkpNkUvmw0n6PkA==
   dependencies:
     "@babel/code-frame" "7.12.11"
-    "@eslint/eslintrc" "^0.4.2"
+    "@eslint/eslintrc" "^0.4.3"
     "@humanwhocodes/config-array" "^0.5.0"
     ajv "^6.10.0"
     chalk "^4.0.0"
@@ -4307,13 +4597,14 @@
     text-table "^0.2.0"
     v8-compile-cache "^2.0.3"
 
-eslint@^7.29.0:
-  version "7.29.0"
-  resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.29.0.tgz#ee2a7648f2e729485e4d0bd6383ec1deabc8b3c0"
-  integrity sha512-82G/JToB9qIy/ArBzIWG9xvvwL3R86AlCjtGw+A29OMZDqhTybz/MByORSukGxeI+YPCR4coYyITKk8BFH9nDA==
+eslint@^7.32.0:
+  version "7.32.0"
+  resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d"
+  integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==
   dependencies:
     "@babel/code-frame" "7.12.11"
-    "@eslint/eslintrc" "^0.4.2"
+    "@eslint/eslintrc" "^0.4.3"
+    "@humanwhocodes/config-array" "^0.5.0"
     ajv "^6.10.0"
     chalk "^4.0.0"
     cross-spawn "^7.0.2"
@@ -4390,6 +4681,16 @@
   resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880"
   integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==
 
+estree-walker@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700"
+  integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==
+
+estree-walker@^2.0.1:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
+  integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
+
 esutils@^2.0.2:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
@@ -4550,17 +4851,17 @@
     snapdragon "^0.8.1"
     to-regex "^3.0.1"
 
-expect@^27.0.2:
-  version "27.0.2"
-  resolved "https://registry.yarnpkg.com/expect/-/expect-27.0.2.tgz#e66ca3a4c9592f1c019fa1d46459a9d2084f3422"
-  integrity sha512-YJFNJe2+P2DqH+ZrXy+ydRQYO87oxRUonZImpDodR1G7qo3NYd3pL+NQ9Keqpez3cehczYwZDBC3A7xk3n7M/w==
+expect@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/expect/-/expect-27.0.6.tgz#a4d74fbe27222c718fff68ef49d78e26a8fd4c05"
+  integrity sha512-psNLt8j2kwg42jGBDSfAlU49CEZxejN1f1PlANWDZqIhBOVU/c2Pm888FcjWJzFewhIsNWfZJeLjUjtKGiPuSw==
   dependencies:
-    "@jest/types" "^27.0.2"
+    "@jest/types" "^27.0.6"
     ansi-styles "^5.0.0"
-    jest-get-type "^27.0.1"
-    jest-matcher-utils "^27.0.2"
-    jest-message-util "^27.0.2"
-    jest-regex-util "^27.0.1"
+    jest-get-type "^27.0.6"
+    jest-matcher-utils "^27.0.6"
+    jest-message-util "^27.0.6"
+    jest-regex-util "^27.0.6"
 
 express@^4.14.0:
   version "4.17.1"
@@ -4860,6 +5161,11 @@
   resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b"
   integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==
 
+follow-redirects@^1.12.1:
+  version "1.14.1"
+  resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43"
+  integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==
+
 for-in@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
@@ -4910,6 +5216,17 @@
   resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
   integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
 
+fs-extra@^0.30.0:
+  version "0.30.0"
+  resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0"
+  integrity sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=
+  dependencies:
+    graceful-fs "^4.1.2"
+    jsonfile "^2.1.0"
+    klaw "^1.0.0"
+    path-is-absolute "^1.0.0"
+    rimraf "^2.2.8"
+
 fs-extra@^10.0.0:
   version "10.0.0"
   resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1"
@@ -5253,7 +5570,7 @@
     url-parse-lax "^1.0.0"
     url-to-options "^1.0.1"
 
-graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4:
+graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4:
   version "4.2.6"
   resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
   integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
@@ -5817,6 +6134,11 @@
   resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e"
   integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==
 
+is-module@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
+  integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=
+
 is-negative-zero@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24"
@@ -5891,6 +6213,13 @@
   resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5"
   integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==
 
+is-reference@^1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7"
+  integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==
+  dependencies:
+    "@types/estree" "*"
+
 is-regex@^1.1.3:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f"
@@ -6048,226 +6377,226 @@
     has-to-string-tag-x "^1.2.0"
     is-object "^1.0.1"
 
-jest-changed-files@^27.0.2:
-  version "27.0.2"
-  resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.0.2.tgz#997253042b4a032950fc5f56abf3c5d1f8560801"
-  integrity sha512-eMeb1Pn7w7x3wue5/vF73LPCJ7DKQuC9wQUR5ebP9hDPpk5hzcT/3Hmz3Q5BOFpR3tgbmaWhJcMTVgC8Z1NuMw==
+jest-changed-files@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.0.6.tgz#bed6183fcdea8a285482e3b50a9a7712d49a7a8b"
+  integrity sha512-BuL/ZDauaq5dumYh5y20sn4IISnf1P9A0TDswTxUi84ORGtVa86ApuBHqICL0vepqAnZiY6a7xeSPWv2/yy4eA==
   dependencies:
-    "@jest/types" "^27.0.2"
+    "@jest/types" "^27.0.6"
     execa "^5.0.0"
     throat "^6.0.1"
 
-jest-circus@^27.0.5:
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.0.5.tgz#b5e327f1d6857c8485126f8e364aefa4378debaa"
-  integrity sha512-p5rO90o1RTh8LPOG6l0Fc9qgp5YGv+8M5CFixhMh7gGHtGSobD1AxX9cjFZujILgY8t30QZ7WVvxlnuG31r8TA==
+jest-circus@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.0.6.tgz#dd4df17c4697db6a2c232aaad4e9cec666926668"
+  integrity sha512-OJlsz6BBeX9qR+7O9lXefWoc2m9ZqcZ5Ohlzz0pTEAG4xMiZUJoacY8f4YDHxgk0oKYxj277AfOk9w6hZYvi1Q==
   dependencies:
-    "@jest/environment" "^27.0.5"
-    "@jest/test-result" "^27.0.2"
-    "@jest/types" "^27.0.2"
+    "@jest/environment" "^27.0.6"
+    "@jest/test-result" "^27.0.6"
+    "@jest/types" "^27.0.6"
     "@types/node" "*"
     chalk "^4.0.0"
     co "^4.6.0"
     dedent "^0.7.0"
-    expect "^27.0.2"
+    expect "^27.0.6"
     is-generator-fn "^2.0.0"
-    jest-each "^27.0.2"
-    jest-matcher-utils "^27.0.2"
-    jest-message-util "^27.0.2"
-    jest-runtime "^27.0.5"
-    jest-snapshot "^27.0.5"
-    jest-util "^27.0.2"
-    pretty-format "^27.0.2"
+    jest-each "^27.0.6"
+    jest-matcher-utils "^27.0.6"
+    jest-message-util "^27.0.6"
+    jest-runtime "^27.0.6"
+    jest-snapshot "^27.0.6"
+    jest-util "^27.0.6"
+    pretty-format "^27.0.6"
     slash "^3.0.0"
     stack-utils "^2.0.3"
     throat "^6.0.1"
 
-jest-cli@^27.0.5:
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.0.5.tgz#f359ba042624cffb96b713010a94bffb7498a37c"
-  integrity sha512-kZqY020QFOFQKVE2knFHirTBElw3/Q0kUbDc3nMfy/x+RQ7zUY89SUuzpHHJoSX1kX7Lq569ncvjNqU3Td/FCA==
+jest-cli@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.0.6.tgz#d021e5f4d86d6a212450d4c7b86cb219f1e6864f"
+  integrity sha512-qUUVlGb9fdKir3RDE+B10ULI+LQrz+MCflEH2UJyoUjoHHCbxDrMxSzjQAPUMsic4SncI62ofYCcAvW6+6rhhg==
   dependencies:
-    "@jest/core" "^27.0.5"
-    "@jest/test-result" "^27.0.2"
-    "@jest/types" "^27.0.2"
+    "@jest/core" "^27.0.6"
+    "@jest/test-result" "^27.0.6"
+    "@jest/types" "^27.0.6"
     chalk "^4.0.0"
     exit "^0.1.2"
     graceful-fs "^4.2.4"
     import-local "^3.0.2"
-    jest-config "^27.0.5"
-    jest-util "^27.0.2"
-    jest-validate "^27.0.2"
+    jest-config "^27.0.6"
+    jest-util "^27.0.6"
+    jest-validate "^27.0.6"
     prompts "^2.0.1"
     yargs "^16.0.3"
 
-jest-config@^27.0.5:
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.0.5.tgz#683da3b0d8237675c29c817f6e3aba1481028e19"
-  integrity sha512-zCUIXag7QIXKEVN4kUKbDBDi9Q53dV5o3eNhGqe+5zAbt1vLs4VE3ceWaYrOub0L4Y7E9pGfM84TX/0ARcE+Qw==
+jest-config@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.0.6.tgz#119fb10f149ba63d9c50621baa4f1f179500277f"
+  integrity sha512-JZRR3I1Plr2YxPBhgqRspDE2S5zprbga3swYNrvY3HfQGu7p/GjyLOqwrYad97tX3U3mzT53TPHVmozacfP/3w==
   dependencies:
     "@babel/core" "^7.1.0"
-    "@jest/test-sequencer" "^27.0.5"
-    "@jest/types" "^27.0.2"
-    babel-jest "^27.0.5"
+    "@jest/test-sequencer" "^27.0.6"
+    "@jest/types" "^27.0.6"
+    babel-jest "^27.0.6"
     chalk "^4.0.0"
     deepmerge "^4.2.2"
     glob "^7.1.1"
     graceful-fs "^4.2.4"
     is-ci "^3.0.0"
-    jest-circus "^27.0.5"
-    jest-environment-jsdom "^27.0.5"
-    jest-environment-node "^27.0.5"
-    jest-get-type "^27.0.1"
-    jest-jasmine2 "^27.0.5"
-    jest-regex-util "^27.0.1"
-    jest-resolve "^27.0.5"
-    jest-runner "^27.0.5"
-    jest-util "^27.0.2"
-    jest-validate "^27.0.2"
+    jest-circus "^27.0.6"
+    jest-environment-jsdom "^27.0.6"
+    jest-environment-node "^27.0.6"
+    jest-get-type "^27.0.6"
+    jest-jasmine2 "^27.0.6"
+    jest-regex-util "^27.0.6"
+    jest-resolve "^27.0.6"
+    jest-runner "^27.0.6"
+    jest-util "^27.0.6"
+    jest-validate "^27.0.6"
     micromatch "^4.0.4"
-    pretty-format "^27.0.2"
+    pretty-format "^27.0.6"
 
-jest-diff@^27.0.2:
-  version "27.0.2"
-  resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.0.2.tgz#f315b87cee5dc134cf42c2708ab27375cc3f5a7e"
-  integrity sha512-BFIdRb0LqfV1hBt8crQmw6gGQHVDhM87SpMIZ45FPYKReZYG5er1+5pIn2zKqvrJp6WNox0ylR8571Iwk2Dmgw==
+jest-diff@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.0.6.tgz#4a7a19ee6f04ad70e0e3388f35829394a44c7b5e"
+  integrity sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg==
   dependencies:
     chalk "^4.0.0"
-    diff-sequences "^27.0.1"
-    jest-get-type "^27.0.1"
-    pretty-format "^27.0.2"
+    diff-sequences "^27.0.6"
+    jest-get-type "^27.0.6"
+    pretty-format "^27.0.6"
 
-jest-docblock@^27.0.1:
-  version "27.0.1"
-  resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.0.1.tgz#bd9752819b49fa4fab1a50b73eb58c653b962e8b"
-  integrity sha512-TA4+21s3oebURc7VgFV4r7ltdIJ5rtBH1E3Tbovcg7AV+oLfD5DcJ2V2vJ5zFA9sL5CFd/d2D6IpsAeSheEdrA==
+jest-docblock@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.0.6.tgz#cc78266acf7fe693ca462cbbda0ea4e639e4e5f3"
+  integrity sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==
   dependencies:
     detect-newline "^3.0.0"
 
-jest-each@^27.0.2:
-  version "27.0.2"
-  resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.0.2.tgz#865ddb4367476ced752167926b656fa0dcecd8c7"
-  integrity sha512-OLMBZBZ6JkoXgUenDtseFRWA43wVl2BwmZYIWQws7eS7pqsIvePqj/jJmEnfq91ALk3LNphgwNK/PRFBYi7ITQ==
+jest-each@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.0.6.tgz#cee117071b04060158dc8d9a66dc50ad40ef453b"
+  integrity sha512-m6yKcV3bkSWrUIjxkE9OC0mhBZZdhovIW5ergBYirqnkLXkyEn3oUUF/QZgyecA1cF1QFyTE8bRRl8Tfg1pfLA==
   dependencies:
-    "@jest/types" "^27.0.2"
+    "@jest/types" "^27.0.6"
     chalk "^4.0.0"
-    jest-get-type "^27.0.1"
-    jest-util "^27.0.2"
-    pretty-format "^27.0.2"
+    jest-get-type "^27.0.6"
+    jest-util "^27.0.6"
+    pretty-format "^27.0.6"
 
-jest-environment-jsdom@^27.0.5:
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.0.5.tgz#c36771977cf4490a9216a70473b39161d193c212"
-  integrity sha512-ToWhViIoTl5738oRaajTMgYhdQL73UWPoV4GqHGk2DPhs+olv8OLq5KoQW8Yf+HtRao52XLqPWvl46dPI88PdA==
+jest-environment-jsdom@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.0.6.tgz#f66426c4c9950807d0a9f209c590ce544f73291f"
+  integrity sha512-FvetXg7lnXL9+78H+xUAsra3IeZRTiegA3An01cWeXBspKXUhAwMM9ycIJ4yBaR0L7HkoMPaZsozCLHh4T8fuw==
   dependencies:
-    "@jest/environment" "^27.0.5"
-    "@jest/fake-timers" "^27.0.5"
-    "@jest/types" "^27.0.2"
+    "@jest/environment" "^27.0.6"
+    "@jest/fake-timers" "^27.0.6"
+    "@jest/types" "^27.0.6"
     "@types/node" "*"
-    jest-mock "^27.0.3"
-    jest-util "^27.0.2"
+    jest-mock "^27.0.6"
+    jest-util "^27.0.6"
     jsdom "^16.6.0"
 
-jest-environment-node@^27.0.5:
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.0.5.tgz#b7238fc2b61ef2fb9563a3b7653a95fa009a6a54"
-  integrity sha512-47qqScV/WMVz5OKF5TWpAeQ1neZKqM3ySwNveEnLyd+yaE/KT6lSMx/0SOx60+ZUcVxPiESYS+Kt2JS9y4PpkQ==
+jest-environment-node@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.0.6.tgz#a6699b7ceb52e8d68138b9808b0c404e505f3e07"
+  integrity sha512-+Vi6yLrPg/qC81jfXx3IBlVnDTI6kmRr08iVa2hFCWmJt4zha0XW7ucQltCAPhSR0FEKEoJ3i+W4E6T0s9is0w==
   dependencies:
-    "@jest/environment" "^27.0.5"
-    "@jest/fake-timers" "^27.0.5"
-    "@jest/types" "^27.0.2"
+    "@jest/environment" "^27.0.6"
+    "@jest/fake-timers" "^27.0.6"
+    "@jest/types" "^27.0.6"
     "@types/node" "*"
-    jest-mock "^27.0.3"
-    jest-util "^27.0.2"
+    jest-mock "^27.0.6"
+    jest-util "^27.0.6"
 
-jest-get-type@^27.0.1:
-  version "27.0.1"
-  resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.0.1.tgz#34951e2b08c8801eb28559d7eb732b04bbcf7815"
-  integrity sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==
+jest-get-type@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.0.6.tgz#0eb5c7f755854279ce9b68a9f1a4122f69047cfe"
+  integrity sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==
 
-jest-haste-map@^27.0.5:
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.0.5.tgz#2e1e55073b5328410a2c0d74b334e513d71f3470"
-  integrity sha512-3LFryGSHxwPFHzKIs6W0BGA2xr6g1MvzSjR3h3D8K8Uqy4vbRm/grpGHzbPtIbOPLC6wFoViRrNEmd116QWSkw==
+jest-haste-map@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.0.6.tgz#4683a4e68f6ecaa74231679dca237279562c8dc7"
+  integrity sha512-4ldjPXX9h8doB2JlRzg9oAZ2p6/GpQUNAeiYXqcpmrKbP0Qev0wdZlxSMOmz8mPOEnt4h6qIzXFLDi8RScX/1w==
   dependencies:
-    "@jest/types" "^27.0.2"
+    "@jest/types" "^27.0.6"
     "@types/graceful-fs" "^4.1.2"
     "@types/node" "*"
     anymatch "^3.0.3"
     fb-watchman "^2.0.0"
     graceful-fs "^4.2.4"
-    jest-regex-util "^27.0.1"
-    jest-serializer "^27.0.1"
-    jest-util "^27.0.2"
-    jest-worker "^27.0.2"
+    jest-regex-util "^27.0.6"
+    jest-serializer "^27.0.6"
+    jest-util "^27.0.6"
+    jest-worker "^27.0.6"
     micromatch "^4.0.4"
     walker "^1.0.7"
   optionalDependencies:
     fsevents "^2.3.2"
 
-jest-jasmine2@^27.0.5:
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.0.5.tgz#8a6eb2a685cdec3af13881145c77553e4e197776"
-  integrity sha512-m3TojR19sFmTn79QoaGy1nOHBcLvtLso6Zh7u+gYxZWGcza4rRPVqwk1hciA5ZOWWZIJOukAcore8JRX992FaA==
+jest-jasmine2@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.0.6.tgz#fd509a9ed3d92bd6edb68a779f4738b100655b37"
+  integrity sha512-cjpH2sBy+t6dvCeKBsHpW41mjHzXgsavaFMp+VWRf0eR4EW8xASk1acqmljFtK2DgyIECMv2yCdY41r2l1+4iA==
   dependencies:
     "@babel/traverse" "^7.1.0"
-    "@jest/environment" "^27.0.5"
-    "@jest/source-map" "^27.0.1"
-    "@jest/test-result" "^27.0.2"
-    "@jest/types" "^27.0.2"
+    "@jest/environment" "^27.0.6"
+    "@jest/source-map" "^27.0.6"
+    "@jest/test-result" "^27.0.6"
+    "@jest/types" "^27.0.6"
     "@types/node" "*"
     chalk "^4.0.0"
     co "^4.6.0"
-    expect "^27.0.2"
+    expect "^27.0.6"
     is-generator-fn "^2.0.0"
-    jest-each "^27.0.2"
-    jest-matcher-utils "^27.0.2"
-    jest-message-util "^27.0.2"
-    jest-runtime "^27.0.5"
-    jest-snapshot "^27.0.5"
-    jest-util "^27.0.2"
-    pretty-format "^27.0.2"
+    jest-each "^27.0.6"
+    jest-matcher-utils "^27.0.6"
+    jest-message-util "^27.0.6"
+    jest-runtime "^27.0.6"
+    jest-snapshot "^27.0.6"
+    jest-util "^27.0.6"
+    pretty-format "^27.0.6"
     throat "^6.0.1"
 
-jest-leak-detector@^27.0.2:
-  version "27.0.2"
-  resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.0.2.tgz#ce19aa9dbcf7a72a9d58907a970427506f624e69"
-  integrity sha512-TZA3DmCOfe8YZFIMD1GxFqXUkQnIoOGQyy4hFCA2mlHtnAaf+FeOMxi0fZmfB41ZL+QbFG6BVaZF5IeFIVy53Q==
+jest-leak-detector@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.0.6.tgz#545854275f85450d4ef4b8fe305ca2a26450450f"
+  integrity sha512-2/d6n2wlH5zEcdctX4zdbgX8oM61tb67PQt4Xh8JFAIy6LRKUnX528HulkaG6nD5qDl5vRV1NXejCe1XRCH5gQ==
   dependencies:
-    jest-get-type "^27.0.1"
-    pretty-format "^27.0.2"
+    jest-get-type "^27.0.6"
+    pretty-format "^27.0.6"
 
-jest-matcher-utils@^27.0.2:
-  version "27.0.2"
-  resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.0.2.tgz#f14c060605a95a466cdc759acc546c6f4cbfc4f0"
-  integrity sha512-Qczi5xnTNjkhcIB0Yy75Txt+Ez51xdhOxsukN7awzq2auZQGPHcQrJ623PZj0ECDEMOk2soxWx05EXdXGd1CbA==
+jest-matcher-utils@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.0.6.tgz#2a8da1e86c620b39459f4352eaa255f0d43e39a9"
+  integrity sha512-OFgF2VCQx9vdPSYTHWJ9MzFCehs20TsyFi6bIHbk5V1u52zJOnvF0Y/65z3GLZHKRuTgVPY4Z6LVePNahaQ+tA==
   dependencies:
     chalk "^4.0.0"
-    jest-diff "^27.0.2"
-    jest-get-type "^27.0.1"
-    pretty-format "^27.0.2"
+    jest-diff "^27.0.6"
+    jest-get-type "^27.0.6"
+    pretty-format "^27.0.6"
 
-jest-message-util@^27.0.2:
-  version "27.0.2"
-  resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.0.2.tgz#181c9b67dff504d8f4ad15cba10d8b80f272048c"
-  integrity sha512-rTqWUX42ec2LdMkoUPOzrEd1Tcm+R1KfLOmFK+OVNo4MnLsEaxO5zPDb2BbdSmthdM/IfXxOZU60P/WbWF8BTw==
+jest-message-util@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.0.6.tgz#158bcdf4785706492d164a39abca6a14da5ab8b5"
+  integrity sha512-rBxIs2XK7rGy+zGxgi+UJKP6WqQ+KrBbD1YMj517HYN3v2BG66t3Xan3FWqYHKZwjdB700KiAJ+iES9a0M+ixw==
   dependencies:
     "@babel/code-frame" "^7.12.13"
-    "@jest/types" "^27.0.2"
+    "@jest/types" "^27.0.6"
     "@types/stack-utils" "^2.0.0"
     chalk "^4.0.0"
     graceful-fs "^4.2.4"
     micromatch "^4.0.4"
-    pretty-format "^27.0.2"
+    pretty-format "^27.0.6"
     slash "^3.0.0"
     stack-utils "^2.0.3"
 
-jest-mock@^27.0.3:
-  version "27.0.3"
-  resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.0.3.tgz#5591844f9192b3335c0dca38e8e45ed297d4d23d"
-  integrity sha512-O5FZn5XDzEp+Xg28mUz4ovVcdwBBPfAhW9+zJLO0Efn2qNbYcDaJvSlRiQ6BCZUCVOJjALicuJQI9mRFjv1o9Q==
+jest-mock@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.0.6.tgz#0efdd40851398307ba16778728f6d34d583e3467"
+  integrity sha512-lzBETUoK8cSxts2NYXSBWT+EJNzmUVtVVwS1sU9GwE1DLCfGsngg+ZVSIe0yd0ZSm+y791esiuo+WSwpXJQ5Bw==
   dependencies:
-    "@jest/types" "^27.0.2"
+    "@jest/types" "^27.0.6"
     "@types/node" "*"
 
 jest-pnp-resolver@^1.2.2:
@@ -6275,76 +6604,76 @@
   resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c"
   integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==
 
-jest-regex-util@^27.0.1:
-  version "27.0.1"
-  resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.0.1.tgz#69d4b1bf5b690faa3490113c47486ed85dd45b68"
-  integrity sha512-6nY6QVcpTgEKQy1L41P4pr3aOddneK17kn3HJw6SdwGiKfgCGTvH02hVXL0GU8GEKtPH83eD2DIDgxHXOxVohQ==
+jest-regex-util@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.0.6.tgz#02e112082935ae949ce5d13b2675db3d8c87d9c5"
+  integrity sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==
 
-jest-resolve-dependencies@^27.0.5:
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.5.tgz#819ccdddd909c65acddb063aac3a49e4ba1ed569"
-  integrity sha512-xUj2dPoEEd59P+nuih4XwNa4nJ/zRd/g4rMvjHrZPEBWeWRq/aJnnM6mug+B+Nx+ILXGtfWHzQvh7TqNV/WbuA==
+jest-resolve-dependencies@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.6.tgz#3e619e0ef391c3ecfcf6ef4056207a3d2be3269f"
+  integrity sha512-mg9x9DS3BPAREWKCAoyg3QucCr0n6S8HEEsqRCKSPjPcu9HzRILzhdzY3imsLoZWeosEbJZz6TKasveczzpJZA==
   dependencies:
-    "@jest/types" "^27.0.2"
-    jest-regex-util "^27.0.1"
-    jest-snapshot "^27.0.5"
+    "@jest/types" "^27.0.6"
+    jest-regex-util "^27.0.6"
+    jest-snapshot "^27.0.6"
 
-jest-resolve@^27.0.5:
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.0.5.tgz#937535a5b481ad58e7121eaea46d1424a1e0c507"
-  integrity sha512-Md65pngRh8cRuWVdWznXBB5eDt391OJpdBaJMxfjfuXCvOhM3qQBtLMCMTykhuUKiBMmy5BhqCW7AVOKmPrW+Q==
+jest-resolve@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.0.6.tgz#e90f436dd4f8fbf53f58a91c42344864f8e55bff"
+  integrity sha512-yKmIgw2LgTh7uAJtzv8UFHGF7Dm7XfvOe/LQ3Txv101fLM8cx2h1QVwtSJ51Q/SCxpIiKfVn6G2jYYMDNHZteA==
   dependencies:
-    "@jest/types" "^27.0.2"
+    "@jest/types" "^27.0.6"
     chalk "^4.0.0"
     escalade "^3.1.1"
     graceful-fs "^4.2.4"
     jest-pnp-resolver "^1.2.2"
-    jest-util "^27.0.2"
-    jest-validate "^27.0.2"
+    jest-util "^27.0.6"
+    jest-validate "^27.0.6"
     resolve "^1.20.0"
     slash "^3.0.0"
 
-jest-runner@^27.0.5:
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.0.5.tgz#b6fdc587e1a5056339205914294555c554efc08a"
-  integrity sha512-HNhOtrhfKPArcECgBTcWOc+8OSL8GoFoa7RsHGnfZR1C1dFohxy9eLtpYBS+koybAHlJLZzNCx2Y/Ic3iEtJpQ==
+jest-runner@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.0.6.tgz#1325f45055539222bbc7256a6976e993ad2f9520"
+  integrity sha512-W3Bz5qAgaSChuivLn+nKOgjqNxM7O/9JOJoKDCqThPIg2sH/d4A/lzyiaFgnb9V1/w29Le11NpzTJSzga1vyYQ==
   dependencies:
-    "@jest/console" "^27.0.2"
-    "@jest/environment" "^27.0.5"
-    "@jest/test-result" "^27.0.2"
-    "@jest/transform" "^27.0.5"
-    "@jest/types" "^27.0.2"
+    "@jest/console" "^27.0.6"
+    "@jest/environment" "^27.0.6"
+    "@jest/test-result" "^27.0.6"
+    "@jest/transform" "^27.0.6"
+    "@jest/types" "^27.0.6"
     "@types/node" "*"
     chalk "^4.0.0"
     emittery "^0.8.1"
     exit "^0.1.2"
     graceful-fs "^4.2.4"
-    jest-docblock "^27.0.1"
-    jest-environment-jsdom "^27.0.5"
-    jest-environment-node "^27.0.5"
-    jest-haste-map "^27.0.5"
-    jest-leak-detector "^27.0.2"
-    jest-message-util "^27.0.2"
-    jest-resolve "^27.0.5"
-    jest-runtime "^27.0.5"
-    jest-util "^27.0.2"
-    jest-worker "^27.0.2"
+    jest-docblock "^27.0.6"
+    jest-environment-jsdom "^27.0.6"
+    jest-environment-node "^27.0.6"
+    jest-haste-map "^27.0.6"
+    jest-leak-detector "^27.0.6"
+    jest-message-util "^27.0.6"
+    jest-resolve "^27.0.6"
+    jest-runtime "^27.0.6"
+    jest-util "^27.0.6"
+    jest-worker "^27.0.6"
     source-map-support "^0.5.6"
     throat "^6.0.1"
 
-jest-runtime@^27.0.5:
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.0.5.tgz#cd5d1aa9754d30ddf9f13038b3cb7b95b46f552d"
-  integrity sha512-V/w/+VasowPESbmhXn5AsBGPfb35T7jZPGZybYTHxZdP7Gwaa+A0EXE6rx30DshHKA98lVCODbCO8KZpEW3hiQ==
+jest-runtime@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.0.6.tgz#45877cfcd386afdd4f317def551fc369794c27c9"
+  integrity sha512-BhvHLRVfKibYyqqEFkybsznKwhrsu7AWx2F3y9G9L95VSIN3/ZZ9vBpm/XCS2bS+BWz3sSeNGLzI3TVQ0uL85Q==
   dependencies:
-    "@jest/console" "^27.0.2"
-    "@jest/environment" "^27.0.5"
-    "@jest/fake-timers" "^27.0.5"
-    "@jest/globals" "^27.0.5"
-    "@jest/source-map" "^27.0.1"
-    "@jest/test-result" "^27.0.2"
-    "@jest/transform" "^27.0.5"
-    "@jest/types" "^27.0.2"
+    "@jest/console" "^27.0.6"
+    "@jest/environment" "^27.0.6"
+    "@jest/fake-timers" "^27.0.6"
+    "@jest/globals" "^27.0.6"
+    "@jest/source-map" "^27.0.6"
+    "@jest/test-result" "^27.0.6"
+    "@jest/transform" "^27.0.6"
+    "@jest/types" "^27.0.6"
     "@types/yargs" "^16.0.0"
     chalk "^4.0.0"
     cjs-module-lexer "^1.0.0"
@@ -6352,30 +6681,30 @@
     exit "^0.1.2"
     glob "^7.1.3"
     graceful-fs "^4.2.4"
-    jest-haste-map "^27.0.5"
-    jest-message-util "^27.0.2"
-    jest-mock "^27.0.3"
-    jest-regex-util "^27.0.1"
-    jest-resolve "^27.0.5"
-    jest-snapshot "^27.0.5"
-    jest-util "^27.0.2"
-    jest-validate "^27.0.2"
+    jest-haste-map "^27.0.6"
+    jest-message-util "^27.0.6"
+    jest-mock "^27.0.6"
+    jest-regex-util "^27.0.6"
+    jest-resolve "^27.0.6"
+    jest-snapshot "^27.0.6"
+    jest-util "^27.0.6"
+    jest-validate "^27.0.6"
     slash "^3.0.0"
     strip-bom "^4.0.0"
     yargs "^16.0.3"
 
-jest-serializer@^27.0.1:
-  version "27.0.1"
-  resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.0.1.tgz#2464d04dcc33fb71dc80b7c82e3c5e8a08cb1020"
-  integrity sha512-svy//5IH6bfQvAbkAEg1s7xhhgHTtXu0li0I2fdKHDsLP2P2MOiscPQIENQep8oU2g2B3jqLyxKKzotZOz4CwQ==
+jest-serializer@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.0.6.tgz#93a6c74e0132b81a2d54623251c46c498bb5bec1"
+  integrity sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==
   dependencies:
     "@types/node" "*"
     graceful-fs "^4.2.4"
 
-jest-snapshot@^27.0.5:
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.0.5.tgz#6e3b9e8e193685372baff771ba34af631fe4d4d5"
-  integrity sha512-H1yFYdgnL1vXvDqMrnDStH6yHFdMEuzYQYc71SnC/IJnuuhW6J16w8GWG1P+qGd3Ag3sQHjbRr0TcwEo/vGS+g==
+jest-snapshot@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.0.6.tgz#f4e6b208bd2e92e888344d78f0f650bcff05a4bf"
+  integrity sha512-NTHaz8He+ATUagUgE7C/UtFcRoHqR2Gc+KDfhQIyx+VFgwbeEMjeP+ILpUTLosZn/ZtbNdCF5LkVnN/l+V751A==
   dependencies:
     "@babel/core" "^7.7.2"
     "@babel/generator" "^7.7.2"
@@ -6383,86 +6712,86 @@
     "@babel/plugin-syntax-typescript" "^7.7.2"
     "@babel/traverse" "^7.7.2"
     "@babel/types" "^7.0.0"
-    "@jest/transform" "^27.0.5"
-    "@jest/types" "^27.0.2"
+    "@jest/transform" "^27.0.6"
+    "@jest/types" "^27.0.6"
     "@types/babel__traverse" "^7.0.4"
     "@types/prettier" "^2.1.5"
     babel-preset-current-node-syntax "^1.0.0"
     chalk "^4.0.0"
-    expect "^27.0.2"
+    expect "^27.0.6"
     graceful-fs "^4.2.4"
-    jest-diff "^27.0.2"
-    jest-get-type "^27.0.1"
-    jest-haste-map "^27.0.5"
-    jest-matcher-utils "^27.0.2"
-    jest-message-util "^27.0.2"
-    jest-resolve "^27.0.5"
-    jest-util "^27.0.2"
+    jest-diff "^27.0.6"
+    jest-get-type "^27.0.6"
+    jest-haste-map "^27.0.6"
+    jest-matcher-utils "^27.0.6"
+    jest-message-util "^27.0.6"
+    jest-resolve "^27.0.6"
+    jest-util "^27.0.6"
     natural-compare "^1.4.0"
-    pretty-format "^27.0.2"
+    pretty-format "^27.0.6"
     semver "^7.3.2"
 
-jest-util@^27.0.2:
-  version "27.0.2"
-  resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.0.2.tgz#fc2c7ace3c75ae561cf1e5fdb643bf685a5be7c7"
-  integrity sha512-1d9uH3a00OFGGWSibpNYr+jojZ6AckOMCXV2Z4K3YXDnzpkAaXQyIpY14FOJPiUmil7CD+A6Qs+lnnh6ctRbIA==
+jest-util@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.0.6.tgz#e8e04eec159de2f4d5f57f795df9cdc091e50297"
+  integrity sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==
   dependencies:
-    "@jest/types" "^27.0.2"
+    "@jest/types" "^27.0.6"
     "@types/node" "*"
     chalk "^4.0.0"
     graceful-fs "^4.2.4"
     is-ci "^3.0.0"
     picomatch "^2.2.3"
 
-jest-validate@^27.0.2:
-  version "27.0.2"
-  resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.0.2.tgz#7fe2c100089449cd5cbb47a5b0b6cb7cda5beee5"
-  integrity sha512-UgBF6/oVu1ofd1XbaSotXKihi8nZhg0Prm8twQ9uCuAfo59vlxCXMPI/RKmrZEVgi3Nd9dS0I8A0wzWU48pOvg==
+jest-validate@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.0.6.tgz#930a527c7a951927df269f43b2dc23262457e2a6"
+  integrity sha512-yhZZOaMH3Zg6DC83n60pLmdU1DQE46DW+KLozPiPbSbPhlXXaiUTDlhHQhHFpaqIFRrInko1FHXjTRpjWRuWfA==
   dependencies:
-    "@jest/types" "^27.0.2"
+    "@jest/types" "^27.0.6"
     camelcase "^6.2.0"
     chalk "^4.0.0"
-    jest-get-type "^27.0.1"
+    jest-get-type "^27.0.6"
     leven "^3.1.0"
-    pretty-format "^27.0.2"
+    pretty-format "^27.0.6"
 
-jest-watcher@^27.0.2:
-  version "27.0.2"
-  resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.0.2.tgz#dab5f9443e2d7f52597186480731a8c6335c5deb"
-  integrity sha512-8nuf0PGuTxWj/Ytfw5fyvNn/R80iXY8QhIT0ofyImUvdnoaBdT6kob0GmhXR+wO+ALYVnh8bQxN4Tjfez0JgkA==
+jest-watcher@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.0.6.tgz#89526f7f9edf1eac4e4be989bcb6dec6b8878d9c"
+  integrity sha512-/jIoKBhAP00/iMGnTwUBLgvxkn7vsOweDrOTSPzc7X9uOyUtJIDthQBTI1EXz90bdkrxorUZVhJwiB69gcHtYQ==
   dependencies:
-    "@jest/test-result" "^27.0.2"
-    "@jest/types" "^27.0.2"
+    "@jest/test-result" "^27.0.6"
+    "@jest/types" "^27.0.6"
     "@types/node" "*"
     ansi-escapes "^4.2.1"
     chalk "^4.0.0"
-    jest-util "^27.0.2"
+    jest-util "^27.0.6"
     string-length "^4.0.1"
 
-jest-worker@^27.0.2:
-  version "27.0.2"
-  resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.2.tgz#4ebeb56cef48b3e7514552f80d0d80c0129f0b05"
-  integrity sha512-EoBdilOTTyOgmHXtw/cPc+ZrCA0KJMrkXzkrPGNwLmnvvlN1nj7MPrxpT7m+otSv2e1TLaVffzDnE/LB14zJMg==
+jest-worker@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.6.tgz#a5fdb1e14ad34eb228cfe162d9f729cdbfa28aed"
+  integrity sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA==
   dependencies:
     "@types/node" "*"
     merge-stream "^2.0.0"
     supports-color "^8.0.0"
 
-jest@^27.0.5:
-  version "27.0.5"
-  resolved "https://registry.yarnpkg.com/jest/-/jest-27.0.5.tgz#141825e105514a834cc8d6e44670509e8d74c5f2"
-  integrity sha512-4NlVMS29gE+JOZvgmSAsz3eOjkSsHqjTajlIsah/4MVSmKvf3zFP/TvgcLoWe2UVHiE9KF741sReqhF0p4mqbQ==
+jest@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/jest/-/jest-27.0.6.tgz#10517b2a628f0409087fbf473db44777d7a04505"
+  integrity sha512-EjV8aETrsD0wHl7CKMibKwQNQc3gIRBXlTikBmmHUeVMKaPFxdcUIBfoDqTSXDoGJIivAYGqCWVlzCSaVjPQsA==
   dependencies:
-    "@jest/core" "^27.0.5"
+    "@jest/core" "^27.0.6"
     import-local "^3.0.2"
-    jest-cli "^27.0.5"
+    jest-cli "^27.0.6"
 
 js-sha3@0.5.7, js-sha3@^0.5.7:
   version "0.5.7"
   resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7"
   integrity sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=
 
-js-sha3@^0.8.0:
+js-sha3@0.8.0, js-sha3@^0.8.0:
   version "0.8.0"
   resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840"
   integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==
@@ -6594,6 +6923,13 @@
   dependencies:
     minimist "^1.2.5"
 
+jsonfile@^2.1.0:
+  version "2.4.0"
+  resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8"
+  integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug=
+  optionalDependencies:
+    graceful-fs "^4.1.6"
+
 jsonfile@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
@@ -6667,6 +7003,13 @@
   resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
   integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
 
+klaw@^1.0.0:
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439"
+  integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk=
+  optionalDependencies:
+    graceful-fs "^4.1.9"
+
 kleur@^3.0.3:
   version "3.0.3"
   resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
@@ -6785,7 +7128,7 @@
   resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
   integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=
 
-lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21, lodash@^4.7.0:
+lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.21, lodash@^4.7.0:
   version "4.17.21"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
   integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -6877,6 +7220,13 @@
     typescript "^3.9.5"
     walkdir "^0.4.1"
 
+magic-string@^0.25.5, magic-string@^0.25.7:
+  version "0.25.7"
+  resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
+  integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==
+  dependencies:
+    sourcemap-codec "^1.4.4"
+
 make-dir@^2.0.0, make-dir@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
@@ -6930,6 +7280,11 @@
   resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
   integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
 
+memorystream@^0.3.1:
+  version "0.3.1"
+  resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2"
+  integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI=
+
 merge-descriptors@1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
@@ -7307,6 +7662,11 @@
   resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.73.tgz#dd4e81ddd5277ff846b80b52bb40c49edf7a7b20"
   integrity sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==
 
+node-releases@^1.1.73:
+  version "1.1.74"
+  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.74.tgz#e5866488080ebaa70a93b91144ccde06f3c3463e"
+  integrity sha512-caJBVempXZPepZoZAPCWRTNxYQ+xtG/KAi4ozTA5A+nJ7IU+kLQCbqaUjb5Rwy14M9upBWiQ4NutcmW04LJSRw==
+
 node-source-walk@^4.0.0, node-source-walk@^4.2.0:
   version "4.2.0"
   resolved "https://registry.yarnpkg.com/node-source-walk/-/node-source-walk-4.2.0.tgz#c2efe731ea8ba9c03c562aa0a9d984e54f27bc2c"
@@ -7753,7 +8113,7 @@
   resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
   integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
 
-picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3:
+picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
   integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
@@ -7935,17 +8295,17 @@
   resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
   integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
 
-prettier@^2.3.1:
-  version "2.3.1"
-  resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.1.tgz#76903c3f8c4449bc9ac597acefa24dc5ad4cbea6"
-  integrity sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==
+prettier@^2.3.2:
+  version "2.3.2"
+  resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d"
+  integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==
 
-pretty-format@^27.0.2:
-  version "27.0.2"
-  resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.0.2.tgz#9283ff8c4f581b186b2d4da461617143dca478a4"
-  integrity sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==
+pretty-format@^27.0.6:
+  version "27.0.6"
+  resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.0.6.tgz#ab770c47b2c6f893a21aefc57b75da63ef49a11f"
+  integrity sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==
   dependencies:
-    "@jest/types" "^27.0.2"
+    "@jest/types" "^27.0.6"
     ansi-regex "^5.0.0"
     ansi-styles "^5.0.0"
     react-is "^17.0.1"
@@ -8345,7 +8705,7 @@
   resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
   integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
 
-require-from-string@^2.0.2:
+require-from-string@^2.0.0, require-from-string@^2.0.2:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
   integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
@@ -8395,7 +8755,7 @@
   resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
   integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
 
-resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.3.2:
+resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.3.2:
   version "1.20.0"
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
   integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
@@ -8436,6 +8796,13 @@
   resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
   integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
 
+rimraf@^2.2.8:
+  version "2.7.1"
+  resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
+  integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
+  dependencies:
+    glob "^7.1.3"
+
 rimraf@^3.0.0, rimraf@^3.0.2:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
@@ -8458,6 +8825,13 @@
   dependencies:
     bn.js "^4.11.1"
 
+rollup@^2.56.2:
+  version "2.56.2"
+  resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.56.2.tgz#a045ff3f6af53ee009b5f5016ca3da0329e5470f"
+  integrity sha512-s8H00ZsRi29M2/lGdm1u8DJpJ9ML8SUOpVVBd33XNeEeL3NVaTiUcSBHzBdF3eAyR0l7VSpsuoVUGrRHq7aPwQ==
+  optionalDependencies:
+    fsevents "~2.3.2"
+
 run-async@^2.4.0:
   version "2.4.1"
   resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455"
@@ -8477,10 +8851,10 @@
   dependencies:
     tslib "^1.9.0"
 
-rxjs@^7.2.0:
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.2.0.tgz#5cd12409639e9514a71c9f5f9192b2c4ae94de31"
-  integrity sha512-aX8w9OpKrQmiPKfT1bqETtUr9JygIz6GZ+gql8v7CijClsP0laoFUdKzxFAoWuRdSlOdU2+crss+cMf+cqMTnw==
+rxjs@^7.3.0:
+  version "7.3.0"
+  resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.3.0.tgz#39fe4f3461dc1e50be1475b2b85a0a88c1e938c6"
+  integrity sha512-p2yuGIg9S1epc3vrjKf6iVb3RCaAYjYskkO+jHIaV0IjOPlJop4UnodOoFb2xeNwlguqLYvGw1b1McillYb5Gw==
   dependencies:
     tslib "~2.1.0"
 
@@ -8546,7 +8920,7 @@
   dependencies:
     semver "^6.3.0"
 
-"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.6.0:
+"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.6.0:
   version "5.7.1"
   resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
   integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@@ -8762,6 +9136,21 @@
     source-map-resolve "^0.5.0"
     use "^3.1.0"
 
+solc@^0.8.6:
+  version "0.8.6"
+  resolved "https://registry.yarnpkg.com/solc/-/solc-0.8.6.tgz#e4341fa6780137df97b94a0cfbd59b3f2037d0e0"
+  integrity sha512-miiDaWdaUnD7A6Cktb/2ug9f+ajcOCDYRr7vgbPEsMoutSlBtp5rca57oMg8iHSuM7jilwdxePujWI/+rbNftQ==
+  dependencies:
+    command-exists "^1.2.8"
+    commander "3.0.2"
+    follow-redirects "^1.12.1"
+    fs-extra "^0.30.0"
+    js-sha3 "0.8.0"
+    memorystream "^0.3.1"
+    require-from-string "^2.0.0"
+    semver "^5.5.0"
+    tmp "0.0.33"
+
 sort-keys@^4.0.0:
   version "4.2.0"
   resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-4.2.0.tgz#6b7638cee42c506fff8c1cecde7376d21315be18"
@@ -8813,6 +9202,11 @@
   resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
   integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
 
+sourcemap-codec@^1.4.4:
+  version "1.4.8"
+  resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
+  integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
+
 spdx-correct@^3.0.0:
   version "3.1.1"
   resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9"
@@ -9210,7 +9604,7 @@
   resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
   integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=
 
-tmp@^0.0.33:
+tmp@0.0.33, tmp@^0.0.33:
   version "0.0.33"
   resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
   integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==
@@ -9358,7 +9752,7 @@
   dependencies:
     tslib "^1.8.1"
 
-tsutils@^3.17.1, tsutils@^3.21.0:
+tsutils@^3.21.0:
   version "3.21.0"
   resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
   integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==
@@ -9372,15 +9766,15 @@
   dependencies:
     safe-buffer "^5.0.1"
 
+tweetnacl@1.x.x, tweetnacl@^1.0.3:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596"
+  integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==
+
 tweetnacl@^0.14.3, tweetnacl@~0.14.0:
   version "0.14.5"
   resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
   integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
-
-tweetnacl@^1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596"
-  integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==
 
 type-check@^0.4.0, type-check@~0.4.0:
   version "0.4.0"
@@ -9446,11 +9840,16 @@
   resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8"
   integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==
 
-typescript@^4.2.4, typescript@^4.3.4:
+typescript@^4.2.4:
   version "4.3.4"
   resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.4.tgz#3f85b986945bcf31071decdd96cf8bfa65f9dcbc"
   integrity sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==
 
+typescript@^4.3.5:
+  version "4.3.5"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4"
+  integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==
+
 uglify-js@^3.1.4:
   version "3.13.9"
   resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.9.tgz#4d8d21dcd497f29cfd8e9378b9df123ad025999b"
@@ -10258,7 +10657,7 @@
     y18n "^5.0.5"
     yargs-parser "^20.2.2"
 
-yargs@^17.0.0, yargs@^17.0.1:
+yargs@^17.0.0:
   version "17.0.1"
   resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.0.1.tgz#6a1ced4ed5ee0b388010ba9fd67af83b9362e0bb"
   integrity sha512-xBBulfCc8Y6gLFcrPvtqKz9hz8SO0l1Ni8GgDekvBX2ro0HRQImDGnikfc33cgzcYUSncapnNcZDjVFIH3f6KQ==
@@ -10271,6 +10670,19 @@
     y18n "^5.0.5"
     yargs-parser "^20.2.2"
 
+yargs@^17.1.0, yargs@^17.1.1:
+  version "17.1.1"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.1.1.tgz#c2a8091564bdb196f7c0a67c1d12e5b85b8067ba"
+  integrity sha512-c2k48R0PwKIqKhPMWjeiF6y2xY/gPMUlro0sgxqXpbOIohWiLNXWslsootttv7E1e73QPAMQSg5FeySbVcpsPQ==
+  dependencies:
+    cliui "^7.0.2"
+    escalade "^3.1.1"
+    get-caller-file "^2.0.5"
+    require-directory "^2.1.1"
+    string-width "^4.2.0"
+    y18n "^5.0.5"
+    yargs-parser "^20.2.2"
+
 yn@3.1.1:
   version "3.1.1"
   resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"