git.delta.rocks / unique-network / refs/commits / 6913914899af

difftreelog

build upgrade frontier

Yaroslav Bolyukin2022-11-16parent: #e8d45f9.patch.diff
in: master

51 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -75,9 +75,9 @@
 
 [[package]]
 name = "aho-corasick"
-version = "0.7.19"
+version = "0.7.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
+checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
 dependencies = [
  "memchr",
 ]
@@ -137,9 +137,9 @@
 
 [[package]]
 name = "array-bytes"
-version = "4.1.0"
+version = "4.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a913633b0c922e6b745072795f50d90ebea78ba31a57e2ac8c2fc7b50950949"
+checksum = "f52f63c5c1316a16a4b35eaac8b76a98248961a533f061684cb2a7cb0eafb6c6"
 
 [[package]]
 name = "arrayref"
@@ -196,30 +196,30 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e14485364214912d3b19cc3435dde4df66065127f05fa0d75c712f36f12c2f28"
 dependencies = [
- "concurrent-queue",
+ "concurrent-queue 1.2.4",
  "event-listener",
  "futures-core",
 ]
 
 [[package]]
 name = "async-executor"
-version = "1.4.1"
+version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965"
+checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b"
 dependencies = [
+ "async-lock",
  "async-task",
- "concurrent-queue",
+ "concurrent-queue 2.0.0",
  "fastrand",
  "futures-lite",
- "once_cell",
  "slab",
 ]
 
 [[package]]
 name = "async-global-executor"
-version = "2.3.0"
+version = "2.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0da5b41ee986eed3f524c380e6d64965aea573882a8907682ad100f7859305ca"
+checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776"
 dependencies = [
  "async-channel",
  "async-executor",
@@ -232,16 +232,16 @@
 
 [[package]]
 name = "async-io"
-version = "1.9.0"
+version = "1.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83e21f3a490c72b3b0cf44962180e60045de2925d8dff97918f7ee43c8f637c7"
+checksum = "e8121296a9f05be7f34aa4196b1747243b3b62e048bb7906f644f3fbfc490cf7"
 dependencies = [
+ "async-lock",
  "autocfg",
- "concurrent-queue",
+ "concurrent-queue 1.2.4",
  "futures-lite",
  "libc",
  "log",
- "once_cell",
  "parking",
  "polling",
  "slab",
@@ -340,9 +340,9 @@
 
 [[package]]
 name = "asynchronous-codec"
-version = "0.6.0"
+version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0de5164e5edbf51c45fb8c2d9664ae1c095cce1b265ecf7569093c0d66ef690"
+checksum = "06a0daa378f5fd10634e44b0a29b2a87b890657658e072a30d6f26e57ddee182"
 dependencies = [
  "bytes",
  "futures-sink",
@@ -595,16 +595,16 @@
  "funty 2.0.0",
  "radium 0.7.0",
  "tap",
- "wyz 0.5.0",
+ "wyz 0.5.1",
 ]
 
 [[package]]
 name = "blake2"
-version = "0.10.4"
+version = "0.10.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9cf849ee05b2ee5fba5e36f97ff8ec2533916700fc0758d40d92136a42f3388"
+checksum = "b12e5fd123190ce1c2e559308a94c9bacad77907d4c6005d9e58fe1a0689e55e"
 dependencies = [
- "digest 0.10.5",
+ "digest 0.10.6",
 ]
 
 [[package]]
@@ -614,7 +614,7 @@
 checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400"
 dependencies = [
  "arrayvec 0.4.12",
- "constant_time_eq",
+ "constant_time_eq 0.1.5",
 ]
 
 [[package]]
@@ -625,7 +625,7 @@
 dependencies = [
  "arrayref",
  "arrayvec 0.7.2",
- "constant_time_eq",
+ "constant_time_eq 0.1.5",
 ]
 
 [[package]]
@@ -636,21 +636,21 @@
 dependencies = [
  "arrayref",
  "arrayvec 0.7.2",
- "constant_time_eq",
+ "constant_time_eq 0.1.5",
 ]
 
 [[package]]
 name = "blake3"
-version = "1.3.1"
+version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f"
+checksum = "895adc16c8b3273fbbc32685a7d55227705eda08c01e77704020f3491924b44b"
 dependencies = [
  "arrayref",
  "arrayvec 0.7.2",
  "cc",
  "cfg-if 1.0.0",
- "constant_time_eq",
- "digest 0.10.5",
+ "constant_time_eq 0.2.4",
+ "digest 0.10.6",
 ]
 
 [[package]]
@@ -769,9 +769,9 @@
 
 [[package]]
 name = "byte-slice-cast"
-version = "1.2.1"
+version = "1.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87c5fdd0166095e1d463fc6cc01aa8ce547ad77a4e84d42eb6762b084e28067e"
+checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c"
 
 [[package]]
 name = "byte-tools"
@@ -787,9 +787,9 @@
 
 [[package]]
 name = "bytes"
-version = "1.2.1"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db"
+checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
 
 [[package]]
 name = "bzip2-sys"
@@ -841,9 +841,9 @@
 
 [[package]]
 name = "cc"
-version = "1.0.73"
+version = "1.0.77"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
+checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
 dependencies = [
  "jobserver",
 ]
@@ -911,9 +911,9 @@
 
 [[package]]
 name = "chrono"
-version = "0.4.22"
+version = "0.4.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1"
+checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
 dependencies = [
  "iana-time-zone",
  "js-sys",
@@ -973,7 +973,7 @@
 dependencies = [
  "glob",
  "libc",
- "libloading 0.7.3",
+ "libloading 0.7.4",
 ]
 
 [[package]]
@@ -1017,9 +1017,9 @@
 
 [[package]]
 name = "cmake"
-version = "0.1.48"
+version = "0.1.49"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a"
+checksum = "db34956e100b30725f2eb215f90d4871051239535632f84fea3bc92722c66b7c"
 dependencies = [
  "cc",
 ]
@@ -1048,9 +1048,9 @@
 
 [[package]]
 name = "comfy-table"
-version = "6.1.1"
+version = "6.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b3d16bb3da60be2f7c7acfc438f2ae6f3496897ce68c291d0509bb67b4e248e"
+checksum = "e621e7e86c46fd8a14c32c6ae3cb95656621b4743a27d0cffedb831d46e7ad21"
 dependencies = [
  "strum",
  "strum_macros",
@@ -1059,9 +1059,9 @@
 
 [[package]]
 name = "concat-idents"
-version = "1.1.3"
+version = "1.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b6f90860248d75014b7b103db8fee4f291c07bfb41306cdf77a0a5ab7a10d2f"
+checksum = "0fe0e1d9f7de897d18e590a7496b5facbe87813f746cf4b8db596ba77e07e832"
 dependencies = [
  "quote",
  "syn",
@@ -1077,6 +1077,15 @@
 ]
 
 [[package]]
+name = "concurrent-queue"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd7bef69dc86e3c610e4e7aed41035e2a7ed12e72dd7530f61327a6579a4390b"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
 name = "console"
 version = "0.15.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1102,6 +1111,12 @@
 checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
 
 [[package]]
+name = "constant_time_eq"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3ad85c1f65dc7b37604eb0e89748faf0b9653065f2a8ef69f96a687ec1e9279"
+
+[[package]]
 name = "convert_case"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1152,18 +1167,18 @@
 
 [[package]]
 name = "cranelift-bforest"
-version = "0.88.1"
+version = "0.88.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44409ccf2d0f663920cab563d2b79fcd6b2e9a2bcc6e929fef76c8f82ad6c17a"
+checksum = "52056f6d0584484b57fa6c1a65c1fcb15f3780d8b6a758426d9e3084169b2ddd"
 dependencies = [
  "cranelift-entity",
 ]
 
 [[package]]
 name = "cranelift-codegen"
-version = "0.88.1"
+version = "0.88.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98de2018ad96eb97f621f7d6b900a0cc661aec8d02ea4a50e56ecb48e5a2fcaf"
+checksum = "18fed94c8770dc25d01154c3ffa64ed0b3ba9d583736f305fed7beebe5d9cf74"
 dependencies = [
  "arrayvec 0.7.2",
  "bumpalo",
@@ -1181,33 +1196,33 @@
 
 [[package]]
 name = "cranelift-codegen-meta"
-version = "0.88.1"
+version = "0.88.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5287ce36e6c4758fbaf298bd1a8697ad97a4f2375a3d1b61142ea538db4877e5"
+checksum = "1c451b81faf237d11c7e4f3165eeb6bac61112762c5cfe7b4c0fb7241474358f"
 dependencies = [
  "cranelift-codegen-shared",
 ]
 
 [[package]]
 name = "cranelift-codegen-shared"
-version = "0.88.1"
+version = "0.88.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2855c24219e2f08827f3f4ffb2da92e134ae8d8ecc185b11ec8f9878cf5f588e"
+checksum = "e7c940133198426d26128f08be2b40b0bd117b84771fd36798969c4d712d81fc"
 
 [[package]]
 name = "cranelift-entity"
-version = "0.88.1"
+version = "0.88.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b65673279d75d34bf11af9660ae2dbd1c22e6d28f163f5c72f4e1dc56d56103"
+checksum = "87a0f1b2fdc18776956370cf8d9b009ded3f855350c480c1c52142510961f352"
 dependencies = [
  "serde",
 ]
 
 [[package]]
 name = "cranelift-frontend"
-version = "0.88.1"
+version = "0.88.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ed2b3d7a4751163f6c4a349205ab1b7d9c00eecf19dcea48592ef1f7688eefc"
+checksum = "34897538b36b216cc8dd324e73263596d51b8cf610da6498322838b2546baf8a"
 dependencies = [
  "cranelift-codegen",
  "log",
@@ -1217,15 +1232,15 @@
 
 [[package]]
 name = "cranelift-isle"
-version = "0.88.1"
+version = "0.88.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3be64cecea9d90105fc6a2ba2d003e98c867c1d6c4c86cc878f97ad9fb916293"
+checksum = "1b2629a569fae540f16a76b70afcc87ad7decb38dc28fa6c648ac73b51e78470"
 
 [[package]]
 name = "cranelift-native"
-version = "0.88.1"
+version = "0.88.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4a03a6ac1b063e416ca4b93f6247978c991475e8271465340caa6f92f3c16a4"
+checksum = "20937dab4e14d3e225c5adfc9c7106bafd4ac669bdb43027b911ff794c6fb318"
 dependencies = [
  "cranelift-codegen",
  "libc",
@@ -1234,9 +1249,9 @@
 
 [[package]]
 name = "cranelift-wasm"
-version = "0.88.1"
+version = "0.88.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c699873f7b30bc5f20dd03a796b4183e073a46616c91704792ec35e45d13f913"
+checksum = "80fc2288957a94fd342a015811479de1837850924166d1f1856d8406e6f3609b"
 dependencies = [
  "cranelift-codegen",
  "cranelift-entity",
@@ -1280,22 +1295,22 @@
 
 [[package]]
 name = "crossbeam-epoch"
-version = "0.9.11"
+version = "0.9.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348"
+checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
 dependencies = [
  "autocfg",
  "cfg-if 1.0.0",
  "crossbeam-utils",
- "memoffset",
+ "memoffset 0.7.1",
  "scopeguard",
 ]
 
 [[package]]
 name = "crossbeam-queue"
-version = "0.3.6"
+version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7"
+checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add"
 dependencies = [
  "cfg-if 1.0.0",
  "crossbeam-utils",
@@ -1303,9 +1318,9 @@
 
 [[package]]
 name = "crossbeam-utils"
-version = "0.8.12"
+version = "0.8.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac"
+checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
 dependencies = [
  "cfg-if 1.0.0",
 ]
@@ -1872,9 +1887,9 @@
 
 [[package]]
 name = "cxx"
-version = "1.0.80"
+version = "1.0.82"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b7d4e43b25d3c994662706a1d4fcfc32aaa6afd287502c111b237093bb23f3a"
+checksum = "d4a41a86530d0fe7f5d9ea779916b7cadd2d4f9add748b99c2c029cbbdfaf453"
 dependencies = [
  "cc",
  "cxxbridge-flags",
@@ -1884,9 +1899,9 @@
 
 [[package]]
 name = "cxx-build"
-version = "1.0.80"
+version = "1.0.82"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84f8829ddc213e2c1368e51a2564c552b65a8cb6a28f31e576270ac81d5e5827"
+checksum = "06416d667ff3e3ad2df1cd8cd8afae5da26cf9cec4d0825040f88b5ca659a2f0"
 dependencies = [
  "cc",
  "codespan-reporting",
@@ -1899,15 +1914,15 @@
 
 [[package]]
 name = "cxxbridge-flags"
-version = "1.0.80"
+version = "1.0.82"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e72537424b474af1460806647c41d4b6d35d09ef7fe031c5c2fa5766047cc56a"
+checksum = "820a9a2af1669deeef27cb271f476ffd196a2c4b6731336011e0ba63e2c7cf71"
 
 [[package]]
 name = "cxxbridge-macro"
-version = "1.0.80"
+version = "1.0.82"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "309e4fb93eed90e1e14bea0da16b209f81813ba9fc7830c20ed151dd7bc0a4d7"
+checksum = "a08a6e2fcc370a089ad3b4aaf54db3b1b4cee38ddabce5896b33eb693275f470"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1993,9 +2008,9 @@
 
 [[package]]
 name = "digest"
-version = "0.10.5"
+version = "0.10.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c"
+checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
 dependencies = [
  "block-buffer 0.10.3",
  "crypto-common",
@@ -2216,9 +2231,9 @@
 
 [[package]]
 name = "env_logger"
-version = "0.9.1"
+version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c90bf5f19754d10198ccb95b70664fc925bd1fc090a0fd9a6ebc54acc8cd6272"
+checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7"
 dependencies = [
  "atty",
  "humantime",
@@ -2479,7 +2494,7 @@
 [[package]]
 name = "fc-consensus"
 version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
 dependencies = [
  "async-trait",
  "fc-db",
@@ -2498,14 +2513,16 @@
 [[package]]
 name = "fc-db"
 version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
 dependencies = [
  "fp-storage",
  "kvdb-rocksdb",
+ "log",
  "parity-db",
  "parity-scale-codec 3.2.1",
  "parking_lot 0.12.1",
  "sc-client-db",
+ "sp-blockchain",
  "sp-core",
  "sp-database",
  "sp-runtime",
@@ -2514,7 +2531,7 @@
 [[package]]
 name = "fc-mapping-sync"
 version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
 dependencies = [
  "fc-db",
  "fp-consensus",
@@ -2531,13 +2548,15 @@
 [[package]]
 name = "fc-rpc"
 version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
 dependencies = [
  "ethereum",
  "ethereum-types",
  "evm",
  "fc-db",
  "fc-rpc-core",
+ "fp-ethereum",
+ "fp-evm",
  "fp-rpc",
  "fp-storage",
  "futures 0.3.25",
@@ -2545,12 +2564,11 @@
  "jsonrpsee",
  "libsecp256k1",
  "log",
- "lru 0.7.8",
+ "lru 0.8.1",
  "parity-scale-codec 3.2.1",
  "prometheus",
  "rand 0.8.5",
  "rlp",
- "rustc-hex",
  "sc-client-api",
  "sc-network",
  "sc-network-common",
@@ -2573,7 +2591,7 @@
 [[package]]
 name = "fc-rpc-core"
 version = "1.1.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
 dependencies = [
  "ethereum",
  "ethereum-types",
@@ -2713,7 +2731,7 @@
 [[package]]
 name = "fp-consensus"
 version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
 dependencies = [
  "ethereum",
  "parity-scale-codec 3.2.1",
@@ -2723,9 +2741,24 @@
 ]
 
 [[package]]
+name = "fp-ethereum"
+version = "1.0.0-dev"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
+dependencies = [
+ "ethereum",
+ "ethereum-types",
+ "fp-evm",
+ "frame-support",
+ "num_enum",
+ "parity-scale-codec 3.2.1",
+ "sp-core",
+ "sp-std",
+]
+
+[[package]]
 name = "fp-evm"
 version = "3.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
 dependencies = [
  "evm",
  "frame-support",
@@ -2739,7 +2772,7 @@
 [[package]]
 name = "fp-evm-mapping"
 version = "0.1.0"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
 dependencies = [
  "frame-support",
  "sp-core",
@@ -2748,7 +2781,7 @@
 [[package]]
 name = "fp-rpc"
 version = "3.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
 dependencies = [
  "ethereum",
  "ethereum-types",
@@ -2765,7 +2798,7 @@
 [[package]]
 name = "fp-self-contained"
 version = "1.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
 dependencies = [
  "ethereum",
  "frame-support",
@@ -2773,17 +2806,16 @@
  "parity-util-mem",
  "scale-info",
  "serde",
- "sp-debug-derive",
- "sp-io",
  "sp-runtime",
 ]
 
 [[package]]
 name = "fp-storage"
 version = "2.0.0"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
 dependencies = [
  "parity-scale-codec 3.2.1",
+ "serde",
 ]
 
 [[package]]
@@ -3040,9 +3072,9 @@
 
 [[package]]
 name = "fs-err"
-version = "2.8.1"
+version = "2.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64db3e262960f0662f43a6366788d5f10f7f244b8f7d7d987f560baf5ded5c50"
+checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541"
 
 [[package]]
 name = "fs-swap"
@@ -3512,9 +3544,9 @@
 
 [[package]]
 name = "hyper"
-version = "0.14.20"
+version = "0.14.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac"
+checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c"
 dependencies = [
  "bytes",
  "futures-channel",
@@ -3536,9 +3568,9 @@
 
 [[package]]
 name = "hyper-rustls"
-version = "0.23.0"
+version = "0.23.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac"
+checksum = "59df7c4e19c950e6e0e868dcc0a300b09a9b88e9ec55bd879ca819087a77355d"
 dependencies = [
  "http",
  "hyper",
@@ -3551,9 +3583,9 @@
 
 [[package]]
 name = "iana-time-zone"
-version = "0.1.51"
+version = "0.1.53"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f5a6ef98976b22b3b7f2f3a806f858cb862044cfa66805aa3ad84cb3d3b785ed"
+checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
 dependencies = [
  "android_system_properties",
  "core-foundation-sys",
@@ -3662,9 +3694,9 @@
 
 [[package]]
 name = "indexmap"
-version = "1.9.1"
+version = "1.9.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
+checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
 dependencies = [
  "autocfg",
  "hashbrown",
@@ -3706,11 +3738,21 @@
 
 [[package]]
 name = "io-lifetimes"
-version = "0.7.4"
+version = "0.7.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6e481ccbe3dea62107216d0d1138bb8ad8e5e5c43009a098bd1990272c497b0"
+checksum = "59ce5ef949d49ee85593fc4d3f3f95ad61657076395cbbce23e2121fc5542074"
 
 [[package]]
+name = "io-lifetimes"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7d367024b3f3414d8e01f437f704f41a9f64ab36f9067fa73e526ad4c763c87"
+dependencies = [
+ "libc",
+ "windows-sys 0.42.0",
+]
+
+[[package]]
 name = "ip_network"
 version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3718,9 +3760,9 @@
 
 [[package]]
 name = "ipconfig"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "723519edce41262b05d4143ceb95050e4c614f483e78e9fd9e39a8275a84ad98"
+checksum = "bd302af1b90f2463a98fa5ad469fc212c8e3175a41c3068601bfa2727591c5be"
 dependencies = [
  "socket2",
  "widestring",
@@ -3730,9 +3772,9 @@
 
 [[package]]
 name = "ipnet"
-version = "2.5.0"
+version = "2.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b"
+checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745"
 
 [[package]]
 name = "itertools"
@@ -3925,9 +3967,12 @@
 
 [[package]]
 name = "keccak"
-version = "0.1.2"
+version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838"
+checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768"
+dependencies = [
+ "cpufeatures",
+]
 
 [[package]]
 name = "kusama-runtime"
@@ -4113,9 +4158,9 @@
 
 [[package]]
 name = "libloading"
-version = "0.7.3"
+version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd"
+checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
 dependencies = [
  "cfg-if 1.0.0",
  "winapi",
@@ -4123,9 +4168,9 @@
 
 [[package]]
 name = "libm"
-version = "0.2.5"
+version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "292a948cd991e376cf75541fe5b97a1081d713c618b4f1b9500f8844e49eb565"
+checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb"
 
 [[package]]
 name = "libp2p"
@@ -4757,6 +4802,12 @@
 checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d"
 
 [[package]]
+name = "linux-raw-sys"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb68f22743a3fb35785f1e7f844ca5a3de2dde5bd0c0ef5b372065814699b121"
+
+[[package]]
 name = "lock_api"
 version = "0.4.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4880,18 +4931,18 @@
 
 [[package]]
 name = "memfd"
-version = "0.6.1"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "480b5a5de855d11ff13195950bdc8b98b5e942ef47afc447f6615cdcc4e15d80"
+checksum = "b20a59d985586e4a5aef64564ac77299f8586d8be6cf9106a5a40207e8908efb"
 dependencies = [
- "rustix",
+ "rustix 0.36.2",
 ]
 
 [[package]]
 name = "memmap2"
-version = "0.5.7"
+version = "0.5.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498"
+checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc"
 dependencies = [
  "libc",
 ]
@@ -4906,6 +4957,15 @@
 ]
 
 [[package]]
+name = "memoffset"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
 name = "memory-db"
 version = "0.29.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5020,7 +5080,7 @@
  "blake2s_simd",
  "blake3",
  "core2",
- "digest 0.10.5",
+ "digest 0.10.6",
  "multihash-derive",
  "sha2 0.10.6",
  "sha3",
@@ -5291,15 +5351,36 @@
 
 [[package]]
 name = "num_cpus"
-version = "1.13.1"
+version = "1.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
+checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5"
 dependencies = [
  "hermit-abi",
  "libc",
 ]
 
 [[package]]
+name = "num_enum"
+version = "0.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9"
+dependencies = [
+ "num_enum_derive",
+]
+
+[[package]]
+name = "num_enum_derive"
+version = "0.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
 name = "num_threads"
 version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5322,9 +5403,9 @@
 
 [[package]]
 name = "once_cell"
-version = "1.15.0"
+version = "1.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1"
+checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
 
 [[package]]
 name = "opal-runtime"
@@ -5577,9 +5658,9 @@
 
 [[package]]
 name = "os_str_bytes"
-version = "6.3.0"
+version = "6.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff"
+checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
 
 [[package]]
 name = "owning_ref"
@@ -5724,7 +5805,7 @@
 [[package]]
 name = "pallet-base-fee"
 version = "1.0.0"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
 dependencies = [
  "fp-evm",
  "frame-support",
@@ -5940,12 +6021,13 @@
 [[package]]
 name = "pallet-ethereum"
 version = "4.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
 dependencies = [
  "ethereum",
  "ethereum-types",
  "evm",
  "fp-consensus",
+ "fp-ethereum",
  "fp-evm",
  "fp-evm-mapping",
  "fp-rpc",
@@ -5953,14 +6035,12 @@
  "fp-storage",
  "frame-support",
  "frame-system",
- "log",
  "pallet-evm",
  "pallet-timestamp",
  "parity-scale-codec 3.2.1",
  "rlp",
  "scale-info",
  "serde",
- "sha3",
  "sp-io",
  "sp-runtime",
  "sp-std",
@@ -5969,8 +6049,9 @@
 [[package]]
 name = "pallet-evm"
 version = "6.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
 dependencies = [
+ "environmental",
  "evm",
  "fp-evm",
  "fp-evm-mapping",
@@ -5986,7 +6067,6 @@
  "rlp",
  "scale-info",
  "serde",
- "sha3",
  "sp-core",
  "sp-io",
  "sp-runtime",
@@ -7163,9 +7243,9 @@
 
 [[package]]
 name = "pest"
-version = "2.4.0"
+version = "2.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dbc7bc69c062e492337d74d59b120c274fd3d261b6bf6d3207d499b4b379c41a"
+checksum = "a528564cc62c19a7acac4d81e01f39e53e25e17b934878f4c6d25cc2836e62f8"
 dependencies = [
  "thiserror",
  "ucd-trie",
@@ -7173,9 +7253,9 @@
 
 [[package]]
 name = "pest_derive"
-version = "2.4.0"
+version = "2.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60b75706b9642ebcb34dab3bc7750f811609a0eb1dd8b88c2d15bf628c1c65b2"
+checksum = "d5fd9bc6500181952d34bd0b2b0163a54d794227b498be0b7afa7698d0a7b18f"
 dependencies = [
  "pest",
  "pest_generator",
@@ -7183,9 +7263,9 @@
 
 [[package]]
 name = "pest_generator"
-version = "2.4.0"
+version = "2.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4f9272122f5979a6511a749af9db9bfc810393f63119970d7085fed1c4ea0db"
+checksum = "d2610d5ac5156217b4ff8e46ddcef7cdf44b273da2ac5bca2ecbfa86a330e7c4"
 dependencies = [
  "pest",
  "pest_meta",
@@ -7196,9 +7276,9 @@
 
 [[package]]
 name = "pest_meta"
-version = "2.4.0"
+version = "2.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c8717927f9b79515e565a64fe46c38b8cd0427e64c40680b14a7365ab09ac8d"
+checksum = "824749bf7e21dd66b36fbe26b3f45c713879cccd4a009a917ab8e045ca8246fe"
 dependencies = [
  "once_cell",
  "pest",
@@ -8556,11 +8636,21 @@
 
 [[package]]
 name = "ppv-lite86"
-version = "0.2.16"
+version = "0.2.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
+checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
 
 [[package]]
+name = "prettyplease"
+version = "0.1.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c142c0e46b57171fe0c528bee8c5b7569e80f0c17e377cd0e30ea57dbc11bb51"
+dependencies = [
+ "proc-macro2",
+ "syn",
+]
+
+[[package]]
 name = "primitive-types"
 version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -8682,12 +8772,12 @@
 
 [[package]]
 name = "prost"
-version = "0.11.0"
+version = "0.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "399c3c31cdec40583bb68f0b18403400d01ec4289c383aa047560439952c4dd7"
+checksum = "a0841812012b2d4a6145fae9a6af1534873c32aa67fff26bd09f8fa42c83f95a"
 dependencies = [
  "bytes",
- "prost-derive 0.11.0",
+ "prost-derive 0.11.2",
 ]
 
 [[package]]
@@ -8714,9 +8804,9 @@
 
 [[package]]
 name = "prost-build"
-version = "0.11.1"
+version = "0.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f835c582e6bd972ba8347313300219fed5bfa52caf175298d860b61ff6069bb"
+checksum = "1d8b442418ea0822409d9e7d047cbf1e7e9e1760b172bf9982cf29d517c93511"
 dependencies = [
  "bytes",
  "heck",
@@ -8725,9 +8815,11 @@
  "log",
  "multimap",
  "petgraph",
- "prost 0.11.0",
- "prost-types 0.11.1",
+ "prettyplease",
+ "prost 0.11.2",
+ "prost-types 0.11.2",
  "regex",
+ "syn",
  "tempfile",
  "which",
 ]
@@ -8760,9 +8852,9 @@
 
 [[package]]
 name = "prost-derive"
-version = "0.11.0"
+version = "0.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7345d5f0e08c0536d7ac7229952590239e77abf0a0100a1b1d890add6ea96364"
+checksum = "164ae68b6587001ca506d3bf7f1000bfa248d0e1217b618108fba4ec1d0cc306"
 dependencies = [
  "anyhow",
  "itertools",
@@ -8783,12 +8875,12 @@
 
 [[package]]
 name = "prost-types"
-version = "0.11.1"
+version = "0.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4dfaa718ad76a44b3415e6c4d53b17c8f99160dcb3a99b10470fce8ad43f6e3e"
+checksum = "747761bc3dc48f9a34553bf65605cf6cb6288ba219f3450b4275dbd81539551a"
 dependencies = [
  "bytes",
- "prost 0.11.0",
+ "prost 0.11.2",
 ]
 
 [[package]]
@@ -9039,11 +9131,10 @@
 
 [[package]]
 name = "rayon"
-version = "1.5.3"
+version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
+checksum = "1e060280438193c554f654141c9ea9417886713b7acd75974c85b18a69a88e0b"
 dependencies = [
- "autocfg",
  "crossbeam-deque",
  "either",
  "rayon-core",
@@ -9051,9 +9142,9 @@
 
 [[package]]
 name = "rayon-core"
-version = "1.9.3"
+version = "1.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
+checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3"
 dependencies = [
  "crossbeam-channel",
  "crossbeam-deque",
@@ -9096,18 +9187,18 @@
 
 [[package]]
 name = "ref-cast"
-version = "1.0.12"
+version = "1.0.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12a733f1746c929b4913fe48f8697fcf9c55e3304ba251a79ffb41adfeaf49c2"
+checksum = "53b15debb4f9d60d767cd8ca9ef7abb2452922f3214671ff052defc7f3502c44"
 dependencies = [
  "ref-cast-impl",
 ]
 
 [[package]]
 name = "ref-cast-impl"
-version = "1.0.12"
+version = "1.0.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5887de4a01acafd221861463be6113e6e87275e79804e56779f4cdc131c60368"
+checksum = "abfa8511e9e94fd3de6585a3d3cd00e01ed556dc9814829280af0e8dc72a8f36"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -9128,9 +9219,9 @@
 
 [[package]]
 name = "regex"
-version = "1.6.0"
+version = "1.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
+checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -9148,9 +9239,9 @@
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.27"
+version = "0.6.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
+checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
 
 [[package]]
 name = "remote-externalities"
@@ -9426,16 +9517,30 @@
 
 [[package]]
 name = "rustix"
-version = "0.35.12"
+version = "0.35.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "985947f9b6423159c4726323f373be0a21bdb514c5af06a849cb3d2dce2d01e8"
+checksum = "727a1a6d65f786ec22df8a81ca3121107f235970dc1705ed681d3e6e8b9cd5f9"
 dependencies = [
  "bitflags",
  "errno",
- "io-lifetimes",
+ "io-lifetimes 0.7.5",
  "libc",
- "linux-raw-sys",
- "windows-sys 0.36.1",
+ "linux-raw-sys 0.0.46",
+ "windows-sys 0.42.0",
+]
+
+[[package]]
+name = "rustix"
+version = "0.36.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "203974af07ea769452490ee8de3e5947971efc3a090dca8a779dd432d3fa46a7"
+dependencies = [
+ "bitflags",
+ "errno",
+ "io-lifetimes 1.0.1",
+ "libc",
+ "linux-raw-sys 0.1.2",
+ "windows-sys 0.42.0",
 ]
 
 [[package]]
@@ -9976,7 +10081,7 @@
  "once_cell",
  "parity-scale-codec 3.2.1",
  "parity-wasm 0.45.0",
- "rustix",
+ "rustix 0.35.13",
  "sc-allocator",
  "sc-executor-common",
  "sp-runtime-interface",
@@ -10135,8 +10240,8 @@
  "futures 0.3.25",
  "libp2p",
  "log",
- "prost 0.11.0",
- "prost-build 0.11.1",
+ "prost 0.11.2",
+ "prost-build 0.11.2",
  "sc-client-api",
  "sc-network-common",
  "sp-blockchain",
@@ -10612,9 +10717,9 @@
 
 [[package]]
 name = "scale-info"
-version = "2.2.0"
+version = "2.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "333af15b02563b8182cd863f925bd31ef8fa86a0e095d30c091956057d436153"
+checksum = "88d8a765117b237ef233705cc2cc4c6a27fccd46eea6ef0c8c6dae5f3ef407f8"
 dependencies = [
  "bitvec 1.0.1",
  "cfg-if 1.0.0",
@@ -10626,9 +10731,9 @@
 
 [[package]]
 name = "scale-info-derive"
-version = "2.2.0"
+version = "2.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53f56acbd0743d29ffa08f911ab5397def774ad01bab3786804cf6ee057fb5e1"
+checksum = "cdcd47b380d8c4541044e341dcd9475f55ba37ddc50c908d945fc036a8642496"
 dependencies = [
  "proc-macro-crate",
  "proc-macro2",
@@ -10804,9 +10909,9 @@
 
 [[package]]
 name = "serde_json"
-version = "1.0.87"
+version = "1.0.89"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45"
+checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
 dependencies = [
  "itoa",
  "ryu",
@@ -10843,7 +10948,7 @@
 dependencies = [
  "cfg-if 1.0.0",
  "cpufeatures",
- "digest 0.10.5",
+ "digest 0.10.6",
 ]
 
 [[package]]
@@ -10879,7 +10984,7 @@
 dependencies = [
  "cfg-if 1.0.0",
  "cpufeatures",
- "digest 0.10.5",
+ "digest 0.10.6",
 ]
 
 [[package]]
@@ -10888,7 +10993,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9"
 dependencies = [
- "digest 0.10.5",
+ "digest 0.10.6",
  "keccak",
 ]
 
@@ -10956,9 +11061,9 @@
 
 [[package]]
 name = "similar"
-version = "2.2.0"
+version = "2.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62ac7f900db32bf3fd12e0117dd3dc4da74bc52ebaac97f39668446d89694803"
+checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf"
 dependencies = [
  "bstr",
  "unicode-segmentation",
@@ -11018,9 +11123,9 @@
 
 [[package]]
 name = "snap"
-version = "1.0.5"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45456094d1983e2ee2a18fdfebce3189fa451699d0502cb8e3b49dba5ba41451"
+checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831"
 
 [[package]]
 name = "snow"
@@ -11318,7 +11423,7 @@
 dependencies = [
  "blake2",
  "byteorder",
- "digest 0.10.5",
+ "digest 0.10.6",
  "sha2 0.10.6",
  "sha3",
  "sp-std",
@@ -11816,9 +11921,9 @@
 
 [[package]]
 name = "ss58-registry"
-version = "1.33.0"
+version = "1.35.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ab7554f8a8b6f8d71cd5a8e6536ef116e2ce0504cf97ebf16311d58065dc8a6"
+checksum = "fa0813c10b9dbdc842c2305f949f724c64866e4ef4d09c9151e96f6a2106773c"
 dependencies = [
  "Inflector",
  "num-format",
@@ -12141,9 +12246,9 @@
 
 [[package]]
 name = "target-lexicon"
-version = "0.12.4"
+version = "0.12.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c02424087780c9b71cc96799eaeddff35af2bc513278cda5c99fc1f5d026d3c1"
+checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d"
 
 [[package]]
 name = "tempfile"
@@ -12368,9 +12473,9 @@
 
 [[package]]
 name = "tokio"
-version = "1.21.2"
+version = "1.22.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099"
+checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3"
 dependencies = [
  "autocfg",
  "bytes",
@@ -12694,7 +12799,7 @@
 checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
 dependencies = [
  "cfg-if 1.0.0",
- "digest 0.10.5",
+ "digest 0.10.6",
  "rand 0.8.5",
  "static_assertions",
 ]
@@ -13340,9 +13445,9 @@
 
 [[package]]
 name = "wasmtime"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1f511c4917c83d04da68333921107db75747c4e11a2f654a8e909cc5e0520dc"
+checksum = "4ad5af6ba38311282f2a21670d96e78266e8c8e2f38cbcd52c254df6ccbc7731"
 dependencies = [
  "anyhow",
  "bincode",
@@ -13368,18 +13473,18 @@
 
 [[package]]
 name = "wasmtime-asm-macros"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39bf3debfe744bf19dd3732990ce6f8c0ced7439e2370ba4e1d8f5a3660a3178"
+checksum = "45de63ddfc8b9223d1adc8f7b2ee5f35d1f6d112833934ad7ea66e4f4339e597"
 dependencies = [
  "cfg-if 1.0.0",
 ]
 
 [[package]]
 name = "wasmtime-cache"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ece42fa4676a263f7558cdaaf5a71c2592bebcbac22a0580e33cf3406c103da2"
+checksum = "bcd849399d17d2270141cfe47fa0d91ee52d5f8ea9b98cf7ddde0d53e5f79882"
 dependencies = [
  "anyhow",
  "base64",
@@ -13387,7 +13492,7 @@
  "directories-next",
  "file-per-thread-logger",
  "log",
- "rustix",
+ "rustix 0.35.13",
  "serde",
  "sha2 0.9.9",
  "toml",
@@ -13397,9 +13502,9 @@
 
 [[package]]
 name = "wasmtime-cranelift"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "058217e28644b012bdcdf0e445f58d496d78c2e0b6a6dd93558e701591dad705"
+checksum = "4bd91339b742ff20bfed4532a27b73c86b5bcbfedd6bea2dcdf2d64471e1b5c6"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -13418,9 +13523,9 @@
 
 [[package]]
 name = "wasmtime-environ"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7af06848df28b7661471d9a80d30a973e0f401f2e3ed5396ad7e225ed217047"
+checksum = "ebb881c61f4f627b5d45c54e629724974f8a8890d455bcbe634330cc27309644"
 dependencies = [
  "anyhow",
  "cranelift-entity",
@@ -13437,9 +13542,9 @@
 
 [[package]]
 name = "wasmtime-jit"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9028fb63a54185b3c192b7500ef8039c7bb8d7f62bfc9e7c258483a33a3d13bb"
+checksum = "1985c628011fe26adf5e23a5301bdc79b245e0e338f14bb58b39e4e25e4d8681"
 dependencies = [
  "addr2line",
  "anyhow",
@@ -13450,7 +13555,7 @@
  "log",
  "object",
  "rustc-demangle",
- "rustix",
+ "rustix 0.35.13",
  "serde",
  "target-lexicon",
  "thiserror",
@@ -13462,20 +13567,20 @@
 
 [[package]]
 name = "wasmtime-jit-debug"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25e82d4ef93296785de7efca92f7679dc67fe68a13b625a5ecc8d7503b377a37"
+checksum = "f671b588486f5ccec8c5a3dba6b4c07eac2e66ab8c60e6f4e53717c77f709731"
 dependencies = [
  "object",
  "once_cell",
- "rustix",
+ "rustix 0.35.13",
 ]
 
 [[package]]
 name = "wasmtime-runtime"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f0e9bea7d517d114fe66b930b2124ee086516ee93eeebfd97f75f366c5b0553"
+checksum = "ee8f92ad4b61736339c29361da85769ebc200f184361959d1792832e592a1afd"
 dependencies = [
  "anyhow",
  "cc",
@@ -13485,10 +13590,10 @@
  "log",
  "mach",
  "memfd",
- "memoffset",
+ "memoffset 0.6.5",
  "paste",
  "rand 0.8.5",
- "rustix",
+ "rustix 0.35.13",
  "thiserror",
  "wasmtime-asm-macros",
  "wasmtime-environ",
@@ -13498,9 +13603,9 @@
 
 [[package]]
 name = "wasmtime-types"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69b83e93ed41b8fdc936244cfd5e455480cf1eca1fd60c78a0040038b4ce5075"
+checksum = "d23d61cb4c46e837b431196dd06abb11731541021916d03476a178b54dc07aeb"
 dependencies = [
  "cranelift-entity",
  "serde",
@@ -13841,9 +13946,9 @@
 
 [[package]]
 name = "winreg"
-version = "0.7.0"
+version = "0.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69"
+checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
 dependencies = [
  "winapi",
 ]
@@ -13856,9 +13961,9 @@
 
 [[package]]
 name = "wyz"
-version = "0.5.0"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30b31594f29d27036c383b53b59ed3476874d518f0efb151b27a4c275141390e"
+checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
 dependencies = [
  "tap",
 ]
modifiedclient/rpc/Cargo.tomldiffbeforeafterboth
--- a/client/rpc/Cargo.toml
+++ b/client/rpc/Cargo.toml
@@ -19,4 +19,4 @@
 sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-rpc = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
modifiedcrates/evm-coder/Cargo.tomldiffbeforeafterboth
--- a/crates/evm-coder/Cargo.toml
+++ b/crates/evm-coder/Cargo.toml
@@ -19,7 +19,7 @@
 # We have tuple-heavy code in solidity.rs
 impl-trait-for-tuples = "0.2.2"
 
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 
 [dev-dependencies]
 # We want to assert some large binary blobs equality in tests
modifiedcrates/evm-coder/src/lib.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/lib.rs
+++ b/crates/evm-coder/src/lib.rs
@@ -197,7 +197,7 @@
 	impl EthCrossAccount {
 		pub fn from_sub_cross_account<T>(cross_account_id: &T::CrossAccountId) -> Self
 		where
-			T: pallet_evm::account::Config,
+			T: pallet_evm::Config,
 			T::AccountId: AsRef<[u8; 32]>,
 		{
 			if cross_account_id.is_canonical_substrate() {
@@ -215,7 +215,7 @@
 
 		pub fn into_sub_cross_account<T>(&self) -> crate::execution::Result<T::CrossAccountId>
 		where
-			T: pallet_evm::account::Config,
+			T: pallet_evm::Config,
 			T::AccountId: From<[u8; 32]>,
 		{
 			if self.eth == Default::default() && self.sub == Default::default() {
@@ -231,7 +231,7 @@
 	}
 
 	/// Convert `CrossAccountId` to `uint256`.
-	pub fn convert_cross_account_to_uint256<T: pallet_evm::account::Config>(
+	pub fn convert_cross_account_to_uint256<T: pallet_evm::Config>(
 		from: &T::CrossAccountId,
 	) -> uint256
 	where
@@ -242,7 +242,7 @@
 	}
 
 	/// Convert `uint256` to `CrossAccountId`.
-	pub fn convert_uint256_to_cross_account<T: pallet_evm::account::Config>(
+	pub fn convert_uint256_to_cross_account<T: pallet_evm::Config>(
 		from: uint256,
 	) -> T::CrossAccountId
 	where
modifiednode/cli/Cargo.tomldiffbeforeafterboth
--- a/node/cli/Cargo.toml
+++ b/node/cli/Cargo.toml
@@ -309,13 +309,13 @@
 jsonrpsee = { version = "0.15.1", features = ["server", "macros"] }
 tokio = { version = "1.19.2", features = ["time"] }
 
-fc-rpc-core = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fc-consensus = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fc-mapping-sync = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fc-rpc = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fc-db = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-rpc = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+fc-rpc-core = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fc-consensus = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fc-mapping-sync = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fc-rpc = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fc-db = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-rpc = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 
 unique-rpc = { default-features = false, path = "../rpc" }
 app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false }
modifiednode/cli/src/service.rsdiffbeforeafterboth
--- a/node/cli/src/service.rs
+++ b/node/cli/src/service.rs
@@ -45,7 +45,8 @@
 use cumulus_relay_chain_interface::{RelayChainError, RelayChainInterface, RelayChainResult};
 use cumulus_relay_chain_rpc_interface::{RelayChainRpcInterface, create_client_and_start_worker};
 
-// Substrate Imports
+// Substrate ImportsA
+use sp_api::BlockT;
 use sc_executor::NativeElseWasmExecutor;
 use sc_executor::NativeExecutionDispatch;
 use sc_network::{NetworkService, NetworkBlock};
@@ -159,7 +160,10 @@
 	}
 }
 
-pub fn open_frontier_backend(config: &Configuration) -> Result<Arc<fc_db::Backend<Block>>, String> {
+pub fn open_frontier_backend<Block: BlockT, C: sp_blockchain::HeaderBackend<Block>>(
+	client: Arc<C>,
+	config: &Configuration,
+) -> Result<Arc<fc_db::Backend<Block>>, String> {
 	let config_dir = config
 		.base_path
 		.as_ref()
@@ -170,6 +174,7 @@
 	let database_dir = config_dir.join("frontier").join("db");
 
 	Ok(Arc::new(fc_db::Backend::<Block>::new(
+		client,
 		&fc_db::DatabaseSettings {
 			source: fc_db::DatabaseSource::RocksDb {
 				path: database_dir,
@@ -285,7 +290,7 @@
 
 	let filter_pool: Option<FilterPool> = Some(Arc::new(Mutex::new(BTreeMap::new())));
 
-	let frontier_backend = open_frontier_backend(config)?;
+	let frontier_backend = open_frontier_backend(client.clone(), config)?;
 
 	let import_queue = build_import_queue(
 		client.clone(),
modifiednode/rpc/Cargo.tomldiffbeforeafterboth
--- a/node/rpc/Cargo.toml
+++ b/node/rpc/Cargo.toml
@@ -40,20 +40,20 @@
 substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 tokio = { version = "1.19.2", features = ["macros", "sync"] }
 
-pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fc-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-storage = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fc-rpc-core = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fc-db = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fc-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-storage = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fc-rpc-core = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fc-db = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 
 pallet-common = { default-features = false, path = "../../pallets/common" }
 up-common = { path = "../../primitives/common" }
 pallet-unique = { path = "../../pallets/unique" }
 uc-rpc = { path = "../../client/rpc" }
 up-rpc = { path = "../../primitives/rpc" }
-app-promotion-rpc = { path = "../../primitives/app_promotion_rpc"}
+app-promotion-rpc = { path = "../../primitives/app_promotion_rpc" }
 rmrk-rpc = { path = "../../primitives/rmrk-rpc" }
 up-data-structs = { default-features = false, path = "../../primitives/data-structs" }
 
modifiednode/rpc/src/lib.rsdiffbeforeafterboth
--- a/node/rpc/src/lib.rs
+++ b/node/rpc/src/lib.rs
@@ -230,6 +230,7 @@
 			block_data_cache.clone(),
 			fee_history_cache,
 			fee_history_limit,
+			10,
 		)
 		.into_rpc(),
 	)?;
modifiedpallets/app-promotion/Cargo.tomldiffbeforeafterboth
--- a/pallets/app-promotion/Cargo.toml
+++ b/pallets/app-promotion/Cargo.toml
@@ -47,28 +47,30 @@
 ################################################################################
 # Substrate Dependencies
 
-codec = { default-features = false, features = ['derive'], package = 'parity-scale-codec', version = '3.1.2' }
-frame-benchmarking = {default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
+codec = { default-features = false, features = [
+    'derive',
+], package = 'parity-scale-codec', version = '3.1.2' }
+frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-frame-system ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-balances ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-timestamp ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-randomness-collective-flip ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm ={ default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-sp-std ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
+frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
+pallet-balances = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
+pallet-timestamp = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
+pallet-randomness-collective-flip = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-sp-io ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
+sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 serde = { default-features = false, features = ['derive'], version = '1.0.130' }
 
 ################################################################################
 # local dependencies
 
-up-data-structs ={ default-features = false, path = "../../primitives/data-structs" }
-pallet-common ={ default-features = false, path = "../common" }
-pallet-unique ={ default-features = false, path = "../unique" }
-pallet-evm-contract-helpers ={ default-features = false, path = "../evm-contract-helpers" }
-pallet-evm-migration ={ default-features = false, path = "../evm-migration" }
+up-data-structs = { default-features = false, path = "../../primitives/data-structs" }
+pallet-common = { default-features = false, path = "../common" }
+pallet-unique = { default-features = false, path = "../unique" }
+pallet-evm-contract-helpers = { default-features = false, path = "../evm-contract-helpers" }
+pallet-evm-migration = { default-features = false, path = "../evm-migration" }
 
 # [dev-dependencies]
 
modifiedpallets/app-promotion/src/lib.rsdiffbeforeafterboth
--- a/pallets/app-promotion/src/lib.rs
+++ b/pallets/app-promotion/src/lib.rs
@@ -102,7 +102,7 @@
 	use frame_system::pallet_prelude::*;
 
 	#[pallet::config]
-	pub trait Config: frame_system::Config + pallet_evm::account::Config {
+	pub trait Config: frame_system::Config + pallet_evm::Config {
 		/// Type to interact with the native token
 		type Currency: ExtendedLockableCurrency<Self::AccountId>
 			+ ReservableCurrency<Self::AccountId>;
@@ -274,11 +274,13 @@
 
 			if !block_pending.is_empty() {
 				block_pending.into_iter().for_each(|(staker, amount)| {
-					<T::Currency as ReservableCurrency<T::AccountId>>::unreserve(&staker, amount);
+					<<T as Config>::Currency as ReservableCurrency<T::AccountId>>::unreserve(
+						&staker, amount,
+					);
 				});
 			}
 
-			T::WeightInfo::on_initialize(counter)
+			<T as Config>::WeightInfo::on_initialize(counter)
 		}
 	}
 
@@ -297,7 +299,7 @@
 		/// # Arguments
 		///
 		/// * `admin`: account of the new admin.
-		#[pallet::weight(T::WeightInfo::set_admin_address())]
+		#[pallet::weight(<T as Config>::WeightInfo::set_admin_address())]
 		pub fn set_admin_address(origin: OriginFor<T>, admin: T::CrossAccountId) -> DispatchResult {
 			ensure_root(origin)?;
 
@@ -315,7 +317,7 @@
 		/// # Arguments
 		///
 		/// * `amount`: in native tokens.
-		#[pallet::weight(T::WeightInfo::stake())]
+		#[pallet::weight(<T as Config>::WeightInfo::stake())]
 		pub fn stake(staker: OriginFor<T>, amount: BalanceOf<T>) -> DispatchResult {
 			let staker_id = ensure_signed(staker)?;
 
@@ -388,7 +390,7 @@
 		/// Moves the sum of all stakes to the `reserved` state.
 		/// After the end of `PendingInterval` this sum becomes completely
 		/// free for further use.
-		#[pallet::weight(T::WeightInfo::unstake())]
+		#[pallet::weight(<T as Config>::WeightInfo::unstake())]
 		pub fn unstake(staker: OriginFor<T>) -> DispatchResultWithPostInfo {
 			let staker_id = ensure_signed(staker)?;
 
@@ -421,7 +423,10 @@
 
 			Self::unlock_balance(&staker_id, total_staked)?;
 
-			<T::Currency as ReservableCurrency<T::AccountId>>::reserve(&staker_id, total_staked)?;
+			<<T as Config>::Currency as ReservableCurrency<T::AccountId>>::reserve(
+				&staker_id,
+				total_staked,
+			)?;
 
 			TotalStaked::<T>::set(
 				TotalStaked::<T>::get()
@@ -445,7 +450,7 @@
 		/// # Arguments
 		///
 		/// * `collection_id`: ID of the collection that will be sponsored by `pallet_id`
-		#[pallet::weight(T::WeightInfo::sponsor_collection())]
+		#[pallet::weight(<T as Config>::WeightInfo::sponsor_collection())]
 		pub fn sponsor_collection(
 			admin: OriginFor<T>,
 			collection_id: CollectionId,
@@ -470,7 +475,7 @@
 		/// # Arguments
 		///
 		/// * `collection_id`: ID of the collection that is sponsored by `pallet_id`
-		#[pallet::weight(T::WeightInfo::stop_sponsoring_collection())]
+		#[pallet::weight(<T as Config>::WeightInfo::stop_sponsoring_collection())]
 		pub fn stop_sponsoring_collection(
 			admin: OriginFor<T>,
 			collection_id: CollectionId,
@@ -499,7 +504,7 @@
 		/// # Arguments
 		///
 		/// * `contract_id`: the contract address that will be sponsored by `pallet_id`
-		#[pallet::weight(T::WeightInfo::sponsor_contract())]
+		#[pallet::weight(<T as Config>::WeightInfo::sponsor_contract())]
 		pub fn sponsor_contract(admin: OriginFor<T>, contract_id: H160) -> DispatchResult {
 			let admin_id = ensure_signed(admin)?;
 
@@ -525,7 +530,7 @@
 		/// # Arguments
 		///
 		/// * `contract_id`: the contract address that is sponsored by `pallet_id`
-		#[pallet::weight(T::WeightInfo::stop_sponsoring_contract())]
+		#[pallet::weight(<T as Config>::WeightInfo::stop_sponsoring_contract())]
 		pub fn stop_sponsoring_contract(admin: OriginFor<T>, contract_id: H160) -> DispatchResult {
 			let admin_id = ensure_signed(admin)?;
 
@@ -555,7 +560,7 @@
 		/// # Arguments
 		///
 		/// * `stakers_number`: the number of stakers for which recalculation will be performed
-		#[pallet::weight(T::WeightInfo::payout_stakers(stakers_number.unwrap_or(20) as u32))]
+		#[pallet::weight(<T as Config>::WeightInfo::payout_stakers(stakers_number.unwrap_or(20) as u32))]
 		pub fn payout_stakers(admin: OriginFor<T>, stakers_number: Option<u8>) -> DispatchResult {
 			let admin_id = ensure_signed(admin)?;
 
@@ -589,7 +594,7 @@
 				let flush_stake = || -> DispatchResult {
 					if let Some(last_id) = &*last_id.borrow() {
 						if !income_acc.borrow().is_zero() {
-							<T::Currency as Currency<T::AccountId>>::transfer(
+							<<T as Config>::Currency as Currency<T::AccountId>>::transfer(
 								&T::TreasuryAccountId::get(),
 								last_id,
 								*income_acc.borrow(),
@@ -700,9 +705,12 @@
 	/// - `amount`: amount of locked funds.
 	fn set_lock_unchecked(staker: &T::AccountId, amount: BalanceOf<T>) {
 		if amount.is_zero() {
-			<T::Currency as LockableCurrency<T::AccountId>>::remove_lock(LOCK_IDENTIFIER, &staker);
+			<<T as Config>::Currency as LockableCurrency<T::AccountId>>::remove_lock(
+				LOCK_IDENTIFIER,
+				&staker,
+			);
 		} else {
-			<T::Currency as LockableCurrency<T::AccountId>>::set_lock(
+			<<T as Config>::Currency as LockableCurrency<T::AccountId>>::set_lock(
 				LOCK_IDENTIFIER,
 				staker,
 				amount,
@@ -717,7 +725,7 @@
 	pub fn get_locked_balance(
 		staker: impl EncodeLike<T::AccountId>,
 	) -> Option<BalanceLock<BalanceOf<T>>> {
-		<T::Currency as ExtendedLockableCurrency<T::AccountId>>::locks(staker)
+		<<T as Config>::Currency as ExtendedLockableCurrency<T::AccountId>>::locks(staker)
 			.into_iter()
 			.find(|l| l.id == LOCK_IDENTIFIER)
 	}
modifiedpallets/common/Cargo.tomldiffbeforeafterboth
--- a/pallets/common/Cargo.toml
+++ b/pallets/common/Cargo.toml
@@ -17,12 +17,12 @@
 sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
 pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }
 evm-coder = { default-features = false, path = '../../crates/evm-coder' }
 ethereum = { version = "0.12.0", default-features = false }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 
 serde = { version = "1.0.130", default-features = false }
 scale-info = { version = "2.0.1", default-features = false, features = [
modifiedpallets/common/src/eth.rsdiffbeforeafterboth
--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -17,7 +17,7 @@
 //! The module contains a number of functions for converting and checking ethereum identifiers.
 
 use evm_coder::types::{uint256, address};
-pub use pallet_evm::account::{Config, CrossAccountId};
+pub use pallet_evm::{Config, account::CrossAccountId};
 use sp_core::H160;
 use up_data_structs::CollectionId;
 
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
before · pallets/common/src/lib.rs
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617//! # Common pallet18//!19//! The Common pallet provides functionality for handling collections.20//!21//! ## Overview22//!23//! The Common pallet provides an interface for common collection operations for different collection types24//! (see [CommonCollectionOperations]), as well as a generic dispatcher for these, see [dispatch] module.25//! It also provides this functionality to EVM, see [erc] and [eth] modules.26//!27//! The Common pallet provides functions for:28//!29//! - Setting and approving collection sponsor.30//! - Get\set\delete allow list.31//! - Get\set\delete collection properties.32//! - Get\set\delete collection property permissions.33//! - Get\set\delete token property permissions.34//! - Get\set\delete collection administrators.35//! - Checking access permissions.36//!37//! ### Terminology38//! **Collection sponsor** - For the collection, you can set a sponsor, at whose expense it will39//! be possible to mint tokens.40//!41//! **Allow list** - List of users who have the right to minting tokens.42//!43//! **Collection properties** - Collection properties are simply key-value stores where various44//! metadata can be placed.45//!46//! **Permissions on token properties** - For each property in the token can be set permission47//! to change, see [`PropertyPermission`].48//!49//! **Collection administrator** - For a collection, you can set administrators who have the right50//! to most actions on the collection.5152#![warn(missing_docs)]53#![cfg_attr(not(feature = "std"), no_std)]54extern crate alloc;5556use core::ops::{Deref, DerefMut};57use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};58use sp_std::vec::Vec;59use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};60use evm_coder::ToLog;61use frame_support::{62	dispatch::{DispatchErrorWithPostInfo, DispatchResultWithPostInfo, Weight, PostDispatchInfo},63	ensure,64	traits::{Imbalance, Get, Currency, WithdrawReasons, ExistenceRequirement},65	dispatch::Pays,66	transactional,67};68use pallet_evm::GasWeightMapping;69use up_data_structs::{70	COLLECTION_NUMBER_LIMIT,71	Collection,72	RpcCollection,73	CollectionFlags,74	RpcCollectionFlags,75	CollectionId,76	CreateItemData,77	MAX_TOKEN_PREFIX_LENGTH,78	COLLECTION_ADMINS_LIMIT,79	TokenId,80	TokenChild,81	CollectionStats,82	MAX_TOKEN_OWNERSHIP,83	CollectionMode,84	NFT_SPONSOR_TRANSFER_TIMEOUT,85	FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,86	REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,87	MAX_SPONSOR_TIMEOUT,88	CUSTOM_DATA_LIMIT,89	CollectionLimits,90	CreateCollectionData,91	SponsorshipState,92	CreateItemExData,93	SponsoringRateLimit,94	budget::Budget,95	PhantomType,96	Property,97	Properties,98	PropertiesPermissionMap,99	PropertyKey,100	PropertyValue,101	PropertyPermission,102	PropertiesError,103	PropertyKeyPermission,104	TokenData,105	TrySetProperty,106	PropertyScope,107	// RMRK108	RmrkCollectionInfo,109	RmrkInstanceInfo,110	RmrkResourceInfo,111	RmrkPropertyInfo,112	RmrkBaseInfo,113	RmrkPartType,114	RmrkBoundedTheme,115	RmrkNftChild,116	CollectionPermissions,117};118119pub use pallet::*;120use sp_core::H160;121use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};122#[cfg(feature = "runtime-benchmarks")]123pub mod benchmarking;124pub mod dispatch;125pub mod erc;126pub mod eth;127pub mod weights;128129/// Weight info.130pub type SelfWeightOf<T> = <T as Config>::WeightInfo;131132/// Collection handle contains information about collection data and id.133/// Also provides functionality to count consumed gas.134///135/// CollectionHandle is used as a generic wrapper for collections of all types.136/// It allows to perform common operations and queries on any collection type,137/// both completely general for all, as well as their respective implementations of [`CommonCollectionOperations`].138#[must_use = "Should call submit_logs or save, otherwise some data will be lost for evm side"]139pub struct CollectionHandle<T: Config> {140	/// Collection id141	pub id: CollectionId,142	collection: Collection<T::AccountId>,143	/// Substrate recorder for counting consumed gas144	pub recorder: SubstrateRecorder<T>,145}146147impl<T: Config> WithRecorder<T> for CollectionHandle<T> {148	fn recorder(&self) -> &SubstrateRecorder<T> {149		&self.recorder150	}151	fn into_recorder(self) -> SubstrateRecorder<T> {152		self.recorder153	}154}155156impl<T: Config> CollectionHandle<T> {157	/// Same as [CollectionHandle::new] but with an explicit gas limit.158	pub fn new_with_gas_limit(id: CollectionId, gas_limit: u64) -> Option<Self> {159		<CollectionById<T>>::get(id).map(|collection| Self {160			id,161			collection,162			recorder: SubstrateRecorder::new(gas_limit),163		})164	}165166	/// Same as [CollectionHandle::new] but with an existed [`SubstrateRecorder`].167	pub fn new_with_recorder(id: CollectionId, recorder: SubstrateRecorder<T>) -> Option<Self> {168		<CollectionById<T>>::get(id).map(|collection| Self {169			id,170			collection,171			recorder,172		})173	}174175	/// Retrives collection data from storage and creates collection handle with default parameters.176	/// If collection not found return `None`177	pub fn new(id: CollectionId) -> Option<Self> {178		Self::new_with_gas_limit(id, u64::MAX)179	}180181	/// Same as [`CollectionHandle::new`] but if collection not found [CollectionNotFound](Error::CollectionNotFound) returned.182	pub fn try_get(id: CollectionId) -> Result<Self, DispatchError> {183		Ok(Self::new(id).ok_or(<Error<T>>::CollectionNotFound)?)184	}185186	/// Consume gas for reading.187	pub fn consume_store_reads(&self, reads: u64) -> evm_coder::execution::Result<()> {188		self.recorder189			.consume_gas(T::GasWeightMapping::weight_to_gas(Weight::from_ref_time(190				<T as frame_system::Config>::DbWeight::get()191					.read192					.saturating_mul(reads),193			)))194	}195196	/// Consume gas for writing.197	pub fn consume_store_writes(&self, writes: u64) -> evm_coder::execution::Result<()> {198		self.recorder199			.consume_gas(T::GasWeightMapping::weight_to_gas(Weight::from_ref_time(200				<T as frame_system::Config>::DbWeight::get()201					.write202					.saturating_mul(writes),203			)))204	}205206	/// Consume gas for reading and writing.207	pub fn consume_store_reads_and_writes(208		&self,209		reads: u64,210		writes: u64,211	) -> evm_coder::execution::Result<()> {212		let weight = <T as frame_system::Config>::DbWeight::get();213		let reads = weight.read.saturating_mul(reads);214		let writes = weight.read.saturating_mul(writes);215		self.recorder216			.consume_gas(T::GasWeightMapping::weight_to_gas(Weight::from_ref_time(217				reads.saturating_add(writes),218			)))219	}220221	/// Save collection to storage.222	pub fn save(&self) -> DispatchResult {223		<CollectionById<T>>::insert(self.id, &self.collection);224		Ok(())225	}226227	/// Set collection sponsor.228	///229	/// Unique collections allows sponsoring for certain actions.230	/// This method allows you to set the sponsor of the collection.231	/// In order for sponsorship to become active, it must be confirmed through [`Self::confirm_sponsorship`].232	pub fn set_sponsor(&mut self, sponsor: T::AccountId) -> DispatchResult {233		self.collection.sponsorship = SponsorshipState::Unconfirmed(sponsor);234		Ok(())235	}236237	/// Confirm sponsorship238	///239	/// In order for the sponsorship to become active, the user set as the sponsor must confirm their participation.240	/// Before confirming sponsorship, the user must be specified as the sponsor of the collection via [`Self::set_sponsor`].241	pub fn confirm_sponsorship(&mut self, sender: &T::AccountId) -> Result<bool, DispatchError> {242		if self.collection.sponsorship.pending_sponsor() != Some(sender) {243			return Ok(false);244		}245246		self.collection.sponsorship = SponsorshipState::Confirmed(sender.clone());247		Ok(true)248	}249250	/// Remove collection sponsor.251	pub fn remove_sponsor(&mut self) -> DispatchResult {252		self.collection.sponsorship = SponsorshipState::Disabled;253		Ok(())254	}255256	/// Checks that the collection was created with, and must be operated upon through **Unique API**.257	/// Now check only the `external` flag and if it's **true**, then return [`Error::CollectionIsExternal`] error.258	pub fn check_is_internal(&self) -> DispatchResult {259		if self.flags.external {260			return Err(<Error<T>>::CollectionIsExternal)?;261		}262263		Ok(())264	}265266	/// Checks that the collection was created with, and must be operated upon through an **assimilated API**.267	/// Now check only the `external` flag and if it's **false**, then return [`Error::CollectionIsInternal`] error.268	pub fn check_is_external(&self) -> DispatchResult {269		if !self.flags.external {270			return Err(<Error<T>>::CollectionIsInternal)?;271		}272273		Ok(())274	}275}276277impl<T: Config> Deref for CollectionHandle<T> {278	type Target = Collection<T::AccountId>;279280	fn deref(&self) -> &Self::Target {281		&self.collection282	}283}284285impl<T: Config> DerefMut for CollectionHandle<T> {286	fn deref_mut(&mut self) -> &mut Self::Target {287		&mut self.collection288	}289}290291impl<T: Config> CollectionHandle<T> {292	/// Checks if the `user` is the owner of the collection.293	pub fn check_is_owner(&self, user: &T::CrossAccountId) -> DispatchResult {294		ensure!(*user.as_sub() == self.owner, <Error<T>>::NoPermission);295		Ok(())296	}297298	/// Returns **true** if the `user` is the owner or administrator of the collection.299	pub fn is_owner_or_admin(&self, user: &T::CrossAccountId) -> bool {300		*user.as_sub() == self.owner || <IsAdmin<T>>::get((self.id, user))301	}302303	/// Checks if the `user` is the owner or administrator of the collection.304	pub fn check_is_owner_or_admin(&self, user: &T::CrossAccountId) -> DispatchResult {305		ensure!(self.is_owner_or_admin(user), <Error<T>>::NoPermission);306		Ok(())307	}308309	/// Return **true** if `user` was not allowed to have tokens, and he can ignore such restrictions.310	pub fn ignores_allowance(&self, user: &T::CrossAccountId) -> bool {311		self.limits.owner_can_transfer() && self.is_owner_or_admin(user)312	}313314	/// Return **true** if `user` does not have enough token parts, and he can ignore such restrictions.315	pub fn ignores_owned_amount(&self, user: &T::CrossAccountId) -> bool {316		self.limits.owner_can_transfer() && self.is_owner_or_admin(user)317	}318319	/// Checks if the user is in the allow list. If not [Error::AddressNotInAllowlist] returns.320	pub fn check_allowlist(&self, user: &T::CrossAccountId) -> DispatchResult {321		ensure!(322			<Allowlist<T>>::get((self.id, user)),323			<Error<T>>::AddressNotInAllowlist324		);325		Ok(())326	}327328	/// Changes collection owner to another account329	/// #### Store read/writes330	/// 1 writes331	fn set_owner_internal(332		&mut self,333		caller: T::CrossAccountId,334		new_owner: T::CrossAccountId,335	) -> DispatchResult {336		self.check_is_owner(&caller)?;337		self.collection.owner = new_owner.as_sub().clone();338		self.save()339	}340}341342#[frame_support::pallet]343pub mod pallet {344	use super::*;345	use pallet_evm::account;346	use dispatch::CollectionDispatch;347	use frame_support::{Blake2_128Concat, pallet_prelude::*, storage::Key, traits::StorageVersion};348	use frame_system::pallet_prelude::*;349	use frame_support::traits::Currency;350	use up_data_structs::{TokenId, mapping::TokenAddressMapping};351	use scale_info::TypeInfo;352	use weights::WeightInfo;353354	#[pallet::config]355	pub trait Config:356		frame_system::Config357		+ pallet_evm_coder_substrate::Config358		+ pallet_evm::Config359		+ TypeInfo360		+ account::Config361	{362		/// Weight information for functions of this pallet.363		type WeightInfo: WeightInfo;364365		/// Events compatible with [`frame_system::Config::Event`].366		type RuntimeEvent: IsType<<Self as frame_system::Config>::RuntimeEvent> + From<Event<Self>>;367368		/// Handler of accounts and payment.369		type Currency: Currency<Self::AccountId>;370371		/// Set price to create a collection.372		#[pallet::constant]373		type CollectionCreationPrice: Get<374			<<Self as Config>::Currency as Currency<Self::AccountId>>::Balance,375		>;376377		/// Dispatcher of operations on collections.378		type CollectionDispatch: CollectionDispatch<Self>;379380		/// Account which holds the chain's treasury.381		type TreasuryAccountId: Get<Self::AccountId>;382383		/// Address under which the CollectionHelper contract would be available.384		type ContractAddress: Get<H160>;385386		/// Mapper for token addresses to Ethereum addresses.387		type EvmTokenAddressMapping: TokenAddressMapping<H160>;388389		/// Mapper for token addresses to [`CrossAccountId`].390		type CrossTokenAddressMapping: TokenAddressMapping<Self::CrossAccountId>;391	}392393	const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);394395	#[pallet::pallet]396	#[pallet::storage_version(STORAGE_VERSION)]397	#[pallet::generate_store(pub(super) trait Store)]398	pub struct Pallet<T>(_);399400	#[pallet::extra_constants]401	impl<T: Config> Pallet<T> {402		/// Maximum admins per collection.403		pub fn collection_admins_limit() -> u32 {404			COLLECTION_ADMINS_LIMIT405		}406	}407408	#[pallet::event]409	#[pallet::generate_deposit(pub fn deposit_event)]410	pub enum Event<T: Config> {411		/// New collection was created412		CollectionCreated(413			/// Globally unique identifier of newly created collection.414			CollectionId,415			/// [`CollectionMode`] converted into _u8_.416			u8,417			/// Collection owner.418			T::AccountId,419		),420421		/// New collection was destroyed422		CollectionDestroyed(423			/// Globally unique identifier of collection.424			CollectionId,425		),426427		/// New item was created.428		ItemCreated(429			/// Id of the collection where item was created.430			CollectionId,431			/// Id of an item. Unique within the collection.432			TokenId,433			/// Owner of newly created item434			T::CrossAccountId,435			/// Always 1 for NFT436			u128,437		),438439		/// Collection item was burned.440		ItemDestroyed(441			/// Id of the collection where item was destroyed.442			CollectionId,443			/// Identifier of burned NFT.444			TokenId,445			/// Which user has destroyed its tokens.446			T::CrossAccountId,447			/// Amount of token pieces destroed. Always 1 for NFT.448			u128,449		),450451		/// Item was transferred452		Transfer(453			/// Id of collection to which item is belong.454			CollectionId,455			/// Id of an item.456			TokenId,457			/// Original owner of item.458			T::CrossAccountId,459			/// New owner of item.460			T::CrossAccountId,461			/// Amount of token pieces transfered. Always 1 for NFT.462			u128,463		),464465		/// Amount pieces of token owned by `sender` was approved for `spender`.466		Approved(467			/// Id of collection to which item is belong.468			CollectionId,469			/// Id of an item.470			TokenId,471			/// Original owner of item.472			T::CrossAccountId,473			/// Id for which the approval was granted.474			T::CrossAccountId,475			/// Amount of token pieces transfered. Always 1 for NFT.476			u128,477		),478479		/// The colletion property has been added or edited.480		CollectionPropertySet(481			/// Id of collection to which property has been set.482			CollectionId,483			/// The property that was set.484			PropertyKey,485		),486487		/// The property has been deleted.488		CollectionPropertyDeleted(489			/// Id of collection to which property has been deleted.490			CollectionId,491			/// The property that was deleted.492			PropertyKey,493		),494495		/// The token property has been added or edited.496		TokenPropertySet(497			/// Identifier of the collection whose token has the property set.498			CollectionId,499			/// The token for which the property was set.500			TokenId,501			/// The property that was set.502			PropertyKey,503		),504505		/// The token property has been deleted.506		TokenPropertyDeleted(507			/// Identifier of the collection whose token has the property deleted.508			CollectionId,509			/// The token for which the property was deleted.510			TokenId,511			/// The property that was deleted.512			PropertyKey,513		),514515		/// The token property permission of a collection has been set.516		PropertyPermissionSet(517			/// ID of collection to which property permission has been set.518			CollectionId,519			/// The property permission that was set.520			PropertyKey,521		),522	}523524	#[pallet::error]525	pub enum Error<T> {526		/// This collection does not exist.527		CollectionNotFound,528		/// Sender parameter and item owner must be equal.529		MustBeTokenOwner,530		/// No permission to perform action531		NoPermission,532		/// Destroying only empty collections is allowed533		CantDestroyNotEmptyCollection,534		/// Collection is not in mint mode.535		PublicMintingNotAllowed,536		/// Address is not in allow list.537		AddressNotInAllowlist,538539		/// Collection name can not be longer than 63 char.540		CollectionNameLimitExceeded,541		/// Collection description can not be longer than 255 char.542		CollectionDescriptionLimitExceeded,543		/// Token prefix can not be longer than 15 char.544		CollectionTokenPrefixLimitExceeded,545		/// Total collections bound exceeded.546		TotalCollectionsLimitExceeded,547		/// Exceeded max admin count548		CollectionAdminCountExceeded,549		/// Collection limit bounds per collection exceeded550		CollectionLimitBoundsExceeded,551		/// Tried to enable permissions which are only permitted to be disabled552		OwnerPermissionsCantBeReverted,553		/// Collection settings not allowing items transferring554		TransferNotAllowed,555		/// Account token limit exceeded per collection556		AccountTokenLimitExceeded,557		/// Collection token limit exceeded558		CollectionTokenLimitExceeded,559		/// Metadata flag frozen560		MetadataFlagFrozen,561562		/// Item does not exist563		TokenNotFound,564		/// Item is balance not enough565		TokenValueTooLow,566		/// Requested value is more than the approved567		ApprovedValueTooLow,568		/// Tried to approve more than owned569		CantApproveMoreThanOwned,570571		/// Can't transfer tokens to ethereum zero address572		AddressIsZero,573574		/// The operation is not supported575		UnsupportedOperation,576577		/// Insufficient funds to perform an action578		NotSufficientFounds,579580		/// User does not satisfy the nesting rule581		UserIsNotAllowedToNest,582		/// Only tokens from specific collections may nest tokens under this one583		SourceCollectionIsNotAllowedToNest,584585		/// Tried to store more data than allowed in collection field586		CollectionFieldSizeExceeded,587588		/// Tried to store more property data than allowed589		NoSpaceForProperty,590591		/// Tried to store more property keys than allowed592		PropertyLimitReached,593594		/// Property key is too long595		PropertyKeyIsTooLong,596597		/// Only ASCII letters, digits, and symbols `_`, `-`, and `.` are allowed598		InvalidCharacterInPropertyKey,599600		/// Empty property keys are forbidden601		EmptyPropertyKey,602603		/// Tried to access an external collection with an internal API604		CollectionIsExternal,605606		/// Tried to access an internal collection with an external API607		CollectionIsInternal,608	}609610	/// Storage of the count of created collections. Essentially contains the last collection ID.611	#[pallet::storage]612	pub type CreatedCollectionCount<T> = StorageValue<Value = CollectionId, QueryKind = ValueQuery>;613614	/// Storage of the count of deleted collections.615	#[pallet::storage]616	pub type DestroyedCollectionCount<T> =617		StorageValue<Value = CollectionId, QueryKind = ValueQuery>;618619	/// Storage of collection info.620	#[pallet::storage]621	pub type CollectionById<T> = StorageMap<622		Hasher = Blake2_128Concat,623		Key = CollectionId,624		Value = Collection<<T as frame_system::Config>::AccountId>,625		QueryKind = OptionQuery,626	>;627628	/// Storage of collection properties.629	#[pallet::storage]630	#[pallet::getter(fn collection_properties)]631	pub type CollectionProperties<T> = StorageMap<632		Hasher = Blake2_128Concat,633		Key = CollectionId,634		Value = Properties,635		QueryKind = ValueQuery,636		OnEmpty = up_data_structs::CollectionProperties,637	>;638639	/// Storage of token property permissions of a collection.640	#[pallet::storage]641	#[pallet::getter(fn property_permissions)]642	pub type CollectionPropertyPermissions<T> = StorageMap<643		Hasher = Blake2_128Concat,644		Key = CollectionId,645		Value = PropertiesPermissionMap,646		QueryKind = ValueQuery,647	>;648649	/// Storage of the amount of collection admins.650	#[pallet::storage]651	pub type AdminAmount<T> = StorageMap<652		Hasher = Blake2_128Concat,653		Key = CollectionId,654		Value = u32,655		QueryKind = ValueQuery,656	>;657658	/// List of collection admins.659	#[pallet::storage]660	pub type IsAdmin<T: Config> = StorageNMap<661		Key = (662			Key<Blake2_128Concat, CollectionId>,663			Key<Blake2_128Concat, T::CrossAccountId>,664		),665		Value = bool,666		QueryKind = ValueQuery,667	>;668669	/// Allowlisted collection users.670	#[pallet::storage]671	pub type Allowlist<T: Config> = StorageNMap<672		Key = (673			Key<Blake2_128Concat, CollectionId>,674			Key<Blake2_128Concat, T::CrossAccountId>,675		),676		Value = bool,677		QueryKind = ValueQuery,678	>;679680	/// Not used by code, exists only to provide some types to metadata.681	#[pallet::storage]682	pub type DummyStorageValue<T: Config> = StorageValue<683		Value = (684			CollectionStats,685			CollectionId,686			TokenId,687			TokenChild,688			PhantomType<(689				TokenData<T::CrossAccountId>,690				RpcCollection<T::AccountId>,691				// RMRK692				RmrkCollectionInfo<T::AccountId>,693				RmrkInstanceInfo<T::AccountId>,694				RmrkResourceInfo,695				RmrkPropertyInfo,696				RmrkBaseInfo<T::AccountId>,697				RmrkPartType,698				RmrkBoundedTheme,699				RmrkNftChild,700			)>,701		),702		QueryKind = OptionQuery,703	>;704705	#[pallet::hooks]706	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {707		fn on_runtime_upgrade() -> Weight {708			StorageVersion::new(1).put::<Pallet<T>>();709710			Weight::zero()711		}712	}713}714715impl<T: Config> Pallet<T> {716	/// Enshure that receiver address is correct.717	///718	/// Ethereum receiver 0x0000000000000000000000000000000000000000 is reserved, and shouldn't own tokens.719	pub fn ensure_correct_receiver(receiver: &T::CrossAccountId) -> DispatchResult {720		ensure!(721			&T::CrossAccountId::from_eth(H160([0; 20])) != receiver,722			<Error<T>>::AddressIsZero723		);724		Ok(())725	}726727	/// Get a vector of collection admins.728	pub fn adminlist(collection: CollectionId) -> Vec<T::CrossAccountId> {729		<IsAdmin<T>>::iter_prefix((collection,))730			.map(|(a, _)| a)731			.collect()732	}733734	/// Get a vector of users allowed to mint tokens.735	pub fn allowlist(collection: CollectionId) -> Vec<T::CrossAccountId> {736		<Allowlist<T>>::iter_prefix((collection,))737			.map(|(a, _)| a)738			.collect()739	}740741	/// Is `user` allowed to mint token in `collection`.742	pub fn allowed(collection: CollectionId, user: T::CrossAccountId) -> bool {743		<Allowlist<T>>::get((collection, user))744	}745746	/// Get statistics of collections.747	pub fn collection_stats() -> CollectionStats {748		let created = <CreatedCollectionCount<T>>::get();749		let destroyed = <DestroyedCollectionCount<T>>::get();750		CollectionStats {751			created: created.0,752			destroyed: destroyed.0,753			alive: created.0 - destroyed.0,754		}755	}756757	/// Get the effective limits for the collection.758	pub fn effective_collection_limits(collection: CollectionId) -> Option<CollectionLimits> {759		let collection = <CollectionById<T>>::get(collection)?;760		let limits = collection.limits;761		let effective_limits = CollectionLimits {762			account_token_ownership_limit: Some(limits.account_token_ownership_limit()),763			sponsored_data_size: Some(limits.sponsored_data_size()),764			sponsored_data_rate_limit: Some(765				limits766					.sponsored_data_rate_limit767					.unwrap_or(SponsoringRateLimit::SponsoringDisabled),768			),769			token_limit: Some(limits.token_limit()),770			sponsor_transfer_timeout: Some(limits.sponsor_transfer_timeout(771				match collection.mode {772					CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,773					CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,774					CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,775				},776			)),777			sponsor_approve_timeout: Some(limits.sponsor_approve_timeout()),778			owner_can_transfer: Some(limits.owner_can_transfer()),779			owner_can_destroy: Some(limits.owner_can_destroy()),780			transfers_enabled: Some(limits.transfers_enabled()),781		};782783		Some(effective_limits)784	}785786	/// Returns information about the `collection` adapted for rpc.787	pub fn rpc_collection(collection: CollectionId) -> Option<RpcCollection<T::AccountId>> {788		let Collection {789			name,790			description,791			owner,792			mode,793			token_prefix,794			sponsorship,795			limits,796			permissions,797			flags,798		} = <CollectionById<T>>::get(collection)?;799800		let token_property_permissions = <CollectionPropertyPermissions<T>>::get(collection)801			.into_iter()802			.map(|(key, permission)| PropertyKeyPermission { key, permission })803			.collect();804805		let properties = <CollectionProperties<T>>::get(collection)806			.into_iter()807			.map(|(key, value)| Property { key, value })808			.collect();809810		let permissions = CollectionPermissions {811			access: Some(permissions.access()),812			mint_mode: Some(permissions.mint_mode()),813			nesting: Some(permissions.nesting().clone()),814		};815816		Some(RpcCollection {817			name: name.into_inner(),818			description: description.into_inner(),819			owner,820			mode,821			token_prefix: token_prefix.into_inner(),822			sponsorship,823			limits,824			permissions,825			token_property_permissions,826			properties,827			read_only: flags.external,828829			flags: RpcCollectionFlags {830				foreign: flags.foreign,831				erc721metadata: flags.erc721metadata,832			},833		})834	}835}836837macro_rules! limit_default {838	($old:ident, $new:ident, $($field:ident $(($arg:expr))? => $check:expr),* $(,)?) => {{839		$(840			if let Some($new) = $new.$field {841				let $old = $old.$field($($arg)?);842				let _ = $new;843				let _ = $old;844				$check845			} else {846				$new.$field = $old.$field847			}848		)*849	}};850}851macro_rules! limit_default_clone {852	($old:ident, $new:ident, $($field:ident $(($arg:expr))? => $check:expr),* $(,)?) => {{853		$(854			if let Some($new) = $new.$field.clone() {855				let $old = $old.$field($($arg)?);856				let _ = $new;857				let _ = $old;858				$check859			} else {860				$new.$field = $old.$field.clone()861			}862		)*863	}};864}865866impl<T: Config> Pallet<T> {867	/// Create new collection.868	///869	/// * `owner` - The owner of the collection.870	/// * `data` - Description of the created collection.871	/// * `flags` - Extra flags to store.872	pub fn init_collection(873		owner: T::CrossAccountId,874		payer: T::CrossAccountId,875		data: CreateCollectionData<T::AccountId>,876		flags: CollectionFlags,877	) -> Result<CollectionId, DispatchError> {878		{879			ensure!(880				data.token_prefix.len() <= MAX_TOKEN_PREFIX_LENGTH as usize,881				Error::<T>::CollectionTokenPrefixLimitExceeded882			);883		}884885		let created_count = <CreatedCollectionCount<T>>::get()886			.0887			.checked_add(1)888			.ok_or(ArithmeticError::Overflow)?;889		let destroyed_count = <DestroyedCollectionCount<T>>::get().0;890		let id = CollectionId(created_count);891892		// bound Total number of collections893		ensure!(894			created_count - destroyed_count <= COLLECTION_NUMBER_LIMIT,895			<Error<T>>::TotalCollectionsLimitExceeded896		);897898		// =========899900		let collection = Collection {901			owner: owner.as_sub().clone(),902			name: data.name,903			mode: data.mode.clone(),904			description: data.description,905			token_prefix: data.token_prefix,906			sponsorship: data907				.pending_sponsor908				.map(SponsorshipState::Unconfirmed)909				.unwrap_or_default(),910			limits: data911				.limits912				.map(|limits| Self::clamp_limits(data.mode.clone(), &Default::default(), limits))913				.unwrap_or_else(|| Ok(CollectionLimits::default()))?,914			permissions: data915				.permissions916				.map(|permissions| {917					Self::clamp_permissions(data.mode.clone(), &Default::default(), permissions)918				})919				.unwrap_or_else(|| Ok(CollectionPermissions::default()))?,920			flags,921		};922923		let mut collection_properties = up_data_structs::CollectionProperties::get();924		collection_properties925			.try_set_from_iter(data.properties.into_iter())926			.map_err(<Error<T>>::from)?;927928		CollectionProperties::<T>::insert(id, collection_properties);929930		let mut token_props_permissions = PropertiesPermissionMap::new();931		token_props_permissions932			.try_set_from_iter(data.token_property_permissions.into_iter())933			.map_err(<Error<T>>::from)?;934935		CollectionPropertyPermissions::<T>::insert(id, token_props_permissions);936937		// Take a (non-refundable) deposit of collection creation938		{939			let mut imbalance =940				<<<T as Config>::Currency as Currency<T::AccountId>>::PositiveImbalance>::zero();941			imbalance.subsume(942				<<T as Config>::Currency as Currency<T::AccountId>>::deposit_creating(943					&T::TreasuryAccountId::get(),944					T::CollectionCreationPrice::get(),945				),946			);947			<T as Config>::Currency::settle(948				payer.as_sub(),949				imbalance,950				WithdrawReasons::TRANSFER,951				ExistenceRequirement::KeepAlive,952			)953			.map_err(|_| Error::<T>::NotSufficientFounds)?;954		}955956		<CreatedCollectionCount<T>>::put(created_count);957		<Pallet<T>>::deposit_event(Event::CollectionCreated(958			id,959			data.mode.id(),960			owner.as_sub().clone(),961		));962		<PalletEvm<T>>::deposit_log(963			erc::CollectionHelpersEvents::CollectionCreated {964				owner: *owner.as_eth(),965				collection_id: eth::collection_id_to_address(id),966			}967			.to_log(T::ContractAddress::get()),968		);969		<CollectionById<T>>::insert(id, collection);970		Ok(id)971	}972973	/// Destroy collection.974	///975	/// * `collection` - Collection handler.976	/// * `sender` - The owner or administrator of the collection.977	pub fn destroy_collection(978		collection: CollectionHandle<T>,979		sender: &T::CrossAccountId,980	) -> DispatchResult {981		ensure!(982			collection.limits.owner_can_destroy(),983			<Error<T>>::NoPermission,984		);985		collection.check_is_owner(sender)?;986987		let destroyed_collections = <DestroyedCollectionCount<T>>::get()988			.0989			.checked_add(1)990			.ok_or(ArithmeticError::Overflow)?;991992		// =========993994		<DestroyedCollectionCount<T>>::put(destroyed_collections);995		<CollectionById<T>>::remove(collection.id);996		<AdminAmount<T>>::remove(collection.id);997		let _ = <IsAdmin<T>>::clear_prefix((collection.id,), u32::MAX, None);998		let _ = <Allowlist<T>>::clear_prefix((collection.id,), u32::MAX, None);999		<CollectionProperties<T>>::remove(collection.id);10001001		<Pallet<T>>::deposit_event(Event::CollectionDestroyed(collection.id));10021003		<PalletEvm<T>>::deposit_log(1004			erc::CollectionHelpersEvents::CollectionDestroyed {1005				collection_id: eth::collection_id_to_address(collection.id),1006			}1007			.to_log(T::ContractAddress::get()),1008		);1009		Ok(())1010	}10111012	/// Set collection property.1013	///1014	/// * `collection` - Collection handler.1015	/// * `sender` - The owner or administrator of the collection.1016	/// * `property` - The property to set.1017	pub fn set_collection_property(1018		collection: &CollectionHandle<T>,1019		sender: &T::CrossAccountId,1020		property: Property,1021	) -> DispatchResult {1022		collection.check_is_owner_or_admin(sender)?;10231024		CollectionProperties::<T>::try_mutate(collection.id, |properties| {1025			let property = property.clone();1026			properties.try_set(property.key, property.value)1027		})1028		.map_err(<Error<T>>::from)?;10291030		Self::deposit_event(Event::CollectionPropertySet(collection.id, property.key));10311032		Ok(())1033	}10341035	/// Set scouped collection property.1036	///1037	/// * `collection_id` - ID of the collection for which the property is being set.1038	/// * `scope` - Property scope.1039	/// * `property` - The property to set.1040	pub fn set_scoped_collection_property(1041		collection_id: CollectionId,1042		scope: PropertyScope,1043		property: Property,1044	) -> DispatchResult {1045		CollectionProperties::<T>::try_mutate(collection_id, |properties| {1046			properties.try_scoped_set(scope, property.key, property.value)1047		})1048		.map_err(<Error<T>>::from)?;10491050		Ok(())1051	}10521053	/// Set scouped collection properties.1054	///1055	/// * `collection_id` - ID of the collection for which the properties is being set.1056	/// * `scope` - Property scope.1057	/// * `properties` - The properties to set.1058	pub fn set_scoped_collection_properties(1059		collection_id: CollectionId,1060		scope: PropertyScope,1061		properties: impl Iterator<Item = Property>,1062	) -> DispatchResult {1063		CollectionProperties::<T>::try_mutate(collection_id, |stored_properties| {1064			stored_properties.try_scoped_set_from_iter(scope, properties)1065		})1066		.map_err(<Error<T>>::from)?;10671068		Ok(())1069	}10701071	/// Set collection properties.1072	///1073	/// * `collection` - Collection handler.1074	/// * `sender` - The owner or administrator of the collection.1075	/// * `properties` - The properties to set.1076	#[transactional]1077	pub fn set_collection_properties(1078		collection: &CollectionHandle<T>,1079		sender: &T::CrossAccountId,1080		properties: Vec<Property>,1081	) -> DispatchResult {1082		for property in properties {1083			Self::set_collection_property(collection, sender, property)?;1084		}10851086		Ok(())1087	}10881089	/// Delete collection property.1090	///1091	/// * `collection` - Collection handler.1092	/// * `sender` - The owner or administrator of the collection.1093	/// * `property` - The property to delete.1094	pub fn delete_collection_property(1095		collection: &CollectionHandle<T>,1096		sender: &T::CrossAccountId,1097		property_key: PropertyKey,1098	) -> DispatchResult {1099		collection.check_is_owner_or_admin(sender)?;11001101		CollectionProperties::<T>::try_mutate(collection.id, |properties| {1102			properties.remove(&property_key)1103		})1104		.map_err(<Error<T>>::from)?;11051106		Self::deposit_event(Event::CollectionPropertyDeleted(1107			collection.id,1108			property_key,1109		));11101111		Ok(())1112	}11131114	/// Delete collection properties.1115	///1116	/// * `collection` - Collection handler.1117	/// * `sender` - The owner or administrator of the collection.1118	/// * `properties` - The properties to delete.1119	#[transactional]1120	pub fn delete_collection_properties(1121		collection: &CollectionHandle<T>,1122		sender: &T::CrossAccountId,1123		property_keys: Vec<PropertyKey>,1124	) -> DispatchResult {1125		for key in property_keys {1126			Self::delete_collection_property(collection, sender, key)?;1127		}11281129		Ok(())1130	}11311132	/// Set collection propetry permission without any checks.1133	///1134	/// Used for migrations.1135	///1136	/// * `collection` - Collection handler.1137	/// * `property_permissions` - Property permissions.1138	pub fn set_property_permission_unchecked(1139		collection: CollectionId,1140		property_permission: PropertyKeyPermission,1141	) -> DispatchResult {1142		<CollectionPropertyPermissions<T>>::try_mutate(collection, |permissions| {1143			permissions.try_set(property_permission.key, property_permission.permission)1144		})1145		.map_err(<Error<T>>::from)?;1146		Ok(())1147	}11481149	/// Set collection property permission.1150	///1151	/// * `collection` - Collection handler.1152	/// * `sender` - The owner or administrator of the collection.1153	/// * `property_permission` - Property permission.1154	pub fn set_property_permission(1155		collection: &CollectionHandle<T>,1156		sender: &T::CrossAccountId,1157		property_permission: PropertyKeyPermission,1158	) -> DispatchResult {1159		Self::set_scoped_property_permission(1160			collection,1161			sender,1162			PropertyScope::None,1163			property_permission,1164		)1165	}11661167	/// Set collection property permission with scope.1168	///1169	/// * `collection` - Collection handler.1170	/// * `sender` - The owner or administrator of the collection.1171	/// * `scope` - Property scope.1172	/// * `property_permission` - Property permission.1173	pub fn set_scoped_property_permission(1174		collection: &CollectionHandle<T>,1175		sender: &T::CrossAccountId,1176		scope: PropertyScope,1177		property_permission: PropertyKeyPermission,1178	) -> DispatchResult {1179		collection.check_is_owner_or_admin(sender)?;11801181		let all_permissions = CollectionPropertyPermissions::<T>::get(collection.id);1182		let current_permission = all_permissions.get(&property_permission.key);1183		if matches![1184			current_permission,1185			Some(PropertyPermission { mutable: false, .. })1186		] {1187			return Err(<Error<T>>::NoPermission.into());1188		}11891190		CollectionPropertyPermissions::<T>::try_mutate(collection.id, |permissions| {1191			let property_permission = property_permission.clone();1192			permissions.try_scoped_set(1193				scope,1194				property_permission.key,1195				property_permission.permission,1196			)1197		})1198		.map_err(<Error<T>>::from)?;11991200		Self::deposit_event(Event::PropertyPermissionSet(1201			collection.id,1202			property_permission.key,1203		));12041205		Ok(())1206	}12071208	/// Set token property permission.1209	///1210	/// * `collection` - Collection handler.1211	/// * `sender` - The owner or administrator of the collection.1212	/// * `property_permissions` - Property permissions.1213	#[transactional]1214	pub fn set_token_property_permissions(1215		collection: &CollectionHandle<T>,1216		sender: &T::CrossAccountId,1217		property_permissions: Vec<PropertyKeyPermission>,1218	) -> DispatchResult {1219		Self::set_scoped_token_property_permissions(1220			collection,1221			sender,1222			PropertyScope::None,1223			property_permissions,1224		)1225	}12261227	/// Set token property permission with scope.1228	///1229	/// * `collection` - Collection handler.1230	/// * `sender` - The owner or administrator of the collection.1231	/// * `scope` - Property scope.1232	/// * `property_permissions` - Property permissions.1233	#[transactional]1234	pub fn set_scoped_token_property_permissions(1235		collection: &CollectionHandle<T>,1236		sender: &T::CrossAccountId,1237		scope: PropertyScope,1238		property_permissions: Vec<PropertyKeyPermission>,1239	) -> DispatchResult {1240		for prop_pemission in property_permissions {1241			Self::set_scoped_property_permission(collection, sender, scope, prop_pemission)?;1242		}12431244		Ok(())1245	}12461247	/// Get collection property.1248	pub fn get_collection_property(1249		collection_id: CollectionId,1250		key: &PropertyKey,1251	) -> Option<PropertyValue> {1252		Self::collection_properties(collection_id).get(key).cloned()1253	}12541255	/// Convert byte vector to property key vector.1256	pub fn bytes_keys_to_property_keys(1257		keys: Vec<Vec<u8>>,1258	) -> Result<Vec<PropertyKey>, DispatchError> {1259		keys.into_iter()1260			.map(|key| -> Result<PropertyKey, DispatchError> {1261				key.try_into()1262					.map_err(|_| <Error<T>>::PropertyKeyIsTooLong.into())1263			})1264			.collect::<Result<Vec<PropertyKey>, DispatchError>>()1265	}12661267	/// Get properties according to given keys.1268	pub fn filter_collection_properties(1269		collection_id: CollectionId,1270		keys: Option<Vec<PropertyKey>>,1271	) -> Result<Vec<Property>, DispatchError> {1272		let properties = Self::collection_properties(collection_id);12731274		let properties = keys1275			.map(|keys| {1276				keys.into_iter()1277					.filter_map(|key| {1278						properties.get(&key).map(|value| Property {1279							key,1280							value: value.clone(),1281						})1282					})1283					.collect()1284			})1285			.unwrap_or_else(|| {1286				properties1287					.into_iter()1288					.map(|(key, value)| Property { key, value })1289					.collect()1290			});12911292		Ok(properties)1293	}12941295	/// Get property permissions according to given keys.1296	pub fn filter_property_permissions(1297		collection_id: CollectionId,1298		keys: Option<Vec<PropertyKey>>,1299	) -> Result<Vec<PropertyKeyPermission>, DispatchError> {1300		let permissions = Self::property_permissions(collection_id);13011302		let key_permissions = keys1303			.map(|keys| {1304				keys.into_iter()1305					.filter_map(|key| {1306						permissions1307							.get(&key)1308							.map(|permission| PropertyKeyPermission {1309								key,1310								permission: permission.clone(),1311							})1312					})1313					.collect()1314			})1315			.unwrap_or_else(|| {1316				permissions1317					.into_iter()1318					.map(|(key, permission)| PropertyKeyPermission { key, permission })1319					.collect()1320			});13211322		Ok(key_permissions)1323	}13241325	/// Toggle `user` participation in the `collection`'s allow list.1326	/// #### Store read/writes1327	/// 1 writes1328	pub fn toggle_allowlist(1329		collection: &CollectionHandle<T>,1330		sender: &T::CrossAccountId,1331		user: &T::CrossAccountId,1332		allowed: bool,1333	) -> DispatchResult {1334		collection.check_is_owner_or_admin(sender)?;13351336		// =========13371338		if allowed {1339			<Allowlist<T>>::insert((collection.id, user), true);1340		} else {1341			<Allowlist<T>>::remove((collection.id, user));1342		}13431344		Ok(())1345	}13461347	/// Toggle `user` participation in the `collection`'s admin list.1348	/// #### Store read/writes1349	/// 2 writes1350	pub fn toggle_admin(1351		collection: &CollectionHandle<T>,1352		sender: &T::CrossAccountId,1353		user: &T::CrossAccountId,1354		admin: bool,1355	) -> DispatchResult {1356		collection.check_is_owner(sender)?;13571358		let was_admin = <IsAdmin<T>>::get((collection.id, user));1359		if was_admin == admin {1360			return Ok(());1361		}1362		let amount = <AdminAmount<T>>::get(collection.id);13631364		if admin {1365			let amount = amount1366				.checked_add(1)1367				.ok_or(<Error<T>>::CollectionAdminCountExceeded)?;1368			ensure!(1369				amount <= Self::collection_admins_limit(),1370				<Error<T>>::CollectionAdminCountExceeded,1371			);13721373			// =========13741375			<AdminAmount<T>>::insert(collection.id, amount);1376			<IsAdmin<T>>::insert((collection.id, user), true);1377		} else {1378			<AdminAmount<T>>::insert(collection.id, amount.saturating_sub(1));1379			<IsAdmin<T>>::remove((collection.id, user));1380		}13811382		Ok(())1383	}13841385	/// Merge set fields from `new_limit` to `old_limit`.1386	pub fn clamp_limits(1387		mode: CollectionMode,1388		old_limit: &CollectionLimits,1389		mut new_limit: CollectionLimits,1390	) -> Result<CollectionLimits, DispatchError> {1391		let limits = old_limit;1392		limit_default!(old_limit, new_limit,1393			account_token_ownership_limit => ensure!(1394				new_limit <= MAX_TOKEN_OWNERSHIP,1395				<Error<T>>::CollectionLimitBoundsExceeded,1396			),1397			sponsored_data_size => ensure!(1398				new_limit <= CUSTOM_DATA_LIMIT,1399				<Error<T>>::CollectionLimitBoundsExceeded,1400			),14011402			sponsored_data_rate_limit => {},1403			token_limit => ensure!(1404				old_limit >= new_limit && new_limit > 0,1405				<Error<T>>::CollectionTokenLimitExceeded1406			),14071408			sponsor_transfer_timeout(match mode {1409				CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,1410				CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,1411				CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,1412			}) => ensure!(1413				new_limit <= MAX_SPONSOR_TIMEOUT,1414				<Error<T>>::CollectionLimitBoundsExceeded,1415			),1416			sponsor_approve_timeout => {},1417			owner_can_transfer => ensure!(1418				!limits.owner_can_transfer_instaled() ||1419				old_limit || !new_limit,1420				<Error<T>>::OwnerPermissionsCantBeReverted,1421			),1422			owner_can_destroy => ensure!(1423				old_limit || !new_limit,1424				<Error<T>>::OwnerPermissionsCantBeReverted,1425			),1426			transfers_enabled => {},1427		);1428		Ok(new_limit)1429	}14301431	/// Merge set fields from `new_permission` to `old_permission`.1432	pub fn clamp_permissions(1433		_mode: CollectionMode,1434		old_permission: &CollectionPermissions,1435		mut new_permission: CollectionPermissions,1436	) -> Result<CollectionPermissions, DispatchError> {1437		limit_default_clone!(old_permission, new_permission,1438			access => {},1439			mint_mode => {},1440			nesting => { /* todo check for permissive, if only it gets out of benchmarks */ },1441		);1442		Ok(new_permission)1443	}1444}14451446/// Indicates unsupported methods by returning [Error::UnsupportedOperation].1447#[macro_export]1448macro_rules! unsupported {1449	($runtime:path) => {1450		Err($crate::Error::<$runtime>::UnsupportedOperation.into())1451	};1452}14531454/// Return weights for various worst-case operations.1455pub trait CommonWeightInfo<CrossAccountId> {1456	/// Weight of item creation.1457	fn create_item() -> Weight;14581459	/// Weight of items creation.1460	fn create_multiple_items(amount: &[CreateItemData]) -> Weight;14611462	/// Weight of items creation.1463	fn create_multiple_items_ex(cost: &CreateItemExData<CrossAccountId>) -> Weight;14641465	/// The weight of the burning item.1466	fn burn_item() -> Weight;14671468	/// Property setting weight.1469	///1470	/// * `amount`- The number of properties to set.1471	fn set_collection_properties(amount: u32) -> Weight;14721473	/// Collection property deletion weight.1474	///1475	/// * `amount`- The number of properties to set.1476	fn delete_collection_properties(amount: u32) -> Weight;14771478	/// Token property setting weight.1479	///1480	/// * `amount`- The number of properties to set.1481	fn set_token_properties(amount: u32) -> Weight;14821483	/// Token property deletion weight.1484	///1485	/// * `amount`- The number of properties to delete.1486	fn delete_token_properties(amount: u32) -> Weight;14871488	/// Token property permissions set weight.1489	///1490	/// * `amount`- The number of property permissions to set.1491	fn set_token_property_permissions(amount: u32) -> Weight;14921493	/// Transfer price of the token or its parts.1494	fn transfer() -> Weight;14951496	/// The price of setting the permission of the operation from another user.1497	fn approve() -> Weight;14981499	/// Transfer price from another user.1500	fn transfer_from() -> Weight;15011502	/// The price of burning a token from another user.1503	fn burn_from() -> Weight;15041505	/// Differs from burn_item in case of Fungible and Refungible, as it should burn1506	/// whole users's balance.1507	///1508	/// This method shouldn't be used directly, as it doesn't count breadth price, use [burn_recursively](CommonWeightInfo::burn_recursively) instead1509	fn burn_recursively_self_raw() -> Weight;15101511	/// Cost of iterating over `amount` children while burning, without counting child burning itself.1512	///1513	/// This method shouldn't be used directly, as it doesn't count depth price, use [burn_recursively](CommonWeightInfo::burn_recursively) instead1514	fn burn_recursively_breadth_raw(amount: u32) -> Weight;15151516	/// The price of recursive burning a token.1517	///1518	/// `max_selfs` - The maximum burning weight of the token itself.1519	/// `max_breadth` - The maximum number of nested tokens to burn.1520	fn burn_recursively(max_selfs: u32, max_breadth: u32) -> Weight {1521		Self::burn_recursively_self_raw()1522			.saturating_mul(max_selfs.max(1) as u64)1523			.saturating_add(Self::burn_recursively_breadth_raw(max_breadth))1524	}15251526	/// The price of retrieving token owner1527	fn token_owner() -> Weight;1528}15291530/// Weight info extension trait for refungible pallet.1531pub trait RefungibleExtensionsWeightInfo {1532	/// Weight of token repartition.1533	fn repartition() -> Weight;1534}15351536/// Common collection operations.1537///1538/// It wraps methods in Fungible, Nonfungible and Refungible pallets1539/// and adds weight info.1540pub trait CommonCollectionOperations<T: Config> {1541	/// Create token.1542	///1543	/// * `sender` - The user who mint the token and pays for the transaction.1544	/// * `to` - The user who will own the token.1545	/// * `data` - Token data.1546	/// * `nesting_budget` - A budget that can be spent on nesting tokens.1547	fn create_item(1548		&self,1549		sender: T::CrossAccountId,1550		to: T::CrossAccountId,1551		data: CreateItemData,1552		nesting_budget: &dyn Budget,1553	) -> DispatchResultWithPostInfo;15541555	/// Create multiple tokens.1556	///1557	/// * `sender` - The user who mint the token and pays for the transaction.1558	/// * `to` - The user who will own the token.1559	/// * `data` - Token data.1560	/// * `nesting_budget` - A budget that can be spent on nesting tokens.1561	fn create_multiple_items(1562		&self,1563		sender: T::CrossAccountId,1564		to: T::CrossAccountId,1565		data: Vec<CreateItemData>,1566		nesting_budget: &dyn Budget,1567	) -> DispatchResultWithPostInfo;15681569	/// Create multiple tokens.1570	///1571	/// * `sender` - The user who mint the token and pays for the transaction.1572	/// * `to` - The user who will own the token.1573	/// * `data` - Token data.1574	/// * `nesting_budget` - A budget that can be spent on nesting tokens.1575	fn create_multiple_items_ex(1576		&self,1577		sender: T::CrossAccountId,1578		data: CreateItemExData<T::CrossAccountId>,1579		nesting_budget: &dyn Budget,1580	) -> DispatchResultWithPostInfo;15811582	/// Burn token.1583	///1584	/// * `sender` - The user who owns the token.1585	/// * `token` - Token id that will burned.1586	/// * `amount` - The number of parts of the token that will be burned.1587	fn burn_item(1588		&self,1589		sender: T::CrossAccountId,1590		token: TokenId,1591		amount: u128,1592	) -> DispatchResultWithPostInfo;15931594	/// Burn token and all nested tokens recursievly.1595	///1596	/// * `sender` - The user who owns the token.1597	/// * `token` - Token id that will burned.1598	/// * `self_budget` - The budget that can be spent on burning tokens.1599	/// * `breadth_budget` - The budget that can be spent on burning nested tokens.1600	fn burn_item_recursively(1601		&self,1602		sender: T::CrossAccountId,1603		token: TokenId,1604		self_budget: &dyn Budget,1605		breadth_budget: &dyn Budget,1606	) -> DispatchResultWithPostInfo;16071608	/// Set collection properties.1609	///1610	/// * `sender` - Must be either the owner of the collection or its admin.1611	/// * `properties` - Properties to be set.1612	fn set_collection_properties(1613		&self,1614		sender: T::CrossAccountId,1615		properties: Vec<Property>,1616	) -> DispatchResultWithPostInfo;16171618	/// Delete collection properties.1619	///1620	/// * `sender` - Must be either the owner of the collection or its admin.1621	/// * `properties` - The properties to be removed.1622	fn delete_collection_properties(1623		&self,1624		sender: &T::CrossAccountId,1625		property_keys: Vec<PropertyKey>,1626	) -> DispatchResultWithPostInfo;16271628	/// Set token properties.1629	///1630	/// The appropriate [`PropertyPermission`] for the token property1631	/// must be set with [`Self::set_token_property_permissions`].1632	///1633	/// * `sender` - Must be either the owner of the token or its admin.1634	/// * `token_id` - The token for which the properties are being set.1635	/// * `properties` - Properties to be set.1636	/// * `budget` - Budget for setting properties.1637	fn set_token_properties(1638		&self,1639		sender: T::CrossAccountId,1640		token_id: TokenId,1641		properties: Vec<Property>,1642		budget: &dyn Budget,1643	) -> DispatchResultWithPostInfo;16441645	/// Remove token properties.1646	///1647	/// The appropriate [`PropertyPermission`] for the token property1648	/// must be set with [`Self::set_token_property_permissions`].1649	///1650	/// * `sender` - Must be either the owner of the token or its admin.1651	/// * `token_id` - The token for which the properties are being remove.1652	/// * `property_keys` - Keys to remove corresponding properties.1653	/// * `budget` - Budget for removing properties.1654	fn delete_token_properties(1655		&self,1656		sender: T::CrossAccountId,1657		token_id: TokenId,1658		property_keys: Vec<PropertyKey>,1659		budget: &dyn Budget,1660	) -> DispatchResultWithPostInfo;16611662	/// Set token property permissions.1663	///1664	/// * `sender` - Must be either the owner of the token or its admin.1665	/// * `token_id` - The token for which the properties are being set.1666	/// * `property_permissions` - Property permissions to be set.1667	/// * `budget` - Budget for setting properties.1668	fn set_token_property_permissions(1669		&self,1670		sender: &T::CrossAccountId,1671		property_permissions: Vec<PropertyKeyPermission>,1672	) -> DispatchResultWithPostInfo;16731674	/// Transfer amount of token pieces.1675	///1676	/// * `sender` - Donor user.1677	/// * `to` - Recepient user.1678	/// * `token` - The token of which parts are being sent.1679	/// * `amount` - The number of parts of the token that will be transferred.1680	/// * `budget` - The maximum budget that can be spent on the transfer.1681	fn transfer(1682		&self,1683		sender: T::CrossAccountId,1684		to: T::CrossAccountId,1685		token: TokenId,1686		amount: u128,1687		budget: &dyn Budget,1688	) -> DispatchResultWithPostInfo;16891690	/// Grant access to another account to transfer parts of the token owned by the calling user via [Self::transfer_from].1691	///1692	/// * `sender` - The user who grants access to the token.1693	/// * `spender` - The user to whom the rights are granted.1694	/// * `token` - The token to which access is granted.1695	/// * `amount` - The amount of pieces that another user can dispose of.1696	fn approve(1697		&self,1698		sender: T::CrossAccountId,1699		spender: T::CrossAccountId,1700		token: TokenId,1701		amount: u128,1702	) -> DispatchResultWithPostInfo;17031704	/// Send parts of a token owned by another user.1705	///1706	/// Before calling this method, you must grant rights to the calling user via [`Self::approve`].1707	///1708	/// * `sender` - The user who must have access to the token (see [`Self::approve`]).1709	/// * `from` - The user who owns the token.1710	/// * `to` - Recepient user.1711	/// * `token` - The token of which parts are being sent.1712	/// * `amount` - The number of parts of the token that will be transferred.1713	/// * `budget` - The maximum budget that can be spent on the transfer.1714	fn transfer_from(1715		&self,1716		sender: T::CrossAccountId,1717		from: T::CrossAccountId,1718		to: T::CrossAccountId,1719		token: TokenId,1720		amount: u128,1721		budget: &dyn Budget,1722	) -> DispatchResultWithPostInfo;17231724	/// Burn parts of a token owned by another user.1725	///1726	/// Before calling this method, you must grant rights to the calling user via [`Self::approve`].1727	///1728	/// * `sender` - The user who must have access to the token (see [`Self::approve`]).1729	/// * `from` - The user who owns the token.1730	/// * `token` - The token of which parts are being sent.1731	/// * `amount` - The number of parts of the token that will be transferred.1732	/// * `budget` - The maximum budget that can be spent on the burn.1733	fn burn_from(1734		&self,1735		sender: T::CrossAccountId,1736		from: T::CrossAccountId,1737		token: TokenId,1738		amount: u128,1739		budget: &dyn Budget,1740	) -> DispatchResultWithPostInfo;17411742	/// Check permission to nest token.1743	///1744	/// * `sender` - The user who initiated the check.1745	/// * `from` - The token that is checked for embedding.1746	/// * `under` - Token under which to check.1747	/// * `budget` - The maximum budget that can be spent on the check.1748	fn check_nesting(1749		&self,1750		sender: T::CrossAccountId,1751		from: (CollectionId, TokenId),1752		under: TokenId,1753		budget: &dyn Budget,1754	) -> DispatchResult;17551756	/// Nest one token into another.1757	///1758	/// * `under` - Token holder.1759	/// * `to_nest` - Nested token.1760	fn nest(&self, under: TokenId, to_nest: (CollectionId, TokenId));17611762	/// Unnest token.1763	///1764	/// * `under` - Token holder.1765	/// * `to_nest` - Token to unnest.1766	fn unnest(&self, under: TokenId, to_nest: (CollectionId, TokenId));17671768	/// Get all user tokens.1769	///1770	/// * `account` - Account for which you need to get tokens.1771	fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId>;17721773	/// Get all the tokens in the collection.1774	fn collection_tokens(&self) -> Vec<TokenId>;17751776	/// Check if the token exists.1777	///1778	/// * `token` - Id token to check.1779	fn token_exists(&self, token: TokenId) -> bool;17801781	/// Get the id of the last minted token.1782	fn last_token_id(&self) -> TokenId;17831784	/// Get the owner of the token.1785	///1786	/// * `token` - The token for which you need to find out the owner.1787	fn token_owner(&self, token: TokenId) -> Option<T::CrossAccountId>;17881789	/// Returns 10 tokens owners in no particular order.1790	///1791	/// * `token` - The token for which you need to find out the owners.1792	fn token_owners(&self, token: TokenId) -> Vec<T::CrossAccountId>;17931794	/// Get the value of the token property by key.1795	///1796	/// * `token` - Token with the property to get.1797	/// * `key` - Property name.1798	fn token_property(&self, token_id: TokenId, key: &PropertyKey) -> Option<PropertyValue>;17991800	/// Get a set of token properties by key vector.1801	///1802	/// * `token` - Token with the property to get.1803	/// * `keys` - Vector of property keys. If this parameter is [None](sp_std::result::Result),1804	/// then all properties are returned.1805	fn token_properties(&self, token: TokenId, keys: Option<Vec<PropertyKey>>) -> Vec<Property>;18061807	/// Amount of unique collection tokens1808	fn total_supply(&self) -> u32;18091810	/// Amount of different tokens account has.1811	///1812	/// * `account` - The account for which need to get the balance.1813	fn account_balance(&self, account: T::CrossAccountId) -> u32;18141815	/// Amount of specific token account have.1816	fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128;18171818	/// Amount of token pieces1819	fn total_pieces(&self, token: TokenId) -> Option<u128>;18201821	/// Get the number of parts of the token that a trusted user can manage.1822	///1823	/// * `sender` - Trusted user.1824	/// * `spender` - Owner of the token.1825	/// * `token` - The token for which to get the value.1826	fn allowance(1827		&self,1828		sender: T::CrossAccountId,1829		spender: T::CrossAccountId,1830		token: TokenId,1831	) -> u128;18321833	/// Get extension for RFT collection.1834	fn refungible_extensions(&self) -> Option<&dyn RefungibleExtensions<T>>;1835}18361837/// Extension for RFT collection.1838pub trait RefungibleExtensions<T>1839where1840	T: Config,1841{1842	/// Change the number of parts of the token.1843	///1844	/// When the value changes down, this function is equivalent to burning parts of the token.1845	///1846	/// * `sender` - The user calling the repartition operation. Must be the owner of the token.1847	/// * `token` - The token for which you want to change the number of parts.1848	/// * `amount` - The new value of the parts of the token.1849	fn repartition(1850		&self,1851		sender: &T::CrossAccountId,1852		token: TokenId,1853		amount: u128,1854	) -> DispatchResultWithPostInfo;1855}18561857/// Merge [`DispatchResult`] with [`Weight`] into [`DispatchResultWithPostInfo`].1858///1859/// Used for [`CommonCollectionOperations`] implementations and flexible enough to do so.1860pub fn with_weight(res: DispatchResult, weight: Weight) -> DispatchResultWithPostInfo {1861	let post_info = PostDispatchInfo {1862		actual_weight: Some(weight),1863		pays_fee: Pays::Yes,1864	};1865	match res {1866		Ok(()) => Ok(post_info),1867		Err(error) => Err(DispatchErrorWithPostInfo { post_info, error }),1868	}1869}18701871impl<T: Config> From<PropertiesError> for Error<T> {1872	fn from(error: PropertiesError) -> Self {1873		match error {1874			PropertiesError::NoSpaceForProperty => Self::NoSpaceForProperty,1875			PropertiesError::PropertyLimitReached => Self::PropertyLimitReached,1876			PropertiesError::InvalidCharacterInPropertyKey => Self::InvalidCharacterInPropertyKey,1877			PropertiesError::PropertyKeyIsTooLong => Self::PropertyKeyIsTooLong,1878			PropertiesError::EmptyPropertyKey => Self::EmptyPropertyKey,1879		}1880	}1881}
after · pallets/common/src/lib.rs
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617//! # Common pallet18//!19//! The Common pallet provides functionality for handling collections.20//!21//! ## Overview22//!23//! The Common pallet provides an interface for common collection operations for different collection types24//! (see [CommonCollectionOperations]), as well as a generic dispatcher for these, see [dispatch] module.25//! It also provides this functionality to EVM, see [erc] and [eth] modules.26//!27//! The Common pallet provides functions for:28//!29//! - Setting and approving collection sponsor.30//! - Get\set\delete allow list.31//! - Get\set\delete collection properties.32//! - Get\set\delete collection property permissions.33//! - Get\set\delete token property permissions.34//! - Get\set\delete collection administrators.35//! - Checking access permissions.36//!37//! ### Terminology38//! **Collection sponsor** - For the collection, you can set a sponsor, at whose expense it will39//! be possible to mint tokens.40//!41//! **Allow list** - List of users who have the right to minting tokens.42//!43//! **Collection properties** - Collection properties are simply key-value stores where various44//! metadata can be placed.45//!46//! **Permissions on token properties** - For each property in the token can be set permission47//! to change, see [`PropertyPermission`].48//!49//! **Collection administrator** - For a collection, you can set administrators who have the right50//! to most actions on the collection.5152#![warn(missing_docs)]53#![cfg_attr(not(feature = "std"), no_std)]54extern crate alloc;5556use core::ops::{Deref, DerefMut};57use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};58use sp_std::vec::Vec;59use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};60use evm_coder::ToLog;61use frame_support::{62	dispatch::{DispatchErrorWithPostInfo, DispatchResultWithPostInfo, Weight, PostDispatchInfo},63	ensure,64	traits::{Imbalance, Get, Currency, WithdrawReasons, ExistenceRequirement},65	dispatch::Pays,66	transactional,67};68use pallet_evm::GasWeightMapping;69use up_data_structs::{70	COLLECTION_NUMBER_LIMIT,71	Collection,72	RpcCollection,73	CollectionFlags,74	RpcCollectionFlags,75	CollectionId,76	CreateItemData,77	MAX_TOKEN_PREFIX_LENGTH,78	COLLECTION_ADMINS_LIMIT,79	TokenId,80	TokenChild,81	CollectionStats,82	MAX_TOKEN_OWNERSHIP,83	CollectionMode,84	NFT_SPONSOR_TRANSFER_TIMEOUT,85	FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,86	REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,87	MAX_SPONSOR_TIMEOUT,88	CUSTOM_DATA_LIMIT,89	CollectionLimits,90	CreateCollectionData,91	SponsorshipState,92	CreateItemExData,93	SponsoringRateLimit,94	budget::Budget,95	PhantomType,96	Property,97	Properties,98	PropertiesPermissionMap,99	PropertyKey,100	PropertyValue,101	PropertyPermission,102	PropertiesError,103	PropertyKeyPermission,104	TokenData,105	TrySetProperty,106	PropertyScope,107	// RMRK108	RmrkCollectionInfo,109	RmrkInstanceInfo,110	RmrkResourceInfo,111	RmrkPropertyInfo,112	RmrkBaseInfo,113	RmrkPartType,114	RmrkBoundedTheme,115	RmrkNftChild,116	CollectionPermissions,117};118119pub use pallet::*;120use sp_core::H160;121use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};122#[cfg(feature = "runtime-benchmarks")]123pub mod benchmarking;124pub mod dispatch;125pub mod erc;126pub mod eth;127pub mod weights;128129/// Weight info.130pub type SelfWeightOf<T> = <T as Config>::WeightInfo;131132/// Collection handle contains information about collection data and id.133/// Also provides functionality to count consumed gas.134///135/// CollectionHandle is used as a generic wrapper for collections of all types.136/// It allows to perform common operations and queries on any collection type,137/// both completely general for all, as well as their respective implementations of [`CommonCollectionOperations`].138#[must_use = "Should call submit_logs or save, otherwise some data will be lost for evm side"]139pub struct CollectionHandle<T: Config> {140	/// Collection id141	pub id: CollectionId,142	collection: Collection<T::AccountId>,143	/// Substrate recorder for counting consumed gas144	pub recorder: SubstrateRecorder<T>,145}146147impl<T: Config> WithRecorder<T> for CollectionHandle<T> {148	fn recorder(&self) -> &SubstrateRecorder<T> {149		&self.recorder150	}151	fn into_recorder(self) -> SubstrateRecorder<T> {152		self.recorder153	}154}155156impl<T: Config> CollectionHandle<T> {157	/// Same as [CollectionHandle::new] but with an explicit gas limit.158	pub fn new_with_gas_limit(id: CollectionId, gas_limit: u64) -> Option<Self> {159		<CollectionById<T>>::get(id).map(|collection| Self {160			id,161			collection,162			recorder: SubstrateRecorder::new(gas_limit),163		})164	}165166	/// Same as [CollectionHandle::new] but with an existed [`SubstrateRecorder`].167	pub fn new_with_recorder(id: CollectionId, recorder: SubstrateRecorder<T>) -> Option<Self> {168		<CollectionById<T>>::get(id).map(|collection| Self {169			id,170			collection,171			recorder,172		})173	}174175	/// Retrives collection data from storage and creates collection handle with default parameters.176	/// If collection not found return `None`177	pub fn new(id: CollectionId) -> Option<Self> {178		Self::new_with_gas_limit(id, u64::MAX)179	}180181	/// Same as [`CollectionHandle::new`] but if collection not found [CollectionNotFound](Error::CollectionNotFound) returned.182	pub fn try_get(id: CollectionId) -> Result<Self, DispatchError> {183		Ok(Self::new(id).ok_or(<Error<T>>::CollectionNotFound)?)184	}185186	/// Consume gas for reading.187	pub fn consume_store_reads(&self, reads: u64) -> evm_coder::execution::Result<()> {188		self.recorder189			.consume_gas(T::GasWeightMapping::weight_to_gas(Weight::from_ref_time(190				<T as frame_system::Config>::DbWeight::get()191					.read192					.saturating_mul(reads),193			)))194	}195196	/// Consume gas for writing.197	pub fn consume_store_writes(&self, writes: u64) -> evm_coder::execution::Result<()> {198		self.recorder199			.consume_gas(T::GasWeightMapping::weight_to_gas(Weight::from_ref_time(200				<T as frame_system::Config>::DbWeight::get()201					.write202					.saturating_mul(writes),203			)))204	}205206	/// Consume gas for reading and writing.207	pub fn consume_store_reads_and_writes(208		&self,209		reads: u64,210		writes: u64,211	) -> evm_coder::execution::Result<()> {212		let weight = <T as frame_system::Config>::DbWeight::get();213		let reads = weight.read.saturating_mul(reads);214		let writes = weight.read.saturating_mul(writes);215		self.recorder216			.consume_gas(T::GasWeightMapping::weight_to_gas(Weight::from_ref_time(217				reads.saturating_add(writes),218			)))219	}220221	/// Save collection to storage.222	pub fn save(&self) -> DispatchResult {223		<CollectionById<T>>::insert(self.id, &self.collection);224		Ok(())225	}226227	/// Set collection sponsor.228	///229	/// Unique collections allows sponsoring for certain actions.230	/// This method allows you to set the sponsor of the collection.231	/// In order for sponsorship to become active, it must be confirmed through [`Self::confirm_sponsorship`].232	pub fn set_sponsor(&mut self, sponsor: T::AccountId) -> DispatchResult {233		self.collection.sponsorship = SponsorshipState::Unconfirmed(sponsor);234		Ok(())235	}236237	/// Confirm sponsorship238	///239	/// In order for the sponsorship to become active, the user set as the sponsor must confirm their participation.240	/// Before confirming sponsorship, the user must be specified as the sponsor of the collection via [`Self::set_sponsor`].241	pub fn confirm_sponsorship(&mut self, sender: &T::AccountId) -> Result<bool, DispatchError> {242		if self.collection.sponsorship.pending_sponsor() != Some(sender) {243			return Ok(false);244		}245246		self.collection.sponsorship = SponsorshipState::Confirmed(sender.clone());247		Ok(true)248	}249250	/// Remove collection sponsor.251	pub fn remove_sponsor(&mut self) -> DispatchResult {252		self.collection.sponsorship = SponsorshipState::Disabled;253		Ok(())254	}255256	/// Checks that the collection was created with, and must be operated upon through **Unique API**.257	/// Now check only the `external` flag and if it's **true**, then return [`Error::CollectionIsExternal`] error.258	pub fn check_is_internal(&self) -> DispatchResult {259		if self.flags.external {260			return Err(<Error<T>>::CollectionIsExternal)?;261		}262263		Ok(())264	}265266	/// Checks that the collection was created with, and must be operated upon through an **assimilated API**.267	/// Now check only the `external` flag and if it's **false**, then return [`Error::CollectionIsInternal`] error.268	pub fn check_is_external(&self) -> DispatchResult {269		if !self.flags.external {270			return Err(<Error<T>>::CollectionIsInternal)?;271		}272273		Ok(())274	}275}276277impl<T: Config> Deref for CollectionHandle<T> {278	type Target = Collection<T::AccountId>;279280	fn deref(&self) -> &Self::Target {281		&self.collection282	}283}284285impl<T: Config> DerefMut for CollectionHandle<T> {286	fn deref_mut(&mut self) -> &mut Self::Target {287		&mut self.collection288	}289}290291impl<T: Config> CollectionHandle<T> {292	/// Checks if the `user` is the owner of the collection.293	pub fn check_is_owner(&self, user: &T::CrossAccountId) -> DispatchResult {294		ensure!(*user.as_sub() == self.owner, <Error<T>>::NoPermission);295		Ok(())296	}297298	/// Returns **true** if the `user` is the owner or administrator of the collection.299	pub fn is_owner_or_admin(&self, user: &T::CrossAccountId) -> bool {300		*user.as_sub() == self.owner || <IsAdmin<T>>::get((self.id, user))301	}302303	/// Checks if the `user` is the owner or administrator of the collection.304	pub fn check_is_owner_or_admin(&self, user: &T::CrossAccountId) -> DispatchResult {305		ensure!(self.is_owner_or_admin(user), <Error<T>>::NoPermission);306		Ok(())307	}308309	/// Return **true** if `user` was not allowed to have tokens, and he can ignore such restrictions.310	pub fn ignores_allowance(&self, user: &T::CrossAccountId) -> bool {311		self.limits.owner_can_transfer() && self.is_owner_or_admin(user)312	}313314	/// Return **true** if `user` does not have enough token parts, and he can ignore such restrictions.315	pub fn ignores_owned_amount(&self, user: &T::CrossAccountId) -> bool {316		self.limits.owner_can_transfer() && self.is_owner_or_admin(user)317	}318319	/// Checks if the user is in the allow list. If not [Error::AddressNotInAllowlist] returns.320	pub fn check_allowlist(&self, user: &T::CrossAccountId) -> DispatchResult {321		ensure!(322			<Allowlist<T>>::get((self.id, user)),323			<Error<T>>::AddressNotInAllowlist324		);325		Ok(())326	}327328	/// Changes collection owner to another account329	/// #### Store read/writes330	/// 1 writes331	fn set_owner_internal(332		&mut self,333		caller: T::CrossAccountId,334		new_owner: T::CrossAccountId,335	) -> DispatchResult {336		self.check_is_owner(&caller)?;337		self.collection.owner = new_owner.as_sub().clone();338		self.save()339	}340}341342#[frame_support::pallet]343pub mod pallet {344	use super::*;345	use dispatch::CollectionDispatch;346	use frame_support::{Blake2_128Concat, pallet_prelude::*, storage::Key, traits::StorageVersion};347	use frame_system::pallet_prelude::*;348	use frame_support::traits::Currency;349	use up_data_structs::{TokenId, mapping::TokenAddressMapping};350	use scale_info::TypeInfo;351	use weights::WeightInfo;352353	#[pallet::config]354	pub trait Config:355		frame_system::Config + pallet_evm_coder_substrate::Config + pallet_evm::Config + TypeInfo356	{357		/// Weight information for functions of this pallet.358		type WeightInfo: WeightInfo;359360		/// Events compatible with [`frame_system::Config::Event`].361		type RuntimeEvent: IsType<<Self as frame_system::Config>::RuntimeEvent> + From<Event<Self>>;362363		/// Handler of accounts and payment.364		type Currency: Currency<Self::AccountId>;365366		/// Set price to create a collection.367		#[pallet::constant]368		type CollectionCreationPrice: Get<369			<<Self as Config>::Currency as Currency<Self::AccountId>>::Balance,370		>;371372		/// Dispatcher of operations on collections.373		type CollectionDispatch: CollectionDispatch<Self>;374375		/// Account which holds the chain's treasury.376		type TreasuryAccountId: Get<Self::AccountId>;377378		/// Address under which the CollectionHelper contract would be available.379		type ContractAddress: Get<H160>;380381		/// Mapper for token addresses to Ethereum addresses.382		type EvmTokenAddressMapping: TokenAddressMapping<H160>;383384		/// Mapper for token addresses to [`CrossAccountId`].385		type CrossTokenAddressMapping: TokenAddressMapping<Self::CrossAccountId>;386	}387388	const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);389390	#[pallet::pallet]391	#[pallet::storage_version(STORAGE_VERSION)]392	#[pallet::generate_store(pub(super) trait Store)]393	pub struct Pallet<T>(_);394395	#[pallet::extra_constants]396	impl<T: Config> Pallet<T> {397		/// Maximum admins per collection.398		pub fn collection_admins_limit() -> u32 {399			COLLECTION_ADMINS_LIMIT400		}401	}402403	#[pallet::event]404	#[pallet::generate_deposit(pub fn deposit_event)]405	pub enum Event<T: Config> {406		/// New collection was created407		CollectionCreated(408			/// Globally unique identifier of newly created collection.409			CollectionId,410			/// [`CollectionMode`] converted into _u8_.411			u8,412			/// Collection owner.413			T::AccountId,414		),415416		/// New collection was destroyed417		CollectionDestroyed(418			/// Globally unique identifier of collection.419			CollectionId,420		),421422		/// New item was created.423		ItemCreated(424			/// Id of the collection where item was created.425			CollectionId,426			/// Id of an item. Unique within the collection.427			TokenId,428			/// Owner of newly created item429			T::CrossAccountId,430			/// Always 1 for NFT431			u128,432		),433434		/// Collection item was burned.435		ItemDestroyed(436			/// Id of the collection where item was destroyed.437			CollectionId,438			/// Identifier of burned NFT.439			TokenId,440			/// Which user has destroyed its tokens.441			T::CrossAccountId,442			/// Amount of token pieces destroed. Always 1 for NFT.443			u128,444		),445446		/// Item was transferred447		Transfer(448			/// Id of collection to which item is belong.449			CollectionId,450			/// Id of an item.451			TokenId,452			/// Original owner of item.453			T::CrossAccountId,454			/// New owner of item.455			T::CrossAccountId,456			/// Amount of token pieces transfered. Always 1 for NFT.457			u128,458		),459460		/// Amount pieces of token owned by `sender` was approved for `spender`.461		Approved(462			/// Id of collection to which item is belong.463			CollectionId,464			/// Id of an item.465			TokenId,466			/// Original owner of item.467			T::CrossAccountId,468			/// Id for which the approval was granted.469			T::CrossAccountId,470			/// Amount of token pieces transfered. Always 1 for NFT.471			u128,472		),473474		/// The colletion property has been added or edited.475		CollectionPropertySet(476			/// Id of collection to which property has been set.477			CollectionId,478			/// The property that was set.479			PropertyKey,480		),481482		/// The property has been deleted.483		CollectionPropertyDeleted(484			/// Id of collection to which property has been deleted.485			CollectionId,486			/// The property that was deleted.487			PropertyKey,488		),489490		/// The token property has been added or edited.491		TokenPropertySet(492			/// Identifier of the collection whose token has the property set.493			CollectionId,494			/// The token for which the property was set.495			TokenId,496			/// The property that was set.497			PropertyKey,498		),499500		/// The token property has been deleted.501		TokenPropertyDeleted(502			/// Identifier of the collection whose token has the property deleted.503			CollectionId,504			/// The token for which the property was deleted.505			TokenId,506			/// The property that was deleted.507			PropertyKey,508		),509510		/// The token property permission of a collection has been set.511		PropertyPermissionSet(512			/// ID of collection to which property permission has been set.513			CollectionId,514			/// The property permission that was set.515			PropertyKey,516		),517	}518519	#[pallet::error]520	pub enum Error<T> {521		/// This collection does not exist.522		CollectionNotFound,523		/// Sender parameter and item owner must be equal.524		MustBeTokenOwner,525		/// No permission to perform action526		NoPermission,527		/// Destroying only empty collections is allowed528		CantDestroyNotEmptyCollection,529		/// Collection is not in mint mode.530		PublicMintingNotAllowed,531		/// Address is not in allow list.532		AddressNotInAllowlist,533534		/// Collection name can not be longer than 63 char.535		CollectionNameLimitExceeded,536		/// Collection description can not be longer than 255 char.537		CollectionDescriptionLimitExceeded,538		/// Token prefix can not be longer than 15 char.539		CollectionTokenPrefixLimitExceeded,540		/// Total collections bound exceeded.541		TotalCollectionsLimitExceeded,542		/// Exceeded max admin count543		CollectionAdminCountExceeded,544		/// Collection limit bounds per collection exceeded545		CollectionLimitBoundsExceeded,546		/// Tried to enable permissions which are only permitted to be disabled547		OwnerPermissionsCantBeReverted,548		/// Collection settings not allowing items transferring549		TransferNotAllowed,550		/// Account token limit exceeded per collection551		AccountTokenLimitExceeded,552		/// Collection token limit exceeded553		CollectionTokenLimitExceeded,554		/// Metadata flag frozen555		MetadataFlagFrozen,556557		/// Item does not exist558		TokenNotFound,559		/// Item is balance not enough560		TokenValueTooLow,561		/// Requested value is more than the approved562		ApprovedValueTooLow,563		/// Tried to approve more than owned564		CantApproveMoreThanOwned,565566		/// Can't transfer tokens to ethereum zero address567		AddressIsZero,568569		/// The operation is not supported570		UnsupportedOperation,571572		/// Insufficient funds to perform an action573		NotSufficientFounds,574575		/// User does not satisfy the nesting rule576		UserIsNotAllowedToNest,577		/// Only tokens from specific collections may nest tokens under this one578		SourceCollectionIsNotAllowedToNest,579580		/// Tried to store more data than allowed in collection field581		CollectionFieldSizeExceeded,582583		/// Tried to store more property data than allowed584		NoSpaceForProperty,585586		/// Tried to store more property keys than allowed587		PropertyLimitReached,588589		/// Property key is too long590		PropertyKeyIsTooLong,591592		/// Only ASCII letters, digits, and symbols `_`, `-`, and `.` are allowed593		InvalidCharacterInPropertyKey,594595		/// Empty property keys are forbidden596		EmptyPropertyKey,597598		/// Tried to access an external collection with an internal API599		CollectionIsExternal,600601		/// Tried to access an internal collection with an external API602		CollectionIsInternal,603	}604605	/// Storage of the count of created collections. Essentially contains the last collection ID.606	#[pallet::storage]607	pub type CreatedCollectionCount<T> = StorageValue<Value = CollectionId, QueryKind = ValueQuery>;608609	/// Storage of the count of deleted collections.610	#[pallet::storage]611	pub type DestroyedCollectionCount<T> =612		StorageValue<Value = CollectionId, QueryKind = ValueQuery>;613614	/// Storage of collection info.615	#[pallet::storage]616	pub type CollectionById<T> = StorageMap<617		Hasher = Blake2_128Concat,618		Key = CollectionId,619		Value = Collection<<T as frame_system::Config>::AccountId>,620		QueryKind = OptionQuery,621	>;622623	/// Storage of collection properties.624	#[pallet::storage]625	#[pallet::getter(fn collection_properties)]626	pub type CollectionProperties<T> = StorageMap<627		Hasher = Blake2_128Concat,628		Key = CollectionId,629		Value = Properties,630		QueryKind = ValueQuery,631		OnEmpty = up_data_structs::CollectionProperties,632	>;633634	/// Storage of token property permissions of a collection.635	#[pallet::storage]636	#[pallet::getter(fn property_permissions)]637	pub type CollectionPropertyPermissions<T> = StorageMap<638		Hasher = Blake2_128Concat,639		Key = CollectionId,640		Value = PropertiesPermissionMap,641		QueryKind = ValueQuery,642	>;643644	/// Storage of the amount of collection admins.645	#[pallet::storage]646	pub type AdminAmount<T> = StorageMap<647		Hasher = Blake2_128Concat,648		Key = CollectionId,649		Value = u32,650		QueryKind = ValueQuery,651	>;652653	/// List of collection admins.654	#[pallet::storage]655	pub type IsAdmin<T: Config> = StorageNMap<656		Key = (657			Key<Blake2_128Concat, CollectionId>,658			Key<Blake2_128Concat, T::CrossAccountId>,659		),660		Value = bool,661		QueryKind = ValueQuery,662	>;663664	/// Allowlisted collection users.665	#[pallet::storage]666	pub type Allowlist<T: Config> = StorageNMap<667		Key = (668			Key<Blake2_128Concat, CollectionId>,669			Key<Blake2_128Concat, T::CrossAccountId>,670		),671		Value = bool,672		QueryKind = ValueQuery,673	>;674675	/// Not used by code, exists only to provide some types to metadata.676	#[pallet::storage]677	pub type DummyStorageValue<T: Config> = StorageValue<678		Value = (679			CollectionStats,680			CollectionId,681			TokenId,682			TokenChild,683			PhantomType<(684				TokenData<T::CrossAccountId>,685				RpcCollection<T::AccountId>,686				// RMRK687				RmrkCollectionInfo<T::AccountId>,688				RmrkInstanceInfo<T::AccountId>,689				RmrkResourceInfo,690				RmrkPropertyInfo,691				RmrkBaseInfo<T::AccountId>,692				RmrkPartType,693				RmrkBoundedTheme,694				RmrkNftChild,695			)>,696		),697		QueryKind = OptionQuery,698	>;699700	#[pallet::hooks]701	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {702		fn on_runtime_upgrade() -> Weight {703			StorageVersion::new(1).put::<Pallet<T>>();704705			Weight::zero()706		}707	}708}709710impl<T: Config> Pallet<T> {711	/// Enshure that receiver address is correct.712	///713	/// Ethereum receiver 0x0000000000000000000000000000000000000000 is reserved, and shouldn't own tokens.714	pub fn ensure_correct_receiver(receiver: &T::CrossAccountId) -> DispatchResult {715		ensure!(716			&T::CrossAccountId::from_eth(H160([0; 20])) != receiver,717			<Error<T>>::AddressIsZero718		);719		Ok(())720	}721722	/// Get a vector of collection admins.723	pub fn adminlist(collection: CollectionId) -> Vec<T::CrossAccountId> {724		<IsAdmin<T>>::iter_prefix((collection,))725			.map(|(a, _)| a)726			.collect()727	}728729	/// Get a vector of users allowed to mint tokens.730	pub fn allowlist(collection: CollectionId) -> Vec<T::CrossAccountId> {731		<Allowlist<T>>::iter_prefix((collection,))732			.map(|(a, _)| a)733			.collect()734	}735736	/// Is `user` allowed to mint token in `collection`.737	pub fn allowed(collection: CollectionId, user: T::CrossAccountId) -> bool {738		<Allowlist<T>>::get((collection, user))739	}740741	/// Get statistics of collections.742	pub fn collection_stats() -> CollectionStats {743		let created = <CreatedCollectionCount<T>>::get();744		let destroyed = <DestroyedCollectionCount<T>>::get();745		CollectionStats {746			created: created.0,747			destroyed: destroyed.0,748			alive: created.0 - destroyed.0,749		}750	}751752	/// Get the effective limits for the collection.753	pub fn effective_collection_limits(collection: CollectionId) -> Option<CollectionLimits> {754		let collection = <CollectionById<T>>::get(collection)?;755		let limits = collection.limits;756		let effective_limits = CollectionLimits {757			account_token_ownership_limit: Some(limits.account_token_ownership_limit()),758			sponsored_data_size: Some(limits.sponsored_data_size()),759			sponsored_data_rate_limit: Some(760				limits761					.sponsored_data_rate_limit762					.unwrap_or(SponsoringRateLimit::SponsoringDisabled),763			),764			token_limit: Some(limits.token_limit()),765			sponsor_transfer_timeout: Some(limits.sponsor_transfer_timeout(766				match collection.mode {767					CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,768					CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,769					CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,770				},771			)),772			sponsor_approve_timeout: Some(limits.sponsor_approve_timeout()),773			owner_can_transfer: Some(limits.owner_can_transfer()),774			owner_can_destroy: Some(limits.owner_can_destroy()),775			transfers_enabled: Some(limits.transfers_enabled()),776		};777778		Some(effective_limits)779	}780781	/// Returns information about the `collection` adapted for rpc.782	pub fn rpc_collection(collection: CollectionId) -> Option<RpcCollection<T::AccountId>> {783		let Collection {784			name,785			description,786			owner,787			mode,788			token_prefix,789			sponsorship,790			limits,791			permissions,792			flags,793		} = <CollectionById<T>>::get(collection)?;794795		let token_property_permissions = <CollectionPropertyPermissions<T>>::get(collection)796			.into_iter()797			.map(|(key, permission)| PropertyKeyPermission { key, permission })798			.collect();799800		let properties = <CollectionProperties<T>>::get(collection)801			.into_iter()802			.map(|(key, value)| Property { key, value })803			.collect();804805		let permissions = CollectionPermissions {806			access: Some(permissions.access()),807			mint_mode: Some(permissions.mint_mode()),808			nesting: Some(permissions.nesting().clone()),809		};810811		Some(RpcCollection {812			name: name.into_inner(),813			description: description.into_inner(),814			owner,815			mode,816			token_prefix: token_prefix.into_inner(),817			sponsorship,818			limits,819			permissions,820			token_property_permissions,821			properties,822			read_only: flags.external,823824			flags: RpcCollectionFlags {825				foreign: flags.foreign,826				erc721metadata: flags.erc721metadata,827			},828		})829	}830}831832macro_rules! limit_default {833	($old:ident, $new:ident, $($field:ident $(($arg:expr))? => $check:expr),* $(,)?) => {{834		$(835			if let Some($new) = $new.$field {836				let $old = $old.$field($($arg)?);837				let _ = $new;838				let _ = $old;839				$check840			} else {841				$new.$field = $old.$field842			}843		)*844	}};845}846macro_rules! limit_default_clone {847	($old:ident, $new:ident, $($field:ident $(($arg:expr))? => $check:expr),* $(,)?) => {{848		$(849			if let Some($new) = $new.$field.clone() {850				let $old = $old.$field($($arg)?);851				let _ = $new;852				let _ = $old;853				$check854			} else {855				$new.$field = $old.$field.clone()856			}857		)*858	}};859}860861impl<T: Config> Pallet<T> {862	/// Create new collection.863	///864	/// * `owner` - The owner of the collection.865	/// * `data` - Description of the created collection.866	/// * `flags` - Extra flags to store.867	pub fn init_collection(868		owner: T::CrossAccountId,869		payer: T::CrossAccountId,870		data: CreateCollectionData<T::AccountId>,871		flags: CollectionFlags,872	) -> Result<CollectionId, DispatchError> {873		{874			ensure!(875				data.token_prefix.len() <= MAX_TOKEN_PREFIX_LENGTH as usize,876				Error::<T>::CollectionTokenPrefixLimitExceeded877			);878		}879880		let created_count = <CreatedCollectionCount<T>>::get()881			.0882			.checked_add(1)883			.ok_or(ArithmeticError::Overflow)?;884		let destroyed_count = <DestroyedCollectionCount<T>>::get().0;885		let id = CollectionId(created_count);886887		// bound Total number of collections888		ensure!(889			created_count - destroyed_count <= COLLECTION_NUMBER_LIMIT,890			<Error<T>>::TotalCollectionsLimitExceeded891		);892893		// =========894895		let collection = Collection {896			owner: owner.as_sub().clone(),897			name: data.name,898			mode: data.mode.clone(),899			description: data.description,900			token_prefix: data.token_prefix,901			sponsorship: data902				.pending_sponsor903				.map(SponsorshipState::Unconfirmed)904				.unwrap_or_default(),905			limits: data906				.limits907				.map(|limits| Self::clamp_limits(data.mode.clone(), &Default::default(), limits))908				.unwrap_or_else(|| Ok(CollectionLimits::default()))?,909			permissions: data910				.permissions911				.map(|permissions| {912					Self::clamp_permissions(data.mode.clone(), &Default::default(), permissions)913				})914				.unwrap_or_else(|| Ok(CollectionPermissions::default()))?,915			flags,916		};917918		let mut collection_properties = up_data_structs::CollectionProperties::get();919		collection_properties920			.try_set_from_iter(data.properties.into_iter())921			.map_err(<Error<T>>::from)?;922923		CollectionProperties::<T>::insert(id, collection_properties);924925		let mut token_props_permissions = PropertiesPermissionMap::new();926		token_props_permissions927			.try_set_from_iter(data.token_property_permissions.into_iter())928			.map_err(<Error<T>>::from)?;929930		CollectionPropertyPermissions::<T>::insert(id, token_props_permissions);931932		// Take a (non-refundable) deposit of collection creation933		{934			let mut imbalance =935				<<<T as Config>::Currency as Currency<T::AccountId>>::PositiveImbalance>::zero();936			imbalance.subsume(937				<<T as Config>::Currency as Currency<T::AccountId>>::deposit_creating(938					&T::TreasuryAccountId::get(),939					T::CollectionCreationPrice::get(),940				),941			);942			<T as Config>::Currency::settle(943				payer.as_sub(),944				imbalance,945				WithdrawReasons::TRANSFER,946				ExistenceRequirement::KeepAlive,947			)948			.map_err(|_| Error::<T>::NotSufficientFounds)?;949		}950951		<CreatedCollectionCount<T>>::put(created_count);952		<Pallet<T>>::deposit_event(Event::CollectionCreated(953			id,954			data.mode.id(),955			owner.as_sub().clone(),956		));957		<PalletEvm<T>>::deposit_log(958			erc::CollectionHelpersEvents::CollectionCreated {959				owner: *owner.as_eth(),960				collection_id: eth::collection_id_to_address(id),961			}962			.to_log(T::ContractAddress::get()),963		);964		<CollectionById<T>>::insert(id, collection);965		Ok(id)966	}967968	/// Destroy collection.969	///970	/// * `collection` - Collection handler.971	/// * `sender` - The owner or administrator of the collection.972	pub fn destroy_collection(973		collection: CollectionHandle<T>,974		sender: &T::CrossAccountId,975	) -> DispatchResult {976		ensure!(977			collection.limits.owner_can_destroy(),978			<Error<T>>::NoPermission,979		);980		collection.check_is_owner(sender)?;981982		let destroyed_collections = <DestroyedCollectionCount<T>>::get()983			.0984			.checked_add(1)985			.ok_or(ArithmeticError::Overflow)?;986987		// =========988989		<DestroyedCollectionCount<T>>::put(destroyed_collections);990		<CollectionById<T>>::remove(collection.id);991		<AdminAmount<T>>::remove(collection.id);992		let _ = <IsAdmin<T>>::clear_prefix((collection.id,), u32::MAX, None);993		let _ = <Allowlist<T>>::clear_prefix((collection.id,), u32::MAX, None);994		<CollectionProperties<T>>::remove(collection.id);995996		<Pallet<T>>::deposit_event(Event::CollectionDestroyed(collection.id));997998		<PalletEvm<T>>::deposit_log(999			erc::CollectionHelpersEvents::CollectionDestroyed {1000				collection_id: eth::collection_id_to_address(collection.id),1001			}1002			.to_log(T::ContractAddress::get()),1003		);1004		Ok(())1005	}10061007	/// Set collection property.1008	///1009	/// * `collection` - Collection handler.1010	/// * `sender` - The owner or administrator of the collection.1011	/// * `property` - The property to set.1012	pub fn set_collection_property(1013		collection: &CollectionHandle<T>,1014		sender: &T::CrossAccountId,1015		property: Property,1016	) -> DispatchResult {1017		collection.check_is_owner_or_admin(sender)?;10181019		CollectionProperties::<T>::try_mutate(collection.id, |properties| {1020			let property = property.clone();1021			properties.try_set(property.key, property.value)1022		})1023		.map_err(<Error<T>>::from)?;10241025		Self::deposit_event(Event::CollectionPropertySet(collection.id, property.key));10261027		Ok(())1028	}10291030	/// Set scouped collection property.1031	///1032	/// * `collection_id` - ID of the collection for which the property is being set.1033	/// * `scope` - Property scope.1034	/// * `property` - The property to set.1035	pub fn set_scoped_collection_property(1036		collection_id: CollectionId,1037		scope: PropertyScope,1038		property: Property,1039	) -> DispatchResult {1040		CollectionProperties::<T>::try_mutate(collection_id, |properties| {1041			properties.try_scoped_set(scope, property.key, property.value)1042		})1043		.map_err(<Error<T>>::from)?;10441045		Ok(())1046	}10471048	/// Set scouped collection properties.1049	///1050	/// * `collection_id` - ID of the collection for which the properties is being set.1051	/// * `scope` - Property scope.1052	/// * `properties` - The properties to set.1053	pub fn set_scoped_collection_properties(1054		collection_id: CollectionId,1055		scope: PropertyScope,1056		properties: impl Iterator<Item = Property>,1057	) -> DispatchResult {1058		CollectionProperties::<T>::try_mutate(collection_id, |stored_properties| {1059			stored_properties.try_scoped_set_from_iter(scope, properties)1060		})1061		.map_err(<Error<T>>::from)?;10621063		Ok(())1064	}10651066	/// Set collection properties.1067	///1068	/// * `collection` - Collection handler.1069	/// * `sender` - The owner or administrator of the collection.1070	/// * `properties` - The properties to set.1071	#[transactional]1072	pub fn set_collection_properties(1073		collection: &CollectionHandle<T>,1074		sender: &T::CrossAccountId,1075		properties: Vec<Property>,1076	) -> DispatchResult {1077		for property in properties {1078			Self::set_collection_property(collection, sender, property)?;1079		}10801081		Ok(())1082	}10831084	/// Delete collection property.1085	///1086	/// * `collection` - Collection handler.1087	/// * `sender` - The owner or administrator of the collection.1088	/// * `property` - The property to delete.1089	pub fn delete_collection_property(1090		collection: &CollectionHandle<T>,1091		sender: &T::CrossAccountId,1092		property_key: PropertyKey,1093	) -> DispatchResult {1094		collection.check_is_owner_or_admin(sender)?;10951096		CollectionProperties::<T>::try_mutate(collection.id, |properties| {1097			properties.remove(&property_key)1098		})1099		.map_err(<Error<T>>::from)?;11001101		Self::deposit_event(Event::CollectionPropertyDeleted(1102			collection.id,1103			property_key,1104		));11051106		Ok(())1107	}11081109	/// Delete collection properties.1110	///1111	/// * `collection` - Collection handler.1112	/// * `sender` - The owner or administrator of the collection.1113	/// * `properties` - The properties to delete.1114	#[transactional]1115	pub fn delete_collection_properties(1116		collection: &CollectionHandle<T>,1117		sender: &T::CrossAccountId,1118		property_keys: Vec<PropertyKey>,1119	) -> DispatchResult {1120		for key in property_keys {1121			Self::delete_collection_property(collection, sender, key)?;1122		}11231124		Ok(())1125	}11261127	/// Set collection propetry permission without any checks.1128	///1129	/// Used for migrations.1130	///1131	/// * `collection` - Collection handler.1132	/// * `property_permissions` - Property permissions.1133	pub fn set_property_permission_unchecked(1134		collection: CollectionId,1135		property_permission: PropertyKeyPermission,1136	) -> DispatchResult {1137		<CollectionPropertyPermissions<T>>::try_mutate(collection, |permissions| {1138			permissions.try_set(property_permission.key, property_permission.permission)1139		})1140		.map_err(<Error<T>>::from)?;1141		Ok(())1142	}11431144	/// Set collection property permission.1145	///1146	/// * `collection` - Collection handler.1147	/// * `sender` - The owner or administrator of the collection.1148	/// * `property_permission` - Property permission.1149	pub fn set_property_permission(1150		collection: &CollectionHandle<T>,1151		sender: &T::CrossAccountId,1152		property_permission: PropertyKeyPermission,1153	) -> DispatchResult {1154		Self::set_scoped_property_permission(1155			collection,1156			sender,1157			PropertyScope::None,1158			property_permission,1159		)1160	}11611162	/// Set collection property permission with scope.1163	///1164	/// * `collection` - Collection handler.1165	/// * `sender` - The owner or administrator of the collection.1166	/// * `scope` - Property scope.1167	/// * `property_permission` - Property permission.1168	pub fn set_scoped_property_permission(1169		collection: &CollectionHandle<T>,1170		sender: &T::CrossAccountId,1171		scope: PropertyScope,1172		property_permission: PropertyKeyPermission,1173	) -> DispatchResult {1174		collection.check_is_owner_or_admin(sender)?;11751176		let all_permissions = CollectionPropertyPermissions::<T>::get(collection.id);1177		let current_permission = all_permissions.get(&property_permission.key);1178		if matches![1179			current_permission,1180			Some(PropertyPermission { mutable: false, .. })1181		] {1182			return Err(<Error<T>>::NoPermission.into());1183		}11841185		CollectionPropertyPermissions::<T>::try_mutate(collection.id, |permissions| {1186			let property_permission = property_permission.clone();1187			permissions.try_scoped_set(1188				scope,1189				property_permission.key,1190				property_permission.permission,1191			)1192		})1193		.map_err(<Error<T>>::from)?;11941195		Self::deposit_event(Event::PropertyPermissionSet(1196			collection.id,1197			property_permission.key,1198		));11991200		Ok(())1201	}12021203	/// Set token property permission.1204	///1205	/// * `collection` - Collection handler.1206	/// * `sender` - The owner or administrator of the collection.1207	/// * `property_permissions` - Property permissions.1208	#[transactional]1209	pub fn set_token_property_permissions(1210		collection: &CollectionHandle<T>,1211		sender: &T::CrossAccountId,1212		property_permissions: Vec<PropertyKeyPermission>,1213	) -> DispatchResult {1214		Self::set_scoped_token_property_permissions(1215			collection,1216			sender,1217			PropertyScope::None,1218			property_permissions,1219		)1220	}12211222	/// Set token property permission with scope.1223	///1224	/// * `collection` - Collection handler.1225	/// * `sender` - The owner or administrator of the collection.1226	/// * `scope` - Property scope.1227	/// * `property_permissions` - Property permissions.1228	#[transactional]1229	pub fn set_scoped_token_property_permissions(1230		collection: &CollectionHandle<T>,1231		sender: &T::CrossAccountId,1232		scope: PropertyScope,1233		property_permissions: Vec<PropertyKeyPermission>,1234	) -> DispatchResult {1235		for prop_pemission in property_permissions {1236			Self::set_scoped_property_permission(collection, sender, scope, prop_pemission)?;1237		}12381239		Ok(())1240	}12411242	/// Get collection property.1243	pub fn get_collection_property(1244		collection_id: CollectionId,1245		key: &PropertyKey,1246	) -> Option<PropertyValue> {1247		Self::collection_properties(collection_id).get(key).cloned()1248	}12491250	/// Convert byte vector to property key vector.1251	pub fn bytes_keys_to_property_keys(1252		keys: Vec<Vec<u8>>,1253	) -> Result<Vec<PropertyKey>, DispatchError> {1254		keys.into_iter()1255			.map(|key| -> Result<PropertyKey, DispatchError> {1256				key.try_into()1257					.map_err(|_| <Error<T>>::PropertyKeyIsTooLong.into())1258			})1259			.collect::<Result<Vec<PropertyKey>, DispatchError>>()1260	}12611262	/// Get properties according to given keys.1263	pub fn filter_collection_properties(1264		collection_id: CollectionId,1265		keys: Option<Vec<PropertyKey>>,1266	) -> Result<Vec<Property>, DispatchError> {1267		let properties = Self::collection_properties(collection_id);12681269		let properties = keys1270			.map(|keys| {1271				keys.into_iter()1272					.filter_map(|key| {1273						properties.get(&key).map(|value| Property {1274							key,1275							value: value.clone(),1276						})1277					})1278					.collect()1279			})1280			.unwrap_or_else(|| {1281				properties1282					.into_iter()1283					.map(|(key, value)| Property { key, value })1284					.collect()1285			});12861287		Ok(properties)1288	}12891290	/// Get property permissions according to given keys.1291	pub fn filter_property_permissions(1292		collection_id: CollectionId,1293		keys: Option<Vec<PropertyKey>>,1294	) -> Result<Vec<PropertyKeyPermission>, DispatchError> {1295		let permissions = Self::property_permissions(collection_id);12961297		let key_permissions = keys1298			.map(|keys| {1299				keys.into_iter()1300					.filter_map(|key| {1301						permissions1302							.get(&key)1303							.map(|permission| PropertyKeyPermission {1304								key,1305								permission: permission.clone(),1306							})1307					})1308					.collect()1309			})1310			.unwrap_or_else(|| {1311				permissions1312					.into_iter()1313					.map(|(key, permission)| PropertyKeyPermission { key, permission })1314					.collect()1315			});13161317		Ok(key_permissions)1318	}13191320	/// Toggle `user` participation in the `collection`'s allow list.1321	/// #### Store read/writes1322	/// 1 writes1323	pub fn toggle_allowlist(1324		collection: &CollectionHandle<T>,1325		sender: &T::CrossAccountId,1326		user: &T::CrossAccountId,1327		allowed: bool,1328	) -> DispatchResult {1329		collection.check_is_owner_or_admin(sender)?;13301331		// =========13321333		if allowed {1334			<Allowlist<T>>::insert((collection.id, user), true);1335		} else {1336			<Allowlist<T>>::remove((collection.id, user));1337		}13381339		Ok(())1340	}13411342	/// Toggle `user` participation in the `collection`'s admin list.1343	/// #### Store read/writes1344	/// 2 writes1345	pub fn toggle_admin(1346		collection: &CollectionHandle<T>,1347		sender: &T::CrossAccountId,1348		user: &T::CrossAccountId,1349		admin: bool,1350	) -> DispatchResult {1351		collection.check_is_owner(sender)?;13521353		let was_admin = <IsAdmin<T>>::get((collection.id, user));1354		if was_admin == admin {1355			return Ok(());1356		}1357		let amount = <AdminAmount<T>>::get(collection.id);13581359		if admin {1360			let amount = amount1361				.checked_add(1)1362				.ok_or(<Error<T>>::CollectionAdminCountExceeded)?;1363			ensure!(1364				amount <= Self::collection_admins_limit(),1365				<Error<T>>::CollectionAdminCountExceeded,1366			);13671368			// =========13691370			<AdminAmount<T>>::insert(collection.id, amount);1371			<IsAdmin<T>>::insert((collection.id, user), true);1372		} else {1373			<AdminAmount<T>>::insert(collection.id, amount.saturating_sub(1));1374			<IsAdmin<T>>::remove((collection.id, user));1375		}13761377		Ok(())1378	}13791380	/// Merge set fields from `new_limit` to `old_limit`.1381	pub fn clamp_limits(1382		mode: CollectionMode,1383		old_limit: &CollectionLimits,1384		mut new_limit: CollectionLimits,1385	) -> Result<CollectionLimits, DispatchError> {1386		let limits = old_limit;1387		limit_default!(old_limit, new_limit,1388			account_token_ownership_limit => ensure!(1389				new_limit <= MAX_TOKEN_OWNERSHIP,1390				<Error<T>>::CollectionLimitBoundsExceeded,1391			),1392			sponsored_data_size => ensure!(1393				new_limit <= CUSTOM_DATA_LIMIT,1394				<Error<T>>::CollectionLimitBoundsExceeded,1395			),13961397			sponsored_data_rate_limit => {},1398			token_limit => ensure!(1399				old_limit >= new_limit && new_limit > 0,1400				<Error<T>>::CollectionTokenLimitExceeded1401			),14021403			sponsor_transfer_timeout(match mode {1404				CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,1405				CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,1406				CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,1407			}) => ensure!(1408				new_limit <= MAX_SPONSOR_TIMEOUT,1409				<Error<T>>::CollectionLimitBoundsExceeded,1410			),1411			sponsor_approve_timeout => {},1412			owner_can_transfer => ensure!(1413				!limits.owner_can_transfer_instaled() ||1414				old_limit || !new_limit,1415				<Error<T>>::OwnerPermissionsCantBeReverted,1416			),1417			owner_can_destroy => ensure!(1418				old_limit || !new_limit,1419				<Error<T>>::OwnerPermissionsCantBeReverted,1420			),1421			transfers_enabled => {},1422		);1423		Ok(new_limit)1424	}14251426	/// Merge set fields from `new_permission` to `old_permission`.1427	pub fn clamp_permissions(1428		_mode: CollectionMode,1429		old_permission: &CollectionPermissions,1430		mut new_permission: CollectionPermissions,1431	) -> Result<CollectionPermissions, DispatchError> {1432		limit_default_clone!(old_permission, new_permission,1433			access => {},1434			mint_mode => {},1435			nesting => { /* todo check for permissive, if only it gets out of benchmarks */ },1436		);1437		Ok(new_permission)1438	}1439}14401441/// Indicates unsupported methods by returning [Error::UnsupportedOperation].1442#[macro_export]1443macro_rules! unsupported {1444	($runtime:path) => {1445		Err($crate::Error::<$runtime>::UnsupportedOperation.into())1446	};1447}14481449/// Return weights for various worst-case operations.1450pub trait CommonWeightInfo<CrossAccountId> {1451	/// Weight of item creation.1452	fn create_item() -> Weight;14531454	/// Weight of items creation.1455	fn create_multiple_items(amount: &[CreateItemData]) -> Weight;14561457	/// Weight of items creation.1458	fn create_multiple_items_ex(cost: &CreateItemExData<CrossAccountId>) -> Weight;14591460	/// The weight of the burning item.1461	fn burn_item() -> Weight;14621463	/// Property setting weight.1464	///1465	/// * `amount`- The number of properties to set.1466	fn set_collection_properties(amount: u32) -> Weight;14671468	/// Collection property deletion weight.1469	///1470	/// * `amount`- The number of properties to set.1471	fn delete_collection_properties(amount: u32) -> Weight;14721473	/// Token property setting weight.1474	///1475	/// * `amount`- The number of properties to set.1476	fn set_token_properties(amount: u32) -> Weight;14771478	/// Token property deletion weight.1479	///1480	/// * `amount`- The number of properties to delete.1481	fn delete_token_properties(amount: u32) -> Weight;14821483	/// Token property permissions set weight.1484	///1485	/// * `amount`- The number of property permissions to set.1486	fn set_token_property_permissions(amount: u32) -> Weight;14871488	/// Transfer price of the token or its parts.1489	fn transfer() -> Weight;14901491	/// The price of setting the permission of the operation from another user.1492	fn approve() -> Weight;14931494	/// Transfer price from another user.1495	fn transfer_from() -> Weight;14961497	/// The price of burning a token from another user.1498	fn burn_from() -> Weight;14991500	/// Differs from burn_item in case of Fungible and Refungible, as it should burn1501	/// whole users's balance.1502	///1503	/// This method shouldn't be used directly, as it doesn't count breadth price, use [burn_recursively](CommonWeightInfo::burn_recursively) instead1504	fn burn_recursively_self_raw() -> Weight;15051506	/// Cost of iterating over `amount` children while burning, without counting child burning itself.1507	///1508	/// This method shouldn't be used directly, as it doesn't count depth price, use [burn_recursively](CommonWeightInfo::burn_recursively) instead1509	fn burn_recursively_breadth_raw(amount: u32) -> Weight;15101511	/// The price of recursive burning a token.1512	///1513	/// `max_selfs` - The maximum burning weight of the token itself.1514	/// `max_breadth` - The maximum number of nested tokens to burn.1515	fn burn_recursively(max_selfs: u32, max_breadth: u32) -> Weight {1516		Self::burn_recursively_self_raw()1517			.saturating_mul(max_selfs.max(1) as u64)1518			.saturating_add(Self::burn_recursively_breadth_raw(max_breadth))1519	}15201521	/// The price of retrieving token owner1522	fn token_owner() -> Weight;1523}15241525/// Weight info extension trait for refungible pallet.1526pub trait RefungibleExtensionsWeightInfo {1527	/// Weight of token repartition.1528	fn repartition() -> Weight;1529}15301531/// Common collection operations.1532///1533/// It wraps methods in Fungible, Nonfungible and Refungible pallets1534/// and adds weight info.1535pub trait CommonCollectionOperations<T: Config> {1536	/// Create token.1537	///1538	/// * `sender` - The user who mint the token and pays for the transaction.1539	/// * `to` - The user who will own the token.1540	/// * `data` - Token data.1541	/// * `nesting_budget` - A budget that can be spent on nesting tokens.1542	fn create_item(1543		&self,1544		sender: T::CrossAccountId,1545		to: T::CrossAccountId,1546		data: CreateItemData,1547		nesting_budget: &dyn Budget,1548	) -> DispatchResultWithPostInfo;15491550	/// Create multiple tokens.1551	///1552	/// * `sender` - The user who mint the token and pays for the transaction.1553	/// * `to` - The user who will own the token.1554	/// * `data` - Token data.1555	/// * `nesting_budget` - A budget that can be spent on nesting tokens.1556	fn create_multiple_items(1557		&self,1558		sender: T::CrossAccountId,1559		to: T::CrossAccountId,1560		data: Vec<CreateItemData>,1561		nesting_budget: &dyn Budget,1562	) -> DispatchResultWithPostInfo;15631564	/// Create multiple tokens.1565	///1566	/// * `sender` - The user who mint the token and pays for the transaction.1567	/// * `to` - The user who will own the token.1568	/// * `data` - Token data.1569	/// * `nesting_budget` - A budget that can be spent on nesting tokens.1570	fn create_multiple_items_ex(1571		&self,1572		sender: T::CrossAccountId,1573		data: CreateItemExData<T::CrossAccountId>,1574		nesting_budget: &dyn Budget,1575	) -> DispatchResultWithPostInfo;15761577	/// Burn token.1578	///1579	/// * `sender` - The user who owns the token.1580	/// * `token` - Token id that will burned.1581	/// * `amount` - The number of parts of the token that will be burned.1582	fn burn_item(1583		&self,1584		sender: T::CrossAccountId,1585		token: TokenId,1586		amount: u128,1587	) -> DispatchResultWithPostInfo;15881589	/// Burn token and all nested tokens recursievly.1590	///1591	/// * `sender` - The user who owns the token.1592	/// * `token` - Token id that will burned.1593	/// * `self_budget` - The budget that can be spent on burning tokens.1594	/// * `breadth_budget` - The budget that can be spent on burning nested tokens.1595	fn burn_item_recursively(1596		&self,1597		sender: T::CrossAccountId,1598		token: TokenId,1599		self_budget: &dyn Budget,1600		breadth_budget: &dyn Budget,1601	) -> DispatchResultWithPostInfo;16021603	/// Set collection properties.1604	///1605	/// * `sender` - Must be either the owner of the collection or its admin.1606	/// * `properties` - Properties to be set.1607	fn set_collection_properties(1608		&self,1609		sender: T::CrossAccountId,1610		properties: Vec<Property>,1611	) -> DispatchResultWithPostInfo;16121613	/// Delete collection properties.1614	///1615	/// * `sender` - Must be either the owner of the collection or its admin.1616	/// * `properties` - The properties to be removed.1617	fn delete_collection_properties(1618		&self,1619		sender: &T::CrossAccountId,1620		property_keys: Vec<PropertyKey>,1621	) -> DispatchResultWithPostInfo;16221623	/// Set token properties.1624	///1625	/// The appropriate [`PropertyPermission`] for the token property1626	/// must be set with [`Self::set_token_property_permissions`].1627	///1628	/// * `sender` - Must be either the owner of the token or its admin.1629	/// * `token_id` - The token for which the properties are being set.1630	/// * `properties` - Properties to be set.1631	/// * `budget` - Budget for setting properties.1632	fn set_token_properties(1633		&self,1634		sender: T::CrossAccountId,1635		token_id: TokenId,1636		properties: Vec<Property>,1637		budget: &dyn Budget,1638	) -> DispatchResultWithPostInfo;16391640	/// Remove token properties.1641	///1642	/// The appropriate [`PropertyPermission`] for the token property1643	/// must be set with [`Self::set_token_property_permissions`].1644	///1645	/// * `sender` - Must be either the owner of the token or its admin.1646	/// * `token_id` - The token for which the properties are being remove.1647	/// * `property_keys` - Keys to remove corresponding properties.1648	/// * `budget` - Budget for removing properties.1649	fn delete_token_properties(1650		&self,1651		sender: T::CrossAccountId,1652		token_id: TokenId,1653		property_keys: Vec<PropertyKey>,1654		budget: &dyn Budget,1655	) -> DispatchResultWithPostInfo;16561657	/// Set token property permissions.1658	///1659	/// * `sender` - Must be either the owner of the token or its admin.1660	/// * `token_id` - The token for which the properties are being set.1661	/// * `property_permissions` - Property permissions to be set.1662	/// * `budget` - Budget for setting properties.1663	fn set_token_property_permissions(1664		&self,1665		sender: &T::CrossAccountId,1666		property_permissions: Vec<PropertyKeyPermission>,1667	) -> DispatchResultWithPostInfo;16681669	/// Transfer amount of token pieces.1670	///1671	/// * `sender` - Donor user.1672	/// * `to` - Recepient user.1673	/// * `token` - The token of which parts are being sent.1674	/// * `amount` - The number of parts of the token that will be transferred.1675	/// * `budget` - The maximum budget that can be spent on the transfer.1676	fn transfer(1677		&self,1678		sender: T::CrossAccountId,1679		to: T::CrossAccountId,1680		token: TokenId,1681		amount: u128,1682		budget: &dyn Budget,1683	) -> DispatchResultWithPostInfo;16841685	/// Grant access to another account to transfer parts of the token owned by the calling user via [Self::transfer_from].1686	///1687	/// * `sender` - The user who grants access to the token.1688	/// * `spender` - The user to whom the rights are granted.1689	/// * `token` - The token to which access is granted.1690	/// * `amount` - The amount of pieces that another user can dispose of.1691	fn approve(1692		&self,1693		sender: T::CrossAccountId,1694		spender: T::CrossAccountId,1695		token: TokenId,1696		amount: u128,1697	) -> DispatchResultWithPostInfo;16981699	/// Send parts of a token owned by another user.1700	///1701	/// Before calling this method, you must grant rights to the calling user via [`Self::approve`].1702	///1703	/// * `sender` - The user who must have access to the token (see [`Self::approve`]).1704	/// * `from` - The user who owns the token.1705	/// * `to` - Recepient user.1706	/// * `token` - The token of which parts are being sent.1707	/// * `amount` - The number of parts of the token that will be transferred.1708	/// * `budget` - The maximum budget that can be spent on the transfer.1709	fn transfer_from(1710		&self,1711		sender: T::CrossAccountId,1712		from: T::CrossAccountId,1713		to: T::CrossAccountId,1714		token: TokenId,1715		amount: u128,1716		budget: &dyn Budget,1717	) -> DispatchResultWithPostInfo;17181719	/// Burn parts of a token owned by another user.1720	///1721	/// Before calling this method, you must grant rights to the calling user via [`Self::approve`].1722	///1723	/// * `sender` - The user who must have access to the token (see [`Self::approve`]).1724	/// * `from` - The user who owns the token.1725	/// * `token` - The token of which parts are being sent.1726	/// * `amount` - The number of parts of the token that will be transferred.1727	/// * `budget` - The maximum budget that can be spent on the burn.1728	fn burn_from(1729		&self,1730		sender: T::CrossAccountId,1731		from: T::CrossAccountId,1732		token: TokenId,1733		amount: u128,1734		budget: &dyn Budget,1735	) -> DispatchResultWithPostInfo;17361737	/// Check permission to nest token.1738	///1739	/// * `sender` - The user who initiated the check.1740	/// * `from` - The token that is checked for embedding.1741	/// * `under` - Token under which to check.1742	/// * `budget` - The maximum budget that can be spent on the check.1743	fn check_nesting(1744		&self,1745		sender: T::CrossAccountId,1746		from: (CollectionId, TokenId),1747		under: TokenId,1748		budget: &dyn Budget,1749	) -> DispatchResult;17501751	/// Nest one token into another.1752	///1753	/// * `under` - Token holder.1754	/// * `to_nest` - Nested token.1755	fn nest(&self, under: TokenId, to_nest: (CollectionId, TokenId));17561757	/// Unnest token.1758	///1759	/// * `under` - Token holder.1760	/// * `to_nest` - Token to unnest.1761	fn unnest(&self, under: TokenId, to_nest: (CollectionId, TokenId));17621763	/// Get all user tokens.1764	///1765	/// * `account` - Account for which you need to get tokens.1766	fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId>;17671768	/// Get all the tokens in the collection.1769	fn collection_tokens(&self) -> Vec<TokenId>;17701771	/// Check if the token exists.1772	///1773	/// * `token` - Id token to check.1774	fn token_exists(&self, token: TokenId) -> bool;17751776	/// Get the id of the last minted token.1777	fn last_token_id(&self) -> TokenId;17781779	/// Get the owner of the token.1780	///1781	/// * `token` - The token for which you need to find out the owner.1782	fn token_owner(&self, token: TokenId) -> Option<T::CrossAccountId>;17831784	/// Returns 10 tokens owners in no particular order.1785	///1786	/// * `token` - The token for which you need to find out the owners.1787	fn token_owners(&self, token: TokenId) -> Vec<T::CrossAccountId>;17881789	/// Get the value of the token property by key.1790	///1791	/// * `token` - Token with the property to get.1792	/// * `key` - Property name.1793	fn token_property(&self, token_id: TokenId, key: &PropertyKey) -> Option<PropertyValue>;17941795	/// Get a set of token properties by key vector.1796	///1797	/// * `token` - Token with the property to get.1798	/// * `keys` - Vector of property keys. If this parameter is [None](sp_std::result::Result),1799	/// then all properties are returned.1800	fn token_properties(&self, token: TokenId, keys: Option<Vec<PropertyKey>>) -> Vec<Property>;18011802	/// Amount of unique collection tokens1803	fn total_supply(&self) -> u32;18041805	/// Amount of different tokens account has.1806	///1807	/// * `account` - The account for which need to get the balance.1808	fn account_balance(&self, account: T::CrossAccountId) -> u32;18091810	/// Amount of specific token account have.1811	fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128;18121813	/// Amount of token pieces1814	fn total_pieces(&self, token: TokenId) -> Option<u128>;18151816	/// Get the number of parts of the token that a trusted user can manage.1817	///1818	/// * `sender` - Trusted user.1819	/// * `spender` - Owner of the token.1820	/// * `token` - The token for which to get the value.1821	fn allowance(1822		&self,1823		sender: T::CrossAccountId,1824		spender: T::CrossAccountId,1825		token: TokenId,1826	) -> u128;18271828	/// Get extension for RFT collection.1829	fn refungible_extensions(&self) -> Option<&dyn RefungibleExtensions<T>>;1830}18311832/// Extension for RFT collection.1833pub trait RefungibleExtensions<T>1834where1835	T: Config,1836{1837	/// Change the number of parts of the token.1838	///1839	/// When the value changes down, this function is equivalent to burning parts of the token.1840	///1841	/// * `sender` - The user calling the repartition operation. Must be the owner of the token.1842	/// * `token` - The token for which you want to change the number of parts.1843	/// * `amount` - The new value of the parts of the token.1844	fn repartition(1845		&self,1846		sender: &T::CrossAccountId,1847		token: TokenId,1848		amount: u128,1849	) -> DispatchResultWithPostInfo;1850}18511852/// Merge [`DispatchResult`] with [`Weight`] into [`DispatchResultWithPostInfo`].1853///1854/// Used for [`CommonCollectionOperations`] implementations and flexible enough to do so.1855pub fn with_weight(res: DispatchResult, weight: Weight) -> DispatchResultWithPostInfo {1856	let post_info = PostDispatchInfo {1857		actual_weight: Some(weight),1858		pays_fee: Pays::Yes,1859	};1860	match res {1861		Ok(()) => Ok(post_info),1862		Err(error) => Err(DispatchErrorWithPostInfo { post_info, error }),1863	}1864}18651866impl<T: Config> From<PropertiesError> for Error<T> {1867	fn from(error: PropertiesError) -> Self {1868		match error {1869			PropertiesError::NoSpaceForProperty => Self::NoSpaceForProperty,1870			PropertiesError::PropertyLimitReached => Self::PropertyLimitReached,1871			PropertiesError::InvalidCharacterInPropertyKey => Self::InvalidCharacterInPropertyKey,1872			PropertiesError::PropertyKeyIsTooLong => Self::PropertyKeyIsTooLong,1873			PropertiesError::EmptyPropertyKey => Self::EmptyPropertyKey,1874		}1875	}1876}
modifiedpallets/configuration/Cargo.tomldiffbeforeafterboth
--- a/pallets/configuration/Cargo.toml
+++ b/pallets/configuration/Cargo.toml
@@ -16,7 +16,7 @@
 sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-arithmetic = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 smallvec = "1.6.1"
 
 [features]
modifiedpallets/evm-coder-substrate/Cargo.tomldiffbeforeafterboth
--- a/pallets/evm-coder-substrate/Cargo.toml
+++ b/pallets/evm-coder-substrate/Cargo.toml
@@ -12,8 +12,8 @@
 sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 ethereum = { version = "0.12.0", default-features = false }
 evm-coder = { default-features = false, path = "../../crates/evm-coder" }
-pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
modifiedpallets/evm-contract-helpers/Cargo.tomldiffbeforeafterboth
--- a/pallets/evm-contract-helpers/Cargo.toml
+++ b/pallets/evm-contract-helpers/Cargo.toml
@@ -19,8 +19,8 @@
 sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 
 # Unique
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.30" }
 
 # Locals
modifiedpallets/evm-contract-helpers/src/lib.rsdiffbeforeafterboth
--- a/pallets/evm-contract-helpers/src/lib.rs
+++ b/pallets/evm-contract-helpers/src/lib.rs
@@ -41,7 +41,7 @@
 
 	#[pallet::config]
 	pub trait Config:
-		frame_system::Config + pallet_evm_coder_substrate::Config + pallet_evm::account::Config
+		frame_system::Config + pallet_evm_coder_substrate::Config + pallet_evm::Config
 	{
 		/// Overarching event type.
 		type RuntimeEvent: IsType<<Self as frame_system::Config>::RuntimeEvent> + From<Event<Self>>;
modifiedpallets/evm-migration/Cargo.tomldiffbeforeafterboth
--- a/pallets/evm-migration/Cargo.toml
+++ b/pallets/evm-migration/Cargo.toml
@@ -16,8 +16,8 @@
 sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 
 [dependencies.codec]
 default-features = false
modifiedpallets/evm-transaction-payment/Cargo.tomldiffbeforeafterboth
--- a/pallets/evm-transaction-payment/Cargo.toml
+++ b/pallets/evm-transaction-payment/Cargo.toml
@@ -14,11 +14,11 @@
 sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.30" }
-fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 
 [dependencies.codec]
 default-features = false
modifiedpallets/evm-transaction-payment/src/lib.rsdiffbeforeafterboth
--- a/pallets/evm-transaction-payment/src/lib.rs
+++ b/pallets/evm-transaction-payment/src/lib.rs
@@ -44,7 +44,7 @@
 	}
 
 	#[pallet::config]
-	pub trait Config: frame_system::Config + pallet_evm::account::Config {
+	pub trait Config: frame_system::Config + pallet_evm::Config {
 		/// Loosly-coupled handlers for evm call sponsoring
 		type EvmSponsorshipHandler: SponsorshipHandler<Self::CrossAccountId, CallContext>;
 	}
modifiedpallets/fungible/Cargo.tomldiffbeforeafterboth
--- a/pallets/fungible/Cargo.toml
+++ b/pallets/fungible/Cargo.toml
@@ -23,7 +23,7 @@
 pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' }
 ethereum = { version = "0.12.0", default-features = false }
 frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 scale-info = { version = "2.0.1", default-features = false, features = [
     "derive",
 ] }
modifiedpallets/fungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/fungible/src/lib.rs
+++ b/pallets/fungible/src/lib.rs
@@ -106,7 +106,7 @@
 pub mod erc;
 pub mod weights;
 
-pub type CreateItemData<T> = (<T as pallet_evm::account::Config>::CrossAccountId, u128);
+pub type CreateItemData<T> = (<T as pallet_evm::Config>::CrossAccountId, u128);
 pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;
 
 #[frame_support::pallet]
modifiedpallets/nonfungible/Cargo.tomldiffbeforeafterboth
--- a/pallets/nonfungible/Cargo.toml
+++ b/pallets/nonfungible/Cargo.toml
@@ -16,7 +16,7 @@
 sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 pallet-common = { default-features = false, path = '../common' }
 pallet-structure = { default-features = false, path = '../structure' }
 up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -127,7 +127,7 @@
 pub mod erc;
 pub mod weights;
 
-pub type CreateItemData<T> = CreateNftExData<<T as pallet_evm::account::Config>::CrossAccountId>;
+pub type CreateItemData<T> = CreateNftExData<<T as pallet_evm::Config>::CrossAccountId>;
 pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;
 
 /// Token data, stored independently from other data used to describe it
modifiedpallets/proxy-rmrk-core/Cargo.tomldiffbeforeafterboth
--- a/pallets/proxy-rmrk-core/Cargo.toml
+++ b/pallets/proxy-rmrk-core/Cargo.toml
@@ -20,7 +20,7 @@
 pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" }
 pallet-structure = { default-features = false, path = "../../pallets/structure" }
 up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 rmrk-traits = { default-features = false, path = "../../primitives/rmrk-traits" }
 scale-info = { version = "2.0.1", default-features = false, features = [
modifiedpallets/proxy-rmrk-core/src/lib.rsdiffbeforeafterboth
--- a/pallets/proxy-rmrk-core/src/lib.rs
+++ b/pallets/proxy-rmrk-core/src/lib.rs
@@ -190,11 +190,13 @@
 #[frame_support::pallet]
 pub mod pallet {
 	use super::*;
-	use pallet_evm::account;
 
 	#[pallet::config]
 	pub trait Config:
-		frame_system::Config + pallet_common::Config + pallet_nonfungible::Config + account::Config
+		frame_system::Config
+		+ pallet_common::Config
+		+ pallet_nonfungible::Config
+		+ pallet_evm::Config
 	{
 		/// Overarching event type.
 		type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
modifiedpallets/proxy-rmrk-equip/Cargo.tomldiffbeforeafterboth
--- a/pallets/proxy-rmrk-equip/Cargo.toml
+++ b/pallets/proxy-rmrk-equip/Cargo.toml
@@ -19,7 +19,7 @@
 pallet-common = { default-features = false, path = '../common' }
 pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" }
 up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 rmrk-traits = { default-features = false, path = "../../primitives/rmrk-traits" }
 scale-info = { version = "2.0.1", default-features = false, features = [
modifiedpallets/refungible/Cargo.tomldiffbeforeafterboth
--- a/pallets/refungible/Cargo.toml
+++ b/pallets/refungible/Cargo.toml
@@ -16,7 +16,7 @@
 sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 evm-coder = { default-features = false, path = '../../crates/evm-coder' }
 pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }
 pallet-common = { default-features = false, path = '../common' }
modifiedpallets/structure/Cargo.tomldiffbeforeafterboth
--- a/pallets/structure/Cargo.toml
+++ b/pallets/structure/Cargo.toml
@@ -16,7 +16,7 @@
 	"derive",
 ] }
 up-data-structs = { path = "../../primitives/data-structs", default-features = false }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 
 [features]
 default = ["std"]
modifiedpallets/unique/Cargo.tomldiffbeforeafterboth
--- a/pallets/unique/Cargo.toml
+++ b/pallets/unique/Cargo.toml
@@ -100,7 +100,7 @@
 scale-info = { version = "2.0.1", default-features = false, features = [
     "derive",
 ] }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 pallet-common = { default-features = false, path = "../common" }
 evm-coder = { default-features = false, path = '../../crates/evm-coder' }
 pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }
modifiedpallets/unique/src/lib.rsdiffbeforeafterboth
--- a/pallets/unique/src/lib.rs
+++ b/pallets/unique/src/lib.rs
@@ -138,7 +138,7 @@
 	pub enum Event<T>
 	where
 		<T as frame_system::Config>::AccountId,
-		<T as pallet_evm::account::Config>::CrossAccountId,
+		<T as pallet_evm::Config>::CrossAccountId,
 	{
 		/// Collection sponsor was removed
 		///
modifiedprimitives/app_promotion_rpc/Cargo.tomldiffbeforeafterboth
--- a/primitives/app_promotion_rpc/Cargo.toml
+++ b/primitives/app_promotion_rpc/Cargo.toml
@@ -14,7 +14,7 @@
 sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 
 [features]
 default = ["std"]
modifiedprimitives/common/Cargo.tomldiffbeforeafterboth
--- a/primitives/common/Cargo.toml
+++ b/primitives/common/Cargo.toml
@@ -48,9 +48,9 @@
 [dependencies.fp-rpc]
 default-features = false
 git = "https://github.com/uniquenetwork/frontier"
-branch = "unique-polkadot-v0.9.30"
+branch = "unique-polkadot-v0.9.30-2"
 
 [dependencies.pallet-evm]
 default-features = false
 git = "https://github.com/uniquenetwork/frontier"
-branch = "unique-polkadot-v0.9.30"
+branch = "unique-polkadot-v0.9.30-2"
modifiedprimitives/data-structs/Cargo.tomldiffbeforeafterboth
--- a/primitives/data-structs/Cargo.toml
+++ b/primitives/data-structs/Cargo.toml
@@ -25,9 +25,11 @@
 sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 derivative = { version = "2.2.0", features = ["use_core"] }
 struct-versioning = { path = "../../crates/struct-versioning" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 rmrk-traits = { default-features = false, path = "../rmrk-traits" }
-bondrewd = { version = "0.1.14", features = ["derive"], default-features = false }
+bondrewd = { version = "0.1.14", features = [
+  "derive",
+], default-features = false }
 
 [features]
 default = ["std"]
modifiedprimitives/data-structs/src/lib.rsdiffbeforeafterboth
--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -962,12 +962,15 @@
 		use scale_info::{
 			Type, Path,
 			build::{FieldsBuilder, UnnamedFields},
+			form::MetaForm,
 			type_params,
 		};
 		Type::builder()
 			.path(Path::new("up_data_structs", "PhantomType"))
 			.type_params(type_params!(T))
-			.composite(<FieldsBuilder<UnnamedFields>>::default().field(|b| b.ty::<[T; 0]>()))
+			.composite(
+				<FieldsBuilder<MetaForm, UnnamedFields>>::default().field(|b| b.ty::<[T; 0]>()),
+			)
 	}
 }
 impl<T> MaxEncodedLen for PhantomType<T> {
modifiedprimitives/rpc/Cargo.tomldiffbeforeafterboth
--- a/primitives/rpc/Cargo.toml
+++ b/primitives/rpc/Cargo.toml
@@ -14,7 +14,7 @@
 sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 
 [features]
 default = ["std"]
modifiedruntime/common/config/ethereum.rsdiffbeforeafterboth
--- a/runtime/common/config/ethereum.rs
+++ b/runtime/common/config/ethereum.rs
@@ -17,19 +17,15 @@
 
 pub type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Runtime>;
 
-impl pallet_evm::account::Config for Runtime {
-	type CrossAccountId = CrossAccountId;
-	type EvmAddressMapping = pallet_evm::HashedAddressMapping<Self::Hashing>;
-	type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;
-}
-
 // Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case
 // (contract, which only writes a lot of data),
 // approximating on top of our real store write weight
 parameter_types! {
 	pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND.ref_time() / <Runtime as frame_system::Config>::DbWeight::get().write;
 	pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000;
-	pub const WeightPerGas: u64 = WEIGHT_PER_SECOND.ref_time() / GasPerSecond::get();
+	pub const WeightTimePerGas: u64 = WEIGHT_PER_SECOND.ref_time() / GasPerSecond::get();
+
+	pub const WeightPerGas: Weight = Weight::from_ref_time(WeightTimePerGas::get());
 }
 
 /// Limiting EVM execution to 50% of block for substrate users and management tasks
@@ -37,17 +33,7 @@
 /// scheduled fairly
 const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50);
 parameter_types! {
-	pub BlockGasLimit: U256 = U256::from((NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get()).ref_time());
-}
-
-pub enum FixedGasWeightMapping {}
-impl pallet_evm::GasWeightMapping for FixedGasWeightMapping {
-	fn gas_to_weight(gas: u64) -> Weight {
-		Weight::from_ref_time(gas).saturating_mul(WeightPerGas::get())
-	}
-	fn weight_to_gas(weight: Weight) -> u64 {
-		(weight / WeightPerGas::get()).ref_time()
-	}
+	pub BlockGasLimit: U256 = U256::from((NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightTimePerGas::get()).ref_time());
 }
 
 pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);
@@ -65,9 +51,13 @@
 }
 
 impl pallet_evm::Config for Runtime {
+	type CrossAccountId = CrossAccountId;
+	type EvmAddressMapping = pallet_evm::HashedAddressMapping<Self::Hashing>;
+	type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;
 	type BlockGasLimit = BlockGasLimit;
 	type FeeCalculator = pallet_configuration::FeeCalculator<Self>;
-	type GasWeightMapping = FixedGasWeightMapping;
+	type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
+	type WeightPerGas = WeightPerGas;
 	type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;
 	type CallOrigin = EnsureAddressTruncated<Self>;
 	type WithdrawOrigin = EnsureAddressTruncated<Self>;
modifiedruntime/common/ethereum/self_contained_call.rsdiffbeforeafterboth
--- a/runtime/common/ethereum/self_contained_call.rs
+++ b/runtime/common/ethereum/self_contained_call.rs
@@ -69,9 +69,13 @@
 	fn pre_dispatch_self_contained(
 		&self,
 		info: &Self::SignedInfo,
+		dispatch_info: &DispatchInfoOf<RuntimeCall>,
+		len: usize,
 	) -> Option<Result<(), TransactionValidityError>> {
 		match self {
-			RuntimeCall::Ethereum(call) => call.pre_dispatch_self_contained(info),
+			RuntimeCall::Ethereum(call) => {
+				call.pre_dispatch_self_contained(info, dispatch_info, len)
+			}
 			_ => None,
 		}
 	}
modifiedruntime/common/runtime_apis.rsdiffbeforeafterboth
--- a/runtime/common/runtime_apis.rs
+++ b/runtime/common/runtime_apis.rs
@@ -493,6 +493,7 @@
                         nonce,
                         access_list.unwrap_or_default(),
                         is_transactional,
+                        false,
                         config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),
                     ).map_err(|err| err.error.into())
                 }
@@ -528,6 +529,7 @@
                         nonce,
                         access_list.unwrap_or_default(),
                         is_transactional,
+                        false,
                         config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),
                     ).map_err(|err| err.error.into())
                 }
modifiedruntime/opal/Cargo.tomldiffbeforeafterboth
--- a/runtime/opal/Cargo.toml
+++ b/runtime/opal/Cargo.toml
@@ -82,7 +82,6 @@
     'pallet-proxy-rmrk-equip/try-runtime',
     'pallet-app-promotion/try-runtime',
     'pallet-foreign-assets/try-runtime',
-    'pallet-evm/try-runtime',
     'pallet-ethereum/try-runtime',
     'pallet-evm-coder-substrate/try-runtime',
     'pallet-evm-contract-helpers/try-runtime',
@@ -174,7 +173,14 @@
     'pallet-test-utils?/std',
 ]
 limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing']
-opal-runtime = ['refungible', 'scheduler', 'rmrk', 'app-promotion', 'foreign-assets', 'pallet-test-utils']
+opal-runtime = [
+    'refungible',
+    'scheduler',
+    'rmrk',
+    'app-promotion',
+    'foreign-assets',
+    'pallet-test-utils',
+]
 
 refungible = []
 scheduler = []
@@ -461,7 +467,7 @@
 up-rpc = { path = "../../primitives/rpc", default-features = false }
 app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false }
 rmrk-rpc = { path = "../../primitives/rmrk-rpc", default-features = false }
-fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 pallet-inflation = { path = '../../pallets/inflation', default-features = false }
 pallet-app-promotion = { path = '../../pallets/app-promotion', default-features = false }
 up-data-structs = { path = '../../primitives/data-structs', default-features = false }
@@ -479,11 +485,11 @@
 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, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 evm-coder = { default-features = false, path = '../../crates/evm-coder' }
 up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.30' }
 pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" }
modifiedruntime/quartz/Cargo.tomldiffbeforeafterboth
--- a/runtime/quartz/Cargo.toml
+++ b/runtime/quartz/Cargo.toml
@@ -80,7 +80,6 @@
     'pallet-proxy-rmrk-equip/try-runtime',
     'pallet-app-promotion/try-runtime',
     'pallet-foreign-assets/try-runtime',
-    'pallet-evm/try-runtime',
     'pallet-ethereum/try-runtime',
     'pallet-evm-coder-substrate/try-runtime',
     'pallet-evm-contract-helpers/try-runtime',
@@ -460,7 +459,7 @@
 pallet-unique = { path = '../../pallets/unique', default-features = false }
 up-rpc = { path = "../../primitives/rpc", default-features = false }
 app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false }
-fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 pallet-inflation = { path = '../../pallets/inflation', default-features = false }
 pallet-app-promotion = { path = '../../pallets/app-promotion', default-features = false }
 up-data-structs = { path = '../../primitives/data-structs', default-features = false }
@@ -478,11 +477,11 @@
 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, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 evm-coder = { default-features = false, path = '../../crates/evm-coder' }
 up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.30' }
 pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" }
modifiedruntime/tests/Cargo.tomldiffbeforeafterboth
--- a/runtime/tests/Cargo.toml
+++ b/runtime/tests/Cargo.toml
@@ -16,7 +16,7 @@
 sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 
-fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 
 frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
@@ -25,8 +25,8 @@
 pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
 
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 
 pallet-common = { path = '../../pallets/common' }
 pallet-structure = { path = '../../pallets/structure' }
modifiedruntime/tests/src/lib.rsdiffbeforeafterboth
--- a/runtime/tests/src/lib.rs
+++ b/runtime/tests/src/lib.rs
@@ -21,6 +21,7 @@
 	parameter_types,
 	traits::{Everything, ConstU32, ConstU64},
 	weights::IdentityFee,
+	pallet_prelude::Weight,
 };
 use sp_runtime::{
 	traits::{BlakeTwo256, IdentityLookup},
@@ -202,6 +203,7 @@
 
 parameter_types! {
 	pub BlockGasLimit: U256 = 0u32.into();
+	pub WeightPerGas: Weight = Weight::from_ref_time(20);
 }
 
 impl pallet_ethereum::Config for Test {
@@ -210,11 +212,15 @@
 }
 
 impl pallet_evm::Config for Test {
+	type CrossAccountId = TestCrossAccountId;
+	type EvmAddressMapping = TestEvmAddressMapping;
+	type EvmBackwardsAddressMapping = TestEvmBackwardsAddressMapping;
 	type RuntimeEvent = RuntimeEvent;
 	type FeeCalculator = ();
-	type GasWeightMapping = ();
-	type CallOrigin = EnsureAddressNever<Self::CrossAccountId>;
-	type WithdrawOrigin = EnsureAddressNever<Self::CrossAccountId>;
+	type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
+	type WeightPerGas = WeightPerGas;
+	type CallOrigin = EnsureAddressNever<Self>;
+	type WithdrawOrigin = EnsureAddressNever<Self>;
 	type AddressMapping = TestEvmAddressMapping;
 	type Currency = Balances;
 	type PrecompilesType = ();
@@ -242,12 +248,6 @@
 	type EvmTokenAddressMapping = EvmTokenAddressMapping;
 	type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;
 	type ContractAddress = EvmCollectionHelpersAddress;
-}
-
-impl pallet_evm::account::Config for Test {
-	type CrossAccountId = TestCrossAccountId;
-	type EvmAddressMapping = TestEvmAddressMapping;
-	type EvmBackwardsAddressMapping = TestEvmBackwardsAddressMapping;
 }
 
 impl pallet_structure::Config for Test {
modifiedruntime/unique/Cargo.tomldiffbeforeafterboth
--- a/runtime/unique/Cargo.toml
+++ b/runtime/unique/Cargo.toml
@@ -81,7 +81,6 @@
     'pallet-proxy-rmrk-equip/try-runtime',
     'pallet-app-promotion/try-runtime',
     'pallet-foreign-assets/try-runtime',
-    'pallet-evm/try-runtime',
     'pallet-ethereum/try-runtime',
     'pallet-evm-coder-substrate/try-runtime',
     'pallet-evm-contract-helpers/try-runtime',
@@ -472,12 +471,12 @@
 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, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
 evm-coder = { default-features = false, path = '../../crates/evm-coder' }
 up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.30' }
 pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" }
modifiedtests/src/eth/contractSponsoring.test.tsdiffbeforeafterboth
--- a/tests/src/eth/contractSponsoring.test.ts
+++ b/tests/src/eth/contractSponsoring.test.ts
@@ -372,7 +372,7 @@
     const originalFlipperBalance = await helper.balance.getEthereum(flipper.options.address);
     expect(originalFlipperBalance).to.be.not.equal('0');
 
-    await expect(flipper.methods.flip().send({from: caller})).to.be.rejectedWith(/InvalidTransaction::Payment/);
+    await expect(flipper.methods.flip().send({from: caller})).to.be.rejectedWith(/Returned error: insufficient funds for gas \* price \+ value/);
     expect(await flipper.methods.getValue().call()).to.be.false;
 
     // Balance should be taken from flipper instead of caller
modifiedtests/src/interfaces/augment-api-errors.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-errors.ts
+++ b/tests/src/interfaces/augment-api-errors.ts
@@ -265,6 +265,14 @@
        **/
       FeeOverflow: AugmentedError<ApiType>;
       /**
+       * Gas limit is too high.
+       **/
+      GasLimitTooHigh: AugmentedError<ApiType>;
+      /**
+       * Gas limit is too low.
+       **/
+      GasLimitTooLow: AugmentedError<ApiType>;
+      /**
        * Gas price is too low.
        **/
       GasPriceTooLow: AugmentedError<ApiType>;
@@ -277,6 +285,14 @@
        **/
       PaymentOverflow: AugmentedError<ApiType>;
       /**
+       * EVM reentrancy
+       **/
+      Reentrancy: AugmentedError<ApiType>;
+      /**
+       * Undefined error.
+       **/
+      Undefined: AugmentedError<ApiType>;
+      /**
        * Withdraw fee failed
        **/
       WithdrawFailed: AugmentedError<ApiType>;
modifiedtests/src/interfaces/augment-api-events.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-events.ts
+++ b/tests/src/interfaces/augment-api-events.ts
@@ -6,7 +6,7 @@
 import '@polkadot/api-base/types/events';
 
 import type { ApiTypes, AugmentedEvent } from '@polkadot/api-base/types';
-import type { Bytes, Null, Option, Result, U256, U8aFixed, bool, u128, u32, u64, u8 } from '@polkadot/types-codec';
+import type { Bytes, Null, Option, Result, U8aFixed, bool, u128, u32, u64, u8 } from '@polkadot/types-codec';
 import type { ITuple } from '@polkadot/types-codec/types';
 import type { AccountId32, H160, H256, Weight } from '@polkadot/types/interfaces/runtime';
 import type { EthereumLog, EvmCoreErrorExitReason, FrameSupportDispatchDispatchInfo, FrameSupportScheduleLookupError, FrameSupportTokensMiscBalanceStatus, OrmlVestingVestingSchedule, PalletEvmAccountBasicCrossAccountIdRepr, PalletForeignAssetsAssetIds, PalletForeignAssetsModuleAssetMetadata, RmrkTraitsNftAccountIdOrCollectionNftTuple, SpRuntimeDispatchError, XcmV1MultiAsset, XcmV1MultiLocation, XcmV1MultiassetMultiAssets, XcmV2Response, XcmV2TraitsError, XcmV2TraitsOutcome, XcmV2Xcm, XcmVersionedMultiAssets, XcmVersionedMultiLocation } from '@polkadot/types/lookup';
@@ -204,9 +204,9 @@
     };
     ethereum: {
       /**
-       * An ethereum transaction was successfully executed. [from, to/contract_address, transaction_hash, exit_reason]
+       * An ethereum transaction was successfully executed.
        **/
-      Executed: AugmentedEvent<ApiType, [H160, H160, H256, EvmCoreErrorExitReason]>;
+      Executed: AugmentedEvent<ApiType, [from: H160, to: H160, transactionHash: H256, exitReason: EvmCoreErrorExitReason], { from: H160, to: H160, transactionHash: H256, exitReason: EvmCoreErrorExitReason }>;
       /**
        * Generic event
        **/
@@ -214,33 +214,25 @@
     };
     evm: {
       /**
-       * A deposit has been made at a given address. \[sender, address, value\]
+       * A contract has been created at given address.
        **/
-      BalanceDeposit: AugmentedEvent<ApiType, [AccountId32, H160, U256]>;
+      Created: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;
       /**
-       * A withdrawal has been made from a given address. \[sender, address, value\]
+       * A contract was attempted to be created, but the execution failed.
        **/
-      BalanceWithdraw: AugmentedEvent<ApiType, [AccountId32, H160, U256]>;
+      CreatedFailed: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;
       /**
-       * A contract has been created at given \[address\].
+       * A contract has been executed successfully with states applied.
        **/
-      Created: AugmentedEvent<ApiType, [H160]>;
+      Executed: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;
       /**
-       * A \[contract\] was attempted to be created, but the execution failed.
+       * A contract has been executed with errors. States are reverted with only gas fees applied.
        **/
-      CreatedFailed: AugmentedEvent<ApiType, [H160]>;
-      /**
-       * A \[contract\] has been executed successfully with states applied.
-       **/
-      Executed: AugmentedEvent<ApiType, [H160]>;
-      /**
-       * A \[contract\] has been executed with errors. States are reverted with only gas fees applied.
-       **/
-      ExecutedFailed: AugmentedEvent<ApiType, [H160]>;
+      ExecutedFailed: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;
       /**
        * Ethereum events from contracts.
        **/
-      Log: AugmentedEvent<ApiType, [EthereumLog]>;
+      Log: AugmentedEvent<ApiType, [log: EthereumLog], { log: EthereumLog }>;
       /**
        * Generic event
        **/
modifiedtests/src/interfaces/default/types.tsdiffbeforeafterboth
--- a/tests/src/interfaces/default/types.ts
+++ b/tests/src/interfaces/default/types.ts
@@ -1347,7 +1347,12 @@
 /** @name PalletEthereumEvent */
 export interface PalletEthereumEvent extends Enum {
   readonly isExecuted: boolean;
-  readonly asExecuted: ITuple<[H160, H160, H256, EvmCoreErrorExitReason]>;
+  readonly asExecuted: {
+    readonly from: H160;
+    readonly to: H160;
+    readonly transactionHash: H256;
+    readonly exitReason: EvmCoreErrorExitReason;
+  } & Struct;
   readonly type: 'Executed';
 }
 
@@ -1457,26 +1462,36 @@
   readonly isWithdrawFailed: boolean;
   readonly isGasPriceTooLow: boolean;
   readonly isInvalidNonce: boolean;
-  readonly type: 'BalanceLow' | 'FeeOverflow' | 'PaymentOverflow' | 'WithdrawFailed' | 'GasPriceTooLow' | 'InvalidNonce';
+  readonly isGasLimitTooLow: boolean;
+  readonly isGasLimitTooHigh: boolean;
+  readonly isUndefined: boolean;
+  readonly isReentrancy: boolean;
+  readonly type: 'BalanceLow' | 'FeeOverflow' | 'PaymentOverflow' | 'WithdrawFailed' | 'GasPriceTooLow' | 'InvalidNonce' | 'GasLimitTooLow' | 'GasLimitTooHigh' | 'Undefined' | 'Reentrancy';
 }
 
 /** @name PalletEvmEvent */
 export interface PalletEvmEvent extends Enum {
   readonly isLog: boolean;
-  readonly asLog: EthereumLog;
+  readonly asLog: {
+    readonly log: EthereumLog;
+  } & Struct;
   readonly isCreated: boolean;
-  readonly asCreated: H160;
+  readonly asCreated: {
+    readonly address: H160;
+  } & Struct;
   readonly isCreatedFailed: boolean;
-  readonly asCreatedFailed: H160;
+  readonly asCreatedFailed: {
+    readonly address: H160;
+  } & Struct;
   readonly isExecuted: boolean;
-  readonly asExecuted: H160;
+  readonly asExecuted: {
+    readonly address: H160;
+  } & Struct;
   readonly isExecutedFailed: boolean;
-  readonly asExecutedFailed: H160;
-  readonly isBalanceDeposit: boolean;
-  readonly asBalanceDeposit: ITuple<[AccountId32, H160, U256]>;
-  readonly isBalanceWithdraw: boolean;
-  readonly asBalanceWithdraw: ITuple<[AccountId32, H160, U256]>;
-  readonly type: 'Log' | 'Created' | 'CreatedFailed' | 'Executed' | 'ExecutedFailed' | 'BalanceDeposit' | 'BalanceWithdraw';
+  readonly asExecutedFailed: {
+    readonly address: H160;
+  } & Struct;
+  readonly type: 'Log' | 'Created' | 'CreatedFailed' | 'Executed' | 'ExecutedFailed';
 }
 
 /** @name PalletEvmMigrationCall */
modifiedtests/src/interfaces/lookup.tsdiffbeforeafterboth
--- a/tests/src/interfaces/lookup.ts
+++ b/tests/src/interfaces/lookup.ts
@@ -1216,13 +1216,21 @@
    **/
   PalletEvmEvent: {
     _enum: {
-      Log: 'EthereumLog',
-      Created: 'H160',
-      CreatedFailed: 'H160',
-      Executed: 'H160',
-      ExecutedFailed: 'H160',
-      BalanceDeposit: '(AccountId32,H160,U256)',
-      BalanceWithdraw: '(AccountId32,H160,U256)'
+      Log: {
+        log: 'EthereumLog',
+      },
+      Created: {
+        address: 'H160',
+      },
+      CreatedFailed: {
+        address: 'H160',
+      },
+      Executed: {
+        address: 'H160',
+      },
+      ExecutedFailed: {
+        address: 'H160'
+      }
     }
   },
   /**
@@ -1234,15 +1242,20 @@
     data: 'Bytes'
   },
   /**
-   * Lookup116: pallet_ethereum::pallet::Event
+   * Lookup114: pallet_ethereum::pallet::Event
    **/
   PalletEthereumEvent: {
     _enum: {
-      Executed: '(H160,H160,H256,EvmCoreErrorExitReason)'
+      Executed: {
+        from: 'H160',
+        to: 'H160',
+        transactionHash: 'H256',
+        exitReason: 'EvmCoreErrorExitReason'
+      }
     }
   },
   /**
-   * Lookup117: evm_core::error::ExitReason
+   * Lookup115: evm_core::error::ExitReason
    **/
   EvmCoreErrorExitReason: {
     _enum: {
@@ -1253,13 +1266,13 @@
     }
   },
   /**
-   * Lookup118: evm_core::error::ExitSucceed
+   * Lookup116: evm_core::error::ExitSucceed
    **/
   EvmCoreErrorExitSucceed: {
     _enum: ['Stopped', 'Returned', 'Suicided']
   },
   /**
-   * Lookup119: evm_core::error::ExitError
+   * Lookup117: evm_core::error::ExitError
    **/
   EvmCoreErrorExitError: {
     _enum: {
@@ -1281,13 +1294,13 @@
     }
   },
   /**
-   * Lookup122: evm_core::error::ExitRevert
+   * Lookup120: evm_core::error::ExitRevert
    **/
   EvmCoreErrorExitRevert: {
     _enum: ['Reverted']
   },
   /**
-   * Lookup123: evm_core::error::ExitFatal
+   * Lookup121: evm_core::error::ExitFatal
    **/
   EvmCoreErrorExitFatal: {
     _enum: {
@@ -1298,7 +1311,7 @@
     }
   },
   /**
-   * Lookup124: pallet_evm_contract_helpers::pallet::Event<T>
+   * Lookup122: pallet_evm_contract_helpers::pallet::Event<T>
    **/
   PalletEvmContractHelpersEvent: {
     _enum: {
@@ -1308,19 +1321,19 @@
     }
   },
   /**
-   * Lookup125: pallet_maintenance::pallet::Event<T>
+   * Lookup123: pallet_maintenance::pallet::Event<T>
    **/
   PalletMaintenanceEvent: {
     _enum: ['MaintenanceEnabled', 'MaintenanceDisabled']
   },
   /**
-   * Lookup126: pallet_test_utils::pallet::Event<T>
+   * Lookup124: pallet_test_utils::pallet::Event<T>
    **/
   PalletTestUtilsEvent: {
     _enum: ['ValueIsSet', 'ShouldRollback']
   },
   /**
-   * Lookup127: frame_system::Phase
+   * Lookup125: frame_system::Phase
    **/
   FrameSystemPhase: {
     _enum: {
@@ -1330,14 +1343,14 @@
     }
   },
   /**
-   * Lookup129: frame_system::LastRuntimeUpgradeInfo
+   * Lookup127: frame_system::LastRuntimeUpgradeInfo
    **/
   FrameSystemLastRuntimeUpgradeInfo: {
     specVersion: 'Compact<u32>',
     specName: 'Text'
   },
   /**
-   * Lookup130: frame_system::pallet::Call<T>
+   * Lookup128: frame_system::pallet::Call<T>
    **/
   FrameSystemCall: {
     _enum: {
@@ -1375,7 +1388,7 @@
     }
   },
   /**
-   * Lookup135: frame_system::limits::BlockWeights
+   * Lookup133: frame_system::limits::BlockWeights
    **/
   FrameSystemLimitsBlockWeights: {
     baseBlock: 'Weight',
@@ -1383,7 +1396,7 @@
     perClass: 'FrameSupportDispatchPerDispatchClassWeightsPerClass'
   },
   /**
-   * Lookup136: frame_support::dispatch::PerDispatchClass<frame_system::limits::WeightsPerClass>
+   * Lookup134: frame_support::dispatch::PerDispatchClass<frame_system::limits::WeightsPerClass>
    **/
   FrameSupportDispatchPerDispatchClassWeightsPerClass: {
     normal: 'FrameSystemLimitsWeightsPerClass',
@@ -1391,7 +1404,7 @@
     mandatory: 'FrameSystemLimitsWeightsPerClass'
   },
   /**
-   * Lookup137: frame_system::limits::WeightsPerClass
+   * Lookup135: frame_system::limits::WeightsPerClass
    **/
   FrameSystemLimitsWeightsPerClass: {
     baseExtrinsic: 'Weight',
@@ -1400,13 +1413,13 @@
     reserved: 'Option<Weight>'
   },
   /**
-   * Lookup139: frame_system::limits::BlockLength
+   * Lookup137: frame_system::limits::BlockLength
    **/
   FrameSystemLimitsBlockLength: {
     max: 'FrameSupportDispatchPerDispatchClassU32'
   },
   /**
-   * Lookup140: frame_support::dispatch::PerDispatchClass<T>
+   * Lookup138: frame_support::dispatch::PerDispatchClass<T>
    **/
   FrameSupportDispatchPerDispatchClassU32: {
     normal: 'u32',
@@ -1414,14 +1427,14 @@
     mandatory: 'u32'
   },
   /**
-   * Lookup141: sp_weights::RuntimeDbWeight
+   * Lookup139: sp_weights::RuntimeDbWeight
    **/
   SpWeightsRuntimeDbWeight: {
     read: 'u64',
     write: 'u64'
   },
   /**
-   * Lookup142: sp_version::RuntimeVersion
+   * Lookup140: sp_version::RuntimeVersion
    **/
   SpVersionRuntimeVersion: {
     specName: 'Text',
@@ -1434,13 +1447,13 @@
     stateVersion: 'u8'
   },
   /**
-   * Lookup147: frame_system::pallet::Error<T>
+   * Lookup145: frame_system::pallet::Error<T>
    **/
   FrameSystemError: {
     _enum: ['InvalidSpecName', 'SpecVersionNeedsToIncrease', 'FailedToExtractRuntimeVersion', 'NonDefaultComposite', 'NonZeroRefCount', 'CallFiltered']
   },
   /**
-   * Lookup148: polkadot_primitives::v2::PersistedValidationData<primitive_types::H256, N>
+   * Lookup146: polkadot_primitives::v2::PersistedValidationData<primitive_types::H256, N>
    **/
   PolkadotPrimitivesV2PersistedValidationData: {
     parentHead: 'Bytes',
@@ -1449,19 +1462,19 @@
     maxPovSize: 'u32'
   },
   /**
-   * Lookup151: polkadot_primitives::v2::UpgradeRestriction
+   * Lookup149: polkadot_primitives::v2::UpgradeRestriction
    **/
   PolkadotPrimitivesV2UpgradeRestriction: {
     _enum: ['Present']
   },
   /**
-   * Lookup152: sp_trie::storage_proof::StorageProof
+   * Lookup150: sp_trie::storage_proof::StorageProof
    **/
   SpTrieStorageProof: {
     trieNodes: 'BTreeSet<Bytes>'
   },
   /**
-   * Lookup154: cumulus_pallet_parachain_system::relay_state_snapshot::MessagingStateSnapshot
+   * Lookup152: cumulus_pallet_parachain_system::relay_state_snapshot::MessagingStateSnapshot
    **/
   CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot: {
     dmqMqcHead: 'H256',
@@ -1470,7 +1483,7 @@
     egressChannels: 'Vec<(u32,PolkadotPrimitivesV2AbridgedHrmpChannel)>'
   },
   /**
-   * Lookup157: polkadot_primitives::v2::AbridgedHrmpChannel
+   * Lookup155: polkadot_primitives::v2::AbridgedHrmpChannel
    **/
   PolkadotPrimitivesV2AbridgedHrmpChannel: {
     maxCapacity: 'u32',
@@ -1481,7 +1494,7 @@
     mqcHead: 'Option<H256>'
   },
   /**
-   * Lookup158: polkadot_primitives::v2::AbridgedHostConfiguration
+   * Lookup156: polkadot_primitives::v2::AbridgedHostConfiguration
    **/
   PolkadotPrimitivesV2AbridgedHostConfiguration: {
     maxCodeSize: 'u32',
@@ -1495,14 +1508,14 @@
     validationUpgradeDelay: 'u32'
   },
   /**
-   * Lookup164: polkadot_core_primitives::OutboundHrmpMessage<polkadot_parachain::primitives::Id>
+   * Lookup162: polkadot_core_primitives::OutboundHrmpMessage<polkadot_parachain::primitives::Id>
    **/
   PolkadotCorePrimitivesOutboundHrmpMessage: {
     recipient: 'u32',
     data: 'Bytes'
   },
   /**
-   * Lookup165: cumulus_pallet_parachain_system::pallet::Call<T>
+   * Lookup163: cumulus_pallet_parachain_system::pallet::Call<T>
    **/
   CumulusPalletParachainSystemCall: {
     _enum: {
@@ -1521,7 +1534,7 @@
     }
   },
   /**
-   * Lookup166: cumulus_primitives_parachain_inherent::ParachainInherentData
+   * Lookup164: cumulus_primitives_parachain_inherent::ParachainInherentData
    **/
   CumulusPrimitivesParachainInherentParachainInherentData: {
     validationData: 'PolkadotPrimitivesV2PersistedValidationData',
@@ -1530,27 +1543,27 @@
     horizontalMessages: 'BTreeMap<u32, Vec<PolkadotCorePrimitivesInboundHrmpMessage>>'
   },
   /**
-   * Lookup168: polkadot_core_primitives::InboundDownwardMessage<BlockNumber>
+   * Lookup166: polkadot_core_primitives::InboundDownwardMessage<BlockNumber>
    **/
   PolkadotCorePrimitivesInboundDownwardMessage: {
     sentAt: 'u32',
     msg: 'Bytes'
   },
   /**
-   * Lookup171: polkadot_core_primitives::InboundHrmpMessage<BlockNumber>
+   * Lookup169: polkadot_core_primitives::InboundHrmpMessage<BlockNumber>
    **/
   PolkadotCorePrimitivesInboundHrmpMessage: {
     sentAt: 'u32',
     data: 'Bytes'
   },
   /**
-   * Lookup174: cumulus_pallet_parachain_system::pallet::Error<T>
+   * Lookup172: cumulus_pallet_parachain_system::pallet::Error<T>
    **/
   CumulusPalletParachainSystemError: {
     _enum: ['OverlappingUpgrades', 'ProhibitedByPolkadot', 'TooBig', 'ValidationDataNotAvailable', 'HostConfigurationNotAvailable', 'NotScheduled', 'NothingAuthorized', 'Unauthorized']
   },
   /**
-   * Lookup176: pallet_balances::BalanceLock<Balance>
+   * Lookup174: pallet_balances::BalanceLock<Balance>
    **/
   PalletBalancesBalanceLock: {
     id: '[u8;8]',
@@ -1558,26 +1571,26 @@
     reasons: 'PalletBalancesReasons'
   },
   /**
-   * Lookup177: pallet_balances::Reasons
+   * Lookup175: pallet_balances::Reasons
    **/
   PalletBalancesReasons: {
     _enum: ['Fee', 'Misc', 'All']
   },
   /**
-   * Lookup180: pallet_balances::ReserveData<ReserveIdentifier, Balance>
+   * Lookup178: pallet_balances::ReserveData<ReserveIdentifier, Balance>
    **/
   PalletBalancesReserveData: {
     id: '[u8;16]',
     amount: 'u128'
   },
   /**
-   * Lookup182: pallet_balances::Releases
+   * Lookup180: pallet_balances::Releases
    **/
   PalletBalancesReleases: {
     _enum: ['V1_0_0', 'V2_0_0']
   },
   /**
-   * Lookup183: pallet_balances::pallet::Call<T, I>
+   * Lookup181: pallet_balances::pallet::Call<T, I>
    **/
   PalletBalancesCall: {
     _enum: {
@@ -1610,13 +1623,13 @@
     }
   },
   /**
-   * Lookup186: pallet_balances::pallet::Error<T, I>
+   * Lookup184: pallet_balances::pallet::Error<T, I>
    **/
   PalletBalancesError: {
     _enum: ['VestingBalance', 'LiquidityRestrictions', 'InsufficientBalance', 'ExistentialDeposit', 'KeepAlive', 'ExistingVestingSchedule', 'DeadAccount', 'TooManyReserves']
   },
   /**
-   * Lookup188: pallet_timestamp::pallet::Call<T>
+   * Lookup186: pallet_timestamp::pallet::Call<T>
    **/
   PalletTimestampCall: {
     _enum: {
@@ -1626,13 +1639,13 @@
     }
   },
   /**
-   * Lookup190: pallet_transaction_payment::Releases
+   * Lookup188: pallet_transaction_payment::Releases
    **/
   PalletTransactionPaymentReleases: {
     _enum: ['V1Ancient', 'V2']
   },
   /**
-   * Lookup191: pallet_treasury::Proposal<sp_core::crypto::AccountId32, Balance>
+   * Lookup189: pallet_treasury::Proposal<sp_core::crypto::AccountId32, Balance>
    **/
   PalletTreasuryProposal: {
     proposer: 'AccountId32',
@@ -1641,7 +1654,7 @@
     bond: 'u128'
   },
   /**
-   * Lookup194: pallet_treasury::pallet::Call<T, I>
+   * Lookup192: pallet_treasury::pallet::Call<T, I>
    **/
   PalletTreasuryCall: {
     _enum: {
@@ -1665,17 +1678,17 @@
     }
   },
   /**
-   * Lookup197: frame_support::PalletId
+   * Lookup195: frame_support::PalletId
    **/
   FrameSupportPalletId: '[u8;8]',
   /**
-   * Lookup198: pallet_treasury::pallet::Error<T, I>
+   * Lookup196: pallet_treasury::pallet::Error<T, I>
    **/
   PalletTreasuryError: {
     _enum: ['InsufficientProposersBalance', 'InvalidIndex', 'TooManyApprovals', 'InsufficientPermission', 'ProposalNotApproved']
   },
   /**
-   * Lookup199: pallet_sudo::pallet::Call<T>
+   * Lookup197: pallet_sudo::pallet::Call<T>
    **/
   PalletSudoCall: {
     _enum: {
@@ -1699,7 +1712,7 @@
     }
   },
   /**
-   * Lookup201: orml_vesting::module::Call<T>
+   * Lookup199: orml_vesting::module::Call<T>
    **/
   OrmlVestingModuleCall: {
     _enum: {
@@ -1718,7 +1731,7 @@
     }
   },
   /**
-   * Lookup203: orml_xtokens::module::Call<T>
+   * Lookup201: orml_xtokens::module::Call<T>
    **/
   OrmlXtokensModuleCall: {
     _enum: {
@@ -1761,7 +1774,7 @@
     }
   },
   /**
-   * Lookup204: xcm::VersionedMultiAsset
+   * Lookup202: xcm::VersionedMultiAsset
    **/
   XcmVersionedMultiAsset: {
     _enum: {
@@ -1770,7 +1783,7 @@
     }
   },
   /**
-   * Lookup207: orml_tokens::module::Call<T>
+   * Lookup205: orml_tokens::module::Call<T>
    **/
   OrmlTokensModuleCall: {
     _enum: {
@@ -1804,7 +1817,7 @@
     }
   },
   /**
-   * Lookup208: cumulus_pallet_xcmp_queue::pallet::Call<T>
+   * Lookup206: cumulus_pallet_xcmp_queue::pallet::Call<T>
    **/
   CumulusPalletXcmpQueueCall: {
     _enum: {
@@ -1853,7 +1866,7 @@
     }
   },
   /**
-   * Lookup209: pallet_xcm::pallet::Call<T>
+   * Lookup207: pallet_xcm::pallet::Call<T>
    **/
   PalletXcmCall: {
     _enum: {
@@ -1907,7 +1920,7 @@
     }
   },
   /**
-   * Lookup210: xcm::VersionedXcm<RuntimeCall>
+   * Lookup208: xcm::VersionedXcm<RuntimeCall>
    **/
   XcmVersionedXcm: {
     _enum: {
@@ -1917,7 +1930,7 @@
     }
   },
   /**
-   * Lookup211: xcm::v0::Xcm<RuntimeCall>
+   * Lookup209: xcm::v0::Xcm<RuntimeCall>
    **/
   XcmV0Xcm: {
     _enum: {
@@ -1971,7 +1984,7 @@
     }
   },
   /**
-   * Lookup213: xcm::v0::order::Order<RuntimeCall>
+   * Lookup211: xcm::v0::order::Order<RuntimeCall>
    **/
   XcmV0Order: {
     _enum: {
@@ -2014,7 +2027,7 @@
     }
   },
   /**
-   * Lookup215: xcm::v0::Response
+   * Lookup213: xcm::v0::Response
    **/
   XcmV0Response: {
     _enum: {
@@ -2022,7 +2035,7 @@
     }
   },
   /**
-   * Lookup216: xcm::v1::Xcm<RuntimeCall>
+   * Lookup214: xcm::v1::Xcm<RuntimeCall>
    **/
   XcmV1Xcm: {
     _enum: {
@@ -2081,7 +2094,7 @@
     }
   },
   /**
-   * Lookup218: xcm::v1::order::Order<RuntimeCall>
+   * Lookup216: xcm::v1::order::Order<RuntimeCall>
    **/
   XcmV1Order: {
     _enum: {
@@ -2126,7 +2139,7 @@
     }
   },
   /**
-   * Lookup220: xcm::v1::Response
+   * Lookup218: xcm::v1::Response
    **/
   XcmV1Response: {
     _enum: {
@@ -2135,11 +2148,11 @@
     }
   },
   /**
-   * Lookup234: cumulus_pallet_xcm::pallet::Call<T>
+   * Lookup232: cumulus_pallet_xcm::pallet::Call<T>
    **/
   CumulusPalletXcmCall: 'Null',
   /**
-   * Lookup235: cumulus_pallet_dmp_queue::pallet::Call<T>
+   * Lookup233: cumulus_pallet_dmp_queue::pallet::Call<T>
    **/
   CumulusPalletDmpQueueCall: {
     _enum: {
@@ -2150,7 +2163,7 @@
     }
   },
   /**
-   * Lookup236: pallet_inflation::pallet::Call<T>
+   * Lookup234: pallet_inflation::pallet::Call<T>
    **/
   PalletInflationCall: {
     _enum: {
@@ -2160,7 +2173,7 @@
     }
   },
   /**
-   * Lookup237: pallet_unique::Call<T>
+   * Lookup235: pallet_unique::Call<T>
    **/
   PalletUniqueCall: {
     _enum: {
@@ -2292,7 +2305,7 @@
     }
   },
   /**
-   * Lookup242: up_data_structs::CollectionMode
+   * Lookup240: up_data_structs::CollectionMode
    **/
   UpDataStructsCollectionMode: {
     _enum: {
@@ -2302,7 +2315,7 @@
     }
   },
   /**
-   * Lookup243: up_data_structs::CreateCollectionData<sp_core::crypto::AccountId32>
+   * Lookup241: up_data_structs::CreateCollectionData<sp_core::crypto::AccountId32>
    **/
   UpDataStructsCreateCollectionData: {
     mode: 'UpDataStructsCollectionMode',
@@ -2317,13 +2330,13 @@
     properties: 'Vec<UpDataStructsProperty>'
   },
   /**
-   * Lookup245: up_data_structs::AccessMode
+   * Lookup243: up_data_structs::AccessMode
    **/
   UpDataStructsAccessMode: {
     _enum: ['Normal', 'AllowList']
   },
   /**
-   * Lookup247: up_data_structs::CollectionLimits
+   * Lookup245: up_data_structs::CollectionLimits
    **/
   UpDataStructsCollectionLimits: {
     accountTokenOwnershipLimit: 'Option<u32>',
@@ -2337,7 +2350,7 @@
     transfersEnabled: 'Option<bool>'
   },
   /**
-   * Lookup249: up_data_structs::SponsoringRateLimit
+   * Lookup247: up_data_structs::SponsoringRateLimit
    **/
   UpDataStructsSponsoringRateLimit: {
     _enum: {
@@ -2346,7 +2359,7 @@
     }
   },
   /**
-   * Lookup252: up_data_structs::CollectionPermissions
+   * Lookup250: up_data_structs::CollectionPermissions
    **/
   UpDataStructsCollectionPermissions: {
     access: 'Option<UpDataStructsAccessMode>',
@@ -2354,7 +2367,7 @@
     nesting: 'Option<UpDataStructsNestingPermissions>'
   },
   /**
-   * Lookup254: up_data_structs::NestingPermissions
+   * Lookup252: up_data_structs::NestingPermissions
    **/
   UpDataStructsNestingPermissions: {
     tokenOwner: 'bool',
@@ -2362,18 +2375,18 @@
     restricted: 'Option<UpDataStructsOwnerRestrictedSet>'
   },
   /**
-   * Lookup256: up_data_structs::OwnerRestrictedSet
+   * Lookup254: up_data_structs::OwnerRestrictedSet
    **/
   UpDataStructsOwnerRestrictedSet: 'BTreeSet<u32>',
   /**
-   * Lookup261: up_data_structs::PropertyKeyPermission
+   * Lookup259: up_data_structs::PropertyKeyPermission
    **/
   UpDataStructsPropertyKeyPermission: {
     key: 'Bytes',
     permission: 'UpDataStructsPropertyPermission'
   },
   /**
-   * Lookup262: up_data_structs::PropertyPermission
+   * Lookup260: up_data_structs::PropertyPermission
    **/
   UpDataStructsPropertyPermission: {
     mutable: 'bool',
@@ -2381,14 +2394,14 @@
     tokenOwner: 'bool'
   },
   /**
-   * Lookup265: up_data_structs::Property
+   * Lookup263: up_data_structs::Property
    **/
   UpDataStructsProperty: {
     key: 'Bytes',
     value: 'Bytes'
   },
   /**
-   * Lookup268: up_data_structs::CreateItemData
+   * Lookup266: up_data_structs::CreateItemData
    **/
   UpDataStructsCreateItemData: {
     _enum: {
@@ -2398,26 +2411,26 @@
     }
   },
   /**
-   * Lookup269: up_data_structs::CreateNftData
+   * Lookup267: up_data_structs::CreateNftData
    **/
   UpDataStructsCreateNftData: {
     properties: 'Vec<UpDataStructsProperty>'
   },
   /**
-   * Lookup270: up_data_structs::CreateFungibleData
+   * Lookup268: up_data_structs::CreateFungibleData
    **/
   UpDataStructsCreateFungibleData: {
     value: 'u128'
   },
   /**
-   * Lookup271: up_data_structs::CreateReFungibleData
+   * Lookup269: up_data_structs::CreateReFungibleData
    **/
   UpDataStructsCreateReFungibleData: {
     pieces: 'u128',
     properties: 'Vec<UpDataStructsProperty>'
   },
   /**
-   * Lookup274: up_data_structs::CreateItemExData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+   * Lookup272: up_data_structs::CreateItemExData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
    **/
   UpDataStructsCreateItemExData: {
     _enum: {
@@ -2428,14 +2441,14 @@
     }
   },
   /**
-   * Lookup276: up_data_structs::CreateNftExData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+   * Lookup274: up_data_structs::CreateNftExData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
    **/
   UpDataStructsCreateNftExData: {
     properties: 'Vec<UpDataStructsProperty>',
     owner: 'PalletEvmAccountBasicCrossAccountIdRepr'
   },
   /**
-   * Lookup283: up_data_structs::CreateRefungibleExSingleOwner<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+   * Lookup281: up_data_structs::CreateRefungibleExSingleOwner<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
    **/
   UpDataStructsCreateRefungibleExSingleOwner: {
     user: 'PalletEvmAccountBasicCrossAccountIdRepr',
@@ -2443,14 +2456,14 @@
     properties: 'Vec<UpDataStructsProperty>'
   },
   /**
-   * Lookup285: up_data_structs::CreateRefungibleExMultipleOwners<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+   * Lookup283: up_data_structs::CreateRefungibleExMultipleOwners<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
    **/
   UpDataStructsCreateRefungibleExMultipleOwners: {
     users: 'BTreeMap<PalletEvmAccountBasicCrossAccountIdRepr, u128>',
     properties: 'Vec<UpDataStructsProperty>'
   },
   /**
-   * Lookup286: pallet_unique_scheduler::pallet::Call<T>
+   * Lookup284: pallet_unique_scheduler::pallet::Call<T>
    **/
   PalletUniqueSchedulerCall: {
     _enum: {
@@ -2478,7 +2491,7 @@
     }
   },
   /**
-   * Lookup289: frame_support::traits::schedule::MaybeHashed<opal_runtime::RuntimeCall, primitive_types::H256>
+   * Lookup287: frame_support::traits::schedule::MaybeHashed<opal_runtime::RuntimeCall, primitive_types::H256>
    **/
   FrameSupportScheduleMaybeHashed: {
     _enum: {
@@ -2487,7 +2500,7 @@
     }
   },
   /**
-   * Lookup290: pallet_configuration::pallet::Call<T>
+   * Lookup288: pallet_configuration::pallet::Call<T>
    **/
   PalletConfigurationCall: {
     _enum: {
@@ -2500,15 +2513,15 @@
     }
   },
   /**
-   * Lookup292: pallet_template_transaction_payment::Call<T>
+   * Lookup290: pallet_template_transaction_payment::Call<T>
    **/
   PalletTemplateTransactionPaymentCall: 'Null',
   /**
-   * Lookup293: pallet_structure::pallet::Call<T>
+   * Lookup291: pallet_structure::pallet::Call<T>
    **/
   PalletStructureCall: 'Null',
   /**
-   * Lookup294: pallet_rmrk_core::pallet::Call<T>
+   * Lookup292: pallet_rmrk_core::pallet::Call<T>
    **/
   PalletRmrkCoreCall: {
     _enum: {
@@ -2599,7 +2612,7 @@
     }
   },
   /**
-   * Lookup300: rmrk_traits::resource::ResourceTypes<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<T, S>>
+   * Lookup298: rmrk_traits::resource::ResourceTypes<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<T, S>>
    **/
   RmrkTraitsResourceResourceTypes: {
     _enum: {
@@ -2609,7 +2622,7 @@
     }
   },
   /**
-   * Lookup302: rmrk_traits::resource::BasicResource<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
+   * Lookup300: rmrk_traits::resource::BasicResource<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
    **/
   RmrkTraitsResourceBasicResource: {
     src: 'Option<Bytes>',
@@ -2618,7 +2631,7 @@
     thumb: 'Option<Bytes>'
   },
   /**
-   * Lookup304: rmrk_traits::resource::ComposableResource<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<T, S>>
+   * Lookup302: rmrk_traits::resource::ComposableResource<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<T, S>>
    **/
   RmrkTraitsResourceComposableResource: {
     parts: 'Vec<u32>',
@@ -2629,7 +2642,7 @@
     thumb: 'Option<Bytes>'
   },
   /**
-   * Lookup305: rmrk_traits::resource::SlotResource<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
+   * Lookup303: rmrk_traits::resource::SlotResource<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
    **/
   RmrkTraitsResourceSlotResource: {
     base: 'u32',
@@ -2640,7 +2653,7 @@
     thumb: 'Option<Bytes>'
   },
   /**
-   * Lookup308: pallet_rmrk_equip::pallet::Call<T>
+   * Lookup306: pallet_rmrk_equip::pallet::Call<T>
    **/
   PalletRmrkEquipCall: {
     _enum: {
@@ -2661,7 +2674,7 @@
     }
   },
   /**
-   * Lookup311: rmrk_traits::part::PartType<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<T, S>>
+   * Lookup309: rmrk_traits::part::PartType<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<T, S>>
    **/
   RmrkTraitsPartPartType: {
     _enum: {
@@ -2670,7 +2683,7 @@
     }
   },
   /**
-   * Lookup313: rmrk_traits::part::FixedPart<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
+   * Lookup311: rmrk_traits::part::FixedPart<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
    **/
   RmrkTraitsPartFixedPart: {
     id: 'u32',
@@ -2678,7 +2691,7 @@
     src: 'Bytes'
   },
   /**
-   * Lookup314: rmrk_traits::part::SlotPart<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<T, S>>
+   * Lookup312: rmrk_traits::part::SlotPart<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<T, S>>
    **/
   RmrkTraitsPartSlotPart: {
     id: 'u32',
@@ -2687,7 +2700,7 @@
     z: 'u32'
   },
   /**
-   * Lookup315: rmrk_traits::part::EquippableList<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
+   * Lookup313: rmrk_traits::part::EquippableList<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
    **/
   RmrkTraitsPartEquippableList: {
     _enum: {
@@ -2697,7 +2710,7 @@
     }
   },
   /**
-   * Lookup317: rmrk_traits::theme::Theme<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<rmrk_traits::theme::ThemeProperty<sp_core::bounded::bounded_vec::BoundedVec<T, S>>, S>>
+   * Lookup315: rmrk_traits::theme::Theme<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<rmrk_traits::theme::ThemeProperty<sp_core::bounded::bounded_vec::BoundedVec<T, S>>, S>>
    **/
   RmrkTraitsTheme: {
     name: 'Bytes',
@@ -2705,14 +2718,14 @@
     inherit: 'bool'
   },
   /**
-   * Lookup319: rmrk_traits::theme::ThemeProperty<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
+   * Lookup317: rmrk_traits::theme::ThemeProperty<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
    **/
   RmrkTraitsThemeThemeProperty: {
     key: 'Bytes',
     value: 'Bytes'
   },
   /**
-   * Lookup321: pallet_app_promotion::pallet::Call<T>
+   * Lookup319: pallet_app_promotion::pallet::Call<T>
    **/
   PalletAppPromotionCall: {
     _enum: {
@@ -2741,7 +2754,7 @@
     }
   },
   /**
-   * Lookup322: pallet_foreign_assets::module::Call<T>
+   * Lookup320: pallet_foreign_assets::module::Call<T>
    **/
   PalletForeignAssetsModuleCall: {
     _enum: {
@@ -2758,7 +2771,7 @@
     }
   },
   /**
-   * Lookup323: pallet_evm::pallet::Call<T>
+   * Lookup321: pallet_evm::pallet::Call<T>
    **/
   PalletEvmCall: {
     _enum: {
@@ -3458,7 +3471,7 @@
    * Lookup450: pallet_evm::pallet::Error<T>
    **/
   PalletEvmError: {
-    _enum: ['BalanceLow', 'FeeOverflow', 'PaymentOverflow', 'WithdrawFailed', 'GasPriceTooLow', 'InvalidNonce']
+    _enum: ['BalanceLow', 'FeeOverflow', 'PaymentOverflow', 'WithdrawFailed', 'GasPriceTooLow', 'InvalidNonce', 'GasLimitTooLow', 'GasLimitTooHigh', 'Undefined', 'Reentrancy']
   },
   /**
    * Lookup453: fp_rpc::TransactionStatus
modifiedtests/src/interfaces/types-lookup.tsdiffbeforeafterboth
--- a/tests/src/interfaces/types-lookup.ts
+++ b/tests/src/interfaces/types-lookup.ts
@@ -1371,20 +1371,26 @@
   /** @name PalletEvmEvent (111) */
   interface PalletEvmEvent extends Enum {
     readonly isLog: boolean;
-    readonly asLog: EthereumLog;
+    readonly asLog: {
+      readonly log: EthereumLog;
+    } & Struct;
     readonly isCreated: boolean;
-    readonly asCreated: H160;
+    readonly asCreated: {
+      readonly address: H160;
+    } & Struct;
     readonly isCreatedFailed: boolean;
-    readonly asCreatedFailed: H160;
+    readonly asCreatedFailed: {
+      readonly address: H160;
+    } & Struct;
     readonly isExecuted: boolean;
-    readonly asExecuted: H160;
+    readonly asExecuted: {
+      readonly address: H160;
+    } & Struct;
     readonly isExecutedFailed: boolean;
-    readonly asExecutedFailed: H160;
-    readonly isBalanceDeposit: boolean;
-    readonly asBalanceDeposit: ITuple<[AccountId32, H160, U256]>;
-    readonly isBalanceWithdraw: boolean;
-    readonly asBalanceWithdraw: ITuple<[AccountId32, H160, U256]>;
-    readonly type: 'Log' | 'Created' | 'CreatedFailed' | 'Executed' | 'ExecutedFailed' | 'BalanceDeposit' | 'BalanceWithdraw';
+    readonly asExecutedFailed: {
+      readonly address: H160;
+    } & Struct;
+    readonly type: 'Log' | 'Created' | 'CreatedFailed' | 'Executed' | 'ExecutedFailed';
   }
 
   /** @name EthereumLog (112) */
@@ -1394,14 +1400,19 @@
     readonly data: Bytes;
   }
 
-  /** @name PalletEthereumEvent (116) */
+  /** @name PalletEthereumEvent (114) */
   interface PalletEthereumEvent extends Enum {
     readonly isExecuted: boolean;
-    readonly asExecuted: ITuple<[H160, H160, H256, EvmCoreErrorExitReason]>;
+    readonly asExecuted: {
+      readonly from: H160;
+      readonly to: H160;
+      readonly transactionHash: H256;
+      readonly exitReason: EvmCoreErrorExitReason;
+    } & Struct;
     readonly type: 'Executed';
   }
 
-  /** @name EvmCoreErrorExitReason (117) */
+  /** @name EvmCoreErrorExitReason (115) */
   interface EvmCoreErrorExitReason extends Enum {
     readonly isSucceed: boolean;
     readonly asSucceed: EvmCoreErrorExitSucceed;
@@ -1414,7 +1425,7 @@
     readonly type: 'Succeed' | 'Error' | 'Revert' | 'Fatal';
   }
 
-  /** @name EvmCoreErrorExitSucceed (118) */
+  /** @name EvmCoreErrorExitSucceed (116) */
   interface EvmCoreErrorExitSucceed extends Enum {
     readonly isStopped: boolean;
     readonly isReturned: boolean;
@@ -1422,7 +1433,7 @@
     readonly type: 'Stopped' | 'Returned' | 'Suicided';
   }
 
-  /** @name EvmCoreErrorExitError (119) */
+  /** @name EvmCoreErrorExitError (117) */
   interface EvmCoreErrorExitError extends Enum {
     readonly isStackUnderflow: boolean;
     readonly isStackOverflow: boolean;
@@ -1443,13 +1454,13 @@
     readonly type: 'StackUnderflow' | 'StackOverflow' | 'InvalidJump' | 'InvalidRange' | 'DesignatedInvalid' | 'CallTooDeep' | 'CreateCollision' | 'CreateContractLimit' | 'OutOfOffset' | 'OutOfGas' | 'OutOfFund' | 'PcUnderflow' | 'CreateEmpty' | 'Other' | 'InvalidCode';
   }
 
-  /** @name EvmCoreErrorExitRevert (122) */
+  /** @name EvmCoreErrorExitRevert (120) */
   interface EvmCoreErrorExitRevert extends Enum {
     readonly isReverted: boolean;
     readonly type: 'Reverted';
   }
 
-  /** @name EvmCoreErrorExitFatal (123) */
+  /** @name EvmCoreErrorExitFatal (121) */
   interface EvmCoreErrorExitFatal extends Enum {
     readonly isNotSupported: boolean;
     readonly isUnhandledInterrupt: boolean;
@@ -1460,7 +1471,7 @@
     readonly type: 'NotSupported' | 'UnhandledInterrupt' | 'CallErrorAsFatal' | 'Other';
   }
 
-  /** @name PalletEvmContractHelpersEvent (124) */
+  /** @name PalletEvmContractHelpersEvent (122) */
   interface PalletEvmContractHelpersEvent extends Enum {
     readonly isContractSponsorSet: boolean;
     readonly asContractSponsorSet: ITuple<[H160, AccountId32]>;
@@ -1471,21 +1482,21 @@
     readonly type: 'ContractSponsorSet' | 'ContractSponsorshipConfirmed' | 'ContractSponsorRemoved';
   }
 
-  /** @name PalletMaintenanceEvent (125) */
+  /** @name PalletMaintenanceEvent (123) */
   interface PalletMaintenanceEvent extends Enum {
     readonly isMaintenanceEnabled: boolean;
     readonly isMaintenanceDisabled: boolean;
     readonly type: 'MaintenanceEnabled' | 'MaintenanceDisabled';
   }
 
-  /** @name PalletTestUtilsEvent (126) */
+  /** @name PalletTestUtilsEvent (124) */
   interface PalletTestUtilsEvent extends Enum {
     readonly isValueIsSet: boolean;
     readonly isShouldRollback: boolean;
     readonly type: 'ValueIsSet' | 'ShouldRollback';
   }
 
-  /** @name FrameSystemPhase (127) */
+  /** @name FrameSystemPhase (125) */
   interface FrameSystemPhase extends Enum {
     readonly isApplyExtrinsic: boolean;
     readonly asApplyExtrinsic: u32;
@@ -1494,13 +1505,13 @@
     readonly type: 'ApplyExtrinsic' | 'Finalization' | 'Initialization';
   }
 
-  /** @name FrameSystemLastRuntimeUpgradeInfo (129) */
+  /** @name FrameSystemLastRuntimeUpgradeInfo (127) */
   interface FrameSystemLastRuntimeUpgradeInfo extends Struct {
     readonly specVersion: Compact<u32>;
     readonly specName: Text;
   }
 
-  /** @name FrameSystemCall (130) */
+  /** @name FrameSystemCall (128) */
   interface FrameSystemCall extends Enum {
     readonly isFillBlock: boolean;
     readonly asFillBlock: {
@@ -1542,21 +1553,21 @@
     readonly type: 'FillBlock' | 'Remark' | 'SetHeapPages' | 'SetCode' | 'SetCodeWithoutChecks' | 'SetStorage' | 'KillStorage' | 'KillPrefix' | 'RemarkWithEvent';
   }
 
-  /** @name FrameSystemLimitsBlockWeights (135) */
+  /** @name FrameSystemLimitsBlockWeights (133) */
   interface FrameSystemLimitsBlockWeights extends Struct {
     readonly baseBlock: Weight;
     readonly maxBlock: Weight;
     readonly perClass: FrameSupportDispatchPerDispatchClassWeightsPerClass;
   }
 
-  /** @name FrameSupportDispatchPerDispatchClassWeightsPerClass (136) */
+  /** @name FrameSupportDispatchPerDispatchClassWeightsPerClass (134) */
   interface FrameSupportDispatchPerDispatchClassWeightsPerClass extends Struct {
     readonly normal: FrameSystemLimitsWeightsPerClass;
     readonly operational: FrameSystemLimitsWeightsPerClass;
     readonly mandatory: FrameSystemLimitsWeightsPerClass;
   }
 
-  /** @name FrameSystemLimitsWeightsPerClass (137) */
+  /** @name FrameSystemLimitsWeightsPerClass (135) */
   interface FrameSystemLimitsWeightsPerClass extends Struct {
     readonly baseExtrinsic: Weight;
     readonly maxExtrinsic: Option<Weight>;
@@ -1564,25 +1575,25 @@
     readonly reserved: Option<Weight>;
   }
 
-  /** @name FrameSystemLimitsBlockLength (139) */
+  /** @name FrameSystemLimitsBlockLength (137) */
   interface FrameSystemLimitsBlockLength extends Struct {
     readonly max: FrameSupportDispatchPerDispatchClassU32;
   }
 
-  /** @name FrameSupportDispatchPerDispatchClassU32 (140) */
+  /** @name FrameSupportDispatchPerDispatchClassU32 (138) */
   interface FrameSupportDispatchPerDispatchClassU32 extends Struct {
     readonly normal: u32;
     readonly operational: u32;
     readonly mandatory: u32;
   }
 
-  /** @name SpWeightsRuntimeDbWeight (141) */
+  /** @name SpWeightsRuntimeDbWeight (139) */
   interface SpWeightsRuntimeDbWeight extends Struct {
     readonly read: u64;
     readonly write: u64;
   }
 
-  /** @name SpVersionRuntimeVersion (142) */
+  /** @name SpVersionRuntimeVersion (140) */
   interface SpVersionRuntimeVersion extends Struct {
     readonly specName: Text;
     readonly implName: Text;
@@ -1594,7 +1605,7 @@
     readonly stateVersion: u8;
   }
 
-  /** @name FrameSystemError (147) */
+  /** @name FrameSystemError (145) */
   interface FrameSystemError extends Enum {
     readonly isInvalidSpecName: boolean;
     readonly isSpecVersionNeedsToIncrease: boolean;
@@ -1605,7 +1616,7 @@
     readonly type: 'InvalidSpecName' | 'SpecVersionNeedsToIncrease' | 'FailedToExtractRuntimeVersion' | 'NonDefaultComposite' | 'NonZeroRefCount' | 'CallFiltered';
   }
 
-  /** @name PolkadotPrimitivesV2PersistedValidationData (148) */
+  /** @name PolkadotPrimitivesV2PersistedValidationData (146) */
   interface PolkadotPrimitivesV2PersistedValidationData extends Struct {
     readonly parentHead: Bytes;
     readonly relayParentNumber: u32;
@@ -1613,18 +1624,18 @@
     readonly maxPovSize: u32;
   }
 
-  /** @name PolkadotPrimitivesV2UpgradeRestriction (151) */
+  /** @name PolkadotPrimitivesV2UpgradeRestriction (149) */
   interface PolkadotPrimitivesV2UpgradeRestriction extends Enum {
     readonly isPresent: boolean;
     readonly type: 'Present';
   }
 
-  /** @name SpTrieStorageProof (152) */
+  /** @name SpTrieStorageProof (150) */
   interface SpTrieStorageProof extends Struct {
     readonly trieNodes: BTreeSet<Bytes>;
   }
 
-  /** @name CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot (154) */
+  /** @name CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot (152) */
   interface CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot extends Struct {
     readonly dmqMqcHead: H256;
     readonly relayDispatchQueueSize: ITuple<[u32, u32]>;
@@ -1632,7 +1643,7 @@
     readonly egressChannels: Vec<ITuple<[u32, PolkadotPrimitivesV2AbridgedHrmpChannel]>>;
   }
 
-  /** @name PolkadotPrimitivesV2AbridgedHrmpChannel (157) */
+  /** @name PolkadotPrimitivesV2AbridgedHrmpChannel (155) */
   interface PolkadotPrimitivesV2AbridgedHrmpChannel extends Struct {
     readonly maxCapacity: u32;
     readonly maxTotalSize: u32;
@@ -1642,7 +1653,7 @@
     readonly mqcHead: Option<H256>;
   }
 
-  /** @name PolkadotPrimitivesV2AbridgedHostConfiguration (158) */
+  /** @name PolkadotPrimitivesV2AbridgedHostConfiguration (156) */
   interface PolkadotPrimitivesV2AbridgedHostConfiguration extends Struct {
     readonly maxCodeSize: u32;
     readonly maxHeadDataSize: u32;
@@ -1655,13 +1666,13 @@
     readonly validationUpgradeDelay: u32;
   }
 
-  /** @name PolkadotCorePrimitivesOutboundHrmpMessage (164) */
+  /** @name PolkadotCorePrimitivesOutboundHrmpMessage (162) */
   interface PolkadotCorePrimitivesOutboundHrmpMessage extends Struct {
     readonly recipient: u32;
     readonly data: Bytes;
   }
 
-  /** @name CumulusPalletParachainSystemCall (165) */
+  /** @name CumulusPalletParachainSystemCall (163) */
   interface CumulusPalletParachainSystemCall extends Enum {
     readonly isSetValidationData: boolean;
     readonly asSetValidationData: {
@@ -1682,7 +1693,7 @@
     readonly type: 'SetValidationData' | 'SudoSendUpwardMessage' | 'AuthorizeUpgrade' | 'EnactAuthorizedUpgrade';
   }
 
-  /** @name CumulusPrimitivesParachainInherentParachainInherentData (166) */
+  /** @name CumulusPrimitivesParachainInherentParachainInherentData (164) */
   interface CumulusPrimitivesParachainInherentParachainInherentData extends Struct {
     readonly validationData: PolkadotPrimitivesV2PersistedValidationData;
     readonly relayChainState: SpTrieStorageProof;
@@ -1690,19 +1701,19 @@
     readonly horizontalMessages: BTreeMap<u32, Vec<PolkadotCorePrimitivesInboundHrmpMessage>>;
   }
 
-  /** @name PolkadotCorePrimitivesInboundDownwardMessage (168) */
+  /** @name PolkadotCorePrimitivesInboundDownwardMessage (166) */
   interface PolkadotCorePrimitivesInboundDownwardMessage extends Struct {
     readonly sentAt: u32;
     readonly msg: Bytes;
   }
 
-  /** @name PolkadotCorePrimitivesInboundHrmpMessage (171) */
+  /** @name PolkadotCorePrimitivesInboundHrmpMessage (169) */
   interface PolkadotCorePrimitivesInboundHrmpMessage extends Struct {
     readonly sentAt: u32;
     readonly data: Bytes;
   }
 
-  /** @name CumulusPalletParachainSystemError (174) */
+  /** @name CumulusPalletParachainSystemError (172) */
   interface CumulusPalletParachainSystemError extends Enum {
     readonly isOverlappingUpgrades: boolean;
     readonly isProhibitedByPolkadot: boolean;
@@ -1715,14 +1726,14 @@
     readonly type: 'OverlappingUpgrades' | 'ProhibitedByPolkadot' | 'TooBig' | 'ValidationDataNotAvailable' | 'HostConfigurationNotAvailable' | 'NotScheduled' | 'NothingAuthorized' | 'Unauthorized';
   }
 
-  /** @name PalletBalancesBalanceLock (176) */
+  /** @name PalletBalancesBalanceLock (174) */
   interface PalletBalancesBalanceLock extends Struct {
     readonly id: U8aFixed;
     readonly amount: u128;
     readonly reasons: PalletBalancesReasons;
   }
 
-  /** @name PalletBalancesReasons (177) */
+  /** @name PalletBalancesReasons (175) */
   interface PalletBalancesReasons extends Enum {
     readonly isFee: boolean;
     readonly isMisc: boolean;
@@ -1730,20 +1741,20 @@
     readonly type: 'Fee' | 'Misc' | 'All';
   }
 
-  /** @name PalletBalancesReserveData (180) */
+  /** @name PalletBalancesReserveData (178) */
   interface PalletBalancesReserveData extends Struct {
     readonly id: U8aFixed;
     readonly amount: u128;
   }
 
-  /** @name PalletBalancesReleases (182) */
+  /** @name PalletBalancesReleases (180) */
   interface PalletBalancesReleases extends Enum {
     readonly isV100: boolean;
     readonly isV200: boolean;
     readonly type: 'V100' | 'V200';
   }
 
-  /** @name PalletBalancesCall (183) */
+  /** @name PalletBalancesCall (181) */
   interface PalletBalancesCall extends Enum {
     readonly isTransfer: boolean;
     readonly asTransfer: {
@@ -1780,7 +1791,7 @@
     readonly type: 'Transfer' | 'SetBalance' | 'ForceTransfer' | 'TransferKeepAlive' | 'TransferAll' | 'ForceUnreserve';
   }
 
-  /** @name PalletBalancesError (186) */
+  /** @name PalletBalancesError (184) */
   interface PalletBalancesError extends Enum {
     readonly isVestingBalance: boolean;
     readonly isLiquidityRestrictions: boolean;
@@ -1793,7 +1804,7 @@
     readonly type: 'VestingBalance' | 'LiquidityRestrictions' | 'InsufficientBalance' | 'ExistentialDeposit' | 'KeepAlive' | 'ExistingVestingSchedule' | 'DeadAccount' | 'TooManyReserves';
   }
 
-  /** @name PalletTimestampCall (188) */
+  /** @name PalletTimestampCall (186) */
   interface PalletTimestampCall extends Enum {
     readonly isSet: boolean;
     readonly asSet: {
@@ -1802,14 +1813,14 @@
     readonly type: 'Set';
   }
 
-  /** @name PalletTransactionPaymentReleases (190) */
+  /** @name PalletTransactionPaymentReleases (188) */
   interface PalletTransactionPaymentReleases extends Enum {
     readonly isV1Ancient: boolean;
     readonly isV2: boolean;
     readonly type: 'V1Ancient' | 'V2';
   }
 
-  /** @name PalletTreasuryProposal (191) */
+  /** @name PalletTreasuryProposal (189) */
   interface PalletTreasuryProposal extends Struct {
     readonly proposer: AccountId32;
     readonly value: u128;
@@ -1817,7 +1828,7 @@
     readonly bond: u128;
   }
 
-  /** @name PalletTreasuryCall (194) */
+  /** @name PalletTreasuryCall (192) */
   interface PalletTreasuryCall extends Enum {
     readonly isProposeSpend: boolean;
     readonly asProposeSpend: {
@@ -1844,10 +1855,10 @@
     readonly type: 'ProposeSpend' | 'RejectProposal' | 'ApproveProposal' | 'Spend' | 'RemoveApproval';
   }
 
-  /** @name FrameSupportPalletId (197) */
+  /** @name FrameSupportPalletId (195) */
   interface FrameSupportPalletId extends U8aFixed {}
 
-  /** @name PalletTreasuryError (198) */
+  /** @name PalletTreasuryError (196) */
   interface PalletTreasuryError extends Enum {
     readonly isInsufficientProposersBalance: boolean;
     readonly isInvalidIndex: boolean;
@@ -1857,7 +1868,7 @@
     readonly type: 'InsufficientProposersBalance' | 'InvalidIndex' | 'TooManyApprovals' | 'InsufficientPermission' | 'ProposalNotApproved';
   }
 
-  /** @name PalletSudoCall (199) */
+  /** @name PalletSudoCall (197) */
   interface PalletSudoCall extends Enum {
     readonly isSudo: boolean;
     readonly asSudo: {
@@ -1880,7 +1891,7 @@
     readonly type: 'Sudo' | 'SudoUncheckedWeight' | 'SetKey' | 'SudoAs';
   }
 
-  /** @name OrmlVestingModuleCall (201) */
+  /** @name OrmlVestingModuleCall (199) */
   interface OrmlVestingModuleCall extends Enum {
     readonly isClaim: boolean;
     readonly isVestedTransfer: boolean;
@@ -1900,7 +1911,7 @@
     readonly type: 'Claim' | 'VestedTransfer' | 'UpdateVestingSchedules' | 'ClaimFor';
   }
 
-  /** @name OrmlXtokensModuleCall (203) */
+  /** @name OrmlXtokensModuleCall (201) */
   interface OrmlXtokensModuleCall extends Enum {
     readonly isTransfer: boolean;
     readonly asTransfer: {
@@ -1947,7 +1958,7 @@
     readonly type: 'Transfer' | 'TransferMultiasset' | 'TransferWithFee' | 'TransferMultiassetWithFee' | 'TransferMulticurrencies' | 'TransferMultiassets';
   }
 
-  /** @name XcmVersionedMultiAsset (204) */
+  /** @name XcmVersionedMultiAsset (202) */
   interface XcmVersionedMultiAsset extends Enum {
     readonly isV0: boolean;
     readonly asV0: XcmV0MultiAsset;
@@ -1956,7 +1967,7 @@
     readonly type: 'V0' | 'V1';
   }
 
-  /** @name OrmlTokensModuleCall (207) */
+  /** @name OrmlTokensModuleCall (205) */
   interface OrmlTokensModuleCall extends Enum {
     readonly isTransfer: boolean;
     readonly asTransfer: {
@@ -1993,7 +2004,7 @@
     readonly type: 'Transfer' | 'TransferAll' | 'TransferKeepAlive' | 'ForceTransfer' | 'SetBalance';
   }
 
-  /** @name CumulusPalletXcmpQueueCall (208) */
+  /** @name CumulusPalletXcmpQueueCall (206) */
   interface CumulusPalletXcmpQueueCall extends Enum {
     readonly isServiceOverweight: boolean;
     readonly asServiceOverweight: {
@@ -2029,7 +2040,7 @@
     readonly type: 'ServiceOverweight' | 'SuspendXcmExecution' | 'ResumeXcmExecution' | 'UpdateSuspendThreshold' | 'UpdateDropThreshold' | 'UpdateResumeThreshold' | 'UpdateThresholdWeight' | 'UpdateWeightRestrictDecay' | 'UpdateXcmpMaxIndividualWeight';
   }
 
-  /** @name PalletXcmCall (209) */
+  /** @name PalletXcmCall (207) */
   interface PalletXcmCall extends Enum {
     readonly isSend: boolean;
     readonly asSend: {
@@ -2091,7 +2102,7 @@
     readonly type: 'Send' | 'TeleportAssets' | 'ReserveTransferAssets' | 'Execute' | 'ForceXcmVersion' | 'ForceDefaultXcmVersion' | 'ForceSubscribeVersionNotify' | 'ForceUnsubscribeVersionNotify' | 'LimitedReserveTransferAssets' | 'LimitedTeleportAssets';
   }
 
-  /** @name XcmVersionedXcm (210) */
+  /** @name XcmVersionedXcm (208) */
   interface XcmVersionedXcm extends Enum {
     readonly isV0: boolean;
     readonly asV0: XcmV0Xcm;
@@ -2102,7 +2113,7 @@
     readonly type: 'V0' | 'V1' | 'V2';
   }
 
-  /** @name XcmV0Xcm (211) */
+  /** @name XcmV0Xcm (209) */
   interface XcmV0Xcm extends Enum {
     readonly isWithdrawAsset: boolean;
     readonly asWithdrawAsset: {
@@ -2165,7 +2176,7 @@
     readonly type: 'WithdrawAsset' | 'ReserveAssetDeposit' | 'TeleportAsset' | 'QueryResponse' | 'TransferAsset' | 'TransferReserveAsset' | 'Transact' | 'HrmpNewChannelOpenRequest' | 'HrmpChannelAccepted' | 'HrmpChannelClosing' | 'RelayedFrom';
   }
 
-  /** @name XcmV0Order (213) */
+  /** @name XcmV0Order (211) */
   interface XcmV0Order extends Enum {
     readonly isNull: boolean;
     readonly isDepositAsset: boolean;
@@ -2213,14 +2224,14 @@
     readonly type: 'Null' | 'DepositAsset' | 'DepositReserveAsset' | 'ExchangeAsset' | 'InitiateReserveWithdraw' | 'InitiateTeleport' | 'QueryHolding' | 'BuyExecution';
   }
 
-  /** @name XcmV0Response (215) */
+  /** @name XcmV0Response (213) */
   interface XcmV0Response extends Enum {
     readonly isAssets: boolean;
     readonly asAssets: Vec<XcmV0MultiAsset>;
     readonly type: 'Assets';
   }
 
-  /** @name XcmV1Xcm (216) */
+  /** @name XcmV1Xcm (214) */
   interface XcmV1Xcm extends Enum {
     readonly isWithdrawAsset: boolean;
     readonly asWithdrawAsset: {
@@ -2289,7 +2300,7 @@
     readonly type: 'WithdrawAsset' | 'ReserveAssetDeposited' | 'ReceiveTeleportedAsset' | 'QueryResponse' | 'TransferAsset' | 'TransferReserveAsset' | 'Transact' | 'HrmpNewChannelOpenRequest' | 'HrmpChannelAccepted' | 'HrmpChannelClosing' | 'RelayedFrom' | 'SubscribeVersion' | 'UnsubscribeVersion';
   }
 
-  /** @name XcmV1Order (218) */
+  /** @name XcmV1Order (216) */
   interface XcmV1Order extends Enum {
     readonly isNoop: boolean;
     readonly isDepositAsset: boolean;
@@ -2339,7 +2350,7 @@
     readonly type: 'Noop' | 'DepositAsset' | 'DepositReserveAsset' | 'ExchangeAsset' | 'InitiateReserveWithdraw' | 'InitiateTeleport' | 'QueryHolding' | 'BuyExecution';
   }
 
-  /** @name XcmV1Response (220) */
+  /** @name XcmV1Response (218) */
   interface XcmV1Response extends Enum {
     readonly isAssets: boolean;
     readonly asAssets: XcmV1MultiassetMultiAssets;
@@ -2348,10 +2359,10 @@
     readonly type: 'Assets' | 'Version';
   }
 
-  /** @name CumulusPalletXcmCall (234) */
+  /** @name CumulusPalletXcmCall (232) */
   type CumulusPalletXcmCall = Null;
 
-  /** @name CumulusPalletDmpQueueCall (235) */
+  /** @name CumulusPalletDmpQueueCall (233) */
   interface CumulusPalletDmpQueueCall extends Enum {
     readonly isServiceOverweight: boolean;
     readonly asServiceOverweight: {
@@ -2361,7 +2372,7 @@
     readonly type: 'ServiceOverweight';
   }
 
-  /** @name PalletInflationCall (236) */
+  /** @name PalletInflationCall (234) */
   interface PalletInflationCall extends Enum {
     readonly isStartInflation: boolean;
     readonly asStartInflation: {
@@ -2370,7 +2381,7 @@
     readonly type: 'StartInflation';
   }
 
-  /** @name PalletUniqueCall (237) */
+  /** @name PalletUniqueCall (235) */
   interface PalletUniqueCall extends Enum {
     readonly isCreateCollection: boolean;
     readonly asCreateCollection: {
@@ -2528,7 +2539,7 @@
     readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetTokenPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetCollectionLimits' | 'SetCollectionPermissions' | 'Repartition';
   }
 
-  /** @name UpDataStructsCollectionMode (242) */
+  /** @name UpDataStructsCollectionMode (240) */
   interface UpDataStructsCollectionMode extends Enum {
     readonly isNft: boolean;
     readonly isFungible: boolean;
@@ -2537,7 +2548,7 @@
     readonly type: 'Nft' | 'Fungible' | 'ReFungible';
   }
 
-  /** @name UpDataStructsCreateCollectionData (243) */
+  /** @name UpDataStructsCreateCollectionData (241) */
   interface UpDataStructsCreateCollectionData extends Struct {
     readonly mode: UpDataStructsCollectionMode;
     readonly access: Option<UpDataStructsAccessMode>;
@@ -2551,14 +2562,14 @@
     readonly properties: Vec<UpDataStructsProperty>;
   }
 
-  /** @name UpDataStructsAccessMode (245) */
+  /** @name UpDataStructsAccessMode (243) */
   interface UpDataStructsAccessMode extends Enum {
     readonly isNormal: boolean;
     readonly isAllowList: boolean;
     readonly type: 'Normal' | 'AllowList';
   }
 
-  /** @name UpDataStructsCollectionLimits (247) */
+  /** @name UpDataStructsCollectionLimits (245) */
   interface UpDataStructsCollectionLimits extends Struct {
     readonly accountTokenOwnershipLimit: Option<u32>;
     readonly sponsoredDataSize: Option<u32>;
@@ -2571,7 +2582,7 @@
     readonly transfersEnabled: Option<bool>;
   }
 
-  /** @name UpDataStructsSponsoringRateLimit (249) */
+  /** @name UpDataStructsSponsoringRateLimit (247) */
   interface UpDataStructsSponsoringRateLimit extends Enum {
     readonly isSponsoringDisabled: boolean;
     readonly isBlocks: boolean;
@@ -2579,43 +2590,43 @@
     readonly type: 'SponsoringDisabled' | 'Blocks';
   }
 
-  /** @name UpDataStructsCollectionPermissions (252) */
+  /** @name UpDataStructsCollectionPermissions (250) */
   interface UpDataStructsCollectionPermissions extends Struct {
     readonly access: Option<UpDataStructsAccessMode>;
     readonly mintMode: Option<bool>;
     readonly nesting: Option<UpDataStructsNestingPermissions>;
   }
 
-  /** @name UpDataStructsNestingPermissions (254) */
+  /** @name UpDataStructsNestingPermissions (252) */
   interface UpDataStructsNestingPermissions extends Struct {
     readonly tokenOwner: bool;
     readonly collectionAdmin: bool;
     readonly restricted: Option<UpDataStructsOwnerRestrictedSet>;
   }
 
-  /** @name UpDataStructsOwnerRestrictedSet (256) */
+  /** @name UpDataStructsOwnerRestrictedSet (254) */
   interface UpDataStructsOwnerRestrictedSet extends BTreeSet<u32> {}
 
-  /** @name UpDataStructsPropertyKeyPermission (261) */
+  /** @name UpDataStructsPropertyKeyPermission (259) */
   interface UpDataStructsPropertyKeyPermission extends Struct {
     readonly key: Bytes;
     readonly permission: UpDataStructsPropertyPermission;
   }
 
-  /** @name UpDataStructsPropertyPermission (262) */
+  /** @name UpDataStructsPropertyPermission (260) */
   interface UpDataStructsPropertyPermission extends Struct {
     readonly mutable: bool;
     readonly collectionAdmin: bool;
     readonly tokenOwner: bool;
   }
 
-  /** @name UpDataStructsProperty (265) */
+  /** @name UpDataStructsProperty (263) */
   interface UpDataStructsProperty extends Struct {
     readonly key: Bytes;
     readonly value: Bytes;
   }
 
-  /** @name UpDataStructsCreateItemData (268) */
+  /** @name UpDataStructsCreateItemData (266) */
   interface UpDataStructsCreateItemData extends Enum {
     readonly isNft: boolean;
     readonly asNft: UpDataStructsCreateNftData;
@@ -2626,23 +2637,23 @@
     readonly type: 'Nft' | 'Fungible' | 'ReFungible';
   }
 
-  /** @name UpDataStructsCreateNftData (269) */
+  /** @name UpDataStructsCreateNftData (267) */
   interface UpDataStructsCreateNftData extends Struct {
     readonly properties: Vec<UpDataStructsProperty>;
   }
 
-  /** @name UpDataStructsCreateFungibleData (270) */
+  /** @name UpDataStructsCreateFungibleData (268) */
   interface UpDataStructsCreateFungibleData extends Struct {
     readonly value: u128;
   }
 
-  /** @name UpDataStructsCreateReFungibleData (271) */
+  /** @name UpDataStructsCreateReFungibleData (269) */
   interface UpDataStructsCreateReFungibleData extends Struct {
     readonly pieces: u128;
     readonly properties: Vec<UpDataStructsProperty>;
   }
 
-  /** @name UpDataStructsCreateItemExData (274) */
+  /** @name UpDataStructsCreateItemExData (272) */
   interface UpDataStructsCreateItemExData extends Enum {
     readonly isNft: boolean;
     readonly asNft: Vec<UpDataStructsCreateNftExData>;
@@ -2655,26 +2666,26 @@
     readonly type: 'Nft' | 'Fungible' | 'RefungibleMultipleItems' | 'RefungibleMultipleOwners';
   }
 
-  /** @name UpDataStructsCreateNftExData (276) */
+  /** @name UpDataStructsCreateNftExData (274) */
   interface UpDataStructsCreateNftExData extends Struct {
     readonly properties: Vec<UpDataStructsProperty>;
     readonly owner: PalletEvmAccountBasicCrossAccountIdRepr;
   }
 
-  /** @name UpDataStructsCreateRefungibleExSingleOwner (283) */
+  /** @name UpDataStructsCreateRefungibleExSingleOwner (281) */
   interface UpDataStructsCreateRefungibleExSingleOwner extends Struct {
     readonly user: PalletEvmAccountBasicCrossAccountIdRepr;
     readonly pieces: u128;
     readonly properties: Vec<UpDataStructsProperty>;
   }
 
-  /** @name UpDataStructsCreateRefungibleExMultipleOwners (285) */
+  /** @name UpDataStructsCreateRefungibleExMultipleOwners (283) */
   interface UpDataStructsCreateRefungibleExMultipleOwners extends Struct {
     readonly users: BTreeMap<PalletEvmAccountBasicCrossAccountIdRepr, u128>;
     readonly properties: Vec<UpDataStructsProperty>;
   }
 
-  /** @name PalletUniqueSchedulerCall (286) */
+  /** @name PalletUniqueSchedulerCall (284) */
   interface PalletUniqueSchedulerCall extends Enum {
     readonly isScheduleNamed: boolean;
     readonly asScheduleNamed: {
@@ -2704,7 +2715,7 @@
     readonly type: 'ScheduleNamed' | 'CancelNamed' | 'ScheduleNamedAfter' | 'ChangeNamedPriority';
   }
 
-  /** @name FrameSupportScheduleMaybeHashed (289) */
+  /** @name FrameSupportScheduleMaybeHashed (287) */
   interface FrameSupportScheduleMaybeHashed extends Enum {
     readonly isValue: boolean;
     readonly asValue: Call;
@@ -2713,7 +2724,7 @@
     readonly type: 'Value' | 'Hash';
   }
 
-  /** @name PalletConfigurationCall (290) */
+  /** @name PalletConfigurationCall (288) */
   interface PalletConfigurationCall extends Enum {
     readonly isSetWeightToFeeCoefficientOverride: boolean;
     readonly asSetWeightToFeeCoefficientOverride: {
@@ -2726,13 +2737,13 @@
     readonly type: 'SetWeightToFeeCoefficientOverride' | 'SetMinGasPriceOverride';
   }
 
-  /** @name PalletTemplateTransactionPaymentCall (292) */
+  /** @name PalletTemplateTransactionPaymentCall (290) */
   type PalletTemplateTransactionPaymentCall = Null;
 
-  /** @name PalletStructureCall (293) */
+  /** @name PalletStructureCall (291) */
   type PalletStructureCall = Null;
 
-  /** @name PalletRmrkCoreCall (294) */
+  /** @name PalletRmrkCoreCall (292) */
   interface PalletRmrkCoreCall extends Enum {
     readonly isCreateCollection: boolean;
     readonly asCreateCollection: {
@@ -2838,7 +2849,7 @@
     readonly type: 'CreateCollection' | 'DestroyCollection' | 'ChangeCollectionIssuer' | 'LockCollection' | 'MintNft' | 'BurnNft' | 'Send' | 'AcceptNft' | 'RejectNft' | 'AcceptResource' | 'AcceptResourceRemoval' | 'SetProperty' | 'SetPriority' | 'AddBasicResource' | 'AddComposableResource' | 'AddSlotResource' | 'RemoveResource';
   }
 
-  /** @name RmrkTraitsResourceResourceTypes (300) */
+  /** @name RmrkTraitsResourceResourceTypes (298) */
   interface RmrkTraitsResourceResourceTypes extends Enum {
     readonly isBasic: boolean;
     readonly asBasic: RmrkTraitsResourceBasicResource;
@@ -2849,7 +2860,7 @@
     readonly type: 'Basic' | 'Composable' | 'Slot';
   }
 
-  /** @name RmrkTraitsResourceBasicResource (302) */
+  /** @name RmrkTraitsResourceBasicResource (300) */
   interface RmrkTraitsResourceBasicResource extends Struct {
     readonly src: Option<Bytes>;
     readonly metadata: Option<Bytes>;
@@ -2857,7 +2868,7 @@
     readonly thumb: Option<Bytes>;
   }
 
-  /** @name RmrkTraitsResourceComposableResource (304) */
+  /** @name RmrkTraitsResourceComposableResource (302) */
   interface RmrkTraitsResourceComposableResource extends Struct {
     readonly parts: Vec<u32>;
     readonly base: u32;
@@ -2867,7 +2878,7 @@
     readonly thumb: Option<Bytes>;
   }
 
-  /** @name RmrkTraitsResourceSlotResource (305) */
+  /** @name RmrkTraitsResourceSlotResource (303) */
   interface RmrkTraitsResourceSlotResource extends Struct {
     readonly base: u32;
     readonly src: Option<Bytes>;
@@ -2877,7 +2888,7 @@
     readonly thumb: Option<Bytes>;
   }
 
-  /** @name PalletRmrkEquipCall (308) */
+  /** @name PalletRmrkEquipCall (306) */
   interface PalletRmrkEquipCall extends Enum {
     readonly isCreateBase: boolean;
     readonly asCreateBase: {
@@ -2899,7 +2910,7 @@
     readonly type: 'CreateBase' | 'ThemeAdd' | 'Equippable';
   }
 
-  /** @name RmrkTraitsPartPartType (311) */
+  /** @name RmrkTraitsPartPartType (309) */
   interface RmrkTraitsPartPartType extends Enum {
     readonly isFixedPart: boolean;
     readonly asFixedPart: RmrkTraitsPartFixedPart;
@@ -2908,14 +2919,14 @@
     readonly type: 'FixedPart' | 'SlotPart';
   }
 
-  /** @name RmrkTraitsPartFixedPart (313) */
+  /** @name RmrkTraitsPartFixedPart (311) */
   interface RmrkTraitsPartFixedPart extends Struct {
     readonly id: u32;
     readonly z: u32;
     readonly src: Bytes;
   }
 
-  /** @name RmrkTraitsPartSlotPart (314) */
+  /** @name RmrkTraitsPartSlotPart (312) */
   interface RmrkTraitsPartSlotPart extends Struct {
     readonly id: u32;
     readonly equippable: RmrkTraitsPartEquippableList;
@@ -2923,7 +2934,7 @@
     readonly z: u32;
   }
 
-  /** @name RmrkTraitsPartEquippableList (315) */
+  /** @name RmrkTraitsPartEquippableList (313) */
   interface RmrkTraitsPartEquippableList extends Enum {
     readonly isAll: boolean;
     readonly isEmpty: boolean;
@@ -2932,20 +2943,20 @@
     readonly type: 'All' | 'Empty' | 'Custom';
   }
 
-  /** @name RmrkTraitsTheme (317) */
+  /** @name RmrkTraitsTheme (315) */
   interface RmrkTraitsTheme extends Struct {
     readonly name: Bytes;
     readonly properties: Vec<RmrkTraitsThemeThemeProperty>;
     readonly inherit: bool;
   }
 
-  /** @name RmrkTraitsThemeThemeProperty (319) */
+  /** @name RmrkTraitsThemeThemeProperty (317) */
   interface RmrkTraitsThemeThemeProperty extends Struct {
     readonly key: Bytes;
     readonly value: Bytes;
   }
 
-  /** @name PalletAppPromotionCall (321) */
+  /** @name PalletAppPromotionCall (319) */
   interface PalletAppPromotionCall extends Enum {
     readonly isSetAdminAddress: boolean;
     readonly asSetAdminAddress: {
@@ -2979,7 +2990,7 @@
     readonly type: 'SetAdminAddress' | 'Stake' | 'Unstake' | 'SponsorCollection' | 'StopSponsoringCollection' | 'SponsorContract' | 'StopSponsoringContract' | 'PayoutStakers';
   }
 
-  /** @name PalletForeignAssetsModuleCall (322) */
+  /** @name PalletForeignAssetsModuleCall (320) */
   interface PalletForeignAssetsModuleCall extends Enum {
     readonly isRegisterForeignAsset: boolean;
     readonly asRegisterForeignAsset: {
@@ -2996,7 +3007,7 @@
     readonly type: 'RegisterForeignAsset' | 'UpdateForeignAsset';
   }
 
-  /** @name PalletEvmCall (323) */
+  /** @name PalletEvmCall (321) */
   interface PalletEvmCall extends Enum {
     readonly isWithdraw: boolean;
     readonly asWithdraw: {
@@ -3708,7 +3719,11 @@
     readonly isWithdrawFailed: boolean;
     readonly isGasPriceTooLow: boolean;
     readonly isInvalidNonce: boolean;
-    readonly type: 'BalanceLow' | 'FeeOverflow' | 'PaymentOverflow' | 'WithdrawFailed' | 'GasPriceTooLow' | 'InvalidNonce';
+    readonly isGasLimitTooLow: boolean;
+    readonly isGasLimitTooHigh: boolean;
+    readonly isUndefined: boolean;
+    readonly isReentrancy: boolean;
+    readonly type: 'BalanceLow' | 'FeeOverflow' | 'PaymentOverflow' | 'WithdrawFailed' | 'GasPriceTooLow' | 'InvalidNonce' | 'GasLimitTooLow' | 'GasLimitTooHigh' | 'Undefined' | 'Reentrancy';
   }
 
   /** @name FpRpcTransactionStatus (453) */
modifiedtests/src/maintenanceMode.seqtest.tsdiffbeforeafterboth
--- a/tests/src/maintenanceMode.seqtest.ts
+++ b/tests/src/maintenanceMode.seqtest.ts
@@ -237,7 +237,7 @@
     expect(tokenId).to.be.equal('1');
 
     await expect(contract.methods.mintWithTokenURI(receiver, 'Test URI').send())
-      .to.be.rejectedWith(/submit transaction to pool failed: Pool\(InvalidTransaction\(InvalidTransaction::Call\)\)/);
+      .to.be.rejectedWith(/Returned error: unknown error/);
 
     await expect(contract.methods.ownerOf(tokenId).call()).rejectedWith(/token not found/);