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

difftreelog

refactor move evm-coder out of the repo

Yaroslav Bolyukin2023-02-05parent: #8dd063b.patch.diff
in: master

51 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -172,9 +172,9 @@
 
 [[package]]
 name = "anyhow"
-version = "1.0.68"
+version = "1.0.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"
+checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800"
 
 [[package]]
 name = "app-promotion-rpc"
@@ -343,9 +343,9 @@
 
 [[package]]
 name = "async-trait"
-version = "0.1.63"
+version = "0.1.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eff18d764974428cf3a9328e23fc5c986f5fbed46e6cd4cdf42544df5d297ec1"
+checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -706,20 +706,9 @@
 
 [[package]]
 name = "bstr"
-version = "0.2.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
-dependencies = [
- "lazy_static",
- "memchr",
- "regex-automata",
-]
-
-[[package]]
-name = "bstr"
-version = "1.1.0"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b45ea9b00a7b3f2988e9a65ad3917e62123c38dba709b666506207be96d1790b"
+checksum = "b7f0778972c64420fdedc63f09919c8a88bda7b25135357fd25a5d9f3257e832"
 dependencies = [
  "memchr",
  "serde",
@@ -760,9 +749,9 @@
 
 [[package]]
 name = "bytes"
-version = "1.3.0"
+version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
+checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
 
 [[package]]
 name = "bzip2-sys"
@@ -808,9 +797,9 @@
 
 [[package]]
 name = "cc"
-version = "1.0.78"
+version = "1.0.79"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
+checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
 dependencies = [
  "jobserver",
 ]
@@ -1027,18 +1016,6 @@
 ]
 
 [[package]]
-name = "console"
-version = "0.15.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60"
-dependencies = [
- "encode_unicode",
- "lazy_static",
- "libc",
- "windows-sys 0.42.0",
-]
-
-[[package]]
 name = "const-oid"
 version = "0.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1221,9 +1198,9 @@
 
 [[package]]
 name = "crc"
-version = "3.0.0"
+version = "3.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53757d12b596c16c78b83458d732a5d1a17ab3f53f2f7412f6fb57cc8a140ab3"
+checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe"
 dependencies = [
  "crc-catalog",
 ]
@@ -1874,9 +1851,9 @@
 
 [[package]]
 name = "curve25519-dalek"
-version = "4.0.0-pre.5"
+version = "4.0.0-rc.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67bc65846be335cb20f4e52d49a437b773a2c1fdb42b19fc84e79e6f6771536f"
+checksum = "8da00a7a9a4eb92a0a0f8e75660926d48f0d0f3c537e455c457bcdaa1e16b1ac"
 dependencies = [
  "cfg-if",
  "fiat-crypto",
@@ -1888,9 +1865,9 @@
 
 [[package]]
 name = "cxx"
-version = "1.0.87"
+version = "1.0.89"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b61a7545f753a88bcbe0a70de1fcc0221e10bfc752f576754fa91e663db1622e"
+checksum = "bc831ee6a32dd495436e317595e639a587aa9907bef96fe6e6abc290ab6204e9"
 dependencies = [
  "cc",
  "cxxbridge-flags",
@@ -1900,9 +1877,9 @@
 
 [[package]]
 name = "cxx-build"
-version = "1.0.87"
+version = "1.0.89"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f464457d494b5ed6905c63b0c4704842aba319084a0a3561cdc1359536b53200"
+checksum = "94331d54f1b1a8895cd81049f7eaaaef9d05a7dcb4d1fd08bf3ff0806246789d"
 dependencies = [
  "cc",
  "codespan-reporting",
@@ -1915,15 +1892,15 @@
 
 [[package]]
 name = "cxxbridge-flags"
-version = "1.0.87"
+version = "1.0.89"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43c7119ce3a3701ed81aca8410b9acf6fc399d2629d057b87e2efa4e63a3aaea"
+checksum = "48dcd35ba14ca9b40d6e4b4b39961f23d835dbb8eed74565ded361d93e1feb8a"
 
 [[package]]
 name = "cxxbridge-macro"
-version = "1.0.87"
+version = "1.0.89"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65e07508b90551e610910fa648a1878991d367064997a596135b86df30daf07e"
+checksum = "81bbeb29798b407ccd82a3324ade1a7286e0d29851475990b612670f6f5124d2"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2268,9 +2245,9 @@
 
 [[package]]
 name = "either"
-version = "1.8.0"
+version = "1.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
+checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
 
 [[package]]
 name = "elliptic-curve"
@@ -2295,12 +2272,6 @@
 ]
 
 [[package]]
-name = "encode_unicode"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
-
-[[package]]
 name = "enum-as-inner"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2474,24 +2445,20 @@
 
 [[package]]
 name = "evm-coder"
-version = "0.1.6"
+version = "0.3.0"
+source = "git+https://github.com/uniquenetwork/evm-coder?tag=v0.3.0#c4bfdf39d84fbe74c6178417177f2a7f81d92bdd"
 dependencies = [
  "ethereum",
  "evm-coder-procedural",
- "evm-core",
- "frame-support",
- "hex",
- "hex-literal",
  "impl-trait-for-tuples",
  "primitive-types",
  "sha3-const",
- "similar-asserts",
- "trybuild",
 ]
 
 [[package]]
 name = "evm-coder-procedural"
-version = "0.2.3"
+version = "0.3.0"
+source = "git+https://github.com/uniquenetwork/evm-coder?tag=v0.3.0#c4bfdf39d84fbe74c6178417177f2a7f81d92bdd"
 dependencies = [
  "Inflector",
  "hex",
@@ -2502,6 +2469,15 @@
 ]
 
 [[package]]
+name = "evm-coder-substrate-procedural"
+version = "0.1.0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
 name = "evm-core"
 version = "0.37.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3227,9 +3203,9 @@
 
 [[package]]
 name = "fs_extra"
-version = "1.2.0"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394"
+checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
 
 [[package]]
 name = "funty"
@@ -3239,9 +3215,9 @@
 
 [[package]]
 name = "futures"
-version = "0.3.25"
+version = "0.3.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0"
+checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -3254,9 +3230,9 @@
 
 [[package]]
 name = "futures-channel"
-version = "0.3.25"
+version = "0.3.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed"
+checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5"
 dependencies = [
  "futures-core",
  "futures-sink",
@@ -3264,15 +3240,15 @@
 
 [[package]]
 name = "futures-core"
-version = "0.3.25"
+version = "0.3.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
+checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608"
 
 [[package]]
 name = "futures-executor"
-version = "0.3.25"
+version = "0.3.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2"
+checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e"
 dependencies = [
  "futures-core",
  "futures-task",
@@ -3282,9 +3258,9 @@
 
 [[package]]
 name = "futures-io"
-version = "0.3.25"
+version = "0.3.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb"
+checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531"
 
 [[package]]
 name = "futures-lite"
@@ -3303,9 +3279,9 @@
 
 [[package]]
 name = "futures-macro"
-version = "0.3.25"
+version = "0.3.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
+checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -3325,15 +3301,15 @@
 
 [[package]]
 name = "futures-sink"
-version = "0.3.25"
+version = "0.3.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
+checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364"
 
 [[package]]
 name = "futures-task"
-version = "0.3.25"
+version = "0.3.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
+checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366"
 
 [[package]]
 name = "futures-timer"
@@ -3343,9 +3319,9 @@
 
 [[package]]
 name = "futures-util"
-version = "0.3.25"
+version = "0.3.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
+checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -3469,7 +3445,7 @@
 checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc"
 dependencies = [
  "aho-corasick",
- "bstr 1.1.0",
+ "bstr",
  "fnv",
  "log",
  "regex",
@@ -3545,9 +3521,9 @@
 
 [[package]]
 name = "heck"
-version = "0.4.0"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
 
 [[package]]
 name = "hermit-abi"
@@ -3568,6 +3544,12 @@
 ]
 
 [[package]]
+name = "hermit-abi"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "856b5cb0902c2b6d65d5fd97dfa30f9b70c7538e770b98eab5ed52d8db923e01"
+
+[[package]]
 name = "hex"
 version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3697,9 +3679,9 @@
 
 [[package]]
 name = "hyper"
-version = "0.14.23"
+version = "0.14.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c"
+checksum = "5e011372fa0b68db8350aa7a248930ecc7839bf46d8485577d69f117a75f164c"
 dependencies = [
  "bytes",
  "futures-channel",
@@ -3914,12 +3896,12 @@
 
 [[package]]
 name = "io-lifetimes"
-version = "1.0.4"
+version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e"
+checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3"
 dependencies = [
  "libc",
- "windows-sys 0.42.0",
+ "windows-sys 0.45.0",
 ]
 
 [[package]]
@@ -3948,14 +3930,14 @@
 
 [[package]]
 name = "is-terminal"
-version = "0.4.2"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189"
+checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef"
 dependencies = [
- "hermit-abi 0.2.6",
- "io-lifetimes 1.0.4",
- "rustix 0.36.7",
- "windows-sys 0.42.0",
+ "hermit-abi 0.3.0",
+ "io-lifetimes 1.0.5",
+ "rustix 0.36.8",
+ "windows-sys 0.45.0",
 ]
 
 [[package]]
@@ -3984,9 +3966,9 @@
 
 [[package]]
 name = "js-sys"
-version = "0.3.60"
+version = "0.3.61"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
+checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730"
 dependencies = [
  "wasm-bindgen",
 ]
@@ -4974,7 +4956,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b20a59d985586e4a5aef64564ac77299f8586d8be6cf9106a5a40207e8908efb"
 dependencies = [
- "rustix 0.36.7",
+ "rustix 0.36.8",
 ]
 
 [[package]]
@@ -5284,9 +5266,9 @@
 
 [[package]]
 name = "netlink-packet-utils"
-version = "0.5.1"
+version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25af9cf0dc55498b7bd94a1508af7a78706aa0ab715a73c5169273e03c84845e"
+checksum = "0ede8a08c71ad5a95cdd0e4e52facd37190977039a4704eb82a283f713747d34"
 dependencies = [
  "anyhow",
  "byteorder",
@@ -6248,6 +6230,8 @@
 version = "0.1.3"
 dependencies = [
  "evm-coder",
+ "evm-coder-substrate-procedural",
+ "evm-core",
  "frame-benchmarking",
  "frame-support",
  "frame-system",
@@ -6256,6 +6240,7 @@
  "scale-info",
  "sp-core",
  "sp-std",
+ "spez",
  "up-data-structs",
 ]
 
@@ -7272,9 +7257,9 @@
 
 [[package]]
 name = "parity-scale-codec"
-version = "3.2.2"
+version = "3.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7ab01d0f889e957861bc65888d5ccbe82c158d0270136ba46820d43837cdf72"
+checksum = "c3840933452adf7b3b9145e27086a5a3376c619dca1a21b1e5a5af0d54979bed"
 dependencies = [
  "arrayvec 0.7.2",
  "bitvec",
@@ -7333,7 +7318,7 @@
 checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
 dependencies = [
  "lock_api",
- "parking_lot_core 0.9.6",
+ "parking_lot_core 0.9.7",
 ]
 
 [[package]]
@@ -7352,15 +7337,15 @@
 
 [[package]]
 name = "parking_lot_core"
-version = "0.9.6"
+version = "0.9.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf"
+checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
 dependencies = [
  "cfg-if",
  "libc",
  "redox_syscall",
  "smallvec",
- "windows-sys 0.42.0",
+ "windows-sys 0.45.0",
 ]
 
 [[package]]
@@ -8838,10 +8823,16 @@
 ]
 
 [[package]]
+name = "proc-macro-hack"
+version = "0.5.20+deprecated"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
+
+[[package]]
 name = "proc-macro2"
-version = "1.0.50"
+version = "1.0.51"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
+checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
 dependencies = [
  "unicode-ident",
 ]
@@ -9675,16 +9666,16 @@
 
 [[package]]
 name = "rustix"
-version = "0.36.7"
+version = "0.36.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03"
+checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644"
 dependencies = [
  "bitflags",
  "errno",
- "io-lifetimes 1.0.4",
+ "io-lifetimes 1.0.5",
  "libc",
  "linux-raw-sys 0.1.4",
- "windows-sys 0.42.0",
+ "windows-sys 0.45.0",
 ]
 
 [[package]]
@@ -10996,9 +10987,9 @@
 
 [[package]]
 name = "security-framework"
-version = "2.8.1"
+version = "2.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c4437699b6d34972de58652c68b98cb5b53a4199ab126db8e20ec8ded29a721"
+checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254"
 dependencies = [
  "bitflags",
  "core-foundation",
@@ -11072,9 +11063,9 @@
 
 [[package]]
 name = "serde_json"
-version = "1.0.91"
+version = "1.0.92"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
+checksum = "7434af0dc1cbd59268aa98b4c22c131c0584d2232f6fb166efb993e2832e896a"
 dependencies = [
  "itoa",
  "ryu",
@@ -11206,26 +11197,6 @@
 ]
 
 [[package]]
-name = "similar"
-version = "2.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf"
-dependencies = [
- "bstr 0.2.17",
- "unicode-segmentation",
-]
-
-[[package]]
-name = "similar-asserts"
-version = "1.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbf644ad016b75129f01a34a355dcb8d66a5bc803e417c7a77cc5d5ee9fa0f18"
-dependencies = [
- "console",
- "similar",
-]
-
-[[package]]
 name = "slab"
 version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -11275,14 +11246,14 @@
 
 [[package]]
 name = "snow"
-version = "0.9.0"
+version = "0.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "774d05a3edae07ce6d68ea6984f3c05e9bba8927e3dd591e3b479e5b03213d0d"
+checksum = "12ba5f4d4ff12bdb6a169ed51b7c48c0e0ac4b0b4b31012b2571e97d78d3201d"
 dependencies = [
  "aes-gcm 0.9.4",
  "blake2",
  "chacha20poly1305",
- "curve25519-dalek 4.0.0-pre.5",
+ "curve25519-dalek 4.0.0-rc.0",
  "rand_core 0.6.4",
  "ring",
  "rustc_version 0.4.0",
@@ -12031,6 +12002,28 @@
 ]
 
 [[package]]
+name = "spez"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "304d2fd6a79879f77b207ba8cd5079c22f872eaad65a3fb8d71799e5bacf368b"
+dependencies = [
+ "proc-macro-hack",
+ "spez-macros",
+]
+
+[[package]]
+name = "spez-macros"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7fa06037d8ccb6cdadc151129062ebc9e4281c1ea44b2c704582245d017d1dc"
+dependencies = [
+ "proc-macro-hack",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
 name = "spin"
 version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -12612,15 +12605,15 @@
 
 [[package]]
 name = "tinyvec_macros"
-version = "0.1.0"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
 
 [[package]]
 name = "tokio"
-version = "1.24.2"
+version = "1.25.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb"
+checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af"
 dependencies = [
  "autocfg",
  "bytes",
@@ -12702,9 +12695,9 @@
 
 [[package]]
 name = "toml_edit"
-version = "0.18.0"
+version = "0.18.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "729bfd096e40da9c001f778f5cdecbd2957929a24e10e5883d9392220a751581"
+checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b"
 dependencies = [
  "indexmap",
  "nom8",
@@ -12976,21 +12969,6 @@
  "sp-weights",
  "substrate-rpc-client",
  "zstd",
-]
-
-[[package]]
-name = "trybuild"
-version = "1.0.76"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ed2c57956f91546d4d33614265a85d55c8e1ab91484853a10335894786d7db6"
-dependencies = [
- "glob",
- "once_cell",
- "serde",
- "serde_derive",
- "serde_json",
- "termcolor",
- "toml",
 ]
 
 [[package]]
@@ -13108,12 +13086,6 @@
 dependencies = [
  "tinyvec",
 ]
-
-[[package]]
-name = "unicode-segmentation"
-version = "1.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"
 
 [[package]]
 name = "unicode-width"
@@ -13446,9 +13418,9 @@
 
 [[package]]
 name = "uuid"
-version = "1.2.2"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c"
+checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79"
 dependencies = [
  "getrandom 0.2.8",
 ]
@@ -13543,9 +13515,9 @@
 
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.83"
+version = "0.2.84"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
+checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b"
 dependencies = [
  "cfg-if",
  "wasm-bindgen-macro",
@@ -13553,9 +13525,9 @@
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.83"
+version = "0.2.84"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
+checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9"
 dependencies = [
  "bumpalo",
  "log",
@@ -13568,9 +13540,9 @@
 
 [[package]]
 name = "wasm-bindgen-futures"
-version = "0.4.33"
+version = "0.4.34"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d"
+checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454"
 dependencies = [
  "cfg-if",
  "js-sys",
@@ -13580,9 +13552,9 @@
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.83"
+version = "0.2.84"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
+checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -13590,9 +13562,9 @@
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.83"
+version = "0.2.84"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
+checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -13603,9 +13575,9 @@
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.83"
+version = "0.2.84"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
+checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
 
 [[package]]
 name = "wasm-instrument"
@@ -13886,9 +13858,9 @@
 
 [[package]]
 name = "web-sys"
-version = "0.3.60"
+version = "0.3.61"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
+checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97"
 dependencies = [
  "js-sys",
  "wasm-bindgen",
@@ -14338,6 +14310,30 @@
 ]
 
 [[package]]
+name = "windows-sys"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc 0.42.1",
+ "windows_i686_gnu 0.42.1",
+ "windows_i686_msvc 0.42.1",
+ "windows_x86_64_gnu 0.42.1",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc 0.42.1",
+]
+
+[[package]]
 name = "windows_aarch64_gnullvm"
 version = "0.42.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -14644,9 +14640,9 @@
 
 [[package]]
 name = "zstd-sys"
-version = "2.0.5+zstd.1.5.2"
+version = "2.0.6+zstd.1.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edc50ffce891ad571e9f9afe5039c4837bede781ac4bb13052ed7ae695518596"
+checksum = "68a3f9792c0c3dc6c165840a75f47ae1f4da402c2d006881129579f6597e801b"
 dependencies = [
  "cc",
  "libc",
modifiedCargo.tomldiffbeforeafterboth
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -19,7 +19,7 @@
 
 [workspace.dependencies]
 # Unique
-evm-coder = { default-features = false, path = "crates/evm-coder" }
+evm-coder = { git = "https://github.com/uniquenetwork/evm-coder", tag = "v0.3.0", default-features = false }
 struct-versioning = { path = "crates/struct-versioning" }
 precompile-utils-macro = { path = "runtime/common/ethereum/precompiles/utils/macro" }
 up-common = { path = "primitives/common", default-features = false }
deletedcrates/evm-coder/CHANGELOG.mddiffbeforeafterboth
--- a/crates/evm-coder/CHANGELOG.md
+++ /dev/null
@@ -1,48 +0,0 @@
-# Change Log
-
-All notable changes to this project will be documented in this file.
-
-<!-- bureaucrate goes here -->
-## [v0.1.6] - 2023-01-12
-
-### Added
-- Support Option<T> type.
-### Removed
-- Frontier dependency.
-
-## [v0.1.5] - 2022-11-30
-
-### Added
-- Derive macro to support structures and enums.
-
-## [v0.1.4] - 2022-11-02
-
-### Added
-
-- Named structures support.
-
-## [v0.1.3] - 2022-08-29
-
-### Fixed
-
-- Parsing simple values.
-
-## [v0.1.2] 2022-08-19
-
-### Added
-
-- Implementation `AbiWrite` for tuples.
-
-### Fixes
-
-- Tuple generation for solidity.
-
-## [v0.1.1] 2022-08-16
-
-### Other changes
-
-- build: Upgrade polkadot to v0.9.27 2c498572636f2b34d53b1c51b7283a761a7dc90a
-
-- build: Upgrade polkadot to v0.9.26 85515e54c4ca1b82a2630034e55dcc804c643bf8
-
-- build: Upgrade polkadot to v0.9.25 cdfb9bdc7b205ff1b5134f034ef9973d769e5e6b
deletedcrates/evm-coder/Cargo.tomldiffbeforeafterboth
--- a/crates/evm-coder/Cargo.toml
+++ /dev/null
@@ -1,32 +0,0 @@
-[package]
-edition = "2021"
-license = "GPLv3"
-name = "evm-coder"
-version = "0.1.6"
-
-[dependencies]
-sha3-const = { version = "0.1.1", default-features = false }
-# evm-coder reexports those proc-macro
-evm-coder-procedural = { path = "./procedural" }
-# Evm uses primitive-types for H160, H256 and others
-primitive-types = { workspace = true }
-# Evm doesn't have reexports for log and others
-ethereum = { workspace = true }
-frame-support = { workspace = true }
-# Error types for execution
-evm-core = { workspace = true }
-# We have tuple-heavy code in solidity.rs
-impl-trait-for-tuples = { workspace = true }
-
-[dev-dependencies]
-# We want to assert some large binary blobs equality in tests
-hex = "0.4.3"
-hex-literal = { workspace = true }
-similar-asserts = "1.4.2"
-trybuild = "1.0"
-
-[features]
-default = ["std"]
-std = ["ethereum/std", "evm-core/std", "frame-support/std", "primitive-types/std"]
-# Stub/interface generation
-stubgen = []
deletedcrates/evm-coder/README.mddiffbeforeafterboth
--- a/crates/evm-coder/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# evm-coder
-
-Library for seamless call translation between Rust and Solidity code
-
-By encoding solidity definitions in Rust, this library also provides generation of
-solidity interfaces for ethereum developers
-
-## Overview
-
-Most of this library functionality shouldn't be used directly, but via macros
-
-- [`solidity_interface`]
-- [`ToLog`]
-
-<!-- TODO: make links useable on github, by publishing crate to docs.rs, and linking it from here instead -->
\ No newline at end of file
deletedcrates/evm-coder/procedural/Cargo.tomldiffbeforeafterboth
--- a/crates/evm-coder/procedural/Cargo.toml
+++ /dev/null
@@ -1,19 +0,0 @@
-[package]
-edition = "2021"
-license = "GPLv3"
-name = "evm-coder-procedural"
-version = "0.2.3"
-
-[lib]
-proc-macro = true
-
-[dependencies]
-# Ethereum uses keccak (=sha3) for selectors
-sha3 = "0.10.1"
-# Value formatting
-Inflector = "0.11.4"
-hex = "0.4.3"
-# General proc-macro utilities
-proc-macro2 = "1.0"
-quote = "1.0"
-syn = { version = "1.0", features = ["full"] }
deletedcrates/evm-coder/procedural/src/abi_derive/derive_enum.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/abi_derive/derive_enum.rs
+++ /dev/null
@@ -1,199 +0,0 @@
-use quote::quote;
-
-use super::extract_docs;
-
-pub fn impl_solidity_option<'a>(
-	docs: Vec<String>,
-	name: &proc_macro2::Ident,
-	enum_options: impl Iterator<Item = &'a syn::Variant> + Clone,
-) -> proc_macro2::TokenStream {
-	let variant_names = enum_options.clone().map(|opt| {
-		let opt = &opt.ident;
-		let s = name.to_string() + "." + opt.to_string().as_str();
-		let as_string = proc_macro2::Literal::string(s.as_str());
-		quote!(#name::#opt => #as_string,)
-	});
-	let solidity_name = name.to_string();
-
-	let solidity_fields = enum_options.map(|v| {
-		let docs = extract_docs(&v.attrs).expect("TODO: handle bad docs");
-		let name = v.ident.to_string();
-		quote! {
-			SolidityEnumVariant {
-				docs: &[#(#docs),*],
-				name: #name,
-			}
-		}
-	});
-
-	quote!(
-		#[cfg(feature = "stubgen")]
-		impl ::evm_coder::solidity::SolidityEnumTy for #name {
-			fn generate_solidity_interface(tc: &evm_coder::solidity::TypeCollector) -> String {
-				use evm_coder::solidity::*;
-				use core::fmt::Write;
-				let interface = SolidityEnum {
-					docs: &[#(#docs),*],
-					name: #solidity_name,
-					fields: &[#(
-						#solidity_fields,
-					)*],
-				};
-				let mut out = String::new();
-				let _ = interface.format(&mut out, tc);
-				tc.collect(out);
-				#solidity_name.to_string()
-			}
-			fn solidity_option(&self) -> &str {
-				match self {
-					#(#variant_names)*
-				}
-			}
-		}
-	)
-}
-
-pub fn impl_enum_from_u8<'a>(
-	name: &proc_macro2::Ident,
-	enum_options: impl Iterator<Item = &'a syn::Variant>,
-) -> proc_macro2::TokenStream {
-	let error_str = format!("Value not convertible into enum \"{name}\"");
-	let error_str = proc_macro2::Literal::string(&error_str);
-	let enum_options = enum_options.enumerate().map(|(i, opt)| {
-		let opt = &opt.ident;
-		let n = proc_macro2::Literal::u8_suffixed(i as u8);
-		quote! {#n => Ok(#name::#opt),}
-	});
-
-	quote!(
-		impl TryFrom<u8> for #name {
-			type Error = &'static str;
-
-			fn try_from(value: u8) -> ::core::result::Result<Self, Self::Error> {
-				const err: &'static str = #error_str;
-				match value {
-					#(#enum_options)*
-					_ => Err(err)
-				}
-			}
-		}
-	)
-}
-
-pub fn impl_enum_abi_type(name: &syn::Ident) -> proc_macro2::TokenStream {
-	quote! {
-		impl ::evm_coder::abi::AbiType for #name {
-			const SIGNATURE: ::evm_coder::custom_signature::SignatureUnit = <u8 as ::evm_coder::abi::AbiType>::SIGNATURE;
-
-			fn is_dynamic() -> bool {
-				<u8 as ::evm_coder::abi::AbiType>::is_dynamic()
-			}
-			fn size() -> usize {
-				<u8 as ::evm_coder::abi::AbiType>::size()
-			}
-		}
-	}
-}
-
-pub fn impl_enum_abi_read(name: &syn::Ident) -> proc_macro2::TokenStream {
-	quote!(
-		impl ::evm_coder::abi::AbiRead for #name {
-			fn abi_read(reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Self> {
-				Ok(
-					<u8 as ::evm_coder::abi::AbiRead>::abi_read(reader)?
-						.try_into()?
-				)
-			}
-		}
-	)
-}
-
-pub fn impl_enum_abi_write(name: &syn::Ident) -> proc_macro2::TokenStream {
-	quote!(
-		impl ::evm_coder::abi::AbiWrite for #name {
-			fn abi_write(&self, writer: &mut ::evm_coder::abi::AbiWriter) {
-				::evm_coder::abi::AbiWrite::abi_write(&(*self as u8), writer);
-			}
-		}
-	)
-}
-
-pub fn impl_enum_solidity_type_name(name: &syn::Ident) -> proc_macro2::TokenStream {
-	quote!(
-		#[cfg(feature = "stubgen")]
-		impl ::evm_coder::solidity::SolidityTypeName for #name {
-			fn solidity_name(
-				writer: &mut impl ::core::fmt::Write,
-				tc: &::evm_coder::solidity::TypeCollector,
-			) -> ::core::fmt::Result {
-				write!(writer, "{}", tc.collect_enum::<Self>())
-			}
-
-			fn is_simple() -> bool {
-				true
-			}
-
-			fn solidity_default(
-				writer: &mut impl ::core::fmt::Write,
-				tc: &::evm_coder::solidity::TypeCollector,
-			) -> ::core::fmt::Result {
-				write!(writer, "{}", <#name as ::evm_coder::solidity::SolidityEnumTy>::solidity_option(&<#name>::default()))
-			}
-		}
-	)
-}
-
-pub fn check_enum_fields(de: &syn::DataEnum) -> syn::Result<()> {
-	for v in de.variants.iter() {
-		if !v.fields.is_empty() {
-			return Err(syn::Error::new(
-				v.ident.span(),
-				"Enumeration parameters should not have fields",
-			));
-		} else if v.discriminant.is_some() {
-			return Err(syn::Error::new(
-				v.ident.span(),
-				"Enumeration options should not have an explicit specified value",
-			));
-		}
-	}
-
-	Ok(())
-}
-
-pub fn check_repr_u8(name: &syn::Ident, attrs: &[syn::Attribute]) -> syn::Result<()> {
-	let mut has_repr = false;
-	for attr in attrs.iter() {
-		if attr.path.is_ident("repr") {
-			has_repr = true;
-			let meta = attr.parse_meta()?;
-			check_meta_u8(&meta)?;
-		}
-	}
-
-	if !has_repr {
-		return Err(syn::Error::new(name.span(), "Enum is not \"repr(u8)\""));
-	}
-
-	Ok(())
-}
-
-fn check_meta_u8(meta: &syn::Meta) -> Result<(), syn::Error> {
-	if let syn::Meta::List(p) = meta {
-		for nm in p.nested.iter() {
-			if let syn::NestedMeta::Meta(syn::Meta::Path(p)) = nm {
-				if !p.is_ident("u8") {
-					return Err(syn::Error::new(
-						p.segments
-							.first()
-							.expect("repr segments are empty")
-							.ident
-							.span(),
-						"Enum is not \"repr(u8)\"",
-					));
-				}
-			}
-		}
-	}
-	Ok(())
-}
deletedcrates/evm-coder/procedural/src/abi_derive/derive_struct.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/abi_derive/derive_struct.rs
+++ /dev/null
@@ -1,231 +0,0 @@
-use super::extract_docs;
-use quote::quote;
-use syn::Field;
-
-pub fn tuple_type<'a>(
-	field_types: impl Iterator<Item = &'a syn::Type> + Clone,
-) -> proc_macro2::TokenStream {
-	let field_types = field_types.map(|ty| quote!(#ty,));
-	quote! {(#(#field_types)*)}
-}
-
-pub fn tuple_ref_type<'a>(
-	field_types: impl Iterator<Item = &'a syn::Type> + Clone,
-) -> proc_macro2::TokenStream {
-	let field_types = field_types.map(|ty| quote!(&#ty,));
-	quote! {(#(#field_types)*)}
-}
-
-pub fn tuple_data_as_ref(
-	is_named_fields: bool,
-	field_names: impl Iterator<Item = syn::Ident> + Clone,
-) -> proc_macro2::TokenStream {
-	let field_names = field_names.enumerate().map(|(i, field)| {
-		if is_named_fields {
-			quote!(&self.#field,)
-		} else {
-			let field = proc_macro2::Literal::usize_unsuffixed(i);
-			quote!(&self.#field,)
-		}
-	});
-	quote! {(#(#field_names)*)}
-}
-
-pub fn tuple_names(
-	is_named_fields: bool,
-	field_names: impl Iterator<Item = syn::Ident> + Clone,
-) -> proc_macro2::TokenStream {
-	let field_names = field_names.enumerate().map(|(i, field)| {
-		if is_named_fields {
-			quote!(#field,)
-		} else {
-			let field = proc_macro2::Ident::new(
-				format!("field{}", i).as_str(),
-				proc_macro2::Span::call_site(),
-			);
-			quote!(#field,)
-		}
-	});
-	quote! {(#(#field_names)*)}
-}
-
-pub fn struct_from_tuple(
-	name: &syn::Ident,
-	is_named_fields: bool,
-	field_names: impl Iterator<Item = syn::Ident> + Clone,
-) -> proc_macro2::TokenStream {
-	let field_names = field_names.enumerate().map(|(i, field)| {
-		if is_named_fields {
-			quote!(#field,)
-		} else {
-			let field = proc_macro2::Ident::new(
-				format!("field{}", i).as_str(),
-				proc_macro2::Span::call_site(),
-			);
-			quote!(#field,)
-		}
-	});
-
-	if is_named_fields {
-		quote! {#name {#(#field_names)*}}
-	} else {
-		quote! {#name (#(#field_names)*)}
-	}
-}
-
-pub fn map_field_to_name(field: (usize, &syn::Field)) -> syn::Ident {
-	match field.1.ident.as_ref() {
-		Some(name) => name.clone(),
-		None => {
-			let mut name = "field".to_string();
-			name.push_str(field.0.to_string().as_str());
-			syn::Ident::new(name.as_str(), proc_macro2::Span::call_site())
-		}
-	}
-}
-
-pub fn map_field_to_type(field: &syn::Field) -> &syn::Type {
-	&field.ty
-}
-
-pub fn impl_can_be_placed_in_vec(ident: &syn::Ident) -> proc_macro2::TokenStream {
-	quote! {
-		impl ::evm_coder::sealed::CanBePlacedInVec for #ident {}
-	}
-}
-
-pub fn impl_struct_abi_type(
-	name: &syn::Ident,
-	tuple_type: proc_macro2::TokenStream,
-) -> proc_macro2::TokenStream {
-	quote! {
-		impl ::evm_coder::abi::AbiType for #name {
-			const SIGNATURE: ::evm_coder::custom_signature::SignatureUnit = <#tuple_type as ::evm_coder::abi::AbiType>::SIGNATURE;
-			fn is_dynamic() -> bool {
-				<#tuple_type as ::evm_coder::abi::AbiType>::is_dynamic()
-			}
-			fn size() -> usize {
-				<#tuple_type as ::evm_coder::abi::AbiType>::size()
-			}
-		}
-	}
-}
-
-pub fn impl_struct_abi_read(
-	name: &syn::Ident,
-	tuple_type: proc_macro2::TokenStream,
-	tuple_names: proc_macro2::TokenStream,
-	struct_from_tuple: proc_macro2::TokenStream,
-) -> proc_macro2::TokenStream {
-	quote!(
-		impl ::evm_coder::abi::AbiRead for #name {
-			fn abi_read(reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Self> {
-				let #tuple_names = <#tuple_type as ::evm_coder::abi::AbiRead>::abi_read(reader)?;
-				Ok(#struct_from_tuple)
-			}
-		}
-	)
-}
-
-pub fn impl_struct_abi_write(
-	name: &syn::Ident,
-	_is_named_fields: bool,
-	tuple_type: proc_macro2::TokenStream,
-	tuple_data: proc_macro2::TokenStream,
-) -> proc_macro2::TokenStream {
-	quote!(
-		impl ::evm_coder::abi::AbiWrite for #name {
-			fn abi_write(&self, writer: &mut ::evm_coder::abi::AbiWriter) {
-				<#tuple_type as ::evm_coder::abi::AbiWrite>::abi_write(&#tuple_data, writer)
-			}
-		}
-	)
-}
-
-pub fn impl_struct_solidity_type<'a>(
-	name: &syn::Ident,
-	docs: Vec<String>,
-	fields: impl Iterator<Item = &'a Field> + Clone,
-) -> proc_macro2::TokenStream {
-	let solidity_name = name.to_string();
-	let solidity_fields = fields.enumerate().map(|(i, f)| {
-		let name = f
-			.ident
-			.as_ref()
-			.map(|i| i.to_string())
-			.unwrap_or_else(|| format!("field_{i}"));
-		let ty = &f.ty;
-		let docs = extract_docs(&f.attrs).expect("TODO: handle bad docs");
-		quote! {
-			SolidityStructField::<#ty> {
-				docs: &[#(#docs),*],
-				name: #name,
-				ty: ::core::marker::PhantomData,
-			}
-		}
-	});
-	quote! {
-		#[cfg(feature = "stubgen")]
-		impl ::evm_coder::solidity::SolidityStructTy for #name {
-			/// Generate solidity definitions for methods described in this struct
-			fn generate_solidity_interface(tc: &evm_coder::solidity::TypeCollector) -> String {
-				use evm_coder::solidity::*;
-				use core::fmt::Write;
-				let interface = SolidityStruct {
-					docs: &[#(#docs),*],
-					name: #solidity_name,
-					fields: (#(
-						#solidity_fields,
-					)*),
-				};
-				let mut out = String::new();
-				let _ = interface.format(&mut out, tc);
-				tc.collect(out);
-				#solidity_name.to_string()
-			}
-		}
-	}
-}
-
-pub fn impl_struct_solidity_type_name<'a>(
-	name: &syn::Ident,
-	field_types: impl Iterator<Item = &'a syn::Type> + Clone,
-	params_count: usize,
-) -> proc_macro2::TokenStream {
-	let arg_dafaults = field_types.enumerate().map(|(i, ty)| {
-		let mut defult_value = quote!(<#ty as ::evm_coder::solidity::SolidityTypeName
-			>::solidity_default(writer, tc)?;);
-		let last_item = params_count - 1;
-		if i != last_item {
-			defult_value.extend(quote! {write!(writer, ",")?;})
-		}
-		defult_value
-	});
-
-	quote! {
-		#[cfg(feature = "stubgen")]
-		impl ::evm_coder::solidity::SolidityTypeName for #name {
-			fn solidity_name(
-				writer: &mut impl ::core::fmt::Write,
-				tc: &::evm_coder::solidity::TypeCollector,
-			) -> ::core::fmt::Result {
-				write!(writer, "{}", tc.collect_struct::<Self>())
-			}
-
-			fn is_simple() -> bool {
-				false
-			}
-
-			fn solidity_default(
-				writer: &mut impl ::core::fmt::Write,
-				tc: &::evm_coder::solidity::TypeCollector,
-			) -> ::core::fmt::Result {
-				write!(writer, "{}(", tc.collect_struct::<Self>())?;
-
-				#(#arg_dafaults)*
-
-				write!(writer, ")")
-			}
-		}
-	}
-}
deletedcrates/evm-coder/procedural/src/abi_derive/mod.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/abi_derive/mod.rs
+++ /dev/null
@@ -1,118 +0,0 @@
-mod derive_enum;
-mod derive_struct;
-
-use quote::quote;
-use derive_struct::*;
-use derive_enum::*;
-
-pub(crate) fn impl_abi_macro(ast: &syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
-	let name = &ast.ident;
-	match &ast.data {
-		syn::Data::Struct(ds) => expand_struct(ds, ast),
-		syn::Data::Enum(de) => expand_enum(de, ast),
-		syn::Data::Union(_) => Err(syn::Error::new(name.span(), "Unions not supported")),
-	}
-}
-
-fn expand_struct(
-	ds: &syn::DataStruct,
-	ast: &syn::DeriveInput,
-) -> syn::Result<proc_macro2::TokenStream> {
-	let name = &ast.ident;
-	let docs = extract_docs(&ast.attrs)?;
-	let (is_named_fields, field_names, field_types, params_count) = match ds.fields {
-		syn::Fields::Named(ref fields) => Ok((
-			true,
-			fields.named.iter().enumerate().map(map_field_to_name),
-			fields.named.iter().map(map_field_to_type),
-			fields.named.len(),
-		)),
-		syn::Fields::Unnamed(ref fields) => Ok((
-			false,
-			fields.unnamed.iter().enumerate().map(map_field_to_name),
-			fields.unnamed.iter().map(map_field_to_type),
-			fields.unnamed.len(),
-		)),
-		syn::Fields::Unit => Err(syn::Error::new(name.span(), "Unit structs not supported")),
-	}?;
-
-	if params_count == 0 {
-		return Err(syn::Error::new(name.span(), "Empty structs not supported"));
-	};
-
-	let tuple_type = tuple_type(field_types.clone());
-	let tuple_ref_type = tuple_ref_type(field_types.clone());
-	let tuple_data = tuple_data_as_ref(is_named_fields, field_names.clone());
-	let tuple_names = tuple_names(is_named_fields, field_names.clone());
-	let struct_from_tuple = struct_from_tuple(name, is_named_fields, field_names.clone());
-
-	let can_be_plcaed_in_vec = impl_can_be_placed_in_vec(name);
-	let abi_type = impl_struct_abi_type(name, tuple_type.clone());
-	let abi_read = impl_struct_abi_read(name, tuple_type, tuple_names, struct_from_tuple);
-	let abi_write = impl_struct_abi_write(name, is_named_fields, tuple_ref_type, tuple_data);
-	let solidity_type = impl_struct_solidity_type(name, docs, ds.fields.iter());
-	let solidity_type_name =
-		impl_struct_solidity_type_name(name, field_types.clone(), params_count);
-
-	Ok(quote! {
-		#can_be_plcaed_in_vec
-		#abi_type
-		#abi_read
-		#abi_write
-		#solidity_type
-		#solidity_type_name
-	})
-}
-
-fn expand_enum(
-	de: &syn::DataEnum,
-	ast: &syn::DeriveInput,
-) -> syn::Result<proc_macro2::TokenStream> {
-	let name = &ast.ident;
-	check_repr_u8(name, &ast.attrs)?;
-	check_enum_fields(de)?;
-	let docs = extract_docs(&ast.attrs)?;
-	let enum_options = de.variants.iter();
-
-	let from = impl_enum_from_u8(name, enum_options.clone());
-	let solidity_option = impl_solidity_option(docs, name, enum_options.clone());
-	let can_be_plcaed_in_vec = impl_can_be_placed_in_vec(name);
-	let abi_type = impl_enum_abi_type(name);
-	let abi_read = impl_enum_abi_read(name);
-	let abi_write = impl_enum_abi_write(name);
-	let solidity_type_name = impl_enum_solidity_type_name(name);
-
-	Ok(quote! {
-		#from
-		#solidity_option
-		#can_be_plcaed_in_vec
-		#abi_type
-		#abi_read
-		#abi_write
-		#solidity_type_name
-	})
-}
-
-fn extract_docs(attrs: &[syn::Attribute]) -> syn::Result<Vec<String>> {
-	attrs
-		.iter()
-		.filter_map(|attr| {
-			if let Some(ps) = attr.path.segments.first() {
-				if ps.ident == "doc" {
-					let meta = match attr.parse_meta() {
-						Ok(meta) => meta,
-						Err(e) => return Some(Err(e)),
-					};
-					match meta {
-						syn::Meta::NameValue(mnv) => match &mnv.lit {
-							syn::Lit::Str(ls) => return Some(Ok(ls.value())),
-							_ => unreachable!(),
-						},
-						_ => unreachable!(),
-					}
-				}
-			}
-			None
-		})
-		.collect()
-}
deletedcrates/evm-coder/procedural/src/lib.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/lib.rs
+++ /dev/null
@@ -1,255 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-#![allow(dead_code)]
-
-use inflector::cases;
-use proc_macro::TokenStream;
-use quote::quote;
-use sha3::{Digest, Keccak256};
-use syn::{
-	DeriveInput, GenericArgument, Ident, ItemImpl, Pat, Path, PathArguments, PathSegment, Type,
-	parse_macro_input, spanned::Spanned,
-};
-
-mod abi_derive;
-mod solidity_interface;
-mod to_log;
-
-fn fn_selector_str(input: &str) -> u32 {
-	let mut hasher = Keccak256::new();
-	hasher.update(input.as_bytes());
-	let result = hasher.finalize();
-
-	let mut selector_bytes = [0; 4];
-	selector_bytes.copy_from_slice(&result[0..4]);
-
-	u32::from_be_bytes(selector_bytes)
-}
-
-/// Returns solidity function selector (first 4 bytes of hash) by its
-/// textual representation
-///
-/// ```ignore
-/// use evm_coder_macros::fn_selector;
-///
-/// assert_eq!(fn_selector!(transfer(address, uint256)), 0xa9059cbb);
-/// ```
-#[proc_macro]
-pub fn fn_selector(input: TokenStream) -> TokenStream {
-	let input = input.to_string().replace(' ', "");
-	let selector = fn_selector_str(&input);
-
-	(quote! {
-		#selector
-	})
-	.into()
-}
-
-fn event_selector_str(input: &str) -> [u8; 32] {
-	let mut hasher = Keccak256::new();
-	hasher.update(input.as_bytes());
-	let result = hasher.finalize();
-
-	let mut selector_bytes = [0; 32];
-	selector_bytes.copy_from_slice(&result[0..32]);
-	selector_bytes
-}
-
-/// Returns solidity topic (hash) by its textual representation
-///
-/// ```ignore
-/// use evm_coder_macros::event_topic;
-///
-/// assert_eq!(
-///     format!("{:x}", event_topic!(Transfer(address, address, uint256))),
-///     "ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
-/// );
-/// ```
-#[proc_macro]
-pub fn event_topic(stream: TokenStream) -> TokenStream {
-	let input = stream.to_string().replace(' ', "");
-	let selector_bytes = event_selector_str(&input);
-
-	(quote! {
-		::primitive_types::H256([#(
-			#selector_bytes,
-		)*])
-	})
-	.into()
-}
-
-fn parse_path(ty: &Type) -> syn::Result<&Path> {
-	match &ty {
-		syn::Type::Path(pat) => {
-			if let Some(qself) = &pat.qself {
-				return Err(syn::Error::new(qself.ty.span(), "no receiver expected"));
-			}
-			Ok(&pat.path)
-		}
-		_ => Err(syn::Error::new(ty.span(), "expected ty to be path")),
-	}
-}
-
-fn parse_path_segment(path: &Path) -> syn::Result<&PathSegment> {
-	if path.segments.len() != 1 {
-		return Err(syn::Error::new(
-			path.span(),
-			"expected path to have only one segment",
-		));
-	}
-	let last_segment = &path.segments.last().unwrap();
-	Ok(last_segment)
-}
-
-fn parse_ident_from_pat(pat: &Pat) -> syn::Result<&Ident> {
-	match pat {
-		Pat::Ident(i) => Ok(&i.ident),
-		_ => Err(syn::Error::new(pat.span(), "expected pat ident")),
-	}
-}
-
-fn parse_ident_from_segment(segment: &PathSegment, allow_generics: bool) -> syn::Result<&Ident> {
-	if segment.arguments != PathArguments::None && !allow_generics {
-		return Err(syn::Error::new(
-			segment.arguments.span(),
-			"unexpected generic type",
-		));
-	}
-	Ok(&segment.ident)
-}
-
-fn parse_ident_from_path(path: &Path, allow_generics: bool) -> syn::Result<&Ident> {
-	let segment = parse_path_segment(path)?;
-	parse_ident_from_segment(segment, allow_generics)
-}
-
-fn parse_ident_from_type(ty: &Type, allow_generics: bool) -> syn::Result<&Ident> {
-	let path = parse_path(ty)?;
-	parse_ident_from_path(path, allow_generics)
-}
-
-// Gets T out of Result<T>
-fn parse_result_ok(ty: &Type) -> syn::Result<&Type> {
-	let path = parse_path(ty)?;
-	let segment = parse_path_segment(path)?;
-
-	if segment.ident != "Result" {
-		return Err(syn::Error::new(
-			ty.span(),
-			"expected Result as return type (no renamed aliases allowed)",
-		));
-	}
-	let args = match &segment.arguments {
-		PathArguments::AngleBracketed(e) => e,
-		_ => {
-			return Err(syn::Error::new(
-				segment.arguments.span(),
-				"missing Result generics",
-			))
-		}
-	};
-
-	let args = &args.args;
-	let arg = args.first().unwrap();
-
-	let ty = match arg {
-		GenericArgument::Type(ty) => ty,
-		_ => {
-			return Err(syn::Error::new(
-				arg.span(),
-				"expected first generic to be type",
-			))
-		}
-	};
-
-	Ok(ty)
-}
-
-fn pascal_ident_to_call(ident: &Ident) -> Ident {
-	let name = format!("{}Call", ident);
-	Ident::new(&name, ident.span())
-}
-fn snake_ident_to_pascal(ident: &Ident) -> Ident {
-	let name = ident.to_string();
-	let name = cases::pascalcase::to_pascal_case(&name);
-	Ident::new(&name, ident.span())
-}
-fn snake_ident_to_screaming(ident: &Ident) -> Ident {
-	let name = ident.to_string();
-	let name = cases::screamingsnakecase::to_screaming_snake_case(&name);
-	Ident::new(&name, ident.span())
-}
-fn pascal_ident_to_snake_call(ident: &Ident) -> Ident {
-	let name = ident.to_string();
-	let name = cases::snakecase::to_snake_case(&name);
-	let name = format!("call_{}", name);
-	Ident::new(&name, ident.span())
-}
-
-/// See documentation for this proc-macro reexported in `evm-coder` crate
-#[proc_macro_attribute]
-pub fn solidity_interface(args: TokenStream, stream: TokenStream) -> TokenStream {
-	let args = parse_macro_input!(args as solidity_interface::InterfaceInfo);
-
-	let input: ItemImpl = match syn::parse(stream) {
-		Ok(t) => t,
-		Err(e) => return e.to_compile_error().into(),
-	};
-
-	let expanded = match solidity_interface::SolidityInterface::try_from(args, &input) {
-		Ok(v) => v.expand(),
-		Err(e) => e.to_compile_error(),
-	};
-
-	(quote! {
-		#input
-
-		#expanded
-	})
-	.into()
-}
-
-#[proc_macro_attribute]
-pub fn solidity(_args: TokenStream, stream: TokenStream) -> TokenStream {
-	stream
-}
-#[proc_macro_attribute]
-pub fn weight(_args: TokenStream, stream: TokenStream) -> TokenStream {
-	stream
-}
-
-/// See documentation for this proc-macro reexported in `evm-coder` crate
-#[proc_macro_derive(ToLog, attributes(indexed))]
-pub fn to_log(value: TokenStream) -> TokenStream {
-	let input = parse_macro_input!(value as DeriveInput);
-
-	match to_log::Events::try_from(&input) {
-		Ok(e) => e.expand(),
-		Err(e) => e.to_compile_error(),
-	}
-	.into()
-}
-
-#[proc_macro_derive(AbiCoder)]
-pub fn abi_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
-	let ast = syn::parse(input).unwrap();
-	let ts = match abi_derive::impl_abi_macro(&ast) {
-		Ok(e) => e,
-		Err(e) => e.to_compile_error(),
-	};
-	ts.into()
-}
deletedcrates/evm-coder/procedural/src/solidity_interface.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/solidity_interface.rs
+++ /dev/null
@@ -1,1099 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-#![allow(dead_code)]
-
-// NOTE: In order to understand this Rust macro better, first read this chapter
-// about Procedural Macros in Rust book:
-// https://doc.rust-lang.org/reference/procedural-macros.html
-
-use proc_macro2::TokenStream;
-use quote::{quote, format_ident};
-use inflector::cases;
-use syn::{
-	Expr, FnArg, Generics, Ident, ImplItem, ImplItemMethod, ItemImpl, Lit, Meta, MetaNameValue,
-	PatType, ReturnType, Type,
-	spanned::Spanned,
-	parse::{Parse, ParseStream},
-	parenthesized, Token, LitInt, LitStr,
-};
-
-use crate::{
-	parse_ident_from_pat, parse_ident_from_path, parse_path, parse_path_segment, parse_result_ok,
-	pascal_ident_to_call, pascal_ident_to_snake_call, snake_ident_to_pascal,
-	snake_ident_to_screaming,
-};
-
-struct Is {
-	name: Ident,
-	pascal_call_name: Ident,
-	snake_call_name: Ident,
-	via: Option<(Type, Ident)>,
-	condition: Option<Expr>,
-}
-impl Is {
-	fn expand_call_def(&self, gen_ref: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {
-		let name = &self.name;
-		let pascal_call_name = &self.pascal_call_name;
-		quote! {
-			#name(#pascal_call_name #gen_ref)
-		}
-	}
-
-	fn expand_interface_id(&self) -> proc_macro2::TokenStream {
-		let pascal_call_name = &self.pascal_call_name;
-		quote! {
-			interface_id ^= u32::from_be_bytes(#pascal_call_name::interface_id());
-		}
-	}
-
-	fn expand_supports_interface(
-		&self,
-		generics: &proc_macro2::TokenStream,
-	) -> proc_macro2::TokenStream {
-		let pascal_call_name = &self.pascal_call_name;
-		let condition = self.condition.as_ref().map(|condition| {
-			quote! {
-				(#condition) &&
-			}
-		});
-		quote! {
-			#condition <#pascal_call_name #generics>::supports_interface(this, interface_id)
-		}
-	}
-
-	fn expand_variant_weight(&self) -> proc_macro2::TokenStream {
-		let name = &self.name;
-		quote! {
-			Self::#name(call) => call.weight()
-		}
-	}
-
-	fn expand_variant_call(
-		&self,
-		call_name: &proc_macro2::Ident,
-		generics: &proc_macro2::TokenStream,
-	) -> proc_macro2::TokenStream {
-		let name = &self.name;
-		let pascal_call_name = &self.pascal_call_name;
-		let via_typ = self
-			.via
-			.as_ref()
-			.map(|(t, _)| quote! {#t})
-			.unwrap_or_else(|| quote! {Self});
-		let via_map = self
-			.via
-			.as_ref()
-			.map(|(_, i)| quote! {.#i()})
-			.unwrap_or_default();
-		let condition = self.condition.as_ref().map(|condition| {
-			quote! {
-				if ({let this = &self; (#condition)})
-			}
-		});
-		quote! {
-			#call_name::#name(call) #condition => return <#via_typ as ::evm_coder::Callable<#pascal_call_name #generics>>::call(self #via_map, Msg {
-				call,
-				caller: c.caller,
-				value: c.value,
-			})
-		}
-	}
-
-	fn expand_parse(&self, generics: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {
-		let name = &self.name;
-		let pascal_call_name = &self.pascal_call_name;
-		quote! {
-			if let Some(parsed_call) = <#pascal_call_name #generics>::parse(method_id, reader)? {
-				return Ok(Some(Self::#name(parsed_call)))
-			}
-		}
-	}
-
-	fn expand_generator(&self, generics: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {
-		let pascal_call_name = &self.pascal_call_name;
-		quote! {
-			<#pascal_call_name #generics>::generate_solidity_interface(tc, is_impl);
-		}
-	}
-
-	fn expand_event_generator(&self) -> proc_macro2::TokenStream {
-		let name = &self.name;
-		quote! {
-			#name::generate_solidity_interface(tc, is_impl);
-		}
-	}
-}
-
-#[derive(Default)]
-struct IsList(Vec<Is>);
-impl Parse for IsList {
-	fn parse(input: ParseStream) -> syn::Result<Self> {
-		let mut out = vec![];
-		loop {
-			if input.is_empty() {
-				break;
-			}
-			let name = input.parse::<Ident>()?;
-			let lookahead = input.lookahead1();
-
-			let mut condition: Option<Expr> = None;
-			let mut via: Option<(Type, Ident)> = None;
-
-			if lookahead.peek(syn::token::Paren) {
-				let contents;
-				parenthesized!(contents in input);
-				let input = contents;
-
-				while !input.is_empty() {
-					let lookahead = input.lookahead1();
-					if lookahead.peek(Token![if]) {
-						input.parse::<Token![if]>()?;
-						let contents;
-						parenthesized!(contents in input);
-						let contents = contents.parse::<Expr>()?;
-
-						if condition.replace(contents).is_some() {
-							return Err(syn::Error::new(input.span(), "condition is already set"));
-						}
-					} else if lookahead.peek(kw::via) {
-						input.parse::<kw::via>()?;
-						let contents;
-						parenthesized!(contents in input);
-
-						let method = contents.parse::<Ident>()?;
-						contents.parse::<kw::returns>()?;
-						let ty = contents.parse::<Type>()?;
-
-						if via.replace((ty, method)).is_some() {
-							return Err(syn::Error::new(input.span(), "via is already set"));
-						}
-					} else {
-						return Err(lookahead.error());
-					}
-
-					if input.peek(Token![,]) {
-						input.parse::<Token![,]>()?;
-					} else if !input.is_empty() {
-						return Err(syn::Error::new(input.span(), "expected end"));
-					}
-				}
-			} else if lookahead.peek(Token![,]) || input.is_empty() {
-				// Pass
-			} else {
-				return Err(lookahead.error());
-			};
-			out.push(Is {
-				pascal_call_name: pascal_ident_to_call(&name),
-				snake_call_name: pascal_ident_to_snake_call(&name),
-				name,
-				via,
-				condition,
-			});
-			if input.peek(Token![,]) {
-				input.parse::<Token![,]>()?;
-				continue;
-			} else {
-				break;
-			}
-		}
-		Ok(Self(out))
-	}
-}
-
-pub struct InterfaceInfo {
-	name: Ident,
-	is: IsList,
-	inline_is: IsList,
-	events: IsList,
-	expect_selector: Option<u32>,
-}
-impl Parse for InterfaceInfo {
-	fn parse(input: ParseStream) -> syn::Result<Self> {
-		let mut name = None;
-		let mut is = None;
-		let mut inline_is = None;
-		let mut events = None;
-		let mut expect_selector = None;
-		// TODO: create proc-macro to optimize proc-macro boilerplate? :D
-		loop {
-			let lookahead = input.lookahead1();
-			if lookahead.peek(kw::name) {
-				let k = input.parse::<kw::name>()?;
-				input.parse::<Token![=]>()?;
-				if name.replace(input.parse::<Ident>()?).is_some() {
-					return Err(syn::Error::new(k.span(), "name is already set"));
-				}
-			} else if lookahead.peek(kw::is) {
-				let k = input.parse::<kw::is>()?;
-				let contents;
-				parenthesized!(contents in input);
-				if is.replace(contents.parse::<IsList>()?).is_some() {
-					return Err(syn::Error::new(k.span(), "is is already set"));
-				}
-			} else if lookahead.peek(kw::inline_is) {
-				let k = input.parse::<kw::inline_is>()?;
-				let contents;
-				parenthesized!(contents in input);
-				if inline_is.replace(contents.parse::<IsList>()?).is_some() {
-					return Err(syn::Error::new(k.span(), "inline_is is already set"));
-				}
-			} else if lookahead.peek(kw::events) {
-				let k = input.parse::<kw::events>()?;
-				let contents;
-				parenthesized!(contents in input);
-				if events.replace(contents.parse::<IsList>()?).is_some() {
-					return Err(syn::Error::new(k.span(), "events is already set"));
-				}
-			} else if lookahead.peek(kw::expect_selector) {
-				let k = input.parse::<kw::expect_selector>()?;
-				input.parse::<Token![=]>()?;
-				let value = input.parse::<LitInt>()?;
-				if expect_selector
-					.replace(value.base10_parse::<u32>()?)
-					.is_some()
-				{
-					return Err(syn::Error::new(k.span(), "expect_selector is already set"));
-				}
-			} else if input.is_empty() {
-				break;
-			} else {
-				return Err(lookahead.error());
-			}
-			if input.peek(Token![,]) {
-				input.parse::<Token![,]>()?;
-			} else {
-				break;
-			}
-		}
-		Ok(Self {
-			name: name.ok_or_else(|| syn::Error::new(input.span(), "missing name"))?,
-			is: is.unwrap_or_default(),
-			inline_is: inline_is.unwrap_or_default(),
-			events: events.unwrap_or_default(),
-			expect_selector,
-		})
-	}
-}
-
-struct MethodInfo {
-	rename_selector: Option<String>,
-	hide: bool,
-}
-impl Parse for MethodInfo {
-	fn parse(input: ParseStream) -> syn::Result<Self> {
-		let mut rename_selector = None;
-		let mut hide = false;
-		while !input.is_empty() {
-			let lookahead = input.lookahead1();
-			if lookahead.peek(kw::rename_selector) {
-				let k = input.parse::<kw::rename_selector>()?;
-				input.parse::<Token![=]>()?;
-				if rename_selector
-					.replace(input.parse::<LitStr>()?.value())
-					.is_some()
-				{
-					return Err(syn::Error::new(k.span(), "rename_selector is already set"));
-				}
-			} else if lookahead.peek(kw::hide) {
-				input.parse::<kw::hide>()?;
-				hide = true;
-			} else {
-				return Err(lookahead.error());
-			}
-
-			if input.peek(Token![,]) {
-				input.parse::<Token![,]>()?;
-			} else if !input.is_empty() {
-				return Err(syn::Error::new(input.span(), "expected end"));
-			}
-		}
-		Ok(Self {
-			rename_selector,
-			hide,
-		})
-	}
-}
-
-trait AbiTypeHelper {
-	fn plain(&self) -> syn::Result<&Ident>;
-	fn is_value(&self) -> bool;
-	fn is_caller(&self) -> bool;
-	fn is_special(&self) -> bool;
-}
-
-impl AbiTypeHelper for Type {
-	fn plain(&self) -> syn::Result<&Ident> {
-		let path = parse_path(self)?;
-		let segment = parse_path_segment(path)?;
-		if !segment.arguments.is_empty() {
-			return Err(syn::Error::new(self.span(), "Not plain type"));
-		}
-		Ok(&segment.ident)
-	}
-
-	fn is_value(&self) -> bool {
-		if let Ok(ident) = self.plain() {
-			return ident == "Value";
-		}
-		false
-	}
-
-	fn is_caller(&self) -> bool {
-		if let Ok(ident) = self.plain() {
-			return ident == "Caller";
-		}
-		false
-	}
-
-	fn is_special(&self) -> bool {
-		self.is_caller() || self.is_value()
-	}
-}
-
-#[derive(Debug)]
-struct MethodArg {
-	name: Ident,
-	camel_name: String,
-	ty: Type,
-}
-impl MethodArg {
-	fn try_from(value: &PatType) -> syn::Result<Self> {
-		let name = parse_ident_from_pat(&value.pat)?.clone();
-		Ok(Self {
-			camel_name: cases::camelcase::to_camel_case(&name.to_string()),
-			name,
-			ty: value.ty.as_ref().clone(),
-		})
-	}
-	fn is_value(&self) -> bool {
-		self.ty.is_value()
-	}
-	fn is_caller(&self) -> bool {
-		self.ty.is_caller()
-	}
-	fn is_special(&self) -> bool {
-		self.ty.is_special()
-	}
-
-	fn expand_call_def(&self) -> proc_macro2::TokenStream {
-		assert!(!self.is_special());
-		let name = &self.name;
-		let ty = &self.ty;
-
-		quote! {
-			#name: #ty
-		}
-	}
-
-	fn expand_parse(&self) -> proc_macro2::TokenStream {
-		assert!(!self.is_special());
-		let name = &self.name;
-		let ty = &self.ty;
-		quote! {
-			#name: {
-				let value = <#ty as ::evm_coder::abi::AbiRead>::abi_read(reader)?;
-				if !is_dynamic {reader.bytes_read(<#ty as ::evm_coder::abi::AbiType>::size())};
-				value
-			}
-		}
-	}
-
-	fn expand_call_arg(&self) -> proc_macro2::TokenStream {
-		if self.is_value() {
-			quote! {
-				c.value.clone()
-			}
-		} else if self.is_caller() {
-			quote! {
-				c.caller.clone()
-			}
-		} else {
-			let name = &self.name;
-			quote! {
-				#name
-			}
-		}
-	}
-
-	fn expand_solidity_argument(&self) -> proc_macro2::TokenStream {
-		let camel_name = &self.camel_name.to_string();
-		let ty = &self.ty;
-		quote! {
-			<NamedArgument<#ty>>::new(#camel_name)
-		}
-	}
-}
-
-#[derive(PartialEq)]
-enum Mutability {
-	Mutable,
-	View,
-	Pure,
-}
-
-/// Group all keywords for this macro. Usage example:
-/// #[solidity_interface(name = "B", inline_is(A))]
-mod kw {
-	syn::custom_keyword!(weight);
-
-	syn::custom_keyword!(via);
-	syn::custom_keyword!(returns);
-	syn::custom_keyword!(name);
-	syn::custom_keyword!(is);
-	syn::custom_keyword!(inline_is);
-	syn::custom_keyword!(events);
-	syn::custom_keyword!(expect_selector);
-
-	syn::custom_keyword!(rename_selector);
-	syn::custom_keyword!(hide);
-}
-
-/// Rust methods are parsed into this structure when Solidity code is generated
-struct Method {
-	name: Ident,
-	camel_name: String,
-	pascal_name: Ident,
-	screaming_name: Ident,
-	hide: bool,
-	args: Vec<MethodArg>,
-	has_normal_args: bool,
-	has_value_args: bool,
-	mutability: Mutability,
-	result: Type,
-	weight: Option<Expr>,
-	docs: Vec<String>,
-}
-impl Method {
-	fn try_from(value: &ImplItemMethod) -> syn::Result<Self> {
-		let mut info = MethodInfo {
-			rename_selector: None,
-			hide: false,
-		};
-		let mut docs = Vec::new();
-		let mut weight = None;
-		for attr in &value.attrs {
-			let ident = parse_ident_from_path(&attr.path, false)?;
-			if ident == "solidity" {
-				info = attr.parse_args::<MethodInfo>()?;
-			} else if ident == "doc" {
-				let args = attr.parse_meta().unwrap();
-				let value = match args {
-					Meta::NameValue(MetaNameValue {
-						lit: Lit::Str(str), ..
-					}) => str.value(),
-					_ => unreachable!(),
-				};
-				docs.push(value);
-			} else if ident == "weight" {
-				weight = Some(attr.parse_args::<Expr>()?);
-			}
-		}
-		let ident = &value.sig.ident;
-		let ident_str = ident.to_string();
-		if !cases::snakecase::is_snake_case(&ident_str) {
-			return Err(syn::Error::new(ident.span(), "method name should be snake_cased\nif alternative solidity name needs to be set - use #[solidity] attribute"));
-		}
-
-		let mut mutability = Mutability::Pure;
-
-		if let Some(FnArg::Receiver(receiver)) = value
-			.sig
-			.inputs
-			.iter()
-			.find(|arg| matches!(arg, FnArg::Receiver(_)))
-		{
-			if receiver.reference.is_none() {
-				return Err(syn::Error::new(
-					receiver.span(),
-					"receiver should be by ref",
-				));
-			}
-			if receiver.mutability.is_some() {
-				mutability = Mutability::Mutable;
-			} else {
-				mutability = Mutability::View;
-			}
-		}
-		let mut args = Vec::new();
-		for typ in value
-			.sig
-			.inputs
-			.iter()
-			.filter(|arg| matches!(arg, FnArg::Typed(_)))
-		{
-			let typ = match typ {
-				FnArg::Typed(typ) => typ,
-				_ => unreachable!(),
-			};
-			args.push(MethodArg::try_from(typ)?);
-		}
-
-		if mutability != Mutability::Mutable && args.iter().any(|arg| arg.is_value()) {
-			return Err(syn::Error::new(
-				args.iter().find(|arg| arg.is_value()).unwrap().ty.span(),
-				"payable function should be mutable",
-			));
-		}
-
-		let result = match &value.sig.output {
-			ReturnType::Type(_, ty) => ty,
-			_ => return Err(syn::Error::new(value.sig.output.span(), "interface method should return Result<value>\nif there is no value to return - specify void (which is alias to unit)")),
-		};
-		let result = parse_result_ok(result)?;
-
-		let camel_name = info
-			.rename_selector
-			.unwrap_or_else(|| cases::camelcase::to_camel_case(&ident.to_string()));
-		let has_normal_args = args.iter().filter(|arg| !arg.is_special()).count() != 0;
-		let has_value_args = args.iter().any(|a| a.is_value());
-
-		Ok(Self {
-			name: ident.clone(),
-			camel_name,
-			pascal_name: snake_ident_to_pascal(ident),
-			screaming_name: snake_ident_to_screaming(ident),
-			hide: info.hide,
-			args,
-			has_normal_args,
-			has_value_args,
-			mutability,
-			result: result.clone(),
-			weight,
-			docs,
-		})
-	}
-	fn expand_call_def(&self) -> proc_macro2::TokenStream {
-		let defs = self
-			.args
-			.iter()
-			.filter(|a| !a.is_special())
-			.map(|a| a.expand_call_def());
-		let pascal_name = &self.pascal_name;
-		let docs = &self.docs;
-
-		if self.has_normal_args {
-			quote! {
-				#(#[doc = #docs])*
-				#[allow(missing_docs)]
-				#pascal_name {
-					#(
-						#defs,
-					)*
-				}
-			}
-		} else {
-			quote! {
-				#(#[doc = #docs])*
-				#[allow(missing_docs)]
-				#pascal_name
-			}
-		}
-	}
-
-	fn expand_const(&self) -> proc_macro2::TokenStream {
-		let screaming_name = &self.screaming_name;
-		let screaming_name_signature = format_ident!("{}_SIGNATURE", &self.screaming_name);
-		let custom_signature = self.expand_custom_signature();
-		quote! {
-			const #screaming_name_signature: ::evm_coder::custom_signature::SignatureUnit = #custom_signature;
-			const #screaming_name: ::evm_coder::types::Bytes4 = {
-				let mut sum = ::evm_coder::sha3_const::Keccak256::new();
-				let mut pos = 0;
-				while pos < Self::#screaming_name_signature.len {
-					sum = sum.update(&[Self::#screaming_name_signature.data[pos]; 1]);
-					pos += 1;
-				}
-				let a = sum.finalize();
-				[a[0], a[1], a[2], a[3]]
-			};
-		}
-	}
-
-	fn expand_interface_id(&self) -> proc_macro2::TokenStream {
-		let screaming_name = &self.screaming_name;
-		quote! {
-			interface_id ^= u32::from_be_bytes(Self::#screaming_name);
-		}
-	}
-
-	fn expand_parse(&self) -> proc_macro2::TokenStream {
-		let pascal_name = &self.pascal_name;
-		let screaming_name = &self.screaming_name;
-		if self.has_normal_args {
-			let args_iter = self.args.iter().filter(|a| !a.is_special());
-			let arg_type = args_iter.clone().map(|a| &a.ty);
-			let parsers = args_iter.map(|a| a.expand_parse());
-			quote! {
-				Self::#screaming_name => {
-					let is_dynamic = false #(|| <#arg_type as ::evm_coder::abi::AbiType>::is_dynamic())*;
-					return Ok(Some(Self::#pascal_name {
-						#(
-							#parsers,
-						)*
-					}))
-				}
-			}
-		} else {
-			quote! { Self::#screaming_name => return Ok(Some(Self::#pascal_name)) }
-		}
-	}
-
-	fn expand_variant_call(&self, call_name: &proc_macro2::Ident) -> proc_macro2::TokenStream {
-		let pascal_name = &self.pascal_name;
-		let name = &self.name;
-
-		let matcher = if self.has_normal_args {
-			let names = self
-				.args
-				.iter()
-				.filter(|a| !a.is_special())
-				.map(|a| &a.name);
-
-			quote! {{
-				#(
-					#names,
-				)*
-			}}
-		} else {
-			quote! {}
-		};
-
-		let receiver = match self.mutability {
-			Mutability::Mutable | Mutability::View => quote! {self.},
-			Mutability::Pure => quote! {Self::},
-		};
-		let args = self.args.iter().map(|a| a.expand_call_arg());
-
-		quote! {
-			#call_name::#pascal_name #matcher => {
-				#[allow(deprecated)]
-				let result = #receiver #name(
-					#(
-						#args,
-					)*
-				)?;
-				(&result).to_result()
-			}
-		}
-	}
-
-	fn expand_variant_weight(&self) -> proc_macro2::TokenStream {
-		let pascal_name = &self.pascal_name;
-		if let Some(weight) = &self.weight {
-			let matcher = if self.has_normal_args {
-				let names = self
-					.args
-					.iter()
-					.filter(|a| !a.is_special())
-					.map(|a| &a.name);
-
-				quote! {{
-					#(
-						#names,
-					)*
-				}}
-			} else {
-				quote! {}
-			};
-			quote! {
-				Self::#pascal_name #matcher => (#weight).into()
-			}
-		} else {
-			let matcher = if self.has_normal_args {
-				quote! {{..}}
-			} else {
-				quote! {}
-			};
-			quote! {
-				Self::#pascal_name #matcher => ().into()
-			}
-		}
-	}
-
-	fn expand_custom_signature(&self) -> proc_macro2::TokenStream {
-		let mut args = TokenStream::new();
-
-		let mut has_params = false;
-		for arg in self.args.iter().filter(|a| !a.is_special()) {
-			has_params = true;
-			let ty = &arg.ty;
-			args.extend(quote! {nameof(<#ty>::SIGNATURE)});
-			args.extend(quote! {fixed(",")})
-		}
-
-		// Remove trailing comma
-		if has_params {
-			args.extend(quote! {shift_left(1)})
-		}
-
-		let func_name = self.camel_name.clone();
-		quote! { ::evm_coder::make_signature!(new fixed(#func_name) fixed("(") #args fixed(")")) }
-	}
-
-	fn expand_solidity_function(&self) -> proc_macro2::TokenStream {
-		let camel_name = &self.camel_name;
-		let mutability = match self.mutability {
-			Mutability::Mutable => quote! {SolidityMutability::Mutable},
-			Mutability::View => quote! { SolidityMutability::View },
-			Mutability::Pure => quote! {SolidityMutability::Pure},
-		};
-		let result = &self.result;
-
-		let args = self
-			.args
-			.iter()
-			.filter(|a| !a.is_special())
-			.map(MethodArg::expand_solidity_argument);
-		let docs = &self.docs;
-		let screaming_name = &self.screaming_name;
-		let hide = self.hide;
-		let custom_signature = self.expand_custom_signature();
-		let is_payable = self.has_value_args;
-
-		quote! {
-			SolidityFunction {
-				docs: &[#(#docs),*],
-				hide: #hide,
-				selector: u32::from_be_bytes(Self::#screaming_name),
-				custom_signature: #custom_signature,
-				name: #camel_name,
-				mutability: #mutability,
-				is_payable: #is_payable,
-				args: (
-					#(
-						#args,
-					)*
-				),
-				result: <UnnamedArgument<#result>>::default(),
-			}
-		}
-	}
-}
-
-fn generics_list(gen: &Generics) -> proc_macro2::TokenStream {
-	if gen.params.is_empty() {
-		return quote! {};
-	}
-	let params = gen.params.iter().map(|p| match p {
-		syn::GenericParam::Type(id) => {
-			let v = &id.ident;
-			quote! {#v}
-		}
-		syn::GenericParam::Lifetime(lt) => {
-			let v = &lt.lifetime;
-			quote! {#v}
-		}
-		syn::GenericParam::Const(c) => {
-			let i = &c.ident;
-			quote! {#i}
-		}
-	});
-	quote! { #(#params),* }
-}
-fn generics_reference(gen: &Generics) -> proc_macro2::TokenStream {
-	if gen.params.is_empty() {
-		return quote! {};
-	}
-	let list = generics_list(gen);
-	quote! { <#list> }
-}
-fn generics_stub(gen: &Generics) -> proc_macro2::TokenStream {
-	if gen.params.is_empty() {
-		return quote! {};
-	}
-	let params = (0..gen.params.len()).map(|_| quote! {()});
-	quote! {<#(#params,)*>}
-}
-fn generics_data(gen: &Generics) -> proc_macro2::TokenStream {
-	let list = generics_list(gen);
-	if gen.params.len() == 1 {
-		quote! {#list}
-	} else {
-		quote! { (#list) }
-	}
-}
-
-pub struct SolidityInterface {
-	generics: Generics,
-	name: Box<syn::Type>,
-	info: InterfaceInfo,
-	methods: Vec<Method>,
-	docs: Vec<String>,
-}
-impl SolidityInterface {
-	pub fn try_from(info: InterfaceInfo, value: &ItemImpl) -> syn::Result<Self> {
-		let mut methods = Vec::new();
-
-		for item in &value.items {
-			if let ImplItem::Method(method) = item {
-				methods.push(Method::try_from(method)?)
-			}
-		}
-		let mut docs = vec![];
-		for attr in &value.attrs {
-			let ident = parse_ident_from_path(&attr.path, false)?;
-			if ident == "doc" {
-				let args = attr.parse_meta().unwrap();
-				let value = match args {
-					Meta::NameValue(MetaNameValue {
-						lit: Lit::Str(str), ..
-					}) => str.value(),
-					_ => unreachable!(),
-				};
-				docs.push(value);
-			}
-		}
-		Ok(Self {
-			generics: value.generics.clone(),
-			name: value.self_ty.clone(),
-			info,
-			methods,
-			docs,
-		})
-	}
-	pub fn expand(self) -> proc_macro2::TokenStream {
-		let name = self.name;
-
-		let solidity_name = self.info.name.to_string();
-		let call_name = pascal_ident_to_call(&self.info.name);
-		let generics = self.generics;
-		let gen_ref = generics_reference(&generics);
-		let gen_data = generics_data(&generics);
-		let gen_stub = generics_stub(&generics);
-		let gen_where = &generics.where_clause;
-
-		let call_sub = self
-			.info
-			.inline_is
-			.0
-			.iter()
-			.chain(self.info.is.0.iter())
-			.map(|c| Is::expand_call_def(c, &gen_ref));
-		let call_parse = self
-			.info
-			.inline_is
-			.0
-			.iter()
-			.chain(self.info.is.0.iter())
-			.map(|is| Is::expand_parse(is, &gen_ref));
-		let call_variants = self
-			.info
-			.inline_is
-			.0
-			.iter()
-			.chain(self.info.is.0.iter())
-			.map(|c| Is::expand_variant_call(c, &call_name, &gen_ref));
-		let weight_variants = self
-			.info
-			.inline_is
-			.0
-			.iter()
-			.chain(self.info.is.0.iter())
-			.map(Is::expand_variant_weight);
-
-		let inline_interface_id = self.info.inline_is.0.iter().map(Is::expand_interface_id);
-		let supports_interface = self
-			.info
-			.is
-			.0
-			.iter()
-			.map(|is| Is::expand_supports_interface(is, &gen_ref));
-
-		let calls = self.methods.iter().map(Method::expand_call_def);
-		let consts = self.methods.iter().map(Method::expand_const);
-		let interface_id = self.methods.iter().map(Method::expand_interface_id);
-		let parsers = self.methods.iter().map(Method::expand_parse);
-		let call_variants_this = self
-			.methods
-			.iter()
-			.map(|m| Method::expand_variant_call(m, &call_name));
-		let weight_variants_this = self.methods.iter().map(Method::expand_variant_weight);
-		let solidity_functions = self.methods.iter().map(Method::expand_solidity_function);
-
-		// TODO: Inline inline_is
-		let solidity_is = self
-			.info
-			.is
-			.0
-			.iter()
-			.chain(self.info.inline_is.0.iter())
-			.map(|is| is.name.to_string());
-		let solidity_events_is = self.info.events.0.iter().map(|is| is.name.to_string());
-		let solidity_generators = self
-			.info
-			.is
-			.0
-			.iter()
-			.chain(self.info.inline_is.0.iter())
-			.map(|is| Is::expand_generator(is, &gen_ref));
-		let solidity_event_generators = self.info.events.0.iter().map(Is::expand_event_generator);
-		let solidity_events_idents = self.info.events.0.iter().map(|is| is.name.clone());
-		let docs = &self.docs;
-
-		let expect_selector = self.info.expect_selector.map(|s| {
-            quote! {
-                const _: () = assert!(#s == u32::from_be_bytes(<#call_name #gen_stub>::interface_id()), "selector mismatch, review contained function selectors");
-            }
-        });
-
-		quote! {
-			#(
-				const _: ::core::marker::PhantomData<#solidity_events_idents> = ::core::marker::PhantomData;
-			)*
-			#[derive(Debug)]
-			#(#[doc = #docs])*
-			pub enum #call_name #gen_ref {
-				/// Inherited method
-				ERC165Call(::evm_coder::ERC165Call, ::core::marker::PhantomData<#gen_data>),
-				#(
-					#calls,
-				)*
-				#(
-					#call_sub,
-				)*
-			}
-
-			#expect_selector
-
-			impl #gen_ref #call_name #gen_ref {
-				#(
-					#consts
-				)*
-				/// Return this call ERC165 selector
-				pub const fn interface_id() -> ::evm_coder::types::Bytes4 {
-					let mut interface_id = 0;
-					#(#interface_id)*
-					#(#inline_interface_id)*
-					u32::to_be_bytes(interface_id)
-				}
-				/// Generate solidity definitions for methods described in this interface
-				#[cfg(feature = "stubgen")]
-				pub fn generate_solidity_interface(tc: &evm_coder::solidity::TypeCollector, is_impl: bool) {
-					use evm_coder::solidity::*;
-					use core::fmt::Write;
-					let interface = SolidityInterface {
-						docs: &[#(#docs),*],
-						name: #solidity_name,
-						selector: Self::interface_id(),
-						is: &["Dummy", "ERC165", #(
-							#solidity_is,
-						)* #(
-							#solidity_events_is,
-						)* ],
-						functions: (#(
-							#solidity_functions,
-						)*),
-					};
-
-					let mut out = ::evm_coder::types::String::new();
-					if #solidity_name.starts_with("Inline") {
-						out.push_str("/// @dev inlined interface\n");
-					}
-					let _ = interface.format(is_impl, &mut out, tc);
-					tc.collect(out);
-					#(
-						#solidity_event_generators
-					)*
-					#(
-						#solidity_generators
-					)*
-					if is_impl {
-						tc.collect("/// @dev common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\ncontract ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool) {\n\t\trequire(false, stub_error);\n\t\tinterfaceID;\n\t\treturn true;\n\t}\n}\n".into());
-					} else {
-						tc.collect("/// @dev common stubs holder\ninterface Dummy {\n}\ninterface ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n".into());
-					}
-				}
-			}
-			impl #gen_ref ::evm_coder::Call for #call_name #gen_ref {
-				fn parse(method_id: ::evm_coder::types::Bytes4, reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Option<Self>> {
-					use ::evm_coder::abi::AbiRead;
-					match method_id {
-						::evm_coder::ERC165Call::INTERFACE_ID => return Ok(
-							::evm_coder::ERC165Call::parse(method_id, reader)?
-							.map(|c| Self::ERC165Call(c, ::core::marker::PhantomData))
-						),
-						#(
-							#parsers,
-						)*
-						_ => {},
-					}
-					#(
-						#call_parse
-					)else*
-					return Ok(None);
-				}
-			}
-			impl #generics #call_name #gen_ref
-			#gen_where
-			{
-				/// Is this contract implements specified ERC165 selector
-				pub fn supports_interface(this: &#name, interface_id: ::evm_coder::types::Bytes4) -> bool {
-					interface_id != u32::to_be_bytes(0xffffff) && (
-						interface_id == ::evm_coder::ERC165Call::INTERFACE_ID ||
-						interface_id == Self::interface_id()
-						#(
-							|| #supports_interface
-						)*
-					)
-				}
-			}
-			impl #generics ::evm_coder::Weighted for #call_name #gen_ref
-			#gen_where
-			{
-				#[allow(unused_variables)]
-				fn weight(&self) -> ::evm_coder::execution::DispatchInfo {
-					match self {
-						#(
-							#weight_variants,
-						)*
-						// TODO: It should be very cheap, but not free
-						Self::ERC165Call(::evm_coder::ERC165Call::SupportsInterface {..}, _) => ::frame_support::weights::Weight::from_ref_time(100).into(),
-						#(
-							#weight_variants_this,
-						)*
-					}
-				}
-			}
-			impl #generics ::evm_coder::Callable<#call_name #gen_ref> for #name
-			#gen_where
-			{
-				#[allow(unreachable_code)] // In case of no inner calls
-				fn call(&mut self, c: Msg<#call_name #gen_ref>) -> ::evm_coder::execution::ResultWithPostInfo<::evm_coder::abi::AbiWriter> {
-					use ::evm_coder::abi::AbiWrite;
-					match c.call {
-						#(
-							#call_variants,
-						)*
-						#call_name::ERC165Call(::evm_coder::ERC165Call::SupportsInterface {interface_id}, _) => {
-							let mut writer = ::evm_coder::abi::AbiWriter::default();
-							writer.bool(&<#call_name #gen_ref>::supports_interface(self, interface_id));
-							return Ok(writer.into());
-						}
-						_ => {},
-					}
-					let mut writer = ::evm_coder::abi::AbiWriter::default();
-					match c.call {
-						#(
-							#call_variants_this,
-						)*
-						_ => Err(::evm_coder::execution::Error::from("method is not available").into()),
-					}
-				}
-			}
-		}
-	}
-}
deletedcrates/evm-coder/procedural/src/to_log.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/to_log.rs
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-use inflector::cases;
-use syn::{Data, DeriveInput, Field, Fields, Ident, Variant, spanned::Spanned};
-use quote::quote;
-
-use crate::{parse_ident_from_path, parse_ident_from_type, snake_ident_to_screaming};
-
-struct EventField {
-	name: Ident,
-	camel_name: String,
-	ty: Ident,
-	indexed: bool,
-}
-
-impl EventField {
-	fn try_from(field: &Field) -> syn::Result<Self> {
-		let name = field.ident.as_ref().unwrap();
-		let ty = parse_ident_from_type(&field.ty, false)?;
-		let mut indexed = false;
-		for attr in &field.attrs {
-			if let Ok(ident) = parse_ident_from_path(&attr.path, false) {
-				if ident == "indexed" {
-					indexed = true;
-				}
-			}
-		}
-		Ok(Self {
-			name: name.to_owned(),
-			camel_name: cases::camelcase::to_camel_case(&name.to_string()),
-			ty: ty.to_owned(),
-			indexed,
-		})
-	}
-	fn expand_solidity_argument(&self) -> proc_macro2::TokenStream {
-		let camel_name = &self.camel_name;
-		let ty = &self.ty;
-		let indexed = self.indexed;
-		quote! {
-			<SolidityEventArgument<#ty>>::new(#indexed, #camel_name)
-		}
-	}
-}
-
-struct Event {
-	name: Ident,
-	name_screaming: Ident,
-	fields: Vec<EventField>,
-	selector: proc_macro2::TokenStream,
-}
-
-impl Event {
-	fn try_from(variant: &Variant) -> syn::Result<Self> {
-		let name = &variant.ident;
-		let name_lit = proc_macro2::Literal::string(name.to_string().as_str());
-		let name_screaming = snake_ident_to_screaming(name);
-
-		let named = match &variant.fields {
-			Fields::Named(named) => named,
-			_ => {
-				return Err(syn::Error::new(
-					variant.fields.span(),
-					"expected named fields",
-				))
-			}
-		};
-		let mut fields = Vec::new();
-		for field in &named.named {
-			fields.push(EventField::try_from(field)?);
-		}
-		if fields.iter().filter(|f| f.indexed).count() > 3 {
-			return Err(syn::Error::new(
-				variant.fields.span(),
-				"events can have at most 4 indexed fields (1 indexed field is reserved for event signature)"
-			));
-		}
-
-		let args = fields.iter().map(|f| {
-			let ty = &f.ty;
-			quote! {nameof(<#ty as ::evm_coder::abi::AbiType>::SIGNATURE) fixed(",")}
-		});
-		// Remove trailing comma
-		let shift = (!fields.is_empty()).then(|| quote! {shift_left(1)});
-
-		let signature = quote! { ::evm_coder::make_signature!(new fixed(#name_lit) fixed("(") #(#args)* #shift fixed(")")) };
-		let selector = quote! {
-			{
-				let signature = #signature;
-				let mut sum = ::evm_coder::sha3_const::Keccak256::new();
-				let mut pos = 0;
-				while pos < signature.len {
-					sum = sum.update(&[signature.data[pos]; 1]);
-					pos += 1;
-				}
-				let a = sum.finalize();
-				let mut selector_bytes = [0; 32];
-				let mut i = 0;
-				while i != 32 {
-					selector_bytes[i] = a[i];
-					i += 1;
-				}
-				selector_bytes
-			}
-		};
-
-		Ok(Self {
-			name: name.to_owned(),
-			name_screaming,
-			fields,
-			selector,
-		})
-	}
-
-	fn expand_serializers(&self) -> proc_macro2::TokenStream {
-		let name = &self.name;
-		let name_screaming = &self.name_screaming;
-		let fields = self.fields.iter().map(|f| &f.name);
-
-		let indexed = self.fields.iter().filter(|f| f.indexed).map(|f| &f.name);
-		let plain = self.fields.iter().filter(|f| !f.indexed).map(|f| &f.name);
-
-		quote! {
-			Self::#name {#(
-				#fields,
-			)*} => {
-				topics.push(::evm_coder::types::Topic::from(Self::#name_screaming));
-				#(
-					topics.push(#indexed.to_topic());
-				)*
-				#(
-					#plain.abi_write(&mut writer);
-				)*
-			}
-		}
-	}
-
-	fn expand_consts(&self) -> proc_macro2::TokenStream {
-		let name_screaming = &self.name_screaming;
-		let selector = &self.selector;
-
-		quote! {
-			const #name_screaming: [u8; 32] = #selector;
-		}
-	}
-
-	fn expand_solidity_function(&self) -> proc_macro2::TokenStream {
-		let name = self.name.to_string();
-		let args = self.fields.iter().map(EventField::expand_solidity_argument);
-		quote! {
-			SolidityEvent {
-				name: #name,
-				args: (
-					#(
-						#args,
-					)*
-				),
-			}
-		}
-	}
-}
-
-pub struct Events {
-	name: Ident,
-	events: Vec<Event>,
-}
-
-impl Events {
-	pub fn try_from(data: &DeriveInput) -> syn::Result<Self> {
-		let name = &data.ident;
-		let en = match &data.data {
-			Data::Enum(en) => en,
-			_ => return Err(syn::Error::new(data.span(), "expected enum")),
-		};
-		let mut events = Vec::new();
-		for variant in &en.variants {
-			events.push(Event::try_from(variant)?);
-		}
-		Ok(Self {
-			name: name.to_owned(),
-			events,
-		})
-	}
-	pub fn expand(&self) -> proc_macro2::TokenStream {
-		let name = &self.name;
-
-		let consts = self.events.iter().map(Event::expand_consts);
-		let serializers = self.events.iter().map(Event::expand_serializers);
-		let solidity_name = self.name.to_string();
-		let solidity_functions = self.events.iter().map(Event::expand_solidity_function);
-
-		quote! {
-			impl #name {
-				#(
-					#consts
-				)*
-
-				/// Generate solidity definitions for methods described in this interface
-				#[cfg(feature = "stubgen")]
-				pub fn generate_solidity_interface(tc: &evm_coder::solidity::TypeCollector, is_impl: bool) {
-					use evm_coder::solidity::*;
-					use core::fmt::Write;
-					let interface = SolidityInterface {
-						docs: &[],
-						selector: [0; 4],
-						name: #solidity_name,
-						is: &[],
-						functions: (#(
-							#solidity_functions,
-						)*),
-					};
-					let mut out = ::evm_coder::types::String::new();
-					out.push_str("/// @dev inlined interface\n");
-					let _ = interface.format(is_impl, &mut out, tc);
-					tc.collect(out);
-				}
-			}
-
-			#[automatically_derived]
-			impl ::evm_coder::events::ToLog for #name {
-				fn to_log(&self, contract: Address) -> ::evm_coder::ethereum::Log {
-					use ::evm_coder::events::ToTopic;
-					use ::evm_coder::abi::AbiWrite;
-					let mut writer = ::evm_coder::abi::AbiWriter::new();
-					let mut topics = Vec::new();
-					match self {
-						#(
-							#serializers,
-						)*
-					}
-					::evm_coder::ethereum::Log {
-						address: contract,
-						topics,
-						data: writer.finish(),
-					}
-				}
-			}
-		}
-	}
-}
deletedcrates/evm-coder/src/abi/impls.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/abi/impls.rs
+++ /dev/null
@@ -1,296 +0,0 @@
-use crate::{
-	custom_signature::SignatureUnit,
-	execution::{Result, ResultWithPostInfo, WithPostDispatchInfo},
-	make_signature, sealed,
-	types::*,
-};
-use super::{traits::*, ABI_ALIGNMENT, AbiReader, AbiWriter};
-use primitive_types::{U256, H160};
-
-#[cfg(not(feature = "std"))]
-use alloc::vec::Vec;
-
-macro_rules! impl_abi_type {
-	($ty:ty, $name:ident, $dynamic:literal) => {
-		impl sealed::CanBePlacedInVec for $ty {}
-
-		impl AbiType for $ty {
-			const SIGNATURE: SignatureUnit = make_signature!(new fixed(stringify!($name)));
-
-			fn is_dynamic() -> bool {
-				$dynamic
-			}
-
-			fn size() -> usize {
-				ABI_ALIGNMENT
-			}
-		}
-	};
-}
-
-macro_rules! impl_abi_readable {
-	($ty:ty, $method:ident) => {
-		impl AbiRead for $ty {
-			fn abi_read(reader: &mut AbiReader) -> Result<$ty> {
-				reader.$method()
-			}
-		}
-	};
-}
-
-macro_rules! impl_abi_writeable {
-	($ty:ty, $method:ident) => {
-		impl AbiWrite for $ty {
-			fn abi_write(&self, writer: &mut AbiWriter) {
-				writer.$method(&self)
-			}
-		}
-	};
-}
-
-macro_rules! impl_abi {
-	($ty:ty, $method:ident, $dynamic:literal) => {
-		impl_abi_type!($ty, $method, $dynamic);
-		impl_abi_readable!($ty, $method);
-		impl_abi_writeable!($ty, $method);
-	};
-}
-
-impl_abi!(bool, bool, false);
-impl_abi!(u8, uint8, false);
-impl_abi!(u32, uint32, false);
-impl_abi!(u64, uint64, false);
-impl_abi!(u128, uint128, false);
-impl_abi!(U256, uint256, false);
-impl_abi!(H160, address, false);
-impl_abi!(String, string, true);
-
-impl_abi_writeable!(&str, string);
-
-impl_abi_type!(Bytes, bytes, true);
-
-impl AbiRead for Bytes {
-	fn abi_read(reader: &mut AbiReader) -> Result<Bytes> {
-		Ok(Bytes(reader.bytes()?))
-	}
-}
-
-impl AbiWrite for Bytes {
-	fn abi_write(&self, writer: &mut AbiWriter) {
-		writer.bytes(self.0.as_slice())
-	}
-}
-
-impl_abi_type!(Bytes4, bytes4, false);
-impl AbiRead for Bytes4 {
-	fn abi_read(reader: &mut AbiReader) -> Result<Bytes4> {
-		reader.bytes4()
-	}
-}
-
-impl<T: AbiWrite> AbiWrite for &T {
-	fn abi_write(&self, writer: &mut AbiWriter) {
-		T::abi_write(self, writer);
-	}
-}
-
-impl<T: AbiType> AbiType for &T {
-	const SIGNATURE: SignatureUnit = T::SIGNATURE;
-
-	fn is_dynamic() -> bool {
-		T::is_dynamic()
-	}
-
-	fn size() -> usize {
-		T::size()
-	}
-}
-
-impl<T: AbiType + AbiRead + sealed::CanBePlacedInVec> AbiRead for Vec<T> {
-	fn abi_read(reader: &mut AbiReader) -> Result<Vec<T>> {
-		let mut sub = reader.subresult(None)?;
-		let size = sub.uint32()? as usize;
-		sub.subresult_offset = sub.offset;
-		let is_dynamic = <T as AbiType>::is_dynamic();
-		let mut out = Vec::with_capacity(size);
-		for _ in 0..size {
-			out.push(<T as AbiRead>::abi_read(&mut sub)?);
-			if !is_dynamic {
-				sub.bytes_read(<T as AbiType>::size());
-			};
-		}
-		Ok(out)
-	}
-}
-
-impl<T: AbiType> AbiType for Vec<T> {
-	const SIGNATURE: SignatureUnit = make_signature!(new nameof(T::SIGNATURE) fixed("[]"));
-
-	fn is_dynamic() -> bool {
-		true
-	}
-
-	fn size() -> usize {
-		ABI_ALIGNMENT
-	}
-}
-
-impl<T: AbiWrite + AbiType> AbiWrite for Vec<T> {
-	fn abi_write(&self, writer: &mut AbiWriter) {
-		let is_dynamic = T::is_dynamic();
-		let mut sub = if is_dynamic {
-			AbiWriter::new_dynamic(is_dynamic)
-		} else {
-			AbiWriter::new()
-		};
-
-		// Write items count
-		(self.len() as u32).abi_write(&mut sub);
-
-		for item in self {
-			item.abi_write(&mut sub);
-		}
-		writer.write_subresult(sub);
-	}
-}
-
-impl AbiWrite for () {
-	fn abi_write(&self, _writer: &mut AbiWriter) {}
-}
-
-/// This particular AbiWrite implementation should be split to another trait,
-/// which only implements `to_result`, but due to lack of specialization feature
-/// in stable Rust, we can't have blanket impl of this trait `for T where T: AbiWrite`,
-/// so here we abusing default trait methods for it
-impl<T: AbiWrite> AbiWrite for ResultWithPostInfo<T> {
-	fn abi_write(&self, _writer: &mut AbiWriter) {
-		debug_assert!(false, "shouldn't be called, see comment")
-	}
-	fn to_result(&self) -> ResultWithPostInfo<AbiWriter> {
-		match self {
-			Ok(v) => Ok(WithPostDispatchInfo {
-				post_info: v.post_info.clone(),
-				data: {
-					let mut out = AbiWriter::new();
-					v.data.abi_write(&mut out);
-					out
-				},
-			}),
-			Err(e) => Err(e.clone()),
-		}
-	}
-}
-
-macro_rules! impl_tuples {
-	($($ident:ident)+) => {
-		impl<$($ident: AbiType,)+> AbiType for ($($ident,)+)
-		where
-        $(
-            $ident: AbiType,
-        )+
-		{
-            const SIGNATURE: SignatureUnit = make_signature!(
-                new fixed("(")
-                $(nameof(<$ident>::SIGNATURE) fixed(","))+
-                shift_left(1)
-                fixed(")")
-            );
-
-			fn is_dynamic() -> bool {
-				false
-				$(
-					|| <$ident>::is_dynamic()
-				)*
-			}
-
-			fn size() -> usize {
-				0 $(+ <$ident>::size())+
-			}
-		}
-
-		impl<$($ident),+> sealed::CanBePlacedInVec for ($($ident,)+) {}
-
-		impl<$($ident),+> AbiRead for ($($ident,)+)
-		where
-			Self: AbiType,
-			$($ident: AbiRead + AbiType,)+
-		{
-			fn abi_read(reader: &mut AbiReader) -> Result<($($ident,)+)> {
-				let is_dynamic = <Self>::is_dynamic();
-				let size = if !is_dynamic { Some(<Self>::size()) } else { None };
-				let mut subresult = reader.subresult(size)?;
-				Ok((
-					$({
-						let value = <$ident>::abi_read(&mut subresult)?;
-						if !is_dynamic {subresult.bytes_read(<$ident as AbiType>::size())};
-						value
-					},)+
-				))
-			}
-		}
-
-		#[allow(non_snake_case)]
-		impl<$($ident),+> AbiWrite for ($($ident,)+)
-		where
-			$($ident: AbiWrite + AbiType,)+
-		{
-			fn abi_write(&self, writer: &mut AbiWriter) {
-				let ($($ident,)+) = self;
-				if <Self as AbiType>::is_dynamic() {
-					let mut sub = AbiWriter::new();
-					$($ident.abi_write(&mut sub);)+
-					writer.write_subresult(sub);
-				} else {
-					$($ident.abi_write(writer);)+
-				}
-			}
-		}
-	};
-}
-
-impl_tuples! {A}
-impl_tuples! {A B}
-impl_tuples! {A B C}
-impl_tuples! {A B C D}
-impl_tuples! {A B C D E}
-impl_tuples! {A B C D E F}
-impl_tuples! {A B C D E F G}
-impl_tuples! {A B C D E F G H}
-impl_tuples! {A B C D E F G H I}
-impl_tuples! {A B C D E F G H I J}
-
-//----- impls for Option -----
-impl<T: AbiType> AbiType for Option<T> {
-	const SIGNATURE: SignatureUnit = <(bool, T)>::SIGNATURE;
-
-	fn is_dynamic() -> bool {
-		<(bool, T)>::is_dynamic()
-	}
-
-	fn size() -> usize {
-		<(bool, T)>::size()
-	}
-}
-
-impl<T: AbiWrite + AbiType + Default> AbiWrite for Option<T> {
-	fn abi_write(&self, writer: &mut AbiWriter) {
-		match self {
-			Some(value) => (true, value).abi_write(writer),
-			None => (false, T::default()).abi_write(writer),
-		}
-	}
-}
-
-impl<T> AbiRead for Option<T>
-where
-	Self: AbiType,
-	T: AbiRead + AbiType,
-{
-	fn abi_read(reader: &mut AbiReader) -> Result<Self>
-	where
-		Self: Sized,
-	{
-		let (status, value) = <(bool, T)>::abi_read(reader)?;
-		Ok(if status { Some(value) } else { None })
-	}
-}
deletedcrates/evm-coder/src/abi/mod.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/abi/mod.rs
+++ /dev/null
@@ -1,348 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-//! Implementation of EVM RLP reader/writer
-
-#![allow(dead_code)]
-
-mod traits;
-pub use traits::*;
-mod impls;
-
-#[cfg(test)]
-mod test;
-
-#[cfg(not(feature = "std"))]
-use alloc::vec::Vec;
-use evm_core::ExitError;
-use primitive_types::{H160, U256};
-
-use crate::{
-	execution::{Result, Error},
-	types::*,
-};
-
-const ABI_ALIGNMENT: usize = 32;
-
-/// View into RLP data, which provides method to read typed items from it
-#[derive(Clone)]
-pub struct AbiReader<'i> {
-	buf: &'i [u8],
-	subresult_offset: usize,
-	offset: usize,
-}
-impl<'i> AbiReader<'i> {
-	/// Start reading RLP buffer, assuming there is no padding bytes
-	pub fn new(buf: &'i [u8]) -> Self {
-		Self {
-			buf,
-			subresult_offset: 0,
-			offset: 0,
-		}
-	}
-	/// Start reading RLP buffer, parsing first 4 bytes as selector
-	pub fn new_call(buf: &'i [u8]) -> Result<(Bytes4, Self)> {
-		if buf.len() < 4 {
-			return Err(Error::Error(ExitError::OutOfOffset));
-		}
-		let mut method_id = [0; 4];
-		method_id.copy_from_slice(&buf[0..4]);
-
-		Ok((
-			method_id,
-			Self {
-				buf,
-				subresult_offset: 4,
-				offset: 4,
-			},
-		))
-	}
-
-	fn read_pad<const S: usize>(
-		buf: &[u8],
-		offset: usize,
-		pad_start: usize,
-		pad_end: usize,
-		block_start: usize,
-		block_end: usize,
-	) -> Result<[u8; S]> {
-		if buf.len() - offset < ABI_ALIGNMENT {
-			return Err(Error::Error(ExitError::OutOfOffset));
-		}
-		let mut block = [0; S];
-		let is_pad_zeroed = buf[pad_start..pad_end].iter().all(|&v| v == 0);
-		if !is_pad_zeroed {
-			return Err(Error::Error(ExitError::InvalidRange));
-		}
-		block.copy_from_slice(&buf[block_start..block_end]);
-		Ok(block)
-	}
-
-	fn read_padleft<const S: usize>(&mut self) -> Result<[u8; S]> {
-		let offset = self.offset;
-		self.offset += ABI_ALIGNMENT;
-		Self::read_pad(
-			self.buf,
-			offset,
-			offset,
-			offset + ABI_ALIGNMENT - S,
-			offset + ABI_ALIGNMENT - S,
-			offset + ABI_ALIGNMENT,
-		)
-	}
-
-	fn read_padright<const S: usize>(&mut self) -> Result<[u8; S]> {
-		let offset = self.offset;
-		self.offset += ABI_ALIGNMENT;
-		Self::read_pad(
-			self.buf,
-			offset,
-			offset + S,
-			offset + ABI_ALIGNMENT,
-			offset,
-			offset + S,
-		)
-	}
-
-	/// Read [`H160`] at current position, then advance
-	pub fn address(&mut self) -> Result<H160> {
-		Ok(H160(self.read_padleft()?))
-	}
-
-	/// Read [`bool`] at current position, then advance
-	pub fn bool(&mut self) -> Result<bool> {
-		let data: [u8; 1] = self.read_padleft()?;
-		match data[0] {
-			0 => Ok(false),
-			1 => Ok(true),
-			_ => Err(Error::Error(ExitError::InvalidRange)),
-		}
-	}
-
-	/// Read [`[u8; 4]`] at current position, then advance
-	pub fn bytes4(&mut self) -> Result<[u8; 4]> {
-		self.read_padright()
-	}
-
-	/// Read [`Vec<u8>`] at current position, then advance
-	pub fn bytes(&mut self) -> Result<Vec<u8>> {
-		let mut subresult = self.subresult(None)?;
-		let length = subresult.uint32()? as usize;
-		if subresult.buf.len() < subresult.offset + length {
-			return Err(Error::Error(ExitError::OutOfOffset));
-		}
-		Ok(subresult.buf[subresult.offset..subresult.offset + length].into())
-	}
-
-	/// Read [`string`] at current position, then advance
-	pub fn string(&mut self) -> Result<String> {
-		String::from_utf8(self.bytes()?).map_err(|_| Error::Error(ExitError::InvalidRange))
-	}
-
-	/// Read [`u8`] at current position, then advance
-	pub fn uint8(&mut self) -> Result<u8> {
-		Ok(self.read_padleft::<1>()?[0])
-	}
-
-	/// Read [`u32`] at current position, then advance
-	pub fn uint32(&mut self) -> Result<u32> {
-		Ok(u32::from_be_bytes(self.read_padleft()?))
-	}
-
-	/// Read [`u128`] at current position, then advance
-	pub fn uint128(&mut self) -> Result<u128> {
-		Ok(u128::from_be_bytes(self.read_padleft()?))
-	}
-
-	/// Read [`U256`] at current position, then advance
-	pub fn uint256(&mut self) -> Result<U256> {
-		let buf: [u8; 32] = self.read_padleft()?;
-		Ok(U256::from_big_endian(&buf))
-	}
-
-	/// Read [`u64`] at current position, then advance
-	pub fn uint64(&mut self) -> Result<u64> {
-		Ok(u64::from_be_bytes(self.read_padleft()?))
-	}
-
-	/// Read [`usize`] at current position, then advance
-	#[deprecated = "dangerous, as usize may have different width in wasm and native execution"]
-	pub fn read_usize(&mut self) -> Result<usize> {
-		Ok(usize::from_be_bytes(self.read_padleft()?))
-	}
-
-	/// Slice recursive buffer, advance one word for buffer offset
-	/// If `size` is [`None`] then [`Self::offset`] and [`Self::subresult_offset`] evals from [`Self::buf`].
-	pub fn subresult(&mut self, size: Option<usize>) -> Result<AbiReader<'i>> {
-		let subresult_offset = self.subresult_offset;
-		let offset = if let Some(size) = size {
-			self.offset += size;
-			0
-		} else {
-			self.uint32()? as usize
-		};
-
-		if offset + self.subresult_offset > self.buf.len() {
-			return Err(Error::Error(ExitError::InvalidRange));
-		}
-
-		let new_offset = offset + subresult_offset;
-		Ok(AbiReader {
-			buf: self.buf,
-			subresult_offset: new_offset,
-			offset: new_offset,
-		})
-	}
-
-	/// Notify about readed data portion.
-	pub fn bytes_read(&mut self, size: usize) {
-		self.subresult_offset += size;
-	}
-
-	/// Is this parser reached end of buffer?
-	pub fn is_finished(&self) -> bool {
-		self.buf.len() == self.offset
-	}
-}
-
-/// Writer for RLP encoded data
-#[derive(Default)]
-pub struct AbiWriter {
-	static_part: Vec<u8>,
-	dynamic_part: Vec<(usize, AbiWriter)>,
-	had_call: bool,
-	is_dynamic: bool,
-}
-impl AbiWriter {
-	/// Initialize internal buffers for output data, assuming no padding required
-	pub fn new() -> Self {
-		Self::default()
-	}
-
-	/// Initialize internal buffers with data size
-	pub fn new_dynamic(is_dynamic: bool) -> Self {
-		Self {
-			is_dynamic,
-			..Default::default()
-		}
-	}
-	/// Initialize internal buffers, inserting method selector at beginning
-	pub fn new_call(method_id: u32) -> Self {
-		let mut val = Self::new();
-		val.static_part.extend(&method_id.to_be_bytes());
-		val.had_call = true;
-		val
-	}
-
-	fn write_padleft(&mut self, block: &[u8]) {
-		assert!(block.len() <= ABI_ALIGNMENT);
-		self.static_part
-			.extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - block.len()]);
-		self.static_part.extend(block);
-	}
-
-	fn write_padright(&mut self, block: &[u8]) {
-		assert!(block.len() <= ABI_ALIGNMENT);
-		self.static_part.extend(block);
-		self.static_part
-			.extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - block.len()]);
-	}
-
-	/// Write [`H160`] to end of buffer
-	pub fn address(&mut self, address: &H160) {
-		self.write_padleft(&address.0)
-	}
-
-	/// Write [`bool`] to end of buffer
-	pub fn bool(&mut self, value: &bool) {
-		self.write_padleft(&[if *value { 1 } else { 0 }])
-	}
-
-	/// Write [`u8`] to end of buffer
-	pub fn uint8(&mut self, value: &u8) {
-		self.write_padleft(&[*value])
-	}
-
-	/// Write [`u32`] to end of buffer
-	pub fn uint32(&mut self, value: &u32) {
-		self.write_padleft(&u32::to_be_bytes(*value))
-	}
-
-	/// Write [`u64`] to end of buffer
-	pub fn uint64(&mut self, value: &u64) {
-		self.write_padleft(&u64::to_be_bytes(*value))
-	}
-
-	/// Write [`u128`] to end of buffer
-	pub fn uint128(&mut self, value: &u128) {
-		self.write_padleft(&u128::to_be_bytes(*value))
-	}
-
-	/// Write [`U256`] to end of buffer
-	pub fn uint256(&mut self, value: &U256) {
-		let mut out = [0; 32];
-		value.to_big_endian(&mut out);
-		self.write_padleft(&out)
-	}
-
-	/// Write [`usize`] to end of buffer
-	#[deprecated = "dangerous, as usize may have different width in wasm and native execution"]
-	pub fn write_usize(&mut self, value: &usize) {
-		self.write_padleft(&usize::to_be_bytes(*value))
-	}
-
-	/// Append recursive data, writing pending offset at end of buffer
-	pub fn write_subresult(&mut self, result: Self) {
-		self.dynamic_part.push((self.static_part.len(), result));
-		// Empty block, to be filled later
-		self.write_padleft(&[]);
-	}
-
-	fn memory(&mut self, value: &[u8]) {
-		let mut sub = Self::new();
-		sub.uint32(&(value.len() as u32));
-		for chunk in value.chunks(ABI_ALIGNMENT) {
-			sub.write_padright(chunk);
-		}
-		self.write_subresult(sub);
-	}
-
-	/// Append recursive [`str`] at end of buffer
-	pub fn string(&mut self, value: &str) {
-		self.memory(value.as_bytes())
-	}
-
-	/// Append recursive [`[u8]`] at end of buffer
-	pub fn bytes(&mut self, value: &[u8]) {
-		self.memory(value)
-	}
-
-	/// Finish writer, concatenating all internal buffers
-	pub fn finish(mut self) -> Vec<u8> {
-		for (static_offset, part) in self.dynamic_part {
-			let part_offset = self.static_part.len()
-				- if self.had_call { 4 } else { 0 }
-				- if self.is_dynamic { ABI_ALIGNMENT } else { 0 };
-
-			let encoded_dynamic_offset = usize::to_be_bytes(part_offset);
-			let start = static_offset + ABI_ALIGNMENT - encoded_dynamic_offset.len();
-			let stop = static_offset + ABI_ALIGNMENT;
-			self.static_part[start..stop].copy_from_slice(&encoded_dynamic_offset);
-			self.static_part.extend(part.finish())
-		}
-		self.static_part
-	}
-}
deletedcrates/evm-coder/src/abi/test.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/abi/test.rs
+++ /dev/null
@@ -1,605 +0,0 @@
-use crate::{
-	abi::{AbiRead, AbiWrite},
-	types::*,
-};
-
-use super::{AbiReader, AbiWriter};
-use hex_literal::hex;
-use primitive_types::{H160, U256};
-
-fn test_impl<T>(function_identifier: u32, decoded_data: T, encoded_data: &[u8])
-where
-	T: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,
-{
-	let (call, mut decoder) = AbiReader::new_call(encoded_data).unwrap();
-	assert_eq!(call, u32::to_be_bytes(function_identifier));
-	let data = <T>::abi_read(&mut decoder).unwrap();
-	assert_eq!(data, decoded_data);
-
-	let mut writer = AbiWriter::new_call(function_identifier);
-	decoded_data.abi_write(&mut writer);
-	let ed = writer.finish();
-	similar_asserts::assert_eq!(encoded_data, ed.as_slice());
-}
-
-macro_rules! test_impl_uint {
-	($type:ident) => {
-		test_impl::<$type>(
-			0xdeadbeef,
-			255 as $type,
-			&hex!(
-				"
-                    deadbeef
-                    00000000000000000000000000000000000000000000000000000000000000ff
-                "
-			),
-		);
-	};
-}
-
-#[test]
-fn encode_decode_uint8() {
-	test_impl_uint!(u8);
-}
-
-#[test]
-fn encode_decode_uint32() {
-	test_impl_uint!(u32);
-}
-
-#[test]
-fn encode_decode_uint128() {
-	test_impl_uint!(u128);
-}
-
-#[test]
-fn encode_decode_uint256() {
-	test_impl::<U256>(
-		0xdeadbeef,
-		U256([255, 0, 0, 0]),
-		&hex!(
-			"
-                deadbeef
-                00000000000000000000000000000000000000000000000000000000000000ff
-            "
-		),
-	);
-}
-
-#[test]
-fn encode_decode_string() {
-	test_impl::<String>(
-		0xdeadbeef,
-		"some string".to_string(),
-		&hex!(
-			"
-                deadbeef
-                0000000000000000000000000000000000000000000000000000000000000020
-                000000000000000000000000000000000000000000000000000000000000000b
-                736f6d6520737472696e67000000000000000000000000000000000000000000
-            "
-		),
-	);
-}
-
-#[test]
-fn encode_decode_tuple_string() {
-	test_impl::<(String,)>(
-		0xdeadbeef,
-		("some string".to_string(),),
-		&hex!(
-			"
-                deadbeef
-                0000000000000000000000000000000000000000000000000000000000000020
-                0000000000000000000000000000000000000000000000000000000000000020
-                000000000000000000000000000000000000000000000000000000000000000b
-                736f6d6520737472696e67000000000000000000000000000000000000000000
-            "
-		),
-	);
-}
-
-#[test]
-fn encode_decode_vec_tuple_address_uint256() {
-	test_impl::<Vec<(Address, U256)>>(
-        0x1ACF2D55,
-        vec![
-            (
-                H160(hex!("2D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC")),
-                U256([10, 0, 0, 0]),
-            ),
-            (
-                H160(hex!("AB8E3D9134955566483B11E6825C9223B6737B10")),
-                U256([20, 0, 0, 0]),
-            ),
-            (
-                H160(hex!("8C582BDF2953046705FC56F189385255EFC1BE18")),
-                U256([30, 0, 0, 0]),
-            ),
-        ],
-        &hex!(
-            "
-                1ACF2D55
-                0000000000000000000000000000000000000000000000000000000000000020 // offset of (address, uint256)[]
-                0000000000000000000000000000000000000000000000000000000000000003 // length of (address, uint256)[]
-
-                0000000000000000000000002D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC // address
-                000000000000000000000000000000000000000000000000000000000000000A // uint256
-
-                000000000000000000000000AB8E3D9134955566483B11E6825C9223B6737B10 // address
-                0000000000000000000000000000000000000000000000000000000000000014 // uint256
-
-                0000000000000000000000008C582BDF2953046705FC56F189385255EFC1BE18 // address
-                000000000000000000000000000000000000000000000000000000000000001E // uint256
-            "
-        )
-    );
-}
-
-#[test]
-fn encode_decode_vec_tuple_uint256_string() {
-	test_impl::<Vec<(U256, String)>>(
-        0xdeadbeef,
-        vec![
-            (1.into(), "Test URI 0".to_string()),
-            (11.into(), "Test URI 1".to_string()),
-            (12.into(), "Test URI 2".to_string()),
-        ],
-        &hex!(
-            "
-                deadbeef
-                0000000000000000000000000000000000000000000000000000000000000020 // offset of (uint256, string)[]
-                0000000000000000000000000000000000000000000000000000000000000003 // length of (uint256, string)[]
-
-                0000000000000000000000000000000000000000000000000000000000000060 // offset of first elem
-                00000000000000000000000000000000000000000000000000000000000000e0 // offset of second elem
-                0000000000000000000000000000000000000000000000000000000000000160 // offset of third elem
-
-                0000000000000000000000000000000000000000000000000000000000000001 // first token id?   					#60
-                0000000000000000000000000000000000000000000000000000000000000040 // offset of string
-                000000000000000000000000000000000000000000000000000000000000000a // size of string
-                5465737420555249203000000000000000000000000000000000000000000000 // string
-
-                000000000000000000000000000000000000000000000000000000000000000b // second token id? Why ==11?			#e0
-                0000000000000000000000000000000000000000000000000000000000000040 // offset of string
-                000000000000000000000000000000000000000000000000000000000000000a // size of string
-                5465737420555249203100000000000000000000000000000000000000000000 // string
-
-                000000000000000000000000000000000000000000000000000000000000000c // third token id?  Why ==12?			#160
-                0000000000000000000000000000000000000000000000000000000000000040 // offset of string
-                000000000000000000000000000000000000000000000000000000000000000a // size of string
-                5465737420555249203200000000000000000000000000000000000000000000 // string
-            "
-        )
-    );
-}
-
-#[test]
-fn dynamic_after_static() {
-	let mut encoder = AbiWriter::new();
-	encoder.bool(&true);
-	encoder.string("test");
-	let encoded = encoder.finish();
-
-	let mut encoder = AbiWriter::new();
-	encoder.bool(&true);
-	// Offset to subresult
-	encoder.uint32(&(32 * 2));
-	// Len of "test"
-	encoder.uint32(&4);
-	encoder.write_padright(&[b't', b'e', b's', b't']);
-	let alternative_encoded = encoder.finish();
-
-	assert_eq!(encoded, alternative_encoded);
-
-	let mut decoder = AbiReader::new(&encoded);
-	assert!(decoder.bool().unwrap());
-	assert_eq!(decoder.string().unwrap(), "test");
-}
-
-#[test]
-fn mint_sample() {
-	let (call, mut decoder) = AbiReader::new_call(&hex!(
-		"
-            50bb4e7f
-            000000000000000000000000ad2c0954693c2b5404b7e50967d3481bea432374
-            0000000000000000000000000000000000000000000000000000000000000001
-            0000000000000000000000000000000000000000000000000000000000000060
-            0000000000000000000000000000000000000000000000000000000000000008
-            5465737420555249000000000000000000000000000000000000000000000000
-        "
-	))
-	.unwrap();
-	assert_eq!(call, u32::to_be_bytes(0x50bb4e7f));
-	assert_eq!(
-		format!("{:?}", decoder.address().unwrap()),
-		"0xad2c0954693c2b5404b7e50967d3481bea432374"
-	);
-	assert_eq!(decoder.uint32().unwrap(), 1);
-	assert_eq!(decoder.string().unwrap(), "Test URI");
-}
-
-#[test]
-fn parse_vec_with_dynamic_type() {
-	let decoded_data = (
-		0x36543006,
-		vec![
-			(1.into(), "Test URI 0".to_string()),
-			(11.into(), "Test URI 1".to_string()),
-			(12.into(), "Test URI 2".to_string()),
-		],
-	);
-
-	let encoded_data = &hex!(
-        "
-            36543006
-            00000000000000000000000053744e6da587ba10b32a2554d2efdcd985bc27a3 // address
-            0000000000000000000000000000000000000000000000000000000000000040 // offset of (uint256, string)[]
-            0000000000000000000000000000000000000000000000000000000000000003 // length of (uint256, string)[]
-
-            0000000000000000000000000000000000000000000000000000000000000060 // offset of first elem
-            00000000000000000000000000000000000000000000000000000000000000e0 // offset of second elem
-            0000000000000000000000000000000000000000000000000000000000000160 // offset of third elem
-
-            0000000000000000000000000000000000000000000000000000000000000001 // first token id?   					#60
-            0000000000000000000000000000000000000000000000000000000000000040 // offset of string
-            000000000000000000000000000000000000000000000000000000000000000a // size of string
-            5465737420555249203000000000000000000000000000000000000000000000 // string
-
-            000000000000000000000000000000000000000000000000000000000000000b // second token id? Why ==11?			#e0
-            0000000000000000000000000000000000000000000000000000000000000040 // offset of string
-            000000000000000000000000000000000000000000000000000000000000000a // size of string
-            5465737420555249203100000000000000000000000000000000000000000000 // string
-
-            000000000000000000000000000000000000000000000000000000000000000c // third token id?  Why ==12?			#160
-            0000000000000000000000000000000000000000000000000000000000000040 // offset of string
-            000000000000000000000000000000000000000000000000000000000000000a // size of string
-            5465737420555249203200000000000000000000000000000000000000000000 // string
-        "
-    );
-
-	let (call, mut decoder) = AbiReader::new_call(encoded_data).unwrap();
-	assert_eq!(call, u32::to_be_bytes(decoded_data.0));
-	let address = decoder.address().unwrap();
-	let data = <Vec<(U256, String)>>::abi_read(&mut decoder).unwrap();
-	assert_eq!(data, decoded_data.1);
-
-	let mut writer = AbiWriter::new_call(decoded_data.0);
-	address.abi_write(&mut writer);
-	decoded_data.1.abi_write(&mut writer);
-	let ed = writer.finish();
-	similar_asserts::assert_eq!(encoded_data, ed.as_slice());
-}
-
-#[test]
-fn encode_decode_vec_tuple_string_bytes() {
-	test_impl::<Vec<(String, Bytes)>>(
-		0xdeadbeef,
-		vec![
-			(
-				"Test URI 0".to_string(),
-				Bytes(vec![
-					0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-					0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-					0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-					0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-				]),
-			),
-			(
-				"Test URI 1".to_string(),
-				Bytes(vec![
-					0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-					0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-					0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-					0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-				]),
-			),
-			("Test URI 2".to_string(), Bytes(vec![0x33, 0x33])),
-		],
-		&hex!(
-			"
-                deadbeef
-                0000000000000000000000000000000000000000000000000000000000000020
-                0000000000000000000000000000000000000000000000000000000000000003
-
-                0000000000000000000000000000000000000000000000000000000000000060
-                0000000000000000000000000000000000000000000000000000000000000140
-                0000000000000000000000000000000000000000000000000000000000000220
-
-                0000000000000000000000000000000000000000000000000000000000000040
-                0000000000000000000000000000000000000000000000000000000000000080
-                000000000000000000000000000000000000000000000000000000000000000a
-                5465737420555249203000000000000000000000000000000000000000000000
-                0000000000000000000000000000000000000000000000000000000000000030
-                1111111111111111111111111111111111111111111111111111111111111111
-                1111111111111111111111111111111100000000000000000000000000000000
-
-                0000000000000000000000000000000000000000000000000000000000000040
-                0000000000000000000000000000000000000000000000000000000000000080
-                000000000000000000000000000000000000000000000000000000000000000a
-                5465737420555249203100000000000000000000000000000000000000000000
-                000000000000000000000000000000000000000000000000000000000000002f
-                2222222222222222222222222222222222222222222222222222222222222222
-                2222222222222222222222222222220000000000000000000000000000000000
-
-                0000000000000000000000000000000000000000000000000000000000000040
-                0000000000000000000000000000000000000000000000000000000000000080
-                000000000000000000000000000000000000000000000000000000000000000a
-                5465737420555249203200000000000000000000000000000000000000000000
-                0000000000000000000000000000000000000000000000000000000000000002
-                3333000000000000000000000000000000000000000000000000000000000000
-            "
-		),
-	);
-}
-
-#[test]
-// #[ignore = "reason"]
-fn encode_decode_tuple0_tuple1_uint8_tuple1_string_bytes_tuple1_uint8_bytes() {
-	let int = 0xff;
-	let by = Bytes(vec![0x11, 0x22, 0x33]);
-	let string = "some string".to_string();
-
-	test_impl::<((u8,), (String, Bytes), (u8, Bytes))>(
-		0xdeadbeef,
-		((int,), (string.clone(), by.clone()), (int, by)),
-		&hex!(
-			"
-                deadbeef
-                0000000000000000000000000000000000000000000000000000000000000020
-                00000000000000000000000000000000000000000000000000000000000000ff
-                0000000000000000000000000000000000000000000000000000000000000060
-                0000000000000000000000000000000000000000000000000000000000000120
-                0000000000000000000000000000000000000000000000000000000000000040
-                0000000000000000000000000000000000000000000000000000000000000080
-                000000000000000000000000000000000000000000000000000000000000000b
-                736f6d6520737472696e67000000000000000000000000000000000000000000
-                0000000000000000000000000000000000000000000000000000000000000003
-                1122330000000000000000000000000000000000000000000000000000000000
-                00000000000000000000000000000000000000000000000000000000000000ff
-                0000000000000000000000000000000000000000000000000000000000000040
-                0000000000000000000000000000000000000000000000000000000000000003
-                1122330000000000000000000000000000000000000000000000000000000000
-            "
-		),
-	);
-}
-
-#[test]
-fn encode_decode_tuple0_tuple1_uint8_tuple1_uint8_uint8_tuple1_uint8_uint8() {
-	test_impl::<((u8,), (u8, u8), (u8, u8))>(
-		0xdeadbeef,
-		((43,), (44, 45), (46, 47)),
-		&hex!(
-			"
-                deadbeef
-                000000000000000000000000000000000000000000000000000000000000002b
-                000000000000000000000000000000000000000000000000000000000000002c
-                000000000000000000000000000000000000000000000000000000000000002d
-                000000000000000000000000000000000000000000000000000000000000002e
-                000000000000000000000000000000000000000000000000000000000000002f
-            "
-		),
-	);
-}
-
-#[test]
-fn encode_decode_tuple0_tuple1_uint8_tuple1_uint8() {
-	test_impl::<((u8,), (u8,))>(
-		0xdeadbeef,
-		((43,), (44,)),
-		&hex!(
-			"
-                deadbeef
-                000000000000000000000000000000000000000000000000000000000000002b
-                000000000000000000000000000000000000000000000000000000000000002c
-            "
-		),
-	);
-}
-
-#[test]
-fn encode_decode_tuple0_tuple1_uint8_uint8() {
-	test_impl::<((u8, u8),)>(
-		0xdeadbeef,
-		((43, 44),),
-		&hex!(
-			"
-                deadbeef
-                000000000000000000000000000000000000000000000000000000000000002b
-                000000000000000000000000000000000000000000000000000000000000002c
-            "
-		),
-	);
-}
-
-#[test]
-fn encode_decode_tuple_uint8_uint8() {
-	test_impl::<(u8, u8)>(
-		0xdeadbeef,
-		(43, 44),
-		&hex!(
-			"
-                deadbeef
-                000000000000000000000000000000000000000000000000000000000000002b
-                000000000000000000000000000000000000000000000000000000000000002c
-            "
-		),
-	);
-}
-
-#[test]
-fn encode_decode_tuple0_tuple1_uint8_uint8_tuple1_uint8_uint8_and_uint8() {
-	test_impl::<((u8, u8), (u8, u8), u8)>(
-		0xdeadbeef,
-		((10, 11), (12, 13), 14),
-		&hex!(
-			"
-                deadbeef
-                000000000000000000000000000000000000000000000000000000000000000a
-                000000000000000000000000000000000000000000000000000000000000000b
-                000000000000000000000000000000000000000000000000000000000000000c
-                000000000000000000000000000000000000000000000000000000000000000d
-                000000000000000000000000000000000000000000000000000000000000000e
-            "
-		),
-	);
-}
-
-#[test]
-fn encode_decode_tuple0_tuple1_string() {
-	test_impl::<((String,),)>(
-		0xdeadbeef,
-		(("some string".to_string(),),),
-		&hex!(
-			"
-                deadbeef
-                0000000000000000000000000000000000000000000000000000000000000020
-                0000000000000000000000000000000000000000000000000000000000000020
-                0000000000000000000000000000000000000000000000000000000000000020
-                000000000000000000000000000000000000000000000000000000000000000b
-                736f6d6520737472696e67000000000000000000000000000000000000000000
-            "
-		),
-	);
-}
-
-#[test]
-fn encode_decode_tuple0_tuple1_uint8_string() {
-	test_impl::<((u8, String),)>(
-		0xdeadbeef,
-		((0xff, "some string".to_string()),),
-		&hex!(
-			"
-                deadbeef
-                0000000000000000000000000000000000000000000000000000000000000020
-                0000000000000000000000000000000000000000000000000000000000000020
-                00000000000000000000000000000000000000000000000000000000000000ff
-                0000000000000000000000000000000000000000000000000000000000000040
-                000000000000000000000000000000000000000000000000000000000000000b
-                736f6d6520737472696e67000000000000000000000000000000000000000000
-            "
-		),
-	);
-}
-
-#[test]
-fn encode_decode_tuple0_tuple1_string_bytes() {
-	test_impl::<((String, Bytes),)>(
-		0xdeadbeef,
-		(("some string".to_string(), Bytes(vec![1, 2, 3])),),
-		&hex!(
-			"
-                deadbeef
-                0000000000000000000000000000000000000000000000000000000000000020
-                0000000000000000000000000000000000000000000000000000000000000020
-                0000000000000000000000000000000000000000000000000000000000000040
-                0000000000000000000000000000000000000000000000000000000000000080
-                000000000000000000000000000000000000000000000000000000000000000b
-                736f6d6520737472696e67000000000000000000000000000000000000000000
-                0000000000000000000000000000000000000000000000000000000000000003
-                0102030000000000000000000000000000000000000000000000000000000000
-            "
-		),
-	);
-}
-
-#[test]
-fn encode_decode_tuple0_tuple1_uint8_tuple1_string() {
-	test_impl::<((u8,), (String,))>(
-		0xdeadbeef,
-		((0xff,), ("some string".to_string(),)),
-		&hex!(
-			"
-                deadbeef
-                0000000000000000000000000000000000000000000000000000000000000020
-                00000000000000000000000000000000000000000000000000000000000000ff
-                0000000000000000000000000000000000000000000000000000000000000040
-                0000000000000000000000000000000000000000000000000000000000000020
-                000000000000000000000000000000000000000000000000000000000000000b
-                736f6d6520737472696e67000000000000000000000000000000000000000000
-            "
-		),
-	);
-}
-
-#[test]
-fn parse_multiple_params() {
-	let encoded_data = hex!(
-		"
-            deadbeef
-            000000000000000000000000000000000000000000000000000000000000000a
-            000000000000000000000000000000000000000000000000000000000000000b
-        "
-	);
-	let (_, mut decoder) = AbiReader::new_call(&encoded_data).unwrap();
-	let p1 = <u8>::abi_read(&mut decoder).unwrap();
-	let p2 = <u8>::abi_read(&mut decoder).unwrap();
-	assert_eq!(p1, 0x0a);
-	assert_eq!(p2, 0x0b);
-}
-
-#[test]
-fn encode_decode_option_uint8_some() {
-	test_impl::<Option<u8>>(
-		0xdeadbeef,
-		Some(44),
-		&hex!(
-			"
-                deadbeef
-                0000000000000000000000000000000000000000000000000000000000000001
-                000000000000000000000000000000000000000000000000000000000000002c
-            "
-		),
-	);
-}
-
-#[test]
-fn encode_decode_option_uint8_none() {
-	test_impl::<Option<u8>>(
-		0xdeadbeef,
-		None,
-		&hex!(
-			"
-                deadbeef
-                0000000000000000000000000000000000000000000000000000000000000000
-                0000000000000000000000000000000000000000000000000000000000000000
-            "
-		),
-	);
-}
-
-#[test]
-fn encode_decode_option_string_some() {
-	test_impl::<Option<String>>(
-		0xdeadbeef,
-		Some("some string".to_string()),
-		&hex!(
-			"
-                deadbeef
-                0000000000000000000000000000000000000000000000000000000000000020
-                0000000000000000000000000000000000000000000000000000000000000001
-                0000000000000000000000000000000000000000000000000000000000000040
-                000000000000000000000000000000000000000000000000000000000000000b
-                736f6d6520737472696e67000000000000000000000000000000000000000000
-            "
-		),
-	);
-}
-
-#[test]
-fn encode_decode_option_string_none() {
-	test_impl::<Option<String>>(
-		0xdeadbeef,
-		None,
-		&hex!(
-			"
-                deadbeef
-                0000000000000000000000000000000000000000000000000000000000000020
-                0000000000000000000000000000000000000000000000000000000000000000
-                0000000000000000000000000000000000000000000000000000000000000040
-                0000000000000000000000000000000000000000000000000000000000000000
-            "
-		),
-	);
-}
deletedcrates/evm-coder/src/abi/traits.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/abi/traits.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-use super::{AbiReader, AbiWriter};
-use crate::{
-	custom_signature::*,
-	execution::{Result, ResultWithPostInfo},
-};
-use core::str::from_utf8;
-
-/// Helper for type.
-pub trait AbiType {
-	/// Signature for Etherium ABI.
-	const SIGNATURE: SignatureUnit;
-
-	/// Signature as str.
-	fn as_str() -> &'static str {
-		from_utf8(&Self::SIGNATURE.data[..Self::SIGNATURE.len]).expect("bad utf-8")
-	}
-
-	/// Is type dynamic sized.
-	fn is_dynamic() -> bool;
-
-	/// Size for type aligned to [`ABI_ALIGNMENT`].
-	fn size() -> usize;
-}
-
-/// [`AbiReader`] implements reading of many types.
-pub trait AbiRead {
-	/// Read item from current position, advanding decoder
-	fn abi_read(reader: &mut AbiReader) -> Result<Self>
-	where
-		Self: Sized;
-}
-
-/// For questions about inability to provide custom implementations,
-/// see [`AbiRead`]
-pub trait AbiWrite {
-	/// Write value to end of specified encoder
-	fn abi_write(&self, writer: &mut AbiWriter);
-	/// Specialization for [`crate::solidity_interface`] implementation,
-	/// see comment in `impl AbiWrite for ResultWithPostInfo`
-	fn to_result(&self) -> ResultWithPostInfo<AbiWriter> {
-		let mut writer = AbiWriter::new();
-		self.abi_write(&mut writer);
-		Ok(writer.into())
-	}
-}
deletedcrates/evm-coder/src/custom_signature.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/custom_signature.rs
+++ /dev/null
@@ -1,326 +0,0 @@
-//! # A module for custom signature support.
-//!
-//! ## Overview
-//! This module allows you to create arbitrary signatures for types and functions in compile time.
-//!
-//! ### Type signatures
-//! To create the desired type signature, you need to create your own trait with the `SIGNATURE` constant.
-//! Then in the implementation, for the required type, use the macro [`make_signature`]
-//! #### Example
-//! ```
-//! use std::str::from_utf8;
-//! use evm_coder::{custom_signature::SignatureUnit, make_signature};
-//!
-//! // Create trait for our signature
-//! trait SoliditySignature {
-//!     const SIGNATURE: SignatureUnit;
-//!
-//!     fn name() -> &'static str {
-//!         from_utf8(&Self::SIGNATURE.data[..Self::SIGNATURE.len]).expect("bad utf-8")
-//!     }
-//! }
-//!
-//! // Make signatures for some types
-//! impl SoliditySignature for u8 {
-//!     const SIGNATURE: SignatureUnit = make_signature!(new fixed("uint8"));
-//! }
-//! impl SoliditySignature for u32 {
-//!     const SIGNATURE: SignatureUnit = make_signature!(new fixed("uint32"));
-//! }
-//! impl<T: SoliditySignature> SoliditySignature for Vec<T> {
-//!     const SIGNATURE: SignatureUnit = make_signature!(new nameof(T::SIGNATURE) fixed("[]"));
-//! }
-//! impl<A: SoliditySignature, B: SoliditySignature> SoliditySignature for (A, B) {
-//!     const SIGNATURE: SignatureUnit = make_signature!(new fixed("(") nameof(A::SIGNATURE) fixed(",") nameof(B::SIGNATURE) fixed(")"));
-//! }
-//! impl<A: SoliditySignature> SoliditySignature for (A,) {
-//!     const SIGNATURE: SignatureUnit = make_signature!(new fixed("(") nameof(A::SIGNATURE) fixed(",") shift_left(1) fixed(")"));
-//! }
-//!
-//! assert_eq!(u8::name(), "uint8");
-//! assert_eq!(<Vec<u8>>::name(), "uint8[]");
-//! assert_eq!(<(u32, u8)>::name(), "(uint32,uint8)");
-//! ```
-//!
-//! ### Function signatures
-//! To create a function signature, the macro [`make_signature`] is also used, which accepts
-//! settings for the function format [`SignaturePreferences`] and function parameters [`SignatureUnit`]
-//! #### Example
-//! ```
-//! use core::str::from_utf8;
-//! use evm_coder::{custom_signature::SignatureUnit, make_signature};
-//! // Trait for our signature
-//! trait SoliditySignature {
-//!     const SIGNATURE: SignatureUnit;
-//!
-//!     fn name() -> &'static str {
-//!         from_utf8(&Self::SIGNATURE.data[..Self::SIGNATURE.len]).expect("bad utf-8")
-//!     }
-//! }
-//!
-//! // Make signatures for some types
-//! impl SoliditySignature for u8 {
-//!     const SIGNATURE: SignatureUnit = make_signature!(new fixed("uint8"));
-//! }
-//! impl<T: SoliditySignature> SoliditySignature for Vec<T> {
-//!     const SIGNATURE: SignatureUnit = make_signature!(new nameof(T::SIGNATURE) fixed("[]"));
-//! }
-//! ```
-
-/// The maximum length of the signature.
-pub const SIGNATURE_SIZE_LIMIT: usize = 256;
-
-/// Storage for the signature or its elements.
-#[derive(Debug)]
-pub struct SignatureUnit {
-	/// Signature data.
-	pub data: [u8; SIGNATURE_SIZE_LIMIT],
-	/// The actual size of the data.
-	pub len: usize,
-}
-
-impl SignatureUnit {
-	/// Create a signature from `&str'.
-	pub const fn new(name: &'static str) -> SignatureUnit {
-		let mut signature = [0_u8; SIGNATURE_SIZE_LIMIT];
-		let name = name.as_bytes();
-		let name_len = name.len();
-		let mut dst_offset = 0;
-		crate::make_signature!(@copy(name, signature, name_len, dst_offset));
-		SignatureUnit {
-			data: signature,
-			len: name_len,
-		}
-	}
-	/// String conversion
-	pub fn as_str(&self) -> Option<&str> {
-		core::str::from_utf8(&self.data[0..self.len]).ok()
-	}
-}
-
-/// ### Macro to create signatures of types and functions.
-///
-/// Format for creating a type of signature:
-/// ```ignore
-/// make_signature!(new fixed("uint8")); // Simple type
-/// make_signature!(new fixed("(") nameof(u8) fixed(",") nameof(u8) fixed(")")); // Composite type
-/// ```
-#[macro_export]
-macro_rules! make_signature {
-	(new $($tt:tt)*) => {
-		($crate::custom_signature::SignatureUnit {
-			data: {
-				let mut out = [0u8; $crate::custom_signature::SIGNATURE_SIZE_LIMIT];
-				let mut dst_offset = 0;
-				$crate::make_signature!(@data(out, dst_offset); $($tt)*);
-				out
-			},
-			len: {0 + $crate::make_signature!(@size; $($tt)*)},
-		})
-	};
-
-	(@size;) => {
-		0
-	};
-	(@size; fixed($expr:expr) $($tt:tt)*) => {
-		$expr.len() + $crate::make_signature!(@size; $($tt)*)
-	};
-	(@size; nameof($expr:expr) $($tt:tt)*) => {
-		$expr.len + $crate::make_signature!(@size; $($tt)*)
-	};
-	(@size; numof($expr:expr) $($tt:tt)*) => {
-		{
-			let mut out = 0;
-			let mut v = $expr;
-			if v == 0 {
-				out = 1;
-			} else {
-				while v > 0 {
-					out += 1;
-					v /= 10;
-				}
-			}
-			out
-		} + $crate::make_signature!(@size; $($tt)*)
-	};
-	(@size; shift_left($expr:expr) $($tt:tt)*) => {
-		$crate::make_signature!(@size; $($tt)*) - $expr
-	};
-
-	(@data($dst:ident, $dst_offset:ident);) => {};
-	(@data($dst:ident, $dst_offset:ident); fixed($expr:expr) $($tt:tt)*) => {
-		{
-			let data = $expr.as_bytes();
-			let data_len = data.len();
-			$crate::make_signature!(@copy(data, $dst, data_len, $dst_offset));
-		}
-		$crate::make_signature!(@data($dst, $dst_offset); $($tt)*)
-	};
-	(@data($dst:ident, $dst_offset:ident); nameof($expr:expr) $($tt:tt)*) => {
-		{
-			$crate::make_signature!(@copy(&$expr.data, $dst, $expr.len, $dst_offset));
-		}
-		$crate::make_signature!(@data($dst, $dst_offset); $($tt)*)
-	};
-	(@data($dst:ident, $dst_offset:ident); numof($expr:expr) $($tt:tt)*) => {
-		{
-			let mut v = $expr;
-			let mut need_to_swap = 0;
-			if v == 0 {
-				$dst[$dst_offset] = b'0';
-				$dst_offset += 1;
-			} else {
-				while v > 0 {
-					let n = (v % 10) as u8;
-					$dst[$dst_offset] = b'0' + n;
-					v /= 10;
-					need_to_swap += 1;
-					$dst_offset += 1;
-				}
-			}
-			let mut i = 0;
-			#[allow(clippy::manual_swap)]
-			while i < need_to_swap / 2 {
-				let a = $dst_offset - i - 1;
-				let b = $dst_offset - need_to_swap + i;
-				let v = $dst[a];
-				$dst[a] = $dst[b];
-				$dst[b] = v;
-				i += 1;
-			}
-		}
-		$crate::make_signature!(@data($dst, $dst_offset); $($tt)*)
-	};
-	(@data($dst:ident, $dst_offset:ident); shift_left($expr:expr) $($tt:tt)*) => {
-		$dst_offset -= $expr;
-		$crate::make_signature!(@data($dst, $dst_offset); $($tt)*)
-	};
-
-	(@copy($src:expr, $dst:expr, $src_len:expr, $dst_offset:ident)) => {
-		{
-			let mut src_offset = 0;
-			let src_len: usize = $src_len;
-			while src_offset < src_len {
-				$dst[$dst_offset] = $src[src_offset];
-				$dst_offset += 1;
-				src_offset += 1;
-			}
-		}
-	}
-}
-
-#[cfg(test)]
-mod test {
-	use core::str::from_utf8;
-
-	use super::{SIGNATURE_SIZE_LIMIT, SignatureUnit};
-
-	trait Name {
-		const NAME: SignatureUnit;
-
-		fn name() -> &'static str {
-			from_utf8(&Self::NAME.data[..Self::NAME.len]).expect("bad utf-8")
-		}
-	}
-
-	impl Name for u8 {
-		const NAME: SignatureUnit = make_signature!(new fixed("uint8"));
-	}
-	impl Name for u32 {
-		const NAME: SignatureUnit = make_signature!(new fixed("uint32"));
-	}
-	impl<T: Name> Name for Vec<T> {
-		const NAME: SignatureUnit = make_signature!(new nameof(T::NAME) fixed("[]"));
-	}
-	impl<A: Name, B: Name> Name for (A, B) {
-		const NAME: SignatureUnit =
-			make_signature!(new fixed("(") nameof(A::NAME) fixed(",") nameof(B::NAME) fixed(")"));
-	}
-	impl<A: Name> Name for (A,) {
-		const NAME: SignatureUnit =
-			make_signature!(new fixed("(") nameof(A::NAME) fixed(",") shift_left(1) fixed(")"));
-	}
-	impl<A: Name, const SIZE: usize> Name for [A; SIZE] {
-		const NAME: SignatureUnit =
-			make_signature!(new nameof(A::NAME) fixed("[") numof(SIZE) fixed("]"));
-	}
-
-	struct MaxSize();
-	impl Name for MaxSize {
-		const NAME: SignatureUnit = SignatureUnit {
-			data: [b'!'; SIGNATURE_SIZE_LIMIT],
-			len: SIGNATURE_SIZE_LIMIT,
-		};
-	}
-
-	#[test]
-	fn simple() {
-		assert_eq!(u8::name(), "uint8");
-		assert_eq!(u32::name(), "uint32");
-	}
-
-	#[test]
-	fn vector_of_simple() {
-		assert_eq!(<Vec<u8>>::name(), "uint8[]");
-		assert_eq!(<Vec<u32>>::name(), "uint32[]");
-	}
-
-	#[test]
-	fn vector_of_vector() {
-		assert_eq!(<Vec<Vec<u8>>>::name(), "uint8[][]");
-	}
-
-	#[test]
-	fn tuple_of_simple() {
-		assert_eq!(<(u32, u8)>::name(), "(uint32,uint8)");
-	}
-
-	#[test]
-	fn tuple_of_tuple() {
-		assert_eq!(
-			<((u32, u8), (u8, u32))>::name(),
-			"((uint32,uint8),(uint8,uint32))"
-		);
-	}
-
-	#[test]
-	fn vector_of_tuple() {
-		assert_eq!(<Vec<(u32, u8)>>::name(), "(uint32,uint8)[]");
-	}
-
-	#[test]
-	fn tuple_of_vector() {
-		assert_eq!(<(Vec<u32>, u8)>::name(), "(uint32[],uint8)");
-	}
-
-	#[test]
-	fn complex() {
-		assert_eq!(
-			<(Vec<u32>, (u32, Vec<u8>))>::name(),
-			"(uint32[],(uint32,uint8[]))"
-		);
-	}
-
-	#[test]
-	fn max_size() {
-		assert_eq!(<MaxSize>::name(), "!".repeat(SIGNATURE_SIZE_LIMIT));
-	}
-
-	#[test]
-	fn shift() {
-		assert_eq!(<(u32,)>::name(), "(uint32)");
-	}
-
-	#[test]
-	fn num() {
-		assert_eq!(<[u8; 0]>::name(), "uint8[0]");
-		assert_eq!(<[u8; 1234]>::name(), "uint8[1234]");
-		assert_eq!(<[u8; 12345]>::name(), "uint8[12345]");
-	}
-
-	#[test]
-	fn over_max_size() {
-		let t = trybuild::TestCases::new();
-		t.compile_fail("tests/build_failed/custom_signature_over_max_size.rs");
-	}
-}
deletedcrates/evm-coder/src/events.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/events.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-use ethereum::Log;
-use primitive_types::{H160, H256, U256};
-
-use crate::types::*;
-
-/// Implementation of this trait should not be written manually,
-/// instead use [`crate::ToLog`] proc macros.
-///
-/// See also [`evm_coder_procedural::ToLog`], [solidity docs on events](https://docs.soliditylang.org/en/develop/contracts.html#events)
-pub trait ToLog {
-	/// Convert event to [`ethereum::Log`].
-	/// Because event by itself doesn't contains current contract
-	/// address, it should be specified manually.
-	fn to_log(&self, contract: H160) -> Log;
-}
-
-/// Only items implementing `ToTopic` may be used as `#[indexed]` field
-/// in [`crate::ToLog`] macro usage.
-///
-/// See also (solidity docs on events)[<https://docs.soliditylang.org/en/develop/contracts.html#events>]
-pub trait ToTopic {
-	/// Convert value to topic to be used in [`ethereum::Log`]
-	fn to_topic(&self) -> H256;
-}
-
-impl ToTopic for H256 {
-	fn to_topic(&self) -> H256 {
-		*self
-	}
-}
-
-impl ToTopic for U256 {
-	fn to_topic(&self) -> H256 {
-		let mut out = [0u8; 32];
-		self.to_big_endian(&mut out);
-		H256(out)
-	}
-}
-
-impl ToTopic for Address {
-	fn to_topic(&self) -> H256 {
-		let mut out = [0u8; 32];
-		out[12..32].copy_from_slice(&self.0);
-		H256(out)
-	}
-}
-
-impl ToTopic for u32 {
-	fn to_topic(&self) -> H256 {
-		let mut out = [0u8; 32];
-		out[28..32].copy_from_slice(&self.to_be_bytes());
-		H256(out)
-	}
-}
deletedcrates/evm-coder/src/execution.rsdiffbeforeafterboth

no changes

deletedcrates/evm-coder/src/lib.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/lib.rs
+++ /dev/null
@@ -1,298 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-#![doc = include_str!("../README.md")]
-#![deny(missing_docs)]
-#![macro_use]
-#![cfg_attr(not(feature = "std"), no_std)]
-#[cfg(not(feature = "std"))]
-extern crate alloc;
-
-use abi::{AbiRead, AbiReader, AbiWriter};
-pub use evm_coder_procedural::{event_topic, fn_selector};
-pub mod abi;
-pub use events::{ToLog, ToTopic};
-use execution::DispatchInfo;
-pub mod execution;
-#[macro_use]
-pub mod custom_signature;
-
-/// Derives call enum implementing [`crate::Callable`], [`crate::Weighted`]
-/// and [`crate::Call`] from impl block.
-///
-/// ## Macro syntax
-///
-/// `#[solidity_interface(name, is, inline_is, events)]`
-/// - *name* - used in generated code, and for Call enum name
-/// - *is* - used to provide inheritance in Solidity
-/// - *inline_is* - same as `is`, but ERC165::SupportsInterface will work differently: For `is` SupportsInterface(A) will return true
-///   if A is one of the interfaces the contract is inherited from (e.g. B is created as `is(A)`). If B is created as `inline_is(A)`
-///   SupportsInterface(A) will internally create a new interface that combines all methods of A and B, so SupportsInterface(A) will return
-///   false.
-///
-/// `#[weight(value)]`
-/// Can be added to every method of impl block, used for deriving [`crate::Weighted`], which
-/// is used by substrate bridge.
-/// - *value*: expression, which evaluates to weight required to call this method.
-/// This expression can use call arguments to calculate non-constant execution time.
-/// This expression should evaluate faster than actual execution does, and may provide worse case
-/// than one is called.
-///
-/// `#[solidity_interface(rename_selector)]`
-/// - *rename_selector* - by default, selector name will be generated by transforming method name
-/// from snake_case to camelCase. Use this option, if other naming convention is required.
-/// I.e: method `token_uri` will be automatically renamed to `tokenUri` in selector, but name
-/// required by ERC721 standard is `tokenURI`, thus we need to specify `rename_selector = "tokenURI"`
-/// explicitly.
-///
-/// Both contract and contract methods may have doccomments, which will end up in a generated
-/// solidity interface file, thus you should use [solidity syntax](https://docs.soliditylang.org/en/latest/natspec-format.html) for writing documentation in this macro
-///
-/// ## Example
-///
-/// ```ignore
-/// struct SuperContract;
-/// struct InlineContract;
-/// struct Contract;
-///
-/// #[derive(ToLog)]
-/// enum ContractEvents {
-///     Event(#[indexed] uint32),
-/// }
-///
-/// /// @dev This contract provides function to multiply two numbers
-/// #[solidity_interface(name = MyContract, is(SuperContract), inline_is(InlineContract))]
-/// impl Contract {
-///     /// Multiply two numbers
-///     /// @param a First number
-///     /// @param b Second number
-///     /// @return uint32 Product of two passed numbers
-///     /// @dev This function returns error in case of overflow
-///     #[weight(200 + a + b)]
-///     #[solidity_interface(rename_selector = "mul")]
-///     fn mul(&mut self, a: uint32, b: uint32) -> Result<uint32> {
-///         Ok(a.checked_mul(b).ok_or("overflow")?)
-///     }
-/// }
-/// ```
-pub use evm_coder_procedural::solidity_interface;
-/// See [`solidity_interface`]
-pub use evm_coder_procedural::solidity;
-/// See [`solidity_interface`]
-pub use evm_coder_procedural::weight;
-pub use evm_coder_procedural::AbiCoder;
-pub use sha3_const;
-
-/// macro reexports
-pub use ethereum;
-
-/// Derives [`ToLog`] for enum
-///
-/// Selectors will be derived from variant names, there is currently no way to have custom naming
-/// for them
-///
-/// `#[indexed]`
-/// Marks this field as indexed, so it will appear in [`ethereum::Log`] topics instead of data
-pub use evm_coder_procedural::ToLog;
-
-// Api of those modules shouldn't be consumed directly, it is only exported for usage in proc macros
-#[doc(hidden)]
-pub mod events;
-#[doc(hidden)]
-#[cfg(feature = "stubgen")]
-pub mod solidity;
-
-/// Sealed traits.
-pub mod sealed {
-	/// Not every type should be directly placed in vec.
-	/// Vec encoding is not memory efficient, as every item will be padded
-	/// to 32 bytes.
-	/// Instead you should use specialized types (`bytes` in case of `Vec<u8>`)
-	pub trait CanBePlacedInVec {}
-}
-
-/// Solidity type definitions (aliases from solidity name to rust type)
-/// To be used in [`solidity_interface`] definitions, to make sure there is no
-/// type conflict between Rust code and generated definitions
-pub mod types {
-	#![allow(non_camel_case_types, missing_docs)]
-
-	#[cfg(not(feature = "std"))]
-	use alloc::{vec::Vec};
-	use primitive_types::{U256, H160, H256};
-
-	pub type Address = H160;
-	pub type Bytes4 = [u8; 4];
-	pub type Topic = H256;
-
-	#[cfg(not(feature = "std"))]
-	pub type String = ::alloc::string::String;
-	#[cfg(feature = "std")]
-	pub type String = ::std::string::String;
-
-	#[derive(Default, Debug, PartialEq, Eq, Clone)]
-	pub struct Bytes(pub Vec<u8>);
-
-	//#region Special types
-	/// Makes function payable
-	pub type Value = U256;
-	/// Makes function caller-sensitive
-	pub type Caller = Address;
-	//#endregion
-
-	/// Ethereum typed call message, similar to solidity
-	/// `msg` object.
-	pub struct Msg<C> {
-		pub call: C,
-		/// Address of user, which called this contract.
-		pub caller: H160,
-		/// Payment amount to contract.
-		/// Contract should reject payment, if target call is not payable,
-		/// and there is no `receiver()` function defined.
-		pub value: U256,
-	}
-
-	impl From<Vec<u8>> for Bytes {
-		fn from(src: Vec<u8>) -> Self {
-			Self(src)
-		}
-	}
-
-	#[allow(clippy::from_over_into)]
-	impl Into<Vec<u8>> for Bytes {
-		fn into(self) -> Vec<u8> {
-			self.0
-		}
-	}
-
-	impl Bytes {
-		#[must_use]
-		pub fn len(&self) -> usize {
-			self.0.len()
-		}
-
-		#[must_use]
-		pub fn is_empty(&self) -> bool {
-			self.len() == 0
-		}
-	}
-}
-
-/// Parseable EVM call, this trait should be implemented with [`solidity_interface`] macro
-pub trait Call: Sized {
-	/// Parse call buffer into typed call enum
-	fn parse(selector: types::Bytes4, input: &mut AbiReader) -> execution::Result<Option<Self>>;
-}
-
-/// Intended to be used as `#[weight]` output type
-/// Should be same between evm-coder and substrate to avoid confusion
-///
-/// Isn't same thing as gas, some mapping is required between those types
-pub type Weight = frame_support::pallet_prelude::Weight;
-
-/// In substrate, we have benchmarking, which allows
-/// us to not rely on gas metering, but instead predict amount of gas to execute call
-pub trait Weighted: Call {
-	/// Predict weight of this call
-	fn weight(&self) -> DispatchInfo;
-}
-
-/// Type callable with ethereum message, may be implemented by [`solidity_interface`] macro
-/// on interface implementation, or for externally-owned real EVM contract
-pub trait Callable<C: Call> {
-	/// Call contract using specified call data
-	fn call(&mut self, call: types::Msg<C>) -> execution::ResultWithPostInfo<AbiWriter>;
-}
-
-/// Implementation of ERC165 is implicitly generated for all interfaces in [`solidity_interface`],
-/// this structure holds parsed data for ERC165Call subvariant
-///
-/// Note: no [`Callable`] implementation is provided, call implementation is inlined into every
-/// implementing contract
-///
-/// See <https://eips.ethereum.org/EIPS/eip-165>
-#[derive(Debug)]
-pub enum ERC165Call {
-	/// ERC165 provides single method, which returns true, if contract
-	/// implements specified interface
-	SupportsInterface {
-		/// Requested interface
-		interface_id: types::Bytes4,
-	},
-}
-
-impl ERC165Call {
-	/// ERC165 selector is provided by standard
-	pub const INTERFACE_ID: types::Bytes4 = u32::to_be_bytes(0x01ffc9a7);
-}
-
-impl Call for ERC165Call {
-	fn parse(selector: types::Bytes4, input: &mut AbiReader) -> execution::Result<Option<Self>> {
-		if selector != Self::INTERFACE_ID {
-			return Ok(None);
-		}
-		Ok(Some(Self::SupportsInterface {
-			interface_id: types::Bytes4::abi_read(input)?,
-		}))
-	}
-}
-
-/// Generate "tests", which will generate solidity code on execution and print it to stdout
-/// Script at .maintain/scripts/generate_api.sh can split this output from test runtime
-///
-/// This macro receives type usage as second argument, but you can use anything as generics,
-/// because no bounds are implied
-#[macro_export]
-macro_rules! generate_stubgen {
-	($name:ident, $decl:ty, $is_impl:literal) => {
-		#[cfg(feature = "stubgen")]
-		#[test]
-		#[ignore]
-		fn $name() {
-			use evm_coder::solidity::TypeCollector;
-			let mut out = TypeCollector::new();
-			<$decl>::generate_solidity_interface(&mut out, $is_impl);
-			println!("=== SNIP START ===");
-			println!("// SPDX-License-Identifier: OTHER");
-			println!("// This code is automatically generated");
-			println!();
-			println!("pragma solidity >=0.8.0 <0.9.0;");
-			println!();
-			for b in out.finish() {
-				println!("{}", b);
-			}
-			println!("=== SNIP END ===");
-		}
-	};
-}
-
-#[cfg(test)]
-mod tests {
-	use super::*;
-
-	#[test]
-	fn function_selector_generation() {
-		assert_eq!(fn_selector!(transfer(address, uint256)), 0xa9059cbb);
-	}
-
-	#[test]
-	fn event_topic_generation() {
-		assert_eq!(
-			hex::encode(&event_topic!(Transfer(address, address, uint256))[..]),
-			"ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
-		);
-	}
-}
deletedcrates/evm-coder/src/solidity/impls.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/solidity/impls.rs
+++ /dev/null
@@ -1,179 +0,0 @@
-use super::{TypeCollector, SolidityTypeName, SolidityTupleTy};
-use crate::{sealed, types::*};
-use core::fmt;
-use primitive_types::{U256, H160};
-
-macro_rules! solidity_type_name {
-    ($($ty:ty => $name:literal $simple:literal = $default:literal),* $(,)?) => {
-        $(
-            impl SolidityTypeName for $ty {
-                fn solidity_name(writer: &mut impl core::fmt::Write, _tc: &TypeCollector) -> core::fmt::Result {
-                    write!(writer, $name)
-                }
-				fn is_simple() -> bool {
-					$simple
-				}
-				fn solidity_default(writer: &mut impl core::fmt::Write, _tc: &TypeCollector) -> core::fmt::Result {
-					write!(writer, $default)
-				}
-            }
-        )*
-    };
-}
-
-solidity_type_name! {
-	u8 => "uint8" true = "0",
-	u32 => "uint32" true = "0",
-	u64 => "uint64" true = "0",
-	u128 => "uint128" true = "0",
-	U256 => "uint256" true = "0",
-	Bytes4 => "bytes4" true = "bytes4(0)",
-	H160 => "address" true = "0x0000000000000000000000000000000000000000",
-	String => "string" false = "\"\"",
-	Bytes => "bytes" false = "hex\"\"",
-	bool => "bool" true = "false",
-}
-
-impl SolidityTypeName for () {
-	fn solidity_name(_writer: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {
-		Ok(())
-	}
-	fn is_simple() -> bool {
-		true
-	}
-	fn solidity_default(_writer: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {
-		Ok(())
-	}
-	fn is_void() -> bool {
-		true
-	}
-}
-
-impl<T: SolidityTypeName + sealed::CanBePlacedInVec> SolidityTypeName for Vec<T> {
-	fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
-		T::solidity_name(writer, tc)?;
-		write!(writer, "[]")
-	}
-	fn is_simple() -> bool {
-		false
-	}
-	fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
-		write!(writer, "new ")?;
-		T::solidity_name(writer, tc)?;
-		write!(writer, "[](0)")
-	}
-}
-
-macro_rules! count {
-    () => (0usize);
-    ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));
-}
-
-macro_rules! impl_tuples {
-	($($ident:ident)+) => {
-		impl<$($ident: SolidityTypeName + 'static),+> SolidityTupleTy for ($($ident,)+) {
-			fn fields(tc: &TypeCollector) -> Vec<String> {
-				let mut collected = Vec::with_capacity(Self::len());
-				$({
-					let mut out = String::new();
-					$ident::solidity_name(&mut out, tc).expect("no fmt error");
-					collected.push(out);
-				})*;
-				collected
-			}
-
-			fn len() -> usize {
-				count!($($ident)*)
-			}
-		}
-		impl<$($ident: SolidityTypeName + 'static),+> SolidityTypeName for ($($ident,)+) {
-			fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
-				write!(writer, "{}", tc.collect_tuple::<Self>())
-			}
-			fn is_simple() -> bool {
-				false
-			}
-			#[allow(unused_assignments)]
-			fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
-				write!(writer, "{}(", tc.collect_tuple::<Self>())?;
-				let mut first = true;
-				$(
-					if !first {
-						write!(writer, ",")?;
-					} else {
-						first = false;
-					}
-					<$ident>::solidity_default(writer, tc)?;
-				)*
-				write!(writer, ")")
-			}
-		}
-	};
-}
-
-impl_tuples! {A}
-impl_tuples! {A B}
-impl_tuples! {A B C}
-impl_tuples! {A B C D}
-impl_tuples! {A B C D E}
-impl_tuples! {A B C D E F}
-impl_tuples! {A B C D E F G}
-impl_tuples! {A B C D E F G H}
-impl_tuples! {A B C D E F G H I}
-impl_tuples! {A B C D E F G H I J}
-
-//----- impls for Option -----
-impl<T: SolidityTypeName + 'static> SolidityTypeName for Option<T> {
-	fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
-		write!(writer, "{}", tc.collect_struct::<Self>())
-	}
-	fn is_simple() -> bool {
-		false
-	}
-	fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
-		write!(writer, "{}(", tc.collect_struct::<Self>())?;
-		bool::solidity_default(writer, tc)?;
-		write!(writer, ", ");
-		T::solidity_default(writer, tc)?;
-		write!(writer, ")")
-	}
-}
-
-impl<T: SolidityTypeName> super::SolidityStructTy for Option<T> {
-	fn generate_solidity_interface(tc: &TypeCollector) -> String {
-		let mut solidity_name = "Option".to_string();
-		let mut generic_name = String::new();
-		T::solidity_name(&mut generic_name, tc);
-		solidity_name.push(
-			generic_name
-				.chars()
-				.next()
-				.expect("Generic name is empty")
-				.to_ascii_uppercase(),
-		);
-		solidity_name.push_str(&generic_name[1..]);
-
-		let interface = super::SolidityStruct {
-			docs: &[" Optional value"],
-			name: solidity_name.as_str(),
-			fields: (
-				super::SolidityStructField::<bool> {
-					docs: &[" Shows the status of accessibility of value"],
-					name: "status",
-					ty: ::core::marker::PhantomData,
-				},
-				super::SolidityStructField::<T> {
-					docs: &[" Actual value if `status` is true"],
-					name: "value",
-					ty: ::core::marker::PhantomData,
-				},
-			),
-		};
-
-		let mut out = String::new();
-		let _ = interface.format(&mut out, tc);
-		tc.collect(out);
-
-		solidity_name.to_string()
-	}
-}
deletedcrates/evm-coder/src/solidity/mod.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/solidity/mod.rs
+++ /dev/null
@@ -1,515 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-//! Implementation detail of [`crate::solidity_interface`] macro code-generation.
-//! You should not rely on any public item from this module, as it is only intended to be used
-//! by procedural macro, API and output format may be changed at any time.
-//!
-//! Purpose of this module is to receive solidity contract definition in module-specified
-//! format, and then output string, representing interface of this contract in solidity language
-
-mod traits;
-pub use traits::*;
-mod impls;
-
-#[cfg(not(feature = "std"))]
-use alloc::{vec::Vec, collections::BTreeMap, format};
-#[cfg(feature = "std")]
-use std::collections::BTreeMap;
-use core::{
-	fmt::{self, Write},
-	marker::PhantomData,
-	cell::{Cell, RefCell},
-	cmp::Reverse,
-};
-use impl_trait_for_tuples::impl_for_tuples;
-use crate::{types::*, custom_signature::SignatureUnit};
-
-#[derive(Default)]
-pub struct TypeCollector {
-	/// Code => id
-	/// id ordering is required to perform topo-sort on the resulting data
-	structs: RefCell<BTreeMap<String, usize>>,
-	anonymous: RefCell<BTreeMap<Vec<String>, usize>>,
-	// generic: RefCell<BTreeMap<String, usize>>,
-	id: Cell<usize>,
-}
-impl TypeCollector {
-	pub fn new() -> Self {
-		Self::default()
-	}
-	pub fn collect(&self, item: String) {
-		let id = self.next_id();
-		self.structs.borrow_mut().insert(item, id);
-	}
-	pub fn next_id(&self) -> usize {
-		let v = self.id.get();
-		self.id.set(v + 1);
-		v
-	}
-	/// Collect typle, deduplicating it by type, and returning generated name
-	pub fn collect_tuple<T: SolidityTupleTy>(&self) -> String {
-		let names = T::fields(self);
-		if let Some(id) = self.anonymous.borrow().get(&names).cloned() {
-			return format!("Tuple{}", id);
-		}
-		let id = self.next_id();
-		let mut str = String::new();
-		writeln!(str, "/// @dev anonymous struct").unwrap();
-		writeln!(str, "struct Tuple{} {{", id).unwrap();
-		for (i, name) in names.iter().enumerate() {
-			writeln!(str, "\t{} field_{};", name, i).unwrap();
-		}
-		writeln!(str, "}}").unwrap();
-		self.collect(str);
-		self.anonymous.borrow_mut().insert(names, id);
-		format!("Tuple{}", id)
-	}
-	pub fn collect_struct<T: SolidityStructTy>(&self) -> String {
-		T::generate_solidity_interface(self)
-	}
-	pub fn collect_enum<T: SolidityEnumTy>(&self) -> String {
-		T::generate_solidity_interface(self)
-	}
-	pub fn finish(self) -> Vec<String> {
-		let mut data = self.structs.into_inner().into_iter().collect::<Vec<_>>();
-		data.sort_by_key(|(_, id)| Reverse(*id));
-		data.into_iter().map(|(code, _)| code).collect()
-	}
-}
-#[derive(Default)]
-pub struct UnnamedArgument<T>(PhantomData<*const T>);
-
-impl<T: SolidityTypeName> SolidityArguments for UnnamedArgument<T> {
-	fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
-		if !T::is_void() {
-			T::solidity_name(writer, tc)?;
-			if !T::is_simple() {
-				write!(writer, " memory")?;
-			}
-			Ok(())
-		} else {
-			Ok(())
-		}
-	}
-	fn solidity_get(&self, _prefix: &str, _writer: &mut impl fmt::Write) -> fmt::Result {
-		Ok(())
-	}
-	fn solidity_default(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
-		T::solidity_default(writer, tc)
-	}
-	fn len(&self) -> usize {
-		if T::is_void() {
-			0
-		} else {
-			1
-		}
-	}
-}
-
-pub struct NamedArgument<T>(&'static str, PhantomData<*const T>);
-
-impl<T> NamedArgument<T> {
-	pub fn new(name: &'static str) -> Self {
-		Self(name, Default::default())
-	}
-}
-
-impl<T: SolidityTypeName> SolidityArguments for NamedArgument<T> {
-	fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
-		if !T::is_void() {
-			T::solidity_name(writer, tc)?;
-			if !T::is_simple() {
-				write!(writer, " memory")?;
-			}
-			write!(writer, " {}", self.0)
-		} else {
-			Ok(())
-		}
-	}
-	fn solidity_get(&self, prefix: &str, writer: &mut impl fmt::Write) -> fmt::Result {
-		writeln!(writer, "\t{prefix}\t{};", self.0)
-	}
-	fn solidity_default(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
-		T::solidity_default(writer, tc)
-	}
-	fn len(&self) -> usize {
-		if T::is_void() {
-			0
-		} else {
-			1
-		}
-	}
-}
-
-pub struct SolidityEventArgument<T>(pub bool, &'static str, PhantomData<*const T>);
-
-impl<T> SolidityEventArgument<T> {
-	pub fn new(indexed: bool, name: &'static str) -> Self {
-		Self(indexed, name, Default::default())
-	}
-}
-
-impl<T: SolidityTypeName> SolidityArguments for SolidityEventArgument<T> {
-	fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
-		if !T::is_void() {
-			T::solidity_name(writer, tc)?;
-			if self.0 {
-				write!(writer, " indexed")?;
-			}
-			write!(writer, " {}", self.1)
-		} else {
-			Ok(())
-		}
-	}
-	fn solidity_get(&self, prefix: &str, writer: &mut impl fmt::Write) -> fmt::Result {
-		writeln!(writer, "\t{prefix}\t{};", self.1)
-	}
-	fn solidity_default(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
-		T::solidity_default(writer, tc)
-	}
-	fn len(&self) -> usize {
-		if T::is_void() {
-			0
-		} else {
-			1
-		}
-	}
-}
-
-impl SolidityArguments for () {
-	fn solidity_name(&self, _writer: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {
-		Ok(())
-	}
-	fn solidity_get(&self, _prefix: &str, _writer: &mut impl fmt::Write) -> fmt::Result {
-		Ok(())
-	}
-	fn solidity_default(&self, _writer: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {
-		Ok(())
-	}
-	fn len(&self) -> usize {
-		0
-	}
-}
-
-#[impl_for_tuples(1, 12)]
-impl SolidityArguments for Tuple {
-	for_tuples!( where #( Tuple: SolidityArguments ),* );
-
-	fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
-		let mut first = true;
-		for_tuples!( #(
-            if !Tuple.is_empty() {
-                if !first {
-                    write!(writer, ", ")?;
-                }
-                first = false;
-                Tuple.solidity_name(writer, tc)?;
-            }
-        )* );
-		Ok(())
-	}
-	fn solidity_get(&self, prefix: &str, writer: &mut impl fmt::Write) -> fmt::Result {
-		for_tuples!( #(
-            Tuple.solidity_get(prefix, writer)?;
-        )* );
-		Ok(())
-	}
-	fn solidity_default(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
-		if self.is_empty() {
-			Ok(())
-		} else if self.len() == 1 {
-			for_tuples!( #(
-				Tuple.solidity_default(writer, tc)?;
-			)* );
-			Ok(())
-		} else {
-			write!(writer, "(")?;
-			let mut first = true;
-			for_tuples!( #(
-				if !Tuple.is_empty() {
-					if !first {
-						write!(writer, ", ")?;
-					}
-					first = false;
-					Tuple.solidity_default(writer, tc)?;
-				}
-			)* );
-			write!(writer, ")")?;
-			Ok(())
-		}
-	}
-	fn len(&self) -> usize {
-		for_tuples!( #( Tuple.len() )+* )
-	}
-}
-
-pub enum SolidityMutability {
-	Pure,
-	View,
-	Mutable,
-}
-pub struct SolidityFunction<A, R> {
-	pub docs: &'static [&'static str],
-	pub selector: u32,
-	pub hide: bool,
-	pub custom_signature: SignatureUnit,
-	pub name: &'static str,
-	pub args: A,
-	pub result: R,
-	pub mutability: SolidityMutability,
-	pub is_payable: bool,
-}
-impl<A: SolidityArguments, R: SolidityArguments> SolidityFunctions for SolidityFunction<A, R> {
-	fn solidity_name(
-		&self,
-		is_impl: bool,
-		writer: &mut impl fmt::Write,
-		tc: &TypeCollector,
-	) -> fmt::Result {
-		let hide_comment = self.hide.then_some("// ").unwrap_or("");
-		for doc in self.docs {
-			writeln!(writer, "\t{hide_comment}///{}", doc)?;
-		}
-		writeln!(
-			writer,
-			"\t{hide_comment}/// @dev EVM selector for this function is: 0x{:0>8x},",
-			self.selector
-		)?;
-		writeln!(
-			writer,
-			"\t{hide_comment}///  or in textual repr: {}",
-			self.custom_signature.as_str().expect("bad utf-8")
-		)?;
-		write!(writer, "\t{hide_comment}function {}(", self.name)?;
-		self.args.solidity_name(writer, tc)?;
-		write!(writer, ")")?;
-		if is_impl {
-			write!(writer, " public")?;
-		} else {
-			write!(writer, " external")?;
-		}
-		match &self.mutability {
-			SolidityMutability::Pure => write!(writer, " pure")?,
-			SolidityMutability::View => write!(writer, " view")?,
-			SolidityMutability::Mutable => {}
-		}
-		if self.is_payable {
-			write!(writer, " payable")?;
-		}
-		if !self.result.is_empty() {
-			write!(writer, " returns (")?;
-			self.result.solidity_name(writer, tc)?;
-			write!(writer, ")")?;
-		}
-		if is_impl {
-			writeln!(writer, " {{")?;
-			writeln!(writer, "\t{hide_comment}\trequire(false, stub_error);")?;
-			self.args.solidity_get(hide_comment, writer)?;
-			match &self.mutability {
-				SolidityMutability::Pure => {}
-				SolidityMutability::View => writeln!(writer, "\t{hide_comment}\tdummy;")?,
-				SolidityMutability::Mutable => writeln!(writer, "\t{hide_comment}\tdummy = 0;")?,
-			}
-			if !self.result.is_empty() {
-				write!(writer, "\t{hide_comment}\treturn ")?;
-				self.result.solidity_default(writer, tc)?;
-				writeln!(writer, ";")?;
-			}
-			writeln!(writer, "\t{hide_comment}}}")?;
-		} else {
-			writeln!(writer, ";")?;
-		}
-		if self.hide {
-			writeln!(writer, "// FORMATTING: FORCE NEWLINE")?;
-		}
-		Ok(())
-	}
-}
-
-#[impl_for_tuples(0, 48)]
-impl SolidityFunctions for Tuple {
-	for_tuples!( where #( Tuple: SolidityFunctions ),* );
-
-	fn solidity_name(
-		&self,
-		is_impl: bool,
-		writer: &mut impl fmt::Write,
-		tc: &TypeCollector,
-	) -> fmt::Result {
-		let mut first = false;
-		for_tuples!( #(
-            Tuple.solidity_name(is_impl, writer, tc)?;
-        )* );
-		Ok(())
-	}
-}
-
-pub struct SolidityInterface<F: SolidityFunctions> {
-	pub docs: &'static [&'static str],
-	pub selector: Bytes4,
-	pub name: &'static str,
-	pub is: &'static [&'static str],
-	pub functions: F,
-}
-
-impl<F: SolidityFunctions> SolidityInterface<F> {
-	pub fn format(
-		&self,
-		is_impl: bool,
-		out: &mut impl fmt::Write,
-		tc: &TypeCollector,
-	) -> fmt::Result {
-		const ZERO_BYTES: [u8; 4] = [0; 4];
-		for doc in self.docs {
-			writeln!(out, "///{}", doc)?;
-		}
-		if self.selector != ZERO_BYTES {
-			writeln!(
-				out,
-				"/// @dev the ERC-165 identifier for this interface is 0x{:0>8x}",
-				u32::from_be_bytes(self.selector)
-			)?;
-		}
-		if is_impl {
-			write!(out, "contract ")?;
-		} else {
-			write!(out, "interface ")?;
-		}
-		write!(out, "{}", self.name)?;
-		if !self.is.is_empty() {
-			write!(out, " is")?;
-			for (i, n) in self.is.iter().enumerate() {
-				if i != 0 {
-					write!(out, ",")?;
-				}
-				write!(out, " {}", n)?;
-			}
-		}
-		writeln!(out, " {{")?;
-		self.functions.solidity_name(is_impl, out, tc)?;
-		writeln!(out, "}}")?;
-		Ok(())
-	}
-}
-
-pub struct SolidityEvent<A> {
-	pub name: &'static str,
-	pub args: A,
-}
-
-impl<A: SolidityArguments> SolidityFunctions for SolidityEvent<A> {
-	fn solidity_name(
-		&self,
-		_is_impl: bool,
-		writer: &mut impl fmt::Write,
-		tc: &TypeCollector,
-	) -> fmt::Result {
-		write!(writer, "\tevent {}(", self.name)?;
-		self.args.solidity_name(writer, tc)?;
-		writeln!(writer, ");")
-	}
-}
-
-#[impl_for_tuples(0, 48)]
-impl SolidityItems for Tuple {
-	for_tuples!( where #( Tuple: SolidityItems ),* );
-
-	fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
-		for_tuples!( #(
-            Tuple.solidity_name(writer, tc)?;
-        )* );
-		Ok(())
-	}
-}
-
-pub struct SolidityStructField<T> {
-	pub docs: &'static [&'static str],
-	pub name: &'static str,
-	pub ty: PhantomData<*const T>,
-}
-
-impl<T> SolidityItems for SolidityStructField<T>
-where
-	T: SolidityTypeName,
-{
-	fn solidity_name(&self, out: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
-		for doc in self.docs {
-			writeln!(out, "///{}", doc)?;
-		}
-		write!(out, "\t")?;
-		T::solidity_name(out, tc)?;
-		writeln!(out, " {};", self.name)?;
-		Ok(())
-	}
-}
-pub struct SolidityStruct<'a, F> {
-	pub docs: &'a [&'a str],
-	// pub generics:
-	pub name: &'a str,
-	pub fields: F,
-}
-impl<F> SolidityStruct<'_, F>
-where
-	F: SolidityItems,
-{
-	pub fn format(&self, out: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
-		for doc in self.docs {
-			writeln!(out, "///{}", doc)?;
-		}
-		writeln!(out, "struct {} {{", self.name)?;
-		self.fields.solidity_name(out, tc)?;
-		writeln!(out, "}}")?;
-		Ok(())
-	}
-}
-
-pub struct SolidityEnumVariant {
-	pub docs: &'static [&'static str],
-	pub name: &'static str,
-}
-impl SolidityItems for SolidityEnumVariant {
-	fn solidity_name(&self, out: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {
-		for doc in self.docs {
-			writeln!(out, "///{}", doc)?;
-		}
-		write!(out, "\t{}", self.name)?;
-		Ok(())
-	}
-}
-pub struct SolidityEnum {
-	pub docs: &'static [&'static str],
-	pub name: &'static str,
-	pub fields: &'static [SolidityEnumVariant],
-}
-impl SolidityEnum {
-	pub fn format(&self, out: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
-		for doc in self.docs {
-			writeln!(out, "///{}", doc)?;
-		}
-		write!(out, "enum {} {{", self.name)?;
-		for (i, field) in self.fields.iter().enumerate() {
-			if i != 0 {
-				write!(out, ",")?;
-			}
-			writeln!(out)?;
-			field.solidity_name(out, tc)?;
-		}
-		writeln!(out)?;
-		writeln!(out, "}}")?;
-		Ok(())
-	}
-}
deletedcrates/evm-coder/src/solidity/traits.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/solidity/traits.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-use super::TypeCollector;
-use core::fmt;
-
-pub trait SolidityTypeName: 'static {
-	fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;
-	/// "simple" types are stored inline, no `memory` modifier should be used in solidity
-	fn is_simple() -> bool;
-	fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;
-	/// Specialization
-	fn is_void() -> bool {
-		false
-	}
-}
-
-pub trait SolidityTupleTy: 'static {
-	fn fields(tc: &TypeCollector) -> Vec<String>;
-	fn len() -> usize;
-}
-pub trait SolidityStructTy: 'static {
-	fn generate_solidity_interface(tc: &TypeCollector) -> String;
-}
-pub trait SolidityEnumTy: 'static {
-	fn generate_solidity_interface(tc: &TypeCollector) -> String;
-	fn solidity_option(&self) -> &str;
-}
-
-pub trait SolidityArguments {
-	fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;
-	fn solidity_get(&self, prefix: &str, writer: &mut impl fmt::Write) -> fmt::Result;
-	fn solidity_default(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;
-	fn is_empty(&self) -> bool {
-		self.len() == 0
-	}
-	fn len(&self) -> usize;
-}
-
-pub trait SolidityFunctions {
-	fn solidity_name(
-		&self,
-		is_impl: bool,
-		writer: &mut impl fmt::Write,
-		tc: &TypeCollector,
-	) -> fmt::Result;
-}
-
-pub trait SolidityItems {
-	fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;
-	// For PhantomData fields
-	// fn is_void()
-}
deletedcrates/evm-coder/tests/abi_derive_generation.rsdiffbeforeafterboth
--- a/crates/evm-coder/tests/abi_derive_generation.rs
+++ /dev/null
@@ -1,765 +0,0 @@
-mod test_struct {
-	use evm_coder_procedural::AbiCoder;
-	use evm_coder::types::Bytes;
-
-	#[test]
-	fn empty_struct() {
-		let t = trybuild::TestCases::new();
-		t.compile_fail("tests/build_failed/abi_derive_struct_generation.rs");
-	}
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TypeStruct1SimpleParam {
-		_a: u8,
-	}
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TypeStruct1DynamicParam {
-		_a: String,
-	}
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TypeStruct2SimpleParam {
-		_a: u8,
-		_b: u32,
-	}
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TypeStruct2DynamicParam {
-		_a: String,
-		_b: Bytes,
-	}
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TypeStruct2MixedParam {
-		_a: u8,
-		_b: Bytes,
-	}
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TypeStruct1DerivedSimpleParam {
-		_a: TypeStruct1SimpleParam,
-	}
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TypeStruct2DerivedSimpleParam {
-		_a: TypeStruct1SimpleParam,
-		_b: TypeStruct2SimpleParam,
-	}
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TypeStruct1DerivedDynamicParam {
-		_a: TypeStruct1DynamicParam,
-	}
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TypeStruct2DerivedDynamicParam {
-		_a: TypeStruct1DynamicParam,
-		_b: TypeStruct2DynamicParam,
-	}
-
-	/// Some docs
-	/// At multi
-	/// line
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TypeStruct3DerivedMixedParam {
-		/// Docs for A
-		/// multi
-		/// line
-		_a: TypeStruct1SimpleParam,
-		/// Docs for B
-		_b: TypeStruct2DynamicParam,
-		/// Docs for C
-		_c: TypeStruct2MixedParam,
-	}
-
-	#[test]
-	fn impl_abi_type_signature() {
-		assert_eq!(
-			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			"(uint8)"
-		);
-		assert_eq!(
-			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			"(string)"
-		);
-		assert_eq!(
-			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			"(uint8,uint32)"
-		);
-		assert_eq!(
-			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			"(string,bytes)"
-		);
-		assert_eq!(
-			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			"(uint8,bytes)"
-		);
-		assert_eq!(
-			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			"((uint8))"
-		);
-		assert_eq!(
-			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			"((uint8),(uint8,uint32))"
-		);
-		assert_eq!(
-			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			"((string))"
-		);
-		assert_eq!(
-			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			"((string),(string,bytes))"
-		);
-		assert_eq!(
-			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			"((uint8),(string,bytes),(uint8,bytes))"
-		);
-	}
-
-	#[test]
-	fn impl_abi_type_is_dynamic() {
-		assert_eq!(
-			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),
-			false
-		);
-		assert_eq!(
-			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),
-			true
-		);
-		assert_eq!(
-			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),
-			false
-		);
-		assert_eq!(
-			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),
-			true
-		);
-		assert_eq!(
-			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic(),
-			true
-		);
-		assert_eq!(
-			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),
-			false
-		);
-		assert_eq!(
-			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),
-			false
-		);
-		assert_eq!(
-			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),
-			true
-		);
-		assert_eq!(
-			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),
-			true
-		);
-		assert_eq!(
-			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic(),
-			true
-		);
-	}
-
-	#[test]
-	fn impl_abi_type_size() {
-		const ABI_ALIGNMENT: usize = 32;
-		assert_eq!(
-			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::size(),
-			ABI_ALIGNMENT
-		);
-		assert_eq!(
-			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::size(),
-			ABI_ALIGNMENT
-		);
-		assert_eq!(
-			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::size(),
-			ABI_ALIGNMENT * 2
-		);
-		assert_eq!(
-			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::size(),
-			ABI_ALIGNMENT * 2
-		);
-		assert_eq!(
-			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::size(),
-			ABI_ALIGNMENT * 2
-		);
-		assert_eq!(
-			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size(),
-			ABI_ALIGNMENT
-		);
-		assert_eq!(
-			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size(),
-			ABI_ALIGNMENT * 3
-		);
-		assert_eq!(
-			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size(),
-			ABI_ALIGNMENT
-		);
-		assert_eq!(
-			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size(),
-			ABI_ALIGNMENT * 3
-		);
-		assert_eq!(
-			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size(),
-			ABI_ALIGNMENT * 5
-		);
-	}
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TupleStruct1SimpleParam(u8);
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TupleStruct1DynamicParam(String);
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TupleStruct2SimpleParam(u8, u32);
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TupleStruct2DynamicParam(String, Bytes);
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TupleStruct2MixedParam(u8, Bytes);
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam);
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TupleStruct2DerivedSimpleParam(TupleStruct1SimpleParam, TupleStruct2SimpleParam);
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam);
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TupleStruct2DerivedDynamicParam(TupleStruct1DynamicParam, TupleStruct2DynamicParam);
-
-	/// Some docs
-	/// At multi
-	/// line
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TupleStruct3DerivedMixedParam(
-		/// Docs for A
-		/// multi
-		/// line
-		TupleStruct1SimpleParam,
-		TupleStruct2DynamicParam,
-		/// Docs for C
-		TupleStruct2MixedParam,
-	);
-
-	#[test]
-	fn impl_abi_type_signature_same_for_structs() {
-		assert_eq!(
-			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			<TupleStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap()
-		);
-		assert_eq!(
-			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			<TupleStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap()
-		);
-		assert_eq!(
-			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			<TupleStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap()
-		);
-		assert_eq!(
-			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			<TupleStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap()
-		);
-		assert_eq!(
-			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			<TupleStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-		);
-		assert_eq!(
-			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			<TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-		);
-		assert_eq!(
-			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			<TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-		);
-		assert_eq!(
-			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			<TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-		);
-		assert_eq!(
-			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			<TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-		);
-		assert_eq!(
-			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			<TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-		);
-	}
-
-	#[test]
-	fn impl_abi_type_is_dynamic_same_for_structs() {
-		assert_eq!(
-			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),
-			<TupleStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic()
-		);
-		assert_eq!(
-			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),
-			<TupleStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic()
-		);
-		assert_eq!(
-			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),
-			<TupleStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic()
-		);
-		assert_eq!(
-			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),
-			<TupleStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic()
-		);
-		assert_eq!(
-			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic(),
-			<TupleStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic()
-		);
-		assert_eq!(
-			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),
-			<TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic()
-		);
-		assert_eq!(
-			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),
-			<TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic()
-		);
-		assert_eq!(
-			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),
-			<TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic()
-		);
-		assert_eq!(
-			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),
-			<TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic()
-		);
-		assert_eq!(
-			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic(),
-			<TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic()
-		);
-	}
-
-	#[test]
-	fn impl_abi_type_size_same_for_structs() {
-		assert_eq!(
-			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::size(),
-			<TupleStruct1SimpleParam as evm_coder::abi::AbiType>::size()
-		);
-		assert_eq!(
-			<TypeStruct1DynamicParam as evm_coder::abi::AbiType>::size(),
-			<TupleStruct1DynamicParam as evm_coder::abi::AbiType>::size()
-		);
-		assert_eq!(
-			<TypeStruct2SimpleParam as evm_coder::abi::AbiType>::size(),
-			<TupleStruct2SimpleParam as evm_coder::abi::AbiType>::size()
-		);
-		assert_eq!(
-			<TypeStruct2DynamicParam as evm_coder::abi::AbiType>::size(),
-			<TupleStruct2DynamicParam as evm_coder::abi::AbiType>::size()
-		);
-		assert_eq!(
-			<TypeStruct2MixedParam as evm_coder::abi::AbiType>::size(),
-			<TupleStruct2MixedParam as evm_coder::abi::AbiType>::size()
-		);
-		assert_eq!(
-			<TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size(),
-			<TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size()
-		);
-		assert_eq!(
-			<TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size(),
-			<TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size()
-		);
-		assert_eq!(
-			<TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size(),
-			<TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size()
-		);
-		assert_eq!(
-			<TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size(),
-			<TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size()
-		);
-		assert_eq!(
-			<TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size(),
-			<TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size()
-		);
-	}
-
-	const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;
-
-	fn test_impl<Tuple, TupleStruct, TypeStruct>(
-		tuple_data: Tuple,
-		tuple_struct_data: TupleStruct,
-		type_struct_data: TypeStruct,
-	) where
-		TypeStruct: evm_coder::abi::AbiWrite
-			+ evm_coder::abi::AbiRead
-			+ std::cmp::PartialEq
-			+ std::fmt::Debug,
-		TupleStruct: evm_coder::abi::AbiWrite
-			+ evm_coder::abi::AbiRead
-			+ std::cmp::PartialEq
-			+ std::fmt::Debug,
-		Tuple: evm_coder::abi::AbiWrite
-			+ evm_coder::abi::AbiRead
-			+ std::cmp::PartialEq
-			+ std::fmt::Debug,
-	{
-		let encoded_type_struct = test_abi_write_impl(&type_struct_data);
-		let encoded_tuple_struct = test_abi_write_impl(&tuple_struct_data);
-		let encoded_tuple = test_abi_write_impl(&tuple_data);
-
-		similar_asserts::assert_eq!(encoded_tuple, encoded_type_struct);
-		similar_asserts::assert_eq!(encoded_tuple, encoded_tuple_struct);
-
-		{
-			let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_tuple).unwrap();
-			let restored_struct_data = <TypeStruct>::abi_read(&mut decoder).unwrap();
-			assert_eq!(restored_struct_data, type_struct_data);
-		}
-		{
-			let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_tuple).unwrap();
-			let restored_struct_data = <TupleStruct>::abi_read(&mut decoder).unwrap();
-			assert_eq!(restored_struct_data, tuple_struct_data);
-		}
-
-		{
-			let (_, mut decoder) =
-				evm_coder::abi::AbiReader::new_call(&encoded_type_struct).unwrap();
-			let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();
-			assert_eq!(restored_tuple_data, tuple_data);
-		}
-		{
-			let (_, mut decoder) =
-				evm_coder::abi::AbiReader::new_call(&encoded_tuple_struct).unwrap();
-			let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();
-			assert_eq!(restored_tuple_data, tuple_data);
-		}
-	}
-
-	fn test_abi_write_impl<A>(data: &A) -> Vec<u8>
-	where
-		A: evm_coder::abi::AbiWrite
-			+ evm_coder::abi::AbiRead
-			+ std::cmp::PartialEq
-			+ std::fmt::Debug,
-	{
-		let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);
-		data.abi_write(&mut writer);
-		let encoded_tuple = writer.finish();
-		encoded_tuple
-	}
-
-	#[test]
-	fn codec_struct_1_simple() {
-		let _a = 0xff;
-		test_impl::<(u8,), TupleStruct1SimpleParam, TypeStruct1SimpleParam>(
-			(_a,),
-			TupleStruct1SimpleParam(_a),
-			TypeStruct1SimpleParam { _a },
-		);
-	}
-
-	#[test]
-	fn codec_struct_1_dynamic() {
-		let _a: String = "some string".into();
-		test_impl::<(String,), TupleStruct1DynamicParam, TypeStruct1DynamicParam>(
-			(_a.clone(),),
-			TupleStruct1DynamicParam(_a.clone()),
-			TypeStruct1DynamicParam { _a },
-		);
-	}
-
-	#[test]
-	fn codec_struct_1_derived_simple() {
-		let _a: u8 = 0xff;
-		test_impl::<((u8,),), TupleStruct1DerivedSimpleParam, TypeStruct1DerivedSimpleParam>(
-			((_a,),),
-			TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam(_a)),
-			TypeStruct1DerivedSimpleParam {
-				_a: TypeStruct1SimpleParam { _a },
-			},
-		);
-	}
-
-	#[test]
-	fn codec_struct_1_derived_dynamic() {
-		let _a: String = "some string".into();
-		test_impl::<((String,),), TupleStruct1DerivedDynamicParam, TypeStruct1DerivedDynamicParam>(
-			((_a.clone(),),),
-			TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam(_a.clone())),
-			TypeStruct1DerivedDynamicParam {
-				_a: TypeStruct1DynamicParam { _a },
-			},
-		);
-	}
-
-	#[test]
-	fn codec_struct_2_simple() {
-		let _a = 0xff;
-		let _b = 0xbeefbaba;
-		test_impl::<(u8, u32), TupleStruct2SimpleParam, TypeStruct2SimpleParam>(
-			(_a, _b),
-			TupleStruct2SimpleParam(_a, _b),
-			TypeStruct2SimpleParam { _a, _b },
-		);
-	}
-
-	#[test]
-	fn codec_struct_2_dynamic() {
-		let _a: String = "some string".into();
-		let _b: Bytes = Bytes(vec![0x11, 0x22, 0x33]);
-		test_impl::<(String, Bytes), TupleStruct2DynamicParam, TypeStruct2DynamicParam>(
-			(_a.clone(), _b.clone()),
-			TupleStruct2DynamicParam(_a.clone(), _b.clone()),
-			TypeStruct2DynamicParam { _a, _b },
-		);
-	}
-
-	#[test]
-	fn codec_struct_2_mixed() {
-		let _a: u8 = 0xff;
-		let _b: Bytes = Bytes(vec![0x11, 0x22, 0x33]);
-		test_impl::<(u8, Bytes), TupleStruct2MixedParam, TypeStruct2MixedParam>(
-			(_a.clone(), _b.clone()),
-			TupleStruct2MixedParam(_a.clone(), _b.clone()),
-			TypeStruct2MixedParam { _a, _b },
-		);
-	}
-
-	#[test]
-	fn codec_struct_2_derived_simple() {
-		let _a = 0xff;
-		let _b = 0xbeefbaba;
-		test_impl::<
-			((u8,), (u8, u32)),
-			TupleStruct2DerivedSimpleParam,
-			TypeStruct2DerivedSimpleParam,
-		>(
-			((_a,), (_a, _b)),
-			TupleStruct2DerivedSimpleParam(
-				TupleStruct1SimpleParam(_a),
-				TupleStruct2SimpleParam(_a, _b),
-			),
-			TypeStruct2DerivedSimpleParam {
-				_a: TypeStruct1SimpleParam { _a },
-				_b: TypeStruct2SimpleParam { _a, _b },
-			},
-		);
-	}
-
-	#[test]
-	fn codec_struct_2_derived_dynamic() {
-		let _a = "some string".to_string();
-		let _b = Bytes(vec![0x11, 0x22, 0x33]);
-		test_impl::<
-			((String,), (String, Bytes)),
-			TupleStruct2DerivedDynamicParam,
-			TypeStruct2DerivedDynamicParam,
-		>(
-			((_a.clone(),), (_a.clone(), _b.clone())),
-			TupleStruct2DerivedDynamicParam(
-				TupleStruct1DynamicParam(_a.clone()),
-				TupleStruct2DynamicParam(_a.clone(), _b.clone()),
-			),
-			TypeStruct2DerivedDynamicParam {
-				_a: TypeStruct1DynamicParam { _a: _a.clone() },
-				_b: TypeStruct2DynamicParam { _a, _b },
-			},
-		);
-	}
-
-	#[test]
-	fn codec_struct_3_derived_mixed() {
-		let int = 0xff;
-		let by = Bytes(vec![0x11, 0x22, 0x33]);
-		let string = "some string".to_string();
-		test_impl::<
-			((u8,), (String, Bytes), (u8, Bytes)),
-			TupleStruct3DerivedMixedParam,
-			TypeStruct3DerivedMixedParam,
-		>(
-			((int,), (string.clone(), by.clone()), (int, by.clone())),
-			TupleStruct3DerivedMixedParam(
-				TupleStruct1SimpleParam(int),
-				TupleStruct2DynamicParam(string.clone(), by.clone()),
-				TupleStruct2MixedParam(int, by.clone()),
-			),
-			TypeStruct3DerivedMixedParam {
-				_a: TypeStruct1SimpleParam { _a: int },
-				_b: TypeStruct2DynamicParam {
-					_a: string.clone(),
-					_b: by.clone(),
-				},
-				_c: TypeStruct2MixedParam { _a: int, _b: by },
-			},
-		);
-	}
-
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TypeStruct2SimpleStruct1Simple {
-		_a: TypeStruct2SimpleParam,
-		_b: TypeStruct2SimpleParam,
-		_c: u8,
-	}
-	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TupleStruct2SimpleStruct1Simple(TupleStruct2SimpleParam, TupleStruct2SimpleParam, u8);
-
-	#[test]
-	fn codec_struct_2_struct_simple_1_simple() {
-		let _a = 0xff;
-		let _b = 0xbeefbaba;
-		test_impl::<
-			((u8, u32), (u8, u32), u8),
-			TupleStruct2SimpleStruct1Simple,
-			TypeStruct2SimpleStruct1Simple,
-		>(
-			((_a, _b), (_a, _b), _a),
-			TupleStruct2SimpleStruct1Simple(
-				TupleStruct2SimpleParam(_a, _b),
-				TupleStruct2SimpleParam(_a, _b),
-				_a,
-			),
-			TypeStruct2SimpleStruct1Simple {
-				_a: TypeStruct2SimpleParam { _a, _b },
-				_b: TypeStruct2SimpleParam { _a, _b },
-				_c: _a,
-			},
-		);
-	}
-}
-
-mod test_enum {
-	use evm_coder::AbiCoder;
-
-	/// Some docs
-	/// At multi
-	/// line
-	#[derive(AbiCoder, Debug, PartialEq, Default, Clone, Copy)]
-	#[repr(u8)]
-	enum Color {
-		/// Docs for Red
-		/// multi
-		/// line
-		Red,
-		Green,
-		/// Docs for Blue
-		#[default]
-		Blue,
-	}
-
-	#[test]
-	fn empty() {}
-
-	#[test]
-	fn bad_enums() {
-		let t = trybuild::TestCases::new();
-		t.compile_fail("tests/build_failed/abi_derive_enum_generation.rs");
-	}
-
-	#[test]
-	fn impl_abi_type_signature_same_for_structs() {
-		assert_eq!(
-			<Color as evm_coder::abi::AbiType>::SIGNATURE
-				.as_str()
-				.unwrap(),
-			<u8 as evm_coder::abi::AbiType>::SIGNATURE.as_str().unwrap()
-		);
-	}
-
-	#[test]
-	fn impl_abi_type_is_dynamic_same_for_structs() {
-		assert_eq!(
-			<Color as evm_coder::abi::AbiType>::is_dynamic(),
-			<u8 as evm_coder::abi::AbiType>::is_dynamic()
-		);
-	}
-
-	#[test]
-	fn impl_abi_type_size_same_for_structs() {
-		assert_eq!(
-			<Color as evm_coder::abi::AbiType>::size(),
-			<u8 as evm_coder::abi::AbiType>::size()
-		);
-	}
-
-	#[test]
-	fn test_coder() {
-		const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;
-
-		let encoded_enum = {
-			let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);
-			<Color as evm_coder::abi::AbiWrite>::abi_write(&Color::Green, &mut writer);
-			writer.finish()
-		};
-
-		let encoded_u8 = {
-			let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);
-			<u8 as evm_coder::abi::AbiWrite>::abi_write(&(Color::Green as u8), &mut writer);
-			writer.finish()
-		};
-
-		similar_asserts::assert_eq!(encoded_enum, encoded_u8);
-
-		{
-			let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_enum).unwrap();
-			let restored_enum_data =
-				<Color as evm_coder::abi::AbiRead>::abi_read(&mut decoder).unwrap();
-			assert_eq!(restored_enum_data, Color::Green);
-		}
-	}
-}
deletedcrates/evm-coder/tests/build_failed/abi_derive_enum_generation.rsdiffbeforeafterboth
--- a/crates/evm-coder/tests/build_failed/abi_derive_enum_generation.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-use evm_coder_procedural::AbiCoder;
-
-#[derive(AbiCoder)]
-enum NonRepr {
-	A,
-	B,
-	C,
-}
-
-#[derive(AbiCoder)]
-#[repr(u32)]
-enum NonReprU8 {
-	A,
-	B,
-	C,
-}
-
-#[derive(AbiCoder)]
-#[repr(u8)]
-enum RustEnum {
-	A(u128),
-	B,
-	C,
-}
-
-#[derive(AbiCoder)]
-#[repr(u8)]
-enum WithExplicit {
-	A = 128,
-	B,
-	C,
-}
-
-fn main() {
-	assert!(false);
-}
deletedcrates/evm-coder/tests/build_failed/abi_derive_enum_generation.stderrdiffbeforeafterboth
--- a/crates/evm-coder/tests/build_failed/abi_derive_enum_generation.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error: Enum is not "repr(u8)"
- --> tests/build_failed/abi_derive_enum_generation.rs:4:6
-  |
-4 | enum NonRepr {
-  |      ^^^^^^^
-
-error: Enum is not "repr(u8)"
-  --> tests/build_failed/abi_derive_enum_generation.rs:11:8
-   |
-11 | #[repr(u32)]
-   |        ^^^
-
-error: Enumeration parameters should not have fields
-  --> tests/build_failed/abi_derive_enum_generation.rs:21:2
-   |
-21 |     A(u128),
-   |     ^
-
-error: Enumeration options should not have an explicit specified value
-  --> tests/build_failed/abi_derive_enum_generation.rs:29:2
-   |
-29 |     A = 128,
-   |     ^
deletedcrates/evm-coder/tests/build_failed/abi_derive_struct_generation.rsdiffbeforeafterboth
--- a/crates/evm-coder/tests/build_failed/abi_derive_struct_generation.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-use evm_coder_procedural::AbiCoder;
-
-#[derive(AbiCoder, PartialEq, Debug)]
-struct EmptyStruct {}
-
-#[derive(AbiCoder, PartialEq, Debug)]
-struct EmptyTupleStruct();
-
-fn main() {
-	assert!(false);
-}
deletedcrates/evm-coder/tests/build_failed/abi_derive_struct_generation.stderrdiffbeforeafterboth
--- a/crates/evm-coder/tests/build_failed/abi_derive_struct_generation.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: Empty structs not supported
- --> tests/build_failed/abi_derive_struct_generation.rs:4:8
-  |
-4 | struct EmptyStruct {}
-  |        ^^^^^^^^^^^
-
-error: Empty structs not supported
- --> tests/build_failed/abi_derive_struct_generation.rs:7:8
-  |
-7 | struct EmptyTupleStruct();
-  |        ^^^^^^^^^^^^^^^^
deletedcrates/evm-coder/tests/build_failed/custom_signature_over_max_size.rsdiffbeforeafterboth
--- a/crates/evm-coder/tests/build_failed/custom_signature_over_max_size.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-#![allow(dead_code)]
-use std::str::from_utf8;
-
-use evm_coder::{
-	make_signature,
-	custom_signature::{SignatureUnit, SIGNATURE_SIZE_LIMIT},
-};
-
-trait Name {
-	const SIGNATURE: SignatureUnit;
-
-	fn name() -> &'static str {
-		from_utf8(&Self::SIGNATURE.data[..Self::SIGNATURE.len]).expect("bad utf-8")
-	}
-}
-
-impl<T: Name> Name for Vec<T> {
-	const SIGNATURE: SignatureUnit =
-		evm_coder::make_signature!(new nameof(T::SIGNATURE) fixed("[]"));
-}
-
-struct MaxSize();
-impl Name for MaxSize {
-	const SIGNATURE: SignatureUnit = SignatureUnit {
-		data: [b'!'; SIGNATURE_SIZE_LIMIT],
-		len: SIGNATURE_SIZE_LIMIT,
-	};
-}
-
-const NAME: SignatureUnit = <Vec<MaxSize>>::SIGNATURE;
-
-fn main() {
-	assert!(false);
-}
deletedcrates/evm-coder/tests/build_failed/custom_signature_over_max_size.stderrdiffbeforeafterboth
--- a/crates/evm-coder/tests/build_failed/custom_signature_over_max_size.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-warning: unused import: `make_signature`
- --> tests/build_failed/custom_signature_over_max_size.rs:5:2
-  |
-5 |     make_signature,
-  |     ^^^^^^^^^^^^^^
-  |
-  = note: `#[warn(unused_imports)]` on by default
-
-error[E0080]: evaluation of `<std::vec::Vec<MaxSize> as Name>::SIGNATURE` failed
-  --> tests/build_failed/custom_signature_over_max_size.rs:19:3
-   |
-19 |         evm_coder::make_signature!(new nameof(T::SIGNATURE) fixed("[]"));
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 256 but the index is 256
-   |
-   = note: this error originates in the macro `$crate::make_signature` which comes from the expansion of the macro `evm_coder::make_signature` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error[E0080]: evaluation of constant value failed
-  --> tests/build_failed/custom_signature_over_max_size.rs:30:29
-   |
-30 | const NAME: SignatureUnit = <Vec<MaxSize>>::SIGNATURE;
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
deletedcrates/evm-coder/tests/conditional_is.rsdiffbeforeafterboth
--- a/crates/evm-coder/tests/conditional_is.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-use evm_coder::{types::*, solidity_interface, execution::Result};
-
-pub struct Contract(bool);
-
-#[solidity_interface(name = A)]
-impl Contract {
-	fn method_a() -> Result<()> {
-		Ok(())
-	}
-}
-
-#[solidity_interface(name = B)]
-impl Contract {
-	fn method_b() -> Result<()> {
-		Ok(())
-	}
-}
-
-#[solidity_interface(name = Contract, is(
-	A(if(this.0)),
-	B(if(!this.0)),
-))]
-impl Contract {}
-
-#[test]
-fn conditional_erc165() {
-	assert!(ContractCall::supports_interface(
-		&Contract(true),
-		ACall::METHOD_A
-	));
-	assert!(!ContractCall::supports_interface(
-		&Contract(false),
-		ACall::METHOD_A
-	));
-
-	assert!(ContractCall::supports_interface(
-		&Contract(false),
-		BCall::METHOD_B
-	));
-	assert!(!ContractCall::supports_interface(
-		&Contract(true),
-		BCall::METHOD_B
-	));
-}
deletedcrates/evm-coder/tests/generics.rsdiffbeforeafterboth
--- a/crates/evm-coder/tests/generics.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-use std::marker::PhantomData;
-use evm_coder::{execution::Result, generate_stubgen, solidity_interface, types::*};
-use primitive_types::U256;
-
-pub struct Generic<T>(PhantomData<T>);
-
-#[solidity_interface(name = GenericIs)]
-impl<T> Generic<T> {
-	fn test_1(&self) -> Result<U256> {
-		unreachable!()
-	}
-}
-
-#[solidity_interface(name = Generic, is(GenericIs))]
-impl<T: Into<u32>> Generic<T> {
-	fn test_2(&self) -> Result<U256> {
-		unreachable!()
-	}
-}
-
-generate_stubgen!(gen_iface, GenericCall<()>, false);
-
-#[solidity_interface(name = GenericWhere)]
-impl<T> Generic<T>
-where
-	T: core::fmt::Debug,
-{
-	fn test_3(&self) -> Result<U256> {
-		unreachable!()
-	}
-}
-
-generate_stubgen!(gen_where_iface, GenericWhereCall<()>, false);
deletedcrates/evm-coder/tests/log.rsdiffbeforeafterboth
--- a/crates/evm-coder/tests/log.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-#![allow(dead_code)]
-
-use evm_coder::{ToLog, types::*};
-use primitive_types::U256;
-
-#[derive(ToLog)]
-enum ERC721Log {
-	Transfer {
-		#[indexed]
-		from: Address,
-		#[indexed]
-		to: Address,
-		value: U256,
-	},
-	Eee {
-		#[indexed]
-		aaa: Address,
-		bbb: U256,
-	},
-}
deletedcrates/evm-coder/tests/random.rsdiffbeforeafterboth
--- a/crates/evm-coder/tests/random.rs
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-#![allow(dead_code)] // This test only checks that macros is not panicking
-
-use evm_coder::{
-	abi::AbiType, ToLog, execution::Result, solidity_interface, types::*, solidity, weight,
-};
-use primitive_types::U256;
-
-pub struct Impls;
-
-#[solidity_interface(name = OurInterface)]
-impl Impls {
-	fn fn_a(&self, _input: U256) -> Result<bool> {
-		unreachable!()
-	}
-}
-
-#[solidity_interface(name = OurInterface1)]
-impl Impls {
-	fn fn_b(&self, _input: u128) -> Result<u32> {
-		unreachable!()
-	}
-}
-
-#[derive(ToLog)]
-enum OurEvents {
-	Event1 {
-		field1: u32,
-	},
-	Event2 {
-		field1: u32,
-		#[indexed]
-		field2: u32,
-	},
-}
-
-#[solidity_interface(
-	name = OurInterface2,
-	is(OurInterface),
-	inline_is(OurInterface1),
-	events(OurEvents)
-)]
-impl Impls {
-	#[solidity(rename_selector = "fnK")]
-	fn fn_c(&self, _input: u32) -> Result<u8> {
-		unreachable!()
-	}
-	fn fn_d(&self, _value: u32) -> Result<u32> {
-		unreachable!()
-	}
-
-	fn caller_sensitive(&self, _caller: Caller) -> Result<u8> {
-		unreachable!()
-	}
-	fn payable(&mut self, _value: Value) -> Result<u8> {
-		unreachable!()
-	}
-
-	#[weight(*_weight)]
-	fn with_weight(&self, _weight: u64) -> Result<()> {
-		unreachable!()
-	}
-
-	/// Doccoment example
-	fn with_doc(&self) -> Result<()> {
-		unreachable!()
-	}
-}
-
-#[solidity_interface(
-	name = ValidSelector,
-	expect_selector = 0x00000000,
-)]
-impl Impls {}
deletedcrates/evm-coder/tests/solidity_generation.rsdiffbeforeafterboth
--- a/crates/evm-coder/tests/solidity_generation.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-use evm_coder::{abi::AbiType, execution::Result, generate_stubgen, solidity_interface, types::*};
-use primitive_types::U256;
-
-pub struct ERC20;
-
-#[solidity_interface(name = ERC20)]
-impl ERC20 {
-	fn decimals(&self) -> Result<u8> {
-		unreachable!()
-	}
-	/// Get balance of specified owner
-	fn balance_of(&self, _owner: Address) -> Result<U256> {
-		unreachable!()
-	}
-	fn transfer(&mut self, _caller: Caller, _to: Address, _value: U256) -> Result<bool> {
-		unreachable!()
-	}
-	fn transfer_from(
-		&mut self,
-		_caller: Caller,
-		_from: Address,
-		_to: Address,
-		_value: U256,
-	) -> Result<bool> {
-		unreachable!()
-	}
-	fn approve(&mut self, _caller: Caller, _spender: Address, _value: U256) -> Result<bool> {
-		unreachable!()
-	}
-	fn allowance(&self, _owner: Address, _spender: Address) -> Result<U256> {
-		unreachable!()
-	}
-}
-
-generate_stubgen!(gen_impl, ERC20Call, true);
-generate_stubgen!(gen_iface, ERC20Call, false);
modifiedcrates/struct-versioning/src/lib.rsdiffbeforeafterboth
--- a/crates/struct-versioning/src/lib.rs
+++ b/crates/struct-versioning/src/lib.rs
@@ -223,7 +223,7 @@
 		};
 		let current_fields = fields
 			.iter()
-			.filter_map(|(ver, field)| ver.exists_on(version).then(|| field));
+			.filter_map(|(ver, field)| ver.exists_on(version).then_some(field));
 
 		let mut doc = Vec::new();
 		if version > attr.first_version {
modifiedpallets/common/src/erc.rsdiffbeforeafterboth
--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -17,12 +17,12 @@
 //! This module contains the implementation of pallet methods for evm.
 
 pub use pallet_evm::{PrecompileOutput, PrecompileResult, PrecompileHandle, account::CrossAccountId};
-use evm_coder::{
+use pallet_evm_coder_substrate::{
 	abi::AbiType,
-	solidity_interface, solidity, ToLog,
+	solidity_interface, ToLog,
 	types::*,
-	execution::{Result, Error},
-	weight,
+	execution::{Result, Error, PreDispatch},
+	frontier_contract,
 };
 use pallet_evm_coder_substrate::dispatch_to_evm;
 use sp_std::{vec, vec::Vec};
@@ -36,6 +36,11 @@
 	Pallet, CollectionHandle, Config, CollectionProperties, SelfWeightOf, eth, weights::WeightInfo,
 };
 
+frontier_contract! {
+	macro_rules! CollectionHandle_result {...}
+	impl<T: Config> Contract for CollectionHandle<T> {...}
+}
+
 /// Events for ethereum collection helper.
 #[derive(ToLog)]
 pub enum CollectionHelpersEvents {
@@ -83,7 +88,7 @@
 }
 
 /// @title A contract that allows you to work with collections.
-#[solidity_interface(name = Collection)]
+#[solidity_interface(name = Collection, enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T: Config> CollectionHandle<T>
 where
 	T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,
@@ -272,7 +277,7 @@
 			None => return Ok(Default::default()),
 		};
 
-		Ok(eth::CrossAddress::from_sub::<T>(&sponsor))
+		Ok(eth::CrossAddress::from_sub::<T>(sponsor))
 	}
 
 	/// Get current collection limits.
@@ -280,11 +285,6 @@
 	/// @return Array of collection limits
 	fn collection_limits(&self) -> Result<Vec<eth::CollectionLimit>> {
 		let limits = &self.collection.limits;
-
-		let convert_value_from_bool = |ob: Option<bool>| match ob {
-			Some(b) => Some(b as u32),
-			None => None,
-		};
 
 		Ok(vec![
 			eth::CollectionLimit::new(
@@ -307,10 +307,12 @@
 						None
 					}
 				})
-				.unwrap_or(eth::CollectionLimit::new(
-					eth::CollectionLimitField::SponsoredDataRateLimit,
-					Default::default(),
-				)),
+				.unwrap_or_else(|| {
+					eth::CollectionLimit::new(
+						eth::CollectionLimitField::SponsoredDataRateLimit,
+						Default::default(),
+					)
+				}),
 			eth::CollectionLimit::new(eth::CollectionLimitField::TokenLimit, limits.token_limit),
 			eth::CollectionLimit::new(
 				eth::CollectionLimitField::SponsorTransferTimeout,
@@ -322,15 +324,15 @@
 			),
 			eth::CollectionLimit::new(
 				eth::CollectionLimitField::OwnerCanTransfer,
-				convert_value_from_bool(limits.owner_can_transfer),
+				limits.owner_can_transfer.map(u32::from),
 			),
 			eth::CollectionLimit::new(
 				eth::CollectionLimitField::OwnerCanDestroy,
-				convert_value_from_bool(limits.owner_can_destroy),
+				limits.owner_can_destroy.map(u32::from),
 			),
 			eth::CollectionLimit::new(
 				eth::CollectionLimitField::TransferEnabled,
-				convert_value_from_bool(limits.transfers_enabled),
+				limits.transfers_enabled.map(u32::from),
 			),
 		])
 	}
@@ -680,7 +682,7 @@
 
 /// Contains static property keys and values.
 pub mod static_property {
-	use evm_coder::{
+	use pallet_evm_coder_substrate::{
 		execution::{Result, Error},
 	};
 	use alloc::format;
modifiedpallets/common/src/eth.rsdiffbeforeafterboth
--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -105,7 +105,9 @@
 		}
 	}
 	/// Converts [`CrossAddress`] to `CrossAccountId`.
-	pub fn into_sub_cross_account<T>(&self) -> evm_coder::execution::Result<T::CrossAccountId>
+	pub fn into_sub_cross_account<T>(
+		&self,
+	) -> pallet_evm_coder_substrate::execution::Result<T::CrossAccountId>
 	where
 		T: pallet_evm::Config,
 		T::AccountId: From<[u8; 32]>,
@@ -130,7 +132,7 @@
 }
 
 impl TryFrom<up_data_structs::Property> for Property {
-	type Error = evm_coder::execution::Error;
+	type Error = pallet_evm_coder_substrate::execution::Error;
 
 	fn try_from(from: up_data_structs::Property) -> Result<Self, Self::Error> {
 		let key = evm_coder::types::String::from_utf8(from.key.into())
@@ -141,7 +143,7 @@
 }
 
 impl TryInto<up_data_structs::Property> for Property {
-	type Error = evm_coder::execution::Error;
+	type Error = pallet_evm_coder_substrate::execution::Error;
 
 	fn try_into(self) -> Result<up_data_structs::Property, Self::Error> {
 		let key = <Vec<u8>>::from(self.key)
@@ -212,7 +214,7 @@
 }
 
 impl TryInto<up_data_structs::CollectionLimits> for CollectionLimit {
-	type Error = evm_coder::execution::Error;
+	type Error = pallet_evm_coder_substrate::execution::Error;
 
 	fn try_into(self) -> Result<up_data_structs::CollectionLimits, Self::Error> {
 		let value = self
@@ -378,7 +380,8 @@
 	/// Convert vector of [`TokenPropertyPermission`] into vector of [`up_data_structs::PropertyKeyPermission`].
 	pub fn into_property_key_permissions(
 		permissions: Vec<TokenPropertyPermission>,
-	) -> evm_coder::execution::Result<Vec<up_data_structs::PropertyKeyPermission>> {
+	) -> pallet_evm_coder_substrate::execution::Result<Vec<up_data_structs::PropertyKeyPermission>>
+	{
 		let mut perms = Vec::new();
 
 		for TokenPropertyPermission { key, permissions } in permissions {
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -192,7 +192,10 @@
 	}
 
 	/// Consume gas for reading.
-	pub fn consume_store_reads(&self, reads: u64) -> evm_coder::execution::Result<()> {
+	pub fn consume_store_reads(
+		&self,
+		reads: u64,
+	) -> pallet_evm_coder_substrate::execution::Result<()> {
 		self.recorder
 			.consume_gas(T::GasWeightMapping::weight_to_gas(Weight::from_ref_time(
 				<T as frame_system::Config>::DbWeight::get()
@@ -202,7 +205,10 @@
 	}
 
 	/// Consume gas for writing.
-	pub fn consume_store_writes(&self, writes: u64) -> evm_coder::execution::Result<()> {
+	pub fn consume_store_writes(
+		&self,
+		writes: u64,
+	) -> pallet_evm_coder_substrate::execution::Result<()> {
 		self.recorder
 			.consume_gas(T::GasWeightMapping::weight_to_gas(Weight::from_ref_time(
 				<T as frame_system::Config>::DbWeight::get()
@@ -216,7 +222,7 @@
 		&self,
 		reads: u64,
 		writes: u64,
-	) -> evm_coder::execution::Result<()> {
+	) -> pallet_evm_coder_substrate::execution::Result<()> {
 		let weight = <T as frame_system::Config>::DbWeight::get();
 		let reads = weight.read.saturating_mul(reads);
 		let writes = weight.read.saturating_mul(writes);
modifiedpallets/evm-coder-substrate/Cargo.tomldiffbeforeafterboth
--- a/pallets/evm-coder-substrate/Cargo.toml
+++ b/pallets/evm-coder-substrate/Cargo.toml
@@ -7,10 +7,11 @@
 [dependencies]
 # Note: `package = "parity-scale-codec"` must be supplied since the `Encode` macro searches for it.
 codec = { workspace = true, package = "parity-scale-codec" }
-
 scale-info = { workspace = true }
 
 evm-coder = { workspace = true }
+evm-core = { workspace = true }
+
 frame-benchmarking = { workspace = true, optional = true }
 frame-support = { workspace = true }
 frame-system = { workspace = true }
@@ -19,6 +20,9 @@
 sp-std = { workspace = true }
 up-data-structs = { workspace = true }
 
+evm-coder-substrate-procedural = { path = "./procedural" }
+spez = "0.1.1"
+
 [features]
 default = ["std"]
 runtime-benchmarks = ['frame-benchmarking']
addedpallets/evm-coder-substrate/procedural/Cargo.tomldiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-coder-substrate/procedural/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+edition = "2021"
+name = "evm-coder-substrate-procedural"
+version = "0.1.0"
+
+[dependencies]
+proc-macro2 = "1.0"
+quote = "1.0"
+syn = "1.0"
+
+[lib]
+proc-macro = true
addedpallets/evm-coder-substrate/procedural/src/lib.rsdiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-coder-substrate/procedural/src/lib.rs
@@ -0,0 +1,135 @@
+use std::result;
+
+use proc_macro2::{TokenStream, Ident};
+use quote::quote;
+use syn::{
+	Error, DeriveInput, Data, Attribute,
+	parse::{Parse, ParseBuffer},
+	spanned::Spanned,
+	Expr, parenthesized,
+};
+
+type Result<T = TokenStream, E = syn::Error> = result::Result<T, E>;
+
+fn parse_attr<A: Parse, I>(attrs: &[Attribute], ident: I) -> Result<Option<A>>
+where
+	Ident: PartialEq<I>,
+{
+	let attrs = attrs
+		.iter()
+		.filter(|a| a.path.is_ident(&ident))
+		.collect::<Vec<_>>();
+	if attrs.len() > 1 {
+		return Err(Error::new(
+			attrs[1].span(),
+			"this attribute may be specified only once",
+		));
+	} else if attrs.is_empty() {
+		return Ok(None);
+	}
+	let attr = attrs[0];
+
+	let parsed = syn::parse2(attr.tokens.clone())?;
+	Ok(Some(parsed))
+}
+
+struct WeightAttr {
+	handler: Expr,
+}
+impl Parse for WeightAttr {
+	fn parse(input: &ParseBuffer) -> Result<Self> {
+		let expr;
+		parenthesized!(expr in input);
+		let handler = Expr::parse(&expr)?;
+
+		Ok(Self { handler })
+	}
+}
+
+#[proc_macro_derive(PreDispatch, attributes(pre_dispatch, weight))]
+pub fn derive_predispatch(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
+	fn inner(input: DeriveInput) -> Result {
+		let (impl_generics, ty_generics, _where_clause) = input.generics.split_for_impl();
+		let ident = &input.ident;
+		let Data::Enum(data) = &input.data else {
+			return Err(Error::new_spanned(input, "PreDispatch input is enum"))
+		};
+
+		let matching = data
+			.variants
+			.iter()
+			.map(|var| {
+				let name = &var.ident;
+				let handler = match &var.fields {
+					syn::Fields::Named(named) => {
+						if let Some(weight) = parse_attr::<WeightAttr, _>(&var.attrs, "weight")? {
+							let weight = &weight.handler;
+							let fields = named.named.iter().flat_map(|n| &n.ident);
+							quote! {
+								{#(#fields,)*} => {
+									::pallet_evm_coder_substrate::execution::DispatchInfo {
+										weight: ::pallet_evm_coder_substrate::execution::Weight::from(#weight),
+									}
+								}
+							}
+						} else {
+							quote! {
+								{..} => {
+									::pallet_evm_coder_substrate::execution::DispatchInfo {
+										weight: ::pallet_evm_coder_substrate::execution::Weight::zero()
+									}
+								}
+							}
+						}
+					}
+					syn::Fields::Unit => {
+						if let Some(weight) = parse_attr::<WeightAttr, _>(&var.attrs, "weight")? {
+							let weight = &weight.handler;
+							quote! {
+								=> {
+									::pallet_evm_coder_substrate::execution::DispatchInfo {
+										weight: ::pallet_evm_coder_substrate::execution::Weight::from(#weight),
+									}
+								}
+							}
+						} else {
+							quote! {
+								=> {
+									::pallet_evm_coder_substrate::execution::DispatchInfo {
+										weight: ::pallet_evm_coder_substrate::execution::Weight::zero()
+									}
+								}
+							}
+						}
+					}
+					syn::Fields::Unnamed(_) => {
+						quote! {
+							(call, ..) => {
+								call.dispatch_info()
+							}
+						}
+					}
+				};
+				Ok(quote! {
+					Self::#name #handler,
+				})
+			})
+			.collect::<Result>()?;
+
+		Ok(quote! {
+			#[allow(unused_variables)]
+			impl #impl_generics ::pallet_evm_coder_substrate::execution::PreDispatch for #ident #ty_generics where T: crate::Config {
+				fn dispatch_info(&self) -> ::pallet_evm_coder_substrate::execution::DispatchInfo {
+					match self {
+						#matching
+					}
+				}
+			}
+		})
+	}
+	let item = syn::parse_macro_input!(item as DeriveInput);
+	match inner(item) {
+		Ok(o) => o.into(),
+		Err(e) => e.into_compile_error().into(),
+	}
+}
addedpallets/evm-coder-substrate/src/execution.rsdiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-coder-substrate/src/execution.rs
@@ -0,0 +1,186 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+//! Contract execution related types
+
+#[cfg(not(feature = "std"))]
+use alloc::string::{String, ToString};
+#[cfg(feature = "std")]
+use std::string::{String, ToString};
+
+use evm_coder::ERC165Call;
+use evm_core::{ExitError, ExitFatal};
+
+pub use frame_support::weights::Weight;
+pub use evm_coder_substrate_procedural::PreDispatch;
+
+/// Execution error, should be convertible between EVM and Substrate.
+#[derive(Debug, Clone)]
+pub enum Error {
+	/// Non-fatal contract error occured
+	Revert(String),
+	/// EVM fatal error
+	Fatal(ExitFatal),
+	/// EVM normal error
+	Error(ExitError),
+}
+
+impl<E> From<E> for Error
+where
+	E: ToString,
+{
+	fn from(e: E) -> Self {
+		Self::Revert(e.to_string())
+	}
+}
+
+/// To be used in [`crate::solidity_interface`] implementation.
+pub type Result<T> = core::result::Result<T, Error>;
+/// Return type of items in [`crate::solidity_interface`] definition
+pub type ResultWithPostInfo<T> =
+	core::result::Result<WithPostDispatchInfo<T>, WithPostDispatchInfo<Error>>;
+
+pub trait PreDispatch {
+	fn dispatch_info(&self) -> DispatchInfo;
+}
+
+impl PreDispatch for ERC165Call {
+	fn dispatch_info(&self) -> DispatchInfo {
+		DispatchInfo {
+			// ERC165 impl should be cheap
+			weight: Weight::from_ref_time(200),
+		}
+	}
+}
+
+/// Static information collected from [`crate::weight`].
+pub struct DispatchInfo {
+	/// Statically predicted call weight
+	pub weight: Weight,
+}
+
+impl From<Weight> for DispatchInfo {
+	fn from(weight: Weight) -> Self {
+		Self { weight }
+	}
+}
+impl From<u64> for DispatchInfo {
+	fn from(weight: u64) -> Self {
+		Self {
+			weight: Weight::from_ref_time(weight),
+		}
+	}
+}
+impl From<()> for DispatchInfo {
+	fn from(_: ()) -> Self {
+		Self {
+			weight: Weight::zero(),
+		}
+	}
+}
+
+/// Weight information that is only available post dispatch.
+/// Note: This can only be used to reduce the weight or fee, not increase it.
+#[derive(Default, Clone)]
+pub struct PostDispatchInfo {
+	/// Actual weight consumed by call
+	pub actual_weight: Option<Weight>,
+}
+
+impl PostDispatchInfo {
+	/// Calculate amount to be returned back to user
+	pub fn calc_unspent(&self, info: &DispatchInfo) -> Weight {
+		info.weight - self.calc_actual_weight(info)
+	}
+
+	/// Calculate actual consumed weight, saturating to weight reported
+	/// pre-dispatch
+	pub fn calc_actual_weight(&self, info: &DispatchInfo) -> Weight {
+		if let Some(actual_weight) = self.actual_weight {
+			actual_weight.min(info.weight)
+		} else {
+			info.weight
+		}
+	}
+}
+
+/// Wrapper for PostDispatchInfo and any user-provided data
+#[derive(Clone)]
+pub struct WithPostDispatchInfo<T> {
+	/// User provided data
+	pub data: T,
+	/// Info known after dispatch
+	pub post_info: PostDispatchInfo,
+}
+
+impl<T> From<T> for WithPostDispatchInfo<T> {
+	fn from(data: T) -> Self {
+		Self {
+			data,
+			post_info: Default::default(),
+		}
+	}
+}
+#[allow(clippy::crate_in_macro_def)]
+#[macro_export]
+macro_rules! frontier_contract {
+	(
+		macro_rules! $res:ident {...}
+		impl$(<$($gen:ident $(: $($(+)? $bound:ty)*)?),+ $(,)?>)? Contract for $ty:ty {...}
+	) => {
+		/// Generate macro to convert function return value into Contract result
+		macro_rules! $res {
+			($i:expr) => {{
+				pallet_evm_coder_substrate::spez! {
+					for res = $i;
+					match<T> ::pallet_evm_coder_substrate::execution::ResultWithPostInfo<T> -> ::pallet_evm_coder_substrate::execution::ResultWithPostInfo<T> {
+						res
+					}
+					match<T> ::pallet_evm_coder_substrate::execution::Result<T> -> ::pallet_evm_coder_substrate::execution::ResultWithPostInfo<T> {
+						res
+							.map(pallet_evm_coder_substrate::execution::WithPostDispatchInfo::from)
+							.map_err(pallet_evm_coder_substrate::execution::WithPostDispatchInfo::from)
+					}
+					match<T> T -> ::pallet_evm_coder_substrate::execution::ResultWithPostInfo<T> {
+						Ok(pallet_evm_coder_substrate::execution::WithPostDispatchInfo::from(res))
+					}
+				}
+			}};
+		}
+		impl $(<$($gen),+>)? $crate::Contract for $ty where T: crate::Config {
+			type Error = ::pallet_evm_coder_substrate::execution::Error;
+			type WithPostInfo<R> = ::pallet_evm_coder_substrate::execution::WithPostDispatchInfo<R>;
+			type Result<R, E> = core::result::Result<R, E>;
+			fn map_post<I, O>(
+				v: Self::WithPostInfo<I>,
+				mapper: impl FnOnce(I) -> O,
+			) -> Self::WithPostInfo<O> {
+				::pallet_evm_coder_substrate::execution::WithPostDispatchInfo {
+					data: mapper(v.data),
+					post_info: v.post_info,
+				}
+			}
+			fn with_default_post<V>(v: V) -> Self::WithPostInfo<V> {
+				::pallet_evm_coder_substrate::execution::WithPostDispatchInfo {
+					data: v,
+					post_info: ::pallet_evm_coder_substrate::execution::PostDispatchInfo {
+						actual_weight: None,
+					},
+				}
+			}
+		}
+	};
+}
modifiedpallets/evm-coder-substrate/src/lib.rsdiffbeforeafterboth
--- a/pallets/evm-coder-substrate/src/lib.rs
+++ b/pallets/evm-coder-substrate/src/lib.rs
@@ -16,10 +16,13 @@
 
 #![cfg_attr(not(feature = "std"), no_std)]
 
+extern crate self as pallet_evm_coder_substrate;
+
 #[cfg(not(feature = "std"))]
 extern crate alloc;
 #[cfg(not(feature = "std"))]
 use alloc::format;
+use execution::PreDispatch;
 use frame_support::dispatch::Weight;
 
 use core::marker::PhantomData;
@@ -37,10 +40,14 @@
 use sp_core::H160;
 // #[cfg(feature = "runtime-benchmarks")]
 // pub mod benchmarking;
+pub mod execution;
+pub use evm_coder::*;
 
+#[doc(hidden)]
+pub use spez::spez;
+
 use evm_coder::{
 	abi::{AbiReader, AbiWrite, AbiWriter},
-	execution,
 	types::{Msg, Value},
 };
 
@@ -175,7 +182,7 @@
 		handle: &mut impl PrecompileHandle,
 		result: execution::Result<Option<AbiWriter>>,
 	) -> Option<PrecompileResult> {
-		use evm_coder::execution::Error;
+		use execution::Error;
 		// We ignore error here, as it should not occur, as we have our own bookkeeping of gas
 		let _ = handle.record_cost(self.initial_gas - self.gas_left());
 		Some(match result {
@@ -200,7 +207,7 @@
 }
 
 pub fn dispatch_to_evm<T: Config>(err: DispatchError) -> execution::Error {
-	use evm_coder::execution::Error as ExError;
+	use execution::Error as ExError;
 	match err {
 		DispatchError::Module(ModuleError { index, error, .. })
 			if index
@@ -231,15 +238,14 @@
 }
 
 /// Helper to simplify implementing bridge between evm-coder definitions and pallet-evm
-pub fn call<
+pub fn call<T, C, E, H>(handle: &mut H, mut e: E) -> Option<PrecompileResult>
+where
 	T: Config,
-	C: evm_coder::Call + evm_coder::Weighted,
+	C: evm_coder::Call + PreDispatch,
 	E: evm_coder::Callable<C> + WithRecorder<T>,
 	H: PrecompileHandle,
->(
-	handle: &mut H,
-	mut e: E,
-) -> Option<PrecompileResult> {
+	execution::ResultWithPostInfo<AbiWriter>: From<ResultWithPostInfoOf<E, AbiWriter>>,
+{
 	let result = call_internal(
 		handle.context().caller,
 		&mut e,
@@ -249,16 +255,18 @@
 	e.into_recorder().evm_to_precompile_output(handle, result)
 }
 
-fn call_internal<
-	T: Config,
-	C: evm_coder::Call + evm_coder::Weighted,
-	E: evm_coder::Callable<C> + WithRecorder<T>,
->(
+fn call_internal<T, C, E>(
 	caller: H160,
 	e: &mut E,
 	value: Value,
 	input: &[u8],
-) -> execution::Result<Option<AbiWriter>> {
+) -> execution::Result<Option<AbiWriter>>
+where
+	T: Config,
+	C: evm_coder::Call + PreDispatch,
+	E: Contract + evm_coder::Callable<C> + WithRecorder<T>,
+	execution::ResultWithPostInfo<AbiWriter>: From<ResultWithPostInfoOf<E, AbiWriter>>,
+{
 	let (selector, mut reader) = AbiReader::new_call(input)?;
 	let call = C::parse(selector, &mut reader)?;
 	if call.is_none() {
@@ -267,15 +275,15 @@
 	}
 	let call = call.unwrap();
 
-	let dispatch_info = call.weight();
+	let dispatch_info = call.dispatch_info();
 	e.recorder()
 		.consume_gas(T::GasWeightMapping::weight_to_gas(dispatch_info.weight))?;
 
-	match e.call(Msg {
+	match execution::ResultWithPostInfo::from(e.call(Msg {
 		call,
 		caller,
 		value,
-	}) {
+	})) {
 		Ok(v) => {
 			let unspent = v.post_info.calc_unspent(&dispatch_info);
 			e.recorder()
@@ -290,3 +298,26 @@
 		}
 	}
 }
+
+#[cfg(test)]
+#[allow(dead_code)]
+mod tests {
+	use core::marker::PhantomData;
+
+	use evm_coder::ERC165Call;
+	use frame_support::weights::Weight;
+
+	use crate::execution::PreDispatch;
+
+	#[derive(PreDispatch)]
+	enum ExampleCall<T: super::Config> {
+		ERC165Call(ERC165Call, PhantomData<fn() -> T>),
+		OtherCall(ERC165Call),
+
+		#[weight(Weight::from_ref_time(a + b))]
+		Example {
+			a: u64,
+			b: u64,
+		},
+	}
+}
modifiedpallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth
--- a/pallets/evm-contract-helpers/src/eth.rs
+++ b/pallets/evm-contract-helpers/src/eth.rs
@@ -20,7 +20,6 @@
 use core::marker::PhantomData;
 use evm_coder::{
 	abi::{AbiWriter, AbiType},
-	execution::Result,
 	generate_stubgen, solidity_interface,
 	types::*,
 	ToLog,
@@ -30,7 +29,11 @@
 	ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure, PrecompileHandle,
 	account::CrossAccountId,
 };
-use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder, dispatch_to_evm};
+use pallet_evm_coder_substrate::{
+	SubstrateRecorder, WithRecorder, dispatch_to_evm,
+	execution::{Result, PreDispatch},
+	frontier_contract,
+};
 use pallet_evm_transaction_payment::CallContext;
 use sp_core::{H160, U256};
 use up_data_structs::SponsorshipState;
@@ -42,6 +45,11 @@
 use up_sponsorship::SponsorshipHandler;
 use sp_std::vec::Vec;
 
+frontier_contract! {
+	macro_rules! ContractHelpers_result {...}
+	impl<T: Config> Contract for ContractHelpers<T> {...}
+}
+
 /// Pallet events.
 #[derive(ToLog)]
 pub enum ContractHelpersEvents {
@@ -84,7 +92,7 @@
 }
 
 /// @title Magic contract, which allows users to reconfigure other contracts
-#[solidity_interface(name = ContractHelpers, events(ContractHelpersEvents))]
+#[solidity_interface(name = ContractHelpers, events(ContractHelpersEvents), enum(derive(PreDispatch)))]
 impl<T: Config> ContractHelpers<T>
 where
 	T::AccountId: AsRef<[u8; 32]>,
modifiedpallets/fungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/fungible/src/erc.rs
+++ b/pallets/fungible/src/erc.rs
@@ -20,10 +20,7 @@
 use core::char::{REPLACEMENT_CHARACTER, decode_utf16};
 use core::convert::TryInto;
 use evm_coder::AbiCoder;
-use evm_coder::{
-	abi::AbiType, ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*,
-	weight,
-};
+use evm_coder::{abi::AbiType, ToLog, generate_stubgen, solidity_interface, types::*};
 use up_data_structs::CollectionMode;
 use pallet_common::{
 	CollectionHandle,
@@ -32,7 +29,11 @@
 };
 use sp_std::vec::Vec;
 use pallet_evm::{account::CrossAccountId, PrecompileHandle};
-use pallet_evm_coder_substrate::{call, dispatch_to_evm};
+use pallet_evm_coder_substrate::{
+	call, dispatch_to_evm,
+	execution::{PreDispatch, Result},
+	frontier_contract,
+};
 use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
 use sp_core::{U256, Get};
 
@@ -41,6 +42,11 @@
 	weights::WeightInfo,
 };
 
+frontier_contract! {
+	macro_rules! FungibleHandle_result {...}
+	impl<T: Config> Contract for FungibleHandle<T> {...}
+}
+
 #[derive(ToLog)]
 pub enum ERC20Events {
 	Transfer {
@@ -65,7 +71,7 @@
 	amount: U256,
 }
 
-#[solidity_interface(name = ERC20, events(ERC20Events), expect_selector = 0x942e8b22)]
+#[solidity_interface(name = ERC20, events(ERC20Events), enum(derive(PreDispatch)), enum_attr(weight), expect_selector = 0x942e8b22)]
 impl<T: Config> FungibleHandle<T> {
 	fn name(&self) -> Result<String> {
 		Ok(decode_utf16(self.name.iter().copied())
@@ -145,7 +151,7 @@
 	}
 }
 
-#[solidity_interface(name = ERC20Mintable)]
+#[solidity_interface(name = ERC20Mintable, enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T: Config> FungibleHandle<T> {
 	/// Mint tokens for `to` account.
 	/// @param to account that will receive minted tokens
@@ -158,13 +164,13 @@
 		let budget = self
 			.recorder
 			.weight_calls_budget(<StructureWeight<T>>::find_parent());
-		<Pallet<T>>::create_item(&self, &caller, (to, amount), &budget)
+		<Pallet<T>>::create_item(self, &caller, (to, amount), &budget)
 			.map_err(dispatch_to_evm::<T>)?;
 		Ok(true)
 	}
 }
 
-#[solidity_interface(name = ERC20UniqueExtensions)]
+#[solidity_interface(name = ERC20UniqueExtensions, enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T: Config> FungibleHandle<T>
 where
 	T::AccountId: From<[u8; 32]>,
@@ -181,10 +187,10 @@
 	}
 
 	/// @notice A description for the collection.
-	fn description(&self) -> Result<String> {
-		Ok(decode_utf16(self.description.iter().copied())
+	fn description(&self) -> String {
+		decode_utf16(self.description.iter().copied())
 			.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
-			.collect::<String>())
+			.collect::<String>()
 	}
 
 	#[weight(<SelfWeightOf<T>>::create_item())]
@@ -278,7 +284,7 @@
 			})
 			.collect::<Result<_>>()?;
 
-		<Pallet<T>>::create_multiple_items(&self, &caller, amounts, &budget)
+		<Pallet<T>>::create_multiple_items(self, &caller, amounts, &budget)
 			.map_err(dispatch_to_evm::<T>)?;
 		Ok(true)
 	}
@@ -330,7 +336,8 @@
 		ERC20Mintable,
 		ERC20UniqueExtensions,
 		Collection(via(common_mut returns CollectionHandle<T>)),
-	)
+	),
+	enum(derive(PreDispatch))
 )]
 impl<T: Config> FungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}
 
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -24,16 +24,16 @@
 	char::{REPLACEMENT_CHARACTER, decode_utf16},
 	convert::TryInto,
 };
-use evm_coder::{
-	abi::AbiType, ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*,
-	weight,
-};
+use evm_coder::{abi::AbiType, ToLog, generate_stubgen, solidity_interface, types::*};
 use frame_support::BoundedVec;
 use up_data_structs::{
 	TokenId, PropertyPermission, PropertyKeyPermission, Property, CollectionId, PropertyKey,
 	CollectionPropertiesVec,
 };
-use pallet_evm_coder_substrate::dispatch_to_evm;
+use pallet_evm_coder_substrate::{
+	dispatch_to_evm, frontier_contract,
+	execution::{Result, PreDispatch, Error},
+};
 use sp_std::{vec::Vec, vec};
 use pallet_common::{
 	CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,
@@ -50,8 +50,13 @@
 	SelfWeightOf, weights::WeightInfo, TokenProperties,
 };
 
+frontier_contract! {
+	macro_rules! NonfungibleHandle_result {...}
+	impl<T: Config> Contract for NonfungibleHandle<T> {...}
+}
+
 /// @title A contract that allows to set and delete token properties and change token property permissions.
-#[solidity_interface(name = TokenProperties)]
+#[solidity_interface(name = TokenProperties, enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T: Config> NonfungibleHandle<T> {
 	/// @notice Set permissions for token property.
 	/// @dev Throws error if `msg.sender` is not admin or owner of the collection.
@@ -59,8 +64,8 @@
 	/// @param isMutable Permission to mutate property.
 	/// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
 	/// @param tokenOwner Permission to mutate property by token owner if property is mutable.
+	#[solidity(hide)]
 	#[weight(<SelfWeightOf<T>>::set_token_property_permissions(1))]
-	#[solidity(hide)]
 	fn set_token_property_permission(
 		&mut self,
 		caller: Caller,
@@ -293,7 +298,7 @@
 
 /// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 /// @dev See https://eips.ethereum.org/EIPS/eip-721
-#[solidity_interface(name = ERC721Metadata, expect_selector = 0x5b5e139f)]
+#[solidity_interface(name = ERC721Metadata, expect_selector = 0x5b5e139f, enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T: Config> NonfungibleHandle<T>
 where
 	T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,
@@ -301,14 +306,14 @@
 	/// @notice A descriptive name for a collection of NFTs in this contract
 	/// @dev real implementation of this function lies in `ERC721UniqueExtensions`
 	#[solidity(hide, rename_selector = "name")]
-	fn name_proxy(&self) -> Result<String> {
+	fn name_proxy(&self) -> String {
 		self.name()
 	}
 
 	/// @notice An abbreviated name for NFTs in this contract
 	/// @dev real implementation of this function lies in `ERC721UniqueExtensions`
 	#[solidity(hide, rename_selector = "symbol")]
-	fn symbol_proxy(&self) -> Result<String> {
+	fn symbol_proxy(&self) -> String {
 		self.symbol()
 	}
 
@@ -362,14 +367,14 @@
 
 /// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 /// @dev See https://eips.ethereum.org/EIPS/eip-721
-#[solidity_interface(name = ERC721Enumerable, expect_selector = 0x780e9d63)]
+#[solidity_interface(name = ERC721Enumerable, expect_selector = 0x780e9d63, enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T: Config> NonfungibleHandle<T> {
 	/// @notice Enumerate valid NFTs
 	/// @param index A counter less than `totalSupply()`
 	/// @return The token identifier for the `index`th NFT,
 	///  (sort order not specified)
-	fn token_by_index(&self, index: U256) -> Result<U256> {
-		Ok(index)
+	fn token_by_index(&self, index: U256) -> U256 {
+		index
 	}
 
 	/// @dev Not implemented
@@ -389,7 +394,7 @@
 
 /// @title ERC-721 Non-Fungible Token Standard
 /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
-#[solidity_interface(name = ERC721, events(ERC721Events), expect_selector = 0x80ac58cd)]
+#[solidity_interface(name = ERC721, events(ERC721Events), enum(derive(PreDispatch)), enum_attr(weight), expect_selector = 0x80ac58cd)]
 impl<T: Config> NonfungibleHandle<T> {
 	/// @notice Count all NFTs assigned to an owner
 	/// @dev NFTs assigned to the zero address are considered invalid, and this
@@ -516,7 +521,7 @@
 }
 
 /// @title ERC721 Token that can be irreversibly burned (destroyed).
-#[solidity_interface(name = ERC721Burnable)]
+#[solidity_interface(name = ERC721Burnable, enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T: Config> NonfungibleHandle<T> {
 	/// @notice Burns a specific ERC721 token.
 	/// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized
@@ -533,7 +538,7 @@
 }
 
 /// @title ERC721 minting logic.
-#[solidity_interface(name = ERC721UniqueMintable)]
+#[solidity_interface(name = ERC721UniqueMintable, enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T: Config> NonfungibleHandle<T> {
 	/// @notice Function to mint a token.
 	/// @param to The new owner
@@ -698,28 +703,28 @@
 }
 
 /// @title Unique extensions for ERC721.
-#[solidity_interface(name = ERC721UniqueExtensions)]
+#[solidity_interface(name = ERC721UniqueExtensions, enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T: Config> NonfungibleHandle<T>
 where
 	T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,
 {
 	/// @notice A descriptive name for a collection of NFTs in this contract
-	fn name(&self) -> Result<String> {
-		Ok(decode_utf16(self.name.iter().copied())
+	fn name(&self) -> String {
+		decode_utf16(self.name.iter().copied())
 			.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
-			.collect::<String>())
+			.collect::<String>()
 	}
 
 	/// @notice An abbreviated name for NFTs in this contract
-	fn symbol(&self) -> Result<String> {
-		Ok(String::from_utf8_lossy(&self.token_prefix).into())
+	fn symbol(&self) -> String {
+		String::from_utf8_lossy(&self.token_prefix).into()
 	}
 
 	/// @notice A description for the collection.
-	fn description(&self) -> Result<String> {
-		Ok(decode_utf16(self.description.iter().copied())
+	fn description(&self) -> String {
+		decode_utf16(self.description.iter().copied())
 			.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
-			.collect::<String>())
+			.collect::<String>()
 	}
 
 	/// Returns the owner (in cross format) of the token.
@@ -1035,8 +1040,8 @@
 	}
 
 	/// @notice Returns collection helper contract address
-	fn collection_helper_address(&self) -> Result<Address> {
-		Ok(T::ContractAddress::get())
+	fn collection_helper_address(&self) -> Address {
+		T::ContractAddress::get()
 	}
 }
 
@@ -1051,7 +1056,8 @@
 		ERC721Metadata(if(this.flags.erc721metadata)),
 		Collection(via(common_mut returns CollectionHandle<T>)),
 		TokenProperties,
-	)
+	),
+	enum(derive(PreDispatch)),
 )]
 impl<T: Config> NonfungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}
 
modifiedpallets/refungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -25,10 +25,7 @@
 	char::{REPLACEMENT_CHARACTER, decode_utf16},
 	convert::TryInto,
 };
-use evm_coder::{
-	abi::AbiType, ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*,
-	weight,
-};
+use evm_coder::{abi::AbiType, ToLog, generate_stubgen, solidity_interface, types::*};
 use frame_support::{BoundedBTreeMap, BoundedVec};
 use pallet_common::{
 	CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,
@@ -37,7 +34,11 @@
 	eth::{self, TokenUri},
 };
 use pallet_evm::{account::CrossAccountId, PrecompileHandle};
-use pallet_evm_coder_substrate::{call, dispatch_to_evm};
+use pallet_evm_coder_substrate::{
+	call, dispatch_to_evm,
+	execution::{PreDispatch, Result, Error},
+	frontier_contract,
+};
 use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
 use sp_core::{H160, U256, Get};
 use sp_std::{collections::btree_map::BTreeMap, vec::Vec, vec};
@@ -51,10 +52,15 @@
 	TokenProperties, TokensMinted, TotalSupply, weights::WeightInfo,
 };
 
+frontier_contract! {
+	macro_rules! RefungibleHandle_result {...}
+	impl<T: Config> Contract for RefungibleHandle<T> {...}
+}
+
 pub const ADDRESS_FOR_PARTIALLY_OWNED_TOKENS: H160 = H160::repeat_byte(0xff);
 
 /// @title A contract that allows to set and delete token properties and change token property permissions.
-#[solidity_interface(name = TokenProperties)]
+#[solidity_interface(name = TokenProperties, enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T: Config> RefungibleHandle<T> {
 	/// @notice Set permissions for token property.
 	/// @dev Throws error if `msg.sender` is not admin or owner of the collection.
@@ -62,8 +68,8 @@
 	/// @param isMutable Permission to mutate property.
 	/// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
 	/// @param tokenOwner Permission to mutate property by token owner if property is mutable.
+	#[solidity(hide)]
 	#[weight(<SelfWeightOf<T>>::set_token_property_permissions(1))]
-	#[solidity(hide)]
 	fn set_token_property_permission(
 		&mut self,
 		caller: Caller,
@@ -290,7 +296,7 @@
 
 /// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 /// @dev See https://eips.ethereum.org/EIPS/eip-721
-#[solidity_interface(name = ERC721Metadata, expect_selector = 0x5b5e139f)]
+#[solidity_interface(name = ERC721Metadata, enum(derive(PreDispatch)), expect_selector = 0x5b5e139f)]
 impl<T: Config> RefungibleHandle<T>
 where
 	T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,
@@ -359,14 +365,14 @@
 
 /// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 /// @dev See https://eips.ethereum.org/EIPS/eip-721
-#[solidity_interface(name = ERC721Enumerable, expect_selector = 0x780e9d63)]
+#[solidity_interface(name = ERC721Enumerable, enum(derive(PreDispatch)), expect_selector = 0x780e9d63)]
 impl<T: Config> RefungibleHandle<T> {
 	/// @notice Enumerate valid RFTs
 	/// @param index A counter less than `totalSupply()`
 	/// @return The token identifier for the `index`th NFT,
 	///  (sort order not specified)
-	fn token_by_index(&self, index: U256) -> Result<U256> {
-		Ok(index)
+	fn token_by_index(&self, index: U256) -> U256 {
+		index
 	}
 
 	/// Not implemented
@@ -386,7 +392,7 @@
 
 /// @title ERC-721 Non-Fungible Token Standard
 /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
-#[solidity_interface(name = ERC721, events(ERC721Events), expect_selector = 0x80ac58cd)]
+#[solidity_interface(name = ERC721, events(ERC721Events), enum(derive(PreDispatch)), enum_attr(weight), expect_selector = 0x80ac58cd)]
 impl<T: Config> RefungibleHandle<T> {
 	/// @notice Count all RFTs assigned to an owner
 	/// @dev RFTs assigned to the zero address are considered invalid, and this
@@ -547,7 +553,7 @@
 }
 
 /// @title ERC721 Token that can be irreversibly burned (destroyed).
-#[solidity_interface(name = ERC721Burnable)]
+#[solidity_interface(name = ERC721Burnable, enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T: Config> RefungibleHandle<T> {
 	/// @notice Burns a specific ERC721 token.
 	/// @dev Throws unless `msg.sender` is the current RFT owner, or an authorized
@@ -567,7 +573,7 @@
 }
 
 /// @title ERC721 minting logic.
-#[solidity_interface(name = ERC721UniqueMintable)]
+#[solidity_interface(name = ERC721UniqueMintable, enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T: Config> RefungibleHandle<T> {
 	/// @notice Function to mint a token.
 	/// @param to The new owner
@@ -739,7 +745,7 @@
 }
 
 /// @title Unique extensions for ERC721.
-#[solidity_interface(name = ERC721UniqueExtensions)]
+#[solidity_interface(name = ERC721UniqueExtensions, enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T: Config> RefungibleHandle<T>
 where
 	T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,
@@ -1120,7 +1126,8 @@
 		ERC721Metadata(if(this.flags.erc721metadata)),
 		Collection(via(common_mut returns CollectionHandle<T>)),
 		TokenProperties,
-	)
+	),
+	enum(derive(PreDispatch)),
 )]
 impl<T: Config> RefungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}
 
modifiedpallets/refungible/src/erc_token.rsdiffbeforeafterboth
--- a/pallets/refungible/src/erc_token.rs
+++ b/pallets/refungible/src/erc_token.rs
@@ -24,40 +24,41 @@
 	convert::TryInto,
 	ops::Deref,
 };
-use evm_coder::{
-	abi::AbiType, ToLog, execution::*, generate_stubgen, solidity_interface, solidity, types::*,
-	weight,
-};
+use evm_coder::{abi::AbiType, ToLog, generate_stubgen, solidity_interface, types::*};
 use pallet_common::{
-	CommonWeightInfo,
 	erc::{CommonEvmHandler, PrecompileResult},
 	eth::{collection_id_to_address, CrossAddress},
 };
 use pallet_evm::{account::CrossAccountId, PrecompileHandle};
-use pallet_evm_coder_substrate::{call, dispatch_to_evm, WithRecorder};
+use pallet_evm_coder_substrate::{
+	call, dispatch_to_evm, WithRecorder, frontier_contract,
+	execution::{Result, PreDispatch},
+};
 use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
 use sp_std::vec::Vec;
 use sp_core::U256;
 use up_data_structs::TokenId;
 
-use crate::{
-	Allowance, Balance, common::CommonWeights, Config, Pallet, RefungibleHandle, SelfWeightOf,
-	TotalSupply, weights::WeightInfo,
-};
+use crate::{Allowance, Balance, Config, Pallet, RefungibleHandle, TotalSupply};
 
 /// Refungible token handle contains information about token's collection and id
 ///
 /// RefungibleTokenHandle doesn't check token's existance upon creation
 pub struct RefungibleTokenHandle<T: Config>(pub RefungibleHandle<T>, pub TokenId);
 
-#[solidity_interface(name = ERC1633)]
+frontier_contract! {
+	macro_rules! RefungibleTokenHandle_result {...}
+	impl<T: Config> Contract for RefungibleTokenHandle<T> {...}
+}
+
+#[solidity_interface(name = ERC1633, enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T: Config> RefungibleTokenHandle<T> {
-	fn parent_token(&self) -> Result<Address> {
-		Ok(collection_id_to_address(self.id))
+	fn parent_token(&self) -> Address {
+		collection_id_to_address(self.id)
 	}
 
-	fn parent_token_id(&self) -> Result<U256> {
-		Ok(self.1.into())
+	fn parent_token_id(&self) -> U256 {
+		self.1.into()
 	}
 }
 
@@ -89,18 +90,18 @@
 ///
 /// @dev Implementation of the basic standard token.
 /// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
-#[solidity_interface(name = ERC20, events(ERC20Events))]
+#[solidity_interface(name = ERC20, events(ERC20Events), enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T: Config> RefungibleTokenHandle<T> {
 	/// @return the name of the token.
-	fn name(&self) -> Result<String> {
-		Ok(decode_utf16(self.name.iter().copied())
+	fn name(&self) -> String {
+		decode_utf16(self.name.iter().copied())
 			.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
-			.collect::<String>())
+			.collect::<String>()
 	}
 
 	/// @return the symbol of the token.
-	fn symbol(&self) -> Result<String> {
-		Ok(String::from_utf8_lossy(&self.token_prefix).into())
+	fn symbol(&self) -> String {
+		String::from_utf8_lossy(&self.token_prefix).into()
 	}
 
 	/// @dev Total number of tokens in existence
@@ -198,7 +199,7 @@
 	}
 }
 
-#[solidity_interface(name = ERC20UniqueExtensions)]
+#[solidity_interface(name = ERC20UniqueExtensions, enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T: Config> RefungibleTokenHandle<T>
 where
 	T::AccountId: From<[u8; 32]>,
@@ -361,7 +362,8 @@
 
 #[solidity_interface(
 	name = UniqueRefungibleToken,
-	is(ERC20, ERC20UniqueExtensions, ERC1633)
+	is(ERC20, ERC20UniqueExtensions, ERC1633),
+	enum(derive(PreDispatch)),
 )]
 impl<T: Config> RefungibleTokenHandle<T> where T::AccountId: From<[u8; 32]> {}
 
modifiedpallets/unique/src/eth/mod.rsdiffbeforeafterboth
--- a/pallets/unique/src/eth/mod.rs
+++ b/pallets/unique/src/eth/mod.rs
@@ -18,9 +18,7 @@
 
 use core::marker::PhantomData;
 use ethereum as _;
-use evm_coder::{
-	abi::AbiType, execution::*, generate_stubgen, solidity, solidity_interface, types::*, weight,
-};
+use evm_coder::{abi::AbiType, generate_stubgen, solidity_interface, types::*};
 use frame_support::traits::Get;
 use crate::Pallet;
 
@@ -32,7 +30,11 @@
 	Pallet as PalletCommon,
 };
 use pallet_evm::{account::CrossAccountId, OnMethodCall, PrecompileHandle, PrecompileResult};
-use pallet_evm_coder_substrate::{dispatch_to_evm, SubstrateRecorder, WithRecorder};
+use pallet_evm_coder_substrate::{
+	dispatch_to_evm, SubstrateRecorder, WithRecorder,
+	execution::{PreDispatch, Result, Error},
+	frontier_contract,
+};
 use up_data_structs::{
 	CollectionDescription, CollectionMode, CollectionName, CollectionTokenPrefix,
 	CreateCollectionData,
@@ -43,6 +45,10 @@
 use alloc::format;
 use sp_std::vec::Vec;
 
+frontier_contract! {
+	macro_rules! EvmCollectionHelpers_result {...}
+	impl<T: Config> Contract for EvmCollectionHelpers<T> {...}
+}
 /// See [`CollectionHelpersCall`]
 pub struct EvmCollectionHelpers<T: Config>(SubstrateRecorder<T>);
 impl<T: Config> WithRecorder<T> for EvmCollectionHelpers<T> {
@@ -135,7 +141,7 @@
 }
 
 /// @title Contract, which allows users to operate with collections
-#[solidity_interface(name = CollectionHelpers, events(CollectionHelpersEvents))]
+#[solidity_interface(name = CollectionHelpers, events(CollectionHelpersEvents), enum(derive(PreDispatch)), enum_attr(weight))]
 impl<T> EvmCollectionHelpers<T>
 where
 	T: Config + pallet_common::Config + pallet_nonfungible::Config + pallet_refungible::Config,
@@ -183,9 +189,9 @@
 	/// @param description Informative description of the collection
 	/// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications
 	/// @return address Address of the newly created collection
-	#[weight(<SelfWeightOf<T>>::create_collection())]
 	#[deprecated(note = "mathod was renamed to `create_nft_collection`, prefer it instead")]
 	#[solidity(hide)]
+	#[weight(<SelfWeightOf<T>>::create_collection())]
 	fn create_nonfungible_collection(
 		&mut self,
 		caller: Caller,
modifiedruntime/tests/Cargo.tomldiffbeforeafterboth
--- a/runtime/tests/Cargo.toml
+++ b/runtime/tests/Cargo.toml
@@ -40,5 +40,5 @@
 parity-scale-codec = { version = "3.2.2", default-features = false, features = ["derive"] }
 scale-info = "*"
 
-evm-coder = { default-features = false, path = "../../crates/evm-coder" }
+evm-coder = { workspace = true }
 up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.37" }