git.delta.rocks / unique-network / refs/commits / 874bac86d4ac

difftreelog

Merge branch 'develop' into feature/evm-collection-calls

Yaroslav Bolyukin2021-08-31parents: #b65bf9a #93b7b22.patch.diff
in: master

26 files changed

added.maintain/frame-weight-template.hbsdiffbeforeafterboth
--- /dev/null
+++ b/.maintain/frame-weight-template.hbs
@@ -0,0 +1,95 @@
+// Template adopted from https://github.com/paritytech/substrate/blob/master/.maintain/frame-weight-template.hbs
+
+//! Autogenerated weights for {{pallet}}
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION {{version}}
+//! DATE: {{date}}, STEPS: `{{cmd.steps}}`, REPEAT: {{cmd.repeat}}, LOW RANGE: `{{cmd.lowest_range_values}}`, HIGH RANGE: `{{cmd.highest_range_values}}`
+//! EXECUTION: {{cmd.execution}}, WASM-EXECUTION: {{cmd.wasm_execution}}, CHAIN: {{cmd.chain}}, DB CACHE: {{cmd.db_cache}}
+
+// Executed Command:
+{{#each args as |arg|~}}
+// {{arg}}
+{{/each}}
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+
+use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
+use sp_std::marker::PhantomData;
+
+/// Weight functions needed for {{pallet}}.
+pub trait WeightInfo {
+	{{~#each benchmarks as |benchmark|}}
+	fn {{benchmark.name~}}
+	(
+		{{~#each benchmark.components as |c| ~}}
+		{{c.name}}: u32, {{/each~}}
+	) -> Weight;
+	{{~/each}}
+}
+
+/// Weights for {{pallet}} using the Substrate node and recommended hardware.
+pub struct SubstrateWeight<T>(PhantomData<T>);
+impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
+	{{~#each benchmarks as |benchmark|}}
+	{{~#each benchmark.comments as |comment|}}
+	// {{comment}}
+	{{~/each}}
+	fn {{benchmark.name~}}
+	(
+		{{~#each benchmark.components as |c| ~}}
+		{{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}}
+	) -> Weight {
+		({{underscore benchmark.base_weight}} as Weight)
+			{{~#each benchmark.component_weight as |cw|}}
+			// Standard Error: {{underscore cw.error}}
+			.saturating_add(({{underscore cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight))
+			{{~/each}}
+			{{~#if (ne benchmark.base_reads "0")}}
+			.saturating_add(T::DbWeight::get().reads({{benchmark.base_reads}} as Weight))
+			{{~/if}}
+			{{~#each benchmark.component_reads as |cr|}}
+			.saturating_add(T::DbWeight::get().reads(({{cr.slope}} as Weight).saturating_mul({{cr.name}} as Weight)))
+			{{~/each}}
+			{{~#if (ne benchmark.base_writes "0")}}
+			.saturating_add(T::DbWeight::get().writes({{benchmark.base_writes}} as Weight))
+			{{~/if}}
+			{{~#each benchmark.component_writes as |cw|}}
+			.saturating_add(T::DbWeight::get().writes(({{cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight)))
+			{{~/each}}
+	}
+	{{~/each}}
+}
+
+// For backwards compatibility and tests
+impl WeightInfo for () {
+	{{~#each benchmarks as |benchmark|}}
+	{{~#each benchmark.comments as |comment|}}
+	// {{comment}}
+	{{~/each}}
+	fn {{benchmark.name~}}
+	(
+		{{~#each benchmark.components as |c| ~}}
+		{{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}}
+	) -> Weight {
+		({{underscore benchmark.base_weight}} as Weight)
+			{{~#each benchmark.component_weight as |cw|}}
+			// Standard Error: {{underscore cw.error}}
+			.saturating_add(({{underscore cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight))
+			{{~/each}}
+			{{~#if (ne benchmark.base_reads "0")}}
+			.saturating_add(RocksDbWeight::get().reads({{benchmark.base_reads}} as Weight))
+			{{~/if}}
+			{{~#each benchmark.component_reads as |cr|}}
+			.saturating_add(RocksDbWeight::get().reads(({{cr.slope}} as Weight).saturating_mul({{cr.name}} as Weight)))
+			{{~/each}}
+			{{~#if (ne benchmark.base_writes "0")}}
+			.saturating_add(RocksDbWeight::get().writes({{benchmark.base_writes}} as Weight))
+			{{~/if}}
+			{{~#each benchmark.component_writes as |cw|}}
+			.saturating_add(RocksDbWeight::get().writes(({{cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight)))
+			{{~/each}}
+	}
+	{{~/each}}
+}
\ No newline at end of file
modifiedCargo.lockdiffbeforeafterboth
703 "once_cell",703 "once_cell",
704]704]
705
706[[package]]
707name = "bp-header-chain"
708version = "0.1.0"
709source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
710dependencies = [
711 "finality-grandpa",
712 "frame-support",
713 "parity-scale-codec",
714 "serde",
715 "sp-core",
716 "sp-finality-grandpa",
717 "sp-runtime",
718 "sp-std",
719]
720
721[[package]]
722name = "bp-messages"
723version = "0.1.0"
724source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
725dependencies = [
726 "bitvec 0.20.4",
727 "bp-runtime",
728 "frame-support",
729 "frame-system",
730 "impl-trait-for-tuples",
731 "parity-scale-codec",
732 "serde",
733 "sp-std",
734]
735
736[[package]]
737name = "bp-polkadot-core"
738version = "0.1.0"
739source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
740dependencies = [
741 "bp-messages",
742 "bp-runtime",
743 "frame-support",
744 "frame-system",
745 "parity-scale-codec",
746 "sp-api",
747 "sp-core",
748 "sp-runtime",
749 "sp-std",
750 "sp-version",
751]
752
753[[package]]
754name = "bp-rococo"
755version = "0.1.0"
756source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
757dependencies = [
758 "bp-messages",
759 "bp-polkadot-core",
760 "bp-runtime",
761 "frame-support",
762 "parity-scale-codec",
763 "smallvec 1.6.1",
764 "sp-api",
765 "sp-runtime",
766 "sp-std",
767 "sp-version",
768]
769
770[[package]]
771name = "bp-runtime"
772version = "0.1.0"
773source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
774dependencies = [
775 "frame-support",
776 "hash-db",
777 "num-traits",
778 "parity-scale-codec",
779 "sp-core",
780 "sp-io",
781 "sp-runtime",
782 "sp-state-machine",
783 "sp-std",
784 "sp-trie",
785]
786
787[[package]]
788name = "bp-test-utils"
789version = "0.1.0"
790source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
791dependencies = [
792 "bp-header-chain",
793 "ed25519-dalek",
794 "finality-grandpa",
795 "parity-scale-codec",
796 "sp-application-crypto",
797 "sp-finality-grandpa",
798 "sp-runtime",
799 "sp-std",
800]
801
802[[package]]
803name = "bp-wococo"
804version = "0.1.0"
805source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
806dependencies = [
807 "bp-messages",
808 "bp-polkadot-core",
809 "bp-rococo",
810 "bp-runtime",
811 "parity-scale-codec",
812 "sp-api",
813 "sp-runtime",
814 "sp-std",
815]
705816
706[[package]]817[[package]]
707name = "bs58"818name = "bs58"
3778 "winapi-build",3889 "winapi-build",
3779]3890]
3891
3892[[package]]
3893name = "kusama-runtime"
3894version = "0.9.8"
3895source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
3896dependencies = [
3897 "beefy-primitives",
3898 "bitvec 0.20.4",
3899 "frame-benchmarking",
3900 "frame-election-provider-support",
3901 "frame-executive",
3902 "frame-support",
3903 "frame-system",
3904 "frame-system-benchmarking",
3905 "frame-system-rpc-runtime-api",
3906 "frame-try-runtime",
3907 "hex-literal",
3908 "log",
3909 "max-encoded-len",
3910 "pallet-authority-discovery",
3911 "pallet-authorship",
3912 "pallet-babe",
3913 "pallet-balances",
3914 "pallet-bounties",
3915 "pallet-collective",
3916 "pallet-democracy",
3917 "pallet-election-provider-multi-phase",
3918 "pallet-elections-phragmen",
3919 "pallet-gilt",
3920 "pallet-grandpa",
3921 "pallet-identity",
3922 "pallet-im-online",
3923 "pallet-indices",
3924 "pallet-membership",
3925 "pallet-mmr-primitives",
3926 "pallet-multisig",
3927 "pallet-nicks",
3928 "pallet-offences",
3929 "pallet-offences-benchmarking",
3930 "pallet-proxy",
3931 "pallet-recovery",
3932 "pallet-scheduler 3.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
3933 "pallet-session",
3934 "pallet-session-benchmarking",
3935 "pallet-society",
3936 "pallet-staking",
3937 "pallet-staking-reward-fn",
3938 "pallet-timestamp",
3939 "pallet-tips",
3940 "pallet-transaction-payment",
3941 "pallet-transaction-payment-rpc-runtime-api",
3942 "pallet-treasury",
3943 "pallet-utility",
3944 "pallet-vesting",
3945 "pallet-xcm",
3946 "parity-scale-codec",
3947 "polkadot-primitives",
3948 "polkadot-runtime-common",
3949 "polkadot-runtime-parachains",
3950 "rustc-hex",
3951 "serde",
3952 "serde_derive",
3953 "smallvec 1.6.1",
3954 "sp-api",
3955 "sp-arithmetic",
3956 "sp-authority-discovery",
3957 "sp-block-builder",
3958 "sp-consensus-babe",
3959 "sp-core",
3960 "sp-inherents",
3961 "sp-io",
3962 "sp-npos-elections",
3963 "sp-offchain",
3964 "sp-runtime",
3965 "sp-session",
3966 "sp-staking",
3967 "sp-std",
3968 "sp-transaction-pool",
3969 "sp-version",
3970 "static_assertions",
3971 "substrate-wasm-builder 4.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
3972 "xcm",
3973 "xcm-builder",
3974 "xcm-executor",
3975]
37803976
3781[[package]]3977[[package]]
3782name = "kv-log-macro"3978name = "kv-log-macro"
5019 "pallet-evm",5215 "pallet-evm",
5020 "pallet-evm-coder-substrate",5216 "pallet-evm-coder-substrate",
5021 "pallet-evm-contract-helpers",5217 "pallet-evm-contract-helpers",
5218 "pallet-evm-migration",
5022 "pallet-evm-transaction-payment",5219 "pallet-evm-transaction-payment",
5023 "pallet-inflation",5220 "pallet-inflation",
5024 "pallet-nft",5221 "pallet-nft",
5321version = "3.0.0"5518version = "3.0.0"
5322source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"5519source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
5323dependencies = [5520dependencies = [
5521 "frame-benchmarking",
5324 "frame-support",5522 "frame-support",
5325 "frame-system",5523 "frame-system",
5326 "pallet-treasury",5524 "pallet-treasury",
5329 "sp-std",5527 "sp-std",
5330]5528]
5529
5530[[package]]
5531name = "pallet-bridge-grandpa"
5532version = "0.1.0"
5533source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
5534dependencies = [
5535 "bp-header-chain",
5536 "bp-runtime",
5537 "bp-test-utils",
5538 "finality-grandpa",
5539 "frame-support",
5540 "frame-system",
5541 "log",
5542 "num-traits",
5543 "parity-scale-codec",
5544 "serde",
5545 "sp-finality-grandpa",
5546 "sp-runtime",
5547 "sp-std",
5548 "sp-trie",
5549]
53315550
5332[[package]]5551[[package]]
5333name = "pallet-collective"5552name = "pallet-collective"
5334version = "3.0.0"5553version = "3.0.0"
5335source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"5554source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
5336dependencies = [5555dependencies = [
5556 "frame-benchmarking",
5337 "frame-support",5557 "frame-support",
5338 "frame-system",5558 "frame-system",
5339 "log",5559 "log",
5423version = "3.0.0"5643version = "3.0.0"
5424source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"5644source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
5425dependencies = [5645dependencies = [
5646 "frame-benchmarking",
5426 "frame-election-provider-support",5647 "frame-election-provider-support",
5427 "frame-support",5648 "frame-support",
5428 "frame-system",5649 "frame-system",
5429 "log",5650 "log",
5430 "parity-scale-codec",5651 "parity-scale-codec",
5652 "rand 0.7.3",
5431 "sp-arithmetic",5653 "sp-arithmetic",
5432 "sp-core",5654 "sp-core",
5433 "sp-io",5655 "sp-io",
5442version = "4.0.0"5664version = "4.0.0"
5443source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"5665source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
5444dependencies = [5666dependencies = [
5667 "frame-benchmarking",
5445 "frame-support",5668 "frame-support",
5446 "frame-system",5669 "frame-system",
5447 "log",5670 "log",
5541 "up-sponsorship",5764 "up-sponsorship",
5542]5765]
5766
5767[[package]]
5768name = "pallet-evm-migration"
5769version = "0.1.0"
5770dependencies = [
5771 "fp-evm",
5772 "frame-benchmarking",
5773 "frame-support",
5774 "frame-system",
5775 "pallet-evm",
5776 "parity-scale-codec",
5777 "sp-core",
5778 "sp-io",
5779 "sp-runtime",
5780 "sp-std",
5781]
55435782
5544[[package]]5783[[package]]
5545name = "pallet-evm-transaction-payment"5784name = "pallet-evm-transaction-payment"
5558 "up-sponsorship",5797 "up-sponsorship",
5559]5798]
5799
5800[[package]]
5801name = "pallet-gilt"
5802version = "3.0.0"
5803source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
5804dependencies = [
5805 "frame-benchmarking",
5806 "frame-support",
5807 "frame-system",
5808 "parity-scale-codec",
5809 "sp-arithmetic",
5810 "sp-runtime",
5811 "sp-std",
5812]
55605813
5561[[package]]5814[[package]]
5562name = "pallet-grandpa"5815name = "pallet-grandpa"
5600version = "3.0.0"5853version = "3.0.0"
5601source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"5854source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
5602dependencies = [5855dependencies = [
5856 "frame-benchmarking",
5603 "frame-support",5857 "frame-support",
5604 "frame-system",5858 "frame-system",
5605 "log",5859 "log",
5618version = "3.0.0"5872version = "3.0.0"
5619source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"5873source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
5620dependencies = [5874dependencies = [
5875 "frame-benchmarking",
5621 "frame-support",5876 "frame-support",
5622 "frame-system",5877 "frame-system",
5623 "parity-scale-codec",5878 "parity-scale-codec",
5717version = "3.0.0"5972version = "3.0.0"
5718source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"5973source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
5719dependencies = [5974dependencies = [
5975 "frame-benchmarking",
5720 "frame-support",5976 "frame-support",
5721 "frame-system",5977 "frame-system",
5722 "parity-scale-codec",5978 "parity-scale-codec",
5821 "sp-std",6077 "sp-std",
5822]6078]
6079
6080[[package]]
6081name = "pallet-offences-benchmarking"
6082version = "3.0.0"
6083source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
6084dependencies = [
6085 "frame-benchmarking",
6086 "frame-election-provider-support",
6087 "frame-support",
6088 "frame-system",
6089 "pallet-babe",
6090 "pallet-balances",
6091 "pallet-grandpa",
6092 "pallet-im-online",
6093 "pallet-offences",
6094 "pallet-session",
6095 "pallet-staking",
6096 "parity-scale-codec",
6097 "sp-runtime",
6098 "sp-staking",
6099 "sp-std",
6100]
58236101
5824[[package]]6102[[package]]
5825name = "pallet-proxy"6103name = "pallet-proxy"
5826version = "3.0.0"6104version = "3.0.0"
5827source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"6105source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
5828dependencies = [6106dependencies = [
6107 "frame-benchmarking",
5829 "frame-support",6108 "frame-support",
5830 "frame-system",6109 "frame-system",
5831 "max-encoded-len",6110 "max-encoded-len",
5849 "sp-std",6128 "sp-std",
5850]6129]
6130
6131[[package]]
6132name = "pallet-recovery"
6133version = "3.0.0"
6134source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
6135dependencies = [
6136 "enumflags2",
6137 "frame-support",
6138 "frame-system",
6139 "parity-scale-codec",
6140 "sp-io",
6141 "sp-runtime",
6142 "sp-std",
6143]
58516144
5852[[package]]6145[[package]]
5853name = "pallet-scheduler"6146name = "pallet-scheduler"
5902 "sp-trie",6195 "sp-trie",
5903]6196]
6197
6198[[package]]
6199name = "pallet-session-benchmarking"
6200version = "3.0.0"
6201source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
6202dependencies = [
6203 "frame-benchmarking",
6204 "frame-support",
6205 "frame-system",
6206 "pallet-session",
6207 "pallet-staking",
6208 "rand 0.7.3",
6209 "sp-runtime",
6210 "sp-session",
6211 "sp-std",
6212]
6213
6214[[package]]
6215name = "pallet-society"
6216version = "3.0.0"
6217source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
6218dependencies = [
6219 "frame-support",
6220 "frame-system",
6221 "parity-scale-codec",
6222 "rand_chacha 0.2.2",
6223 "sp-runtime",
6224 "sp-std",
6225]
59046226
5905[[package]]6227[[package]]
5906name = "pallet-staking"6228name = "pallet-staking"
5907version = "3.0.0"6229version = "3.0.0"
5908source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"6230source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
5909dependencies = [6231dependencies = [
6232 "frame-benchmarking",
5910 "frame-election-provider-support",6233 "frame-election-provider-support",
5911 "frame-support",6234 "frame-support",
5912 "frame-system",6235 "frame-system",
5915 "pallet-session",6238 "pallet-session",
5916 "parity-scale-codec",6239 "parity-scale-codec",
5917 "paste",6240 "paste",
6241 "rand_chacha 0.2.2",
5918 "serde",6242 "serde",
5919 "sp-application-crypto",6243 "sp-application-crypto",
5920 "sp-io",6244 "sp-io",
5935 "syn",6259 "syn",
5936]6260]
6261
6262[[package]]
6263name = "pallet-staking-reward-fn"
6264version = "3.0.0"
6265source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
6266dependencies = [
6267 "log",
6268 "sp-arithmetic",
6269]
59376270
5938[[package]]6271[[package]]
5939name = "pallet-sudo"6272name = "pallet-sudo"
5971version = "3.0.0"6304version = "3.0.0"
5972source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"6305source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
5973dependencies = [6306dependencies = [
6307 "frame-benchmarking",
5974 "frame-support",6308 "frame-support",
5975 "frame-system",6309 "frame-system",
5976 "pallet-treasury",6310 "pallet-treasury",
6029version = "3.0.0"6363version = "3.0.0"
6030source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"6364source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
6031dependencies = [6365dependencies = [
6366 "frame-benchmarking",
6032 "frame-support",6367 "frame-support",
6033 "frame-system",6368 "frame-system",
6034 "impl-trait-for-tuples",6369 "impl-trait-for-tuples",
6044version = "3.0.0"6379version = "3.0.0"
6045source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"6380source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
6046dependencies = [6381dependencies = [
6382 "frame-benchmarking",
6047 "frame-support",6383 "frame-support",
6048 "frame-system",6384 "frame-system",
6049 "parity-scale-codec",6385 "parity-scale-codec",
6059source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"6395source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
6060dependencies = [6396dependencies = [
6061 "enumflags2",6397 "enumflags2",
6398 "frame-benchmarking",
6062 "frame-support",6399 "frame-support",
6063 "frame-system",6400 "frame-system",
6064 "parity-scale-codec",6401 "parity-scale-codec",
6074 "frame-support",6411 "frame-support",
6075 "frame-system",6412 "frame-system",
6076 "parity-scale-codec",6413 "parity-scale-codec",
6414 "serde",
6077 "sp-runtime",6415 "sp-runtime",
6078 "sp-std",6416 "sp-std",
6079 "xcm",6417 "xcm",
7149dependencies = [7487dependencies = [
7150 "beefy-primitives",7488 "beefy-primitives",
7151 "bitvec 0.20.4",7489 "bitvec 0.20.4",
7490 "frame-benchmarking",
7152 "frame-election-provider-support",7491 "frame-election-provider-support",
7153 "frame-executive",7492 "frame-executive",
7154 "frame-support",7493 "frame-support",
7155 "frame-system",7494 "frame-system",
7495 "frame-system-benchmarking",
7156 "frame-system-rpc-runtime-api",7496 "frame-system-rpc-runtime-api",
7157 "frame-try-runtime",7497 "frame-try-runtime",
7498 "hex-literal",
7158 "log",7499 "log",
7159 "max-encoded-len",7500 "max-encoded-len",
7160 "pallet-authority-discovery",7501 "pallet-authority-discovery",
7175 "pallet-multisig",7516 "pallet-multisig",
7176 "pallet-nicks",7517 "pallet-nicks",
7177 "pallet-offences",7518 "pallet-offences",
7519 "pallet-offences-benchmarking",
7178 "pallet-proxy",7520 "pallet-proxy",
7179 "pallet-scheduler 3.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",7521 "pallet-scheduler 3.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
7180 "pallet-session",7522 "pallet-session",
7523 "pallet-session-benchmarking",
7181 "pallet-staking",7524 "pallet-staking",
7182 "pallet-staking-reward-curve",7525 "pallet-staking-reward-curve",
7183 "pallet-timestamp",7526 "pallet-timestamp",
7220dependencies = [7563dependencies = [
7221 "beefy-primitives",7564 "beefy-primitives",
7222 "bitvec 0.20.4",7565 "bitvec 0.20.4",
7566 "frame-benchmarking",
7223 "frame-support",7567 "frame-support",
7224 "frame-system",7568 "frame-system",
7225 "impl-trait-for-tuples",7569 "impl-trait-for-tuples",
7226 "libsecp256k1 0.3.5",7570 "libsecp256k1 0.3.5",
7227 "log",7571 "log",
7228 "pallet-authorship",7572 "pallet-authorship",
7573 "pallet-babe",
7229 "pallet-balances",7574 "pallet-balances",
7230 "pallet-beefy",7575 "pallet-beefy",
7231 "pallet-election-provider-multi-phase",7576 "pallet-election-provider-multi-phase",
7263dependencies = [7608dependencies = [
7264 "bitvec 0.20.4",7609 "bitvec 0.20.4",
7265 "derive_more",7610 "derive_more",
7611 "frame-benchmarking",
7266 "frame-support",7612 "frame-support",
7267 "frame-system",7613 "frame-system",
7614 "libsecp256k1 0.3.5",
7268 "log",7615 "log",
7269 "pallet-authority-discovery",7616 "pallet-authority-discovery",
7270 "pallet-authorship",7617 "pallet-authorship",
7304 "frame-system-rpc-runtime-api",7651 "frame-system-rpc-runtime-api",
7305 "futures 0.3.16",7652 "futures 0.3.16",
7306 "hex-literal",7653 "hex-literal",
7654 "kusama-runtime",
7307 "kvdb",7655 "kvdb",
7308 "kvdb-rocksdb",7656 "kvdb-rocksdb",
7309 "pallet-babe",7657 "pallet-babe",
7339 "polkadot-runtime",7687 "polkadot-runtime",
7340 "polkadot-runtime-parachains",7688 "polkadot-runtime-parachains",
7341 "polkadot-statement-distribution",7689 "polkadot-statement-distribution",
7690 "rococo-runtime",
7342 "sc-authority-discovery",7691 "sc-authority-discovery",
7343 "sc-basic-authorship",7692 "sc-basic-authorship",
7344 "sc-block-builder",7693 "sc-block-builder",
7380 "substrate-prometheus-endpoint",7729 "substrate-prometheus-endpoint",
7381 "thiserror",7730 "thiserror",
7382 "tracing",7731 "tracing",
7732 "westend-runtime",
7383]7733]
73847734
7385[[package]]7735[[package]]
8143 "librocksdb-sys",8493 "librocksdb-sys",
8144]8494]
8495
8496[[package]]
8497name = "rococo-runtime"
8498version = "0.9.8"
8499source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
8500dependencies = [
8501 "beefy-primitives",
8502 "bp-rococo",
8503 "bp-wococo",
8504 "frame-executive",
8505 "frame-support",
8506 "frame-system",
8507 "frame-system-rpc-runtime-api",
8508 "hex-literal",
8509 "log",
8510 "max-encoded-len",
8511 "pallet-authority-discovery",
8512 "pallet-authorship",
8513 "pallet-babe",
8514 "pallet-balances",
8515 "pallet-beefy",
8516 "pallet-bridge-grandpa",
8517 "pallet-collective",
8518 "pallet-grandpa",
8519 "pallet-im-online",
8520 "pallet-indices",
8521 "pallet-membership",
8522 "pallet-mmr",
8523 "pallet-mmr-primitives",
8524 "pallet-offences",
8525 "pallet-proxy",
8526 "pallet-session",
8527 "pallet-staking",
8528 "pallet-staking-reward-curve",
8529 "pallet-sudo",
8530 "pallet-timestamp",
8531 "pallet-transaction-payment",
8532 "pallet-transaction-payment-rpc-runtime-api",
8533 "pallet-utility",
8534 "pallet-xcm",
8535 "parity-scale-codec",
8536 "polkadot-parachain",
8537 "polkadot-primitives",
8538 "polkadot-runtime-common",
8539 "polkadot-runtime-parachains",
8540 "serde",
8541 "serde_derive",
8542 "smallvec 1.6.1",
8543 "sp-api",
8544 "sp-authority-discovery",
8545 "sp-block-builder",
8546 "sp-consensus-babe",
8547 "sp-core",
8548 "sp-inherents",
8549 "sp-io",
8550 "sp-offchain",
8551 "sp-runtime",
8552 "sp-session",
8553 "sp-staking",
8554 "sp-std",
8555 "sp-transaction-pool",
8556 "sp-version",
8557 "substrate-wasm-builder 4.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
8558 "xcm",
8559 "xcm-builder",
8560 "xcm-executor",
8561]
81458562
8146[[package]]8563[[package]]
8147name = "rpassword"8564name = "rpassword"
12043 "cc",12460 "cc",
12044]12461]
12462
12463[[package]]
12464name = "westend-runtime"
12465version = "0.9.8"
12466source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
12467dependencies = [
12468 "beefy-primitives",
12469 "bitvec 0.20.4",
12470 "frame-benchmarking",
12471 "frame-election-provider-support",
12472 "frame-executive",
12473 "frame-support",
12474 "frame-system",
12475 "frame-system-benchmarking",
12476 "frame-system-rpc-runtime-api",
12477 "frame-try-runtime",
12478 "hex-literal",
12479 "log",
12480 "max-encoded-len",
12481 "pallet-authority-discovery",
12482 "pallet-authorship",
12483 "pallet-babe",
12484 "pallet-balances",
12485 "pallet-collective",
12486 "pallet-democracy",
12487 "pallet-election-provider-multi-phase",
12488 "pallet-elections-phragmen",
12489 "pallet-grandpa",
12490 "pallet-identity",
12491 "pallet-im-online",
12492 "pallet-indices",
12493 "pallet-membership",
12494 "pallet-mmr-primitives",
12495 "pallet-multisig",
12496 "pallet-nicks",
12497 "pallet-offences",
12498 "pallet-offences-benchmarking",
12499 "pallet-proxy",
12500 "pallet-recovery",
12501 "pallet-scheduler 3.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
12502 "pallet-session",
12503 "pallet-session-benchmarking",
12504 "pallet-society",
12505 "pallet-staking",
12506 "pallet-staking-reward-curve",
12507 "pallet-sudo",
12508 "pallet-timestamp",
12509 "pallet-transaction-payment",
12510 "pallet-transaction-payment-rpc-runtime-api",
12511 "pallet-treasury",
12512 "pallet-utility",
12513 "pallet-vesting",
12514 "pallet-xcm",
12515 "parity-scale-codec",
12516 "polkadot-parachain",
12517 "polkadot-primitives",
12518 "polkadot-runtime-common",
12519 "polkadot-runtime-parachains",
12520 "rustc-hex",
12521 "serde",
12522 "serde_derive",
12523 "smallvec 1.6.1",
12524 "sp-api",
12525 "sp-authority-discovery",
12526 "sp-block-builder",
12527 "sp-consensus-babe",
12528 "sp-core",
12529 "sp-inherents",
12530 "sp-io",
12531 "sp-npos-elections",
12532 "sp-offchain",
12533 "sp-runtime",
12534 "sp-session",
12535 "sp-staking",
12536 "sp-std",
12537 "sp-transaction-pool",
12538 "sp-version",
12539 "static_assertions",
12540 "substrate-wasm-builder 4.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
12541 "xcm",
12542 "xcm-builder",
12543 "xcm-executor",
12544]
1204512545
12046[[package]]12546[[package]]
12047name = "which"12547name = "which"
modifiedMakefilediffbeforeafterboth
--- a/Makefile
+++ b/Makefile
@@ -22,3 +22,18 @@
 	INPUT=$< OUTPUT=$@ ./.maintain/scripts/compile_stub.sh
 
 evm_stubs: $(NFT_EVM_STUBS)/UniqueFungible.raw $(NFT_EVM_STUBS)/UniqueNFT.raw $(CONTRACT_HELPERS_STUBS)/ContractHelpers.raw
+
+.PHONY: _bench
+_bench:
+	cargo run --release --features runtime-benchmarks -- \
+	benchmark --pallet pallet-$(PALLET) \
+	--wasm-execution compiled --extrinsic '*' \
+	--template .maintain/frame-weight-template.hbs --steps=50 --repeat=20 \
+	--output=./pallets/$(PALLET)/src/weights.rs
+
+.PHONY: bench-evm-migration
+bench-evm-migration:
+	make _bench PALLET=evm-migration
+
+.PHONY: bench
+bench: bench-evm-migration
modifiedcrates/evm-coder/tests/a.rsdiffbeforeafterboth
--- a/crates/evm-coder/tests/a.rs
+++ b/crates/evm-coder/tests/a.rs
@@ -2,6 +2,7 @@
 
 use evm_coder::{solidity_interface, types::*, ToLog, execution::Result};
 use evm_coder_macros::solidity;
+use std as sp_std;
 
 struct Impls;
 
modifiednode/cli/Cargo.tomldiffbeforeafterboth
--- a/node/cli/Cargo.toml
+++ b/node/cli/Cargo.toml
@@ -317,4 +317,7 @@
 
 [features]
 default = []
-runtime-benchmarks = ['nft-runtime/runtime-benchmarks']
+runtime-benchmarks = [
+    'nft-runtime/runtime-benchmarks',
+    'polkadot-service/runtime-benchmarks',
+]
addedpallets/evm-migration/Cargo.tomldiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-migration/Cargo.toml
@@ -0,0 +1,36 @@
+[package]
+name = "pallet-evm-migration"
+version = "0.1.0"
+edition = "2018"
+
+[dependencies]
+frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+frame-benchmarking = { default-features = false, version = '3.0.0', optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-io = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-core = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+pallet-evm = { default-features = false, version = "5.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+fp-evm = { default-features = false, version = "2.0.0", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+
+[dependencies.codec]
+default-features = false
+features = ['derive']
+package = 'parity-scale-codec'
+version = '2.0.0'
+
+[features]
+default = ["std", "runtime-benchmarks"]
+std = [
+    "frame-support/std",
+    "frame-system/std",
+    "frame-benchmarking/std",
+    "sp-runtime/std",
+    "sp-std/std",
+    "sp-io/std",
+    "sp-core/std",
+    "pallet-evm/std",
+    "fp-evm/std",
+]
+runtime-benchmarks = ["frame-benchmarking"]
addedpallets/evm-migration/src/benchmarking.rsdiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-migration/src/benchmarking.rs
@@ -0,0 +1,30 @@
+use super::{Call, Config, Pallet};
+use frame_benchmarking::benchmarks;
+use frame_system::RawOrigin;
+use sp_core::{H160, H256};
+use sp_std::vec::Vec;
+
+benchmarks! {
+	begin {
+	}: _(RawOrigin::Root, H160::default())
+
+	set_data {
+		let b in 0..80;
+		let address = H160::from_low_u64_be(b as u64);
+		let mut data = Vec::new();
+		for i in 0..b {
+			data.push((
+				H256::from_low_u64_be(i as u64),
+				H256::from_low_u64_be(i as u64),
+			));
+		}
+		<Pallet<T>>::begin(RawOrigin::Root.into(), address)?;
+	}: _(RawOrigin::Root, address, data)
+
+	finish {
+		let b in 0..80;
+		let address = H160::from_low_u64_be(b as u64);
+		let data: Vec<u8> = (0..b as u8).collect();
+		<Pallet<T>>::begin(RawOrigin::Root.into(), address)?;
+	}: _(RawOrigin::Root, address, data)
+}
addedpallets/evm-migration/src/lib.rsdiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-migration/src/lib.rs
@@ -0,0 +1,111 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+
+pub use pallet::*;
+#[cfg(feature = "runtime-benchmarks")]
+pub mod benchmarking;
+pub mod weights;
+
+#[frame_support::pallet]
+pub mod pallet {
+	use frame_support::{pallet_prelude::*, transactional};
+	use frame_system::pallet_prelude::*;
+	use sp_core::{H160, H256};
+	use sp_std::vec::Vec;
+	use super::weights::WeightInfo;
+
+	#[pallet::config]
+	pub trait Config: frame_system::Config + pallet_evm::Config {
+		type WeightInfo: WeightInfo;
+	}
+
+	type SelfWeightOf<T> = <T as Config>::WeightInfo;
+
+	#[pallet::pallet]
+	#[pallet::generate_store(pub(super) trait Store)]
+	pub struct Pallet<T>(_);
+
+	#[pallet::error]
+	pub enum Error<T> {
+		AccountNotEmpty,
+		AccountIsNotMigrating,
+	}
+
+	#[pallet::storage]
+	pub(super) type MigrationPending<T: Config> =
+		StorageMap<Hasher = Twox64Concat, Key = H160, Value = bool, QueryKind = ValueQuery>;
+
+	#[pallet::call]
+	impl<T: Config> Pallet<T> {
+		#[pallet::weight(<SelfWeightOf<T>>::begin())]
+		pub fn begin(origin: OriginFor<T>, address: H160) -> DispatchResult {
+			ensure_root(origin)?;
+			ensure!(
+				<pallet_evm::Pallet<T>>::is_account_empty(&address)
+					&& !<MigrationPending<T>>::get(&address),
+				<Error<T>>::AccountNotEmpty,
+			);
+
+			<MigrationPending<T>>::insert(address, true);
+			Ok(())
+		}
+
+		#[pallet::weight(<SelfWeightOf<T>>::set_data(data.len() as u32))]
+		pub fn set_data(
+			origin: OriginFor<T>,
+			address: H160,
+			data: Vec<(H256, H256)>,
+		) -> DispatchResult {
+			use frame_support::StorageDoubleMap;
+			ensure_root(origin)?;
+			ensure!(
+				<MigrationPending<T>>::get(&address),
+				<Error<T>>::AccountIsNotMigrating,
+			);
+
+			for (k, v) in data {
+				pallet_evm::AccountStorages::insert(&address, k, v);
+			}
+			Ok(())
+		}
+
+		#[pallet::weight(<SelfWeightOf<T>>::finish(code.len() as u32))]
+		#[transactional]
+		pub fn finish(origin: OriginFor<T>, address: H160, code: Vec<u8>) -> DispatchResult {
+			use frame_support::StorageMap;
+			ensure_root(origin)?;
+			ensure!(
+				<MigrationPending<T>>::get(&address),
+				<Error<T>>::AccountIsNotMigrating,
+			);
+
+			pallet_evm::AccountCodes::insert(&address, code);
+			<MigrationPending<T>>::remove(address);
+			Ok(())
+		}
+	}
+
+	pub struct OnMethodCall<T>(PhantomData<T>);
+	impl<T: Config> pallet_evm::OnMethodCall<T> for OnMethodCall<T> {
+		fn is_reserved(contract: &H160) -> bool {
+			<MigrationPending<T>>::get(&contract)
+		}
+
+		fn is_used(_contract: &H160) -> bool {
+			false
+		}
+
+		fn call(
+			_source: &H160,
+			_arget: &H160,
+			_gas_left: u64,
+			_input: &[u8],
+			_value: sp_core::U256,
+		) -> Option<pallet_evm::PrecompileOutput> {
+			None
+		}
+
+		fn get_code(_contract: &H160) -> Option<Vec<u8>> {
+			None
+		}
+	}
+}
addedpallets/evm-migration/src/weights.rsdiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-migration/src/weights.rs
@@ -0,0 +1,80 @@
+// Template adopted from https://github.com/paritytech/substrate/blob/master/.maintain/frame-weight-template.hbs
+
+//! Autogenerated weights for pallet_evm_migration
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
+//! DATE: 2021-08-12, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 128
+
+// Executed Command:
+// target/release/nft
+// benchmark
+// --pallet
+// pallet-evm-migration
+// --wasm-execution
+// compiled
+// --extrinsic
+// *
+// --template
+// .maintain/frame-weight-template.hbs
+// --steps=50
+// --repeat=20
+// --output=./pallets/evm-migration/src/weights.rs
+
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+
+use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
+use sp_std::marker::PhantomData;
+
+/// Weight functions needed for pallet_evm_migration.
+pub trait WeightInfo {
+	fn begin() -> Weight;
+	fn set_data(b: u32, ) -> Weight;
+	fn finish(b: u32, ) -> Weight;
+}
+
+/// Weights for pallet_evm_migration using the Substrate node and recommended hardware.
+pub struct SubstrateWeight<T>(PhantomData<T>);
+impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
+	fn begin() -> Weight {
+		(6_210_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(3 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn set_data(b: u32, ) -> Weight {
+		(2_926_000 as Weight)
+			// Standard Error: 4_000
+			.saturating_add((649_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(b as Weight)))
+	}
+	fn finish(_b: u32, ) -> Weight {
+		(4_309_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes(2 as Weight))
+	}
+}
+
+// For backwards compatibility and tests
+impl WeightInfo for () {
+	fn begin() -> Weight {
+		(6_210_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(3 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn set_data(b: u32, ) -> Weight {
+		(2_926_000 as Weight)
+			// Standard Error: 4_000
+			.saturating_add((649_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(b as Weight)))
+	}
+	fn finish(_b: u32, ) -> Weight {
+		(4_309_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(2 as Weight))
+	}
+}
\ No newline at end of file
deletedpallets/nft-transaction-payment/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/nft-transaction-payment/src/benchmarking.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#![cfg(feature = "runtime-benchmarks")]
-
-use super::*;
-
-use sp_std::prelude::*;
-use frame_system::RawOrigin;
-use frame_benchmarking::{benchmarks};
-use frame_support::traits::OnInitialize;
-
-benchmarks! {
-
-	// on_initialize {
-		// let block1: T::BlockNumber = T::BlockNumber::from(1u32);
-		// let block2: T::BlockNumber = T::BlockNumber::from(2u32);
-		// Inflation::<T>::on_initialize(block1); // Create Treasury account
-	// }: { Inflation::<T>::on_initialize(block2); } // Benchmark deposit_into_existing path
-
-}
modifiedpallets/nft-transaction-payment/src/lib.rsdiffbeforeafterboth
--- a/pallets/nft-transaction-payment/src/lib.rs
+++ b/pallets/nft-transaction-payment/src/lib.rs
@@ -11,9 +11,6 @@
 #[cfg(feature = "std")]
 pub use serde::*;
 
-#[cfg(feature = "runtime-benchmarks")]
-mod benchmarking;
-
 use frame_support::{decl_module, decl_storage};
 use sp_std::prelude::*;
 use up_sponsorship::SponsorshipHandler;
modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -1399,6 +1399,11 @@
 		item_id: TokenId,
 		amount: u128,
 	) -> DispatchResult {
+		if sender == from {
+			// Transfer by `from`, because it is either equal to sender, or derived from him
+			return Self::transfer_internal(from, recipient, collection, item_id, amount);
+		}
+
 		// Check approval
 		collection.consume_sload()?;
 		let approval: u128 =
modifiedpallets/nft/src/mock.rsdiffbeforeafterboth
--- a/pallets/nft/src/mock.rs
+++ b/pallets/nft/src/mock.rs
@@ -129,8 +129,11 @@
 	fn as_sub(&self) -> &u64 {
 		&self.0
 	}
-	fn from_eth(_eth: sp_core::H160) -> Self {
-		unimplemented!()
+	fn from_eth(eth: sp_core::H160) -> Self {
+		let mut sub_raw = [0; 8];
+		sub_raw.copy_from_slice(&eth.0[0..8]);
+		let sub = u64::from_be_bytes(sub_raw);
+		Self(sub, eth)
 	}
 	fn as_eth(&self) -> &sp_core::H160 {
 		&self.1
modifiedruntime/Cargo.tomldiffbeforeafterboth
--- a/runtime/Cargo.toml
+++ b/runtime/Cargo.toml
@@ -23,11 +23,14 @@
     'frame-support/runtime-benchmarks',
     'frame-system-benchmarking',
     'frame-system/runtime-benchmarks',
+    'pallet-evm-migration/runtime-benchmarks',
     'pallet-balances/runtime-benchmarks',
     'pallet-timestamp/runtime-benchmarks',
     'pallet-nft/runtime-benchmarks',
     'pallet-inflation/runtime-benchmarks',
+    'pallet-xcm/runtime-benchmarks',
     'sp-runtime/runtime-benchmarks',
+    'xcm-builder/runtime-benchmarks',
 ]
 std = [
     'codec/std',
@@ -56,6 +59,7 @@
     'pallet-treasury/std',
     'pallet-vesting/std',
     'pallet-evm/std',
+    'pallet-evm-migration/std',
     'pallet-evm-contract-helpers/std',
     'pallet-evm-transaction-payment/std',
     'pallet-evm-coder-substrate/std',
@@ -392,6 +396,7 @@
 # pallet-contract-helpers = { path = '../pallets/contract-helpers', default-features = false, version = '0.1.0' }
 pallet-nft-transaction-payment = { path = '../pallets/nft-transaction-payment', default-features = false, version = '3.0.0' }
 pallet-nft-charge-transaction = { path = '../pallets/nft-charge-transaction', default-features = false, version = '3.0.0' }
+pallet-evm-migration = { path = '../pallets/evm-migration', default-features = false }
 pallet-evm-contract-helpers = { path = '../pallets/evm-contract-helpers', default-features = false }
 pallet-evm-transaction-payment = { path = '../pallets/evm-transaction-payment', default-features = false }
 pallet-evm-coder-substrate = { default-features = false, path = "../pallets/evm-coder-substrate" }
modifiedruntime/src/lib.rsdiffbeforeafterboth
--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -252,6 +252,7 @@
 	type Currency = Balances;
 	type Event = Event;
 	type OnMethodCall = (
+		pallet_evm_migration::OnMethodCall<Self>,
 		pallet_nft::NftErcSupport<Self>,
 		pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,
 	);
@@ -263,6 +264,10 @@
 	type FindAuthor = EthereumFindAuthor<Aura>;
 }
 
+impl pallet_evm_migration::Config for Runtime {
+	type WeightInfo = pallet_evm_migration::weights::SubstrateWeight<Self>;
+}
+
 pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);
 impl<F: FindAuthor<u32>> FindAuthor<H160> for EthereumFindAuthor<F> {
 	fn find_author<'a, I>(digests: I) -> Option<H160>
@@ -819,6 +824,7 @@
 		EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150,
 		EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,
 		EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,
+		EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,
 	}
 );
 
@@ -1180,6 +1186,7 @@
 			let mut batches = Vec::<BenchmarkBatch>::new();
 			let params = (&config, &whitelist);
 
+			add_benchmark!(params, batches, pallet_evm_migration, EvmMigration);
 			add_benchmark!(params, batches, pallet_nft, Nft);
 			add_benchmark!(params, batches, pallet_inflation, Inflation);
 
modifiedtests/package.jsondiffbeforeafterboth
--- a/tests/package.json
+++ b/tests/package.json
@@ -24,8 +24,8 @@
     "lint": "eslint --ext .ts,.js src/",
     "fix": "eslint --ext .ts,.js src/ --fix",
     "test": "mocha --timeout 9999999 -r ts-node/register './**/*.test.ts'",
-    "testEth": "mocha --timeout 9999999 -r ts-node/register ./**/eth/**/*.test.ts",
-    "load": "mocha --timeout 9999999 -r ts-node/register ./**/*.load.ts",
+    "testEth": "mocha --timeout 9999999 -r ts-node/register './**/eth/**/*.test.ts'",
+    "load": "mocha --timeout 9999999 -r ts-node/register './**/*.load.ts'",
     "loadTransfer": "ts-node src/transfer.nload.ts",
     "testCollision": "mocha --timeout 9999999 -r ts-node/register ./src/collision-tests/*.test.ts",
     "testAddCollectionAdmin": "mocha --timeout 9999999 -r ts-node/register ./**/addCollectionAdmin.test.ts",
@@ -85,4 +85,4 @@
       "artifacts"
     ]
   }
-}
\ No newline at end of file
+}
addedtests/src/eth/marketplace/MarketPlaceKSM.abidiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/marketplace/MarketPlaceKSM.abi
@@ -0,0 +1 @@
+[{"inputs":[{"internalType":"address","name":"_escrow","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"asks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"asksbySeller","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"balanceKSM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_idCollection","type":"address"},{"internalType":"uint256","name":"_idNFT","type":"uint256"}],"name":"buy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_currencyCode","type":"uint256"},{"internalType":"address","name":"_sender","type":"address"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_currencyCode","type":"uint256"},{"internalType":"address","name":"_sender","type":"address"}],"name":"escrowBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"offers","outputs":[{"internalType":"uint256","name":"idNFT","type":"uint256"},{"internalType":"uint256","name":"currencyCode","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"time","type":"uint256"},{"internalType":"address","name":"idCollection","type":"address"},{"internalType":"address","name":"userAddr","type":"address"},{"internalType":"uint8","name":"flagActive","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_currencyCode","type":"uint256"},{"internalType":"address","name":"_idCollection","type":"address"},{"internalType":"uint256","name":"_idNFT","type":"uint256"},{"internalType":"uint8","name":"_active","type":"uint8"}],"name":"setAsk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newEscrow","type":"address"}],"name":"setEscrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newEscrow","type":"address"}],"name":"setowner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_currencyCode","type":"uint256"},{"internalType":"address","name":"_sender","type":"address"}],"name":"withdraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
\ No newline at end of file
addedtests/src/eth/marketplace/MarketPlaceKSM.bindiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/marketplace/MarketPlaceKSM.bin
@@ -0,0 +1 @@
+608060405234801561001057600080fd5b50604051610e27380380610e2783398101604081905261002f9161005d565b600480546001600160a01b039092166001600160a01b0319928316179055600580549091163317905561008d565b60006020828403121561006f57600080fd5b81516001600160a01b038116811461008657600080fd5b9392505050565b610d8b8061009c6000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c806399f2d4eb1161007157806399f2d4eb1461018e5780639df55f52146101a1578063c10c35461461010f578063cce7ec13146101b4578063db87db52146101c7578063e22d4f7d146101fa57600080fd5b80630ad58d2f146100ae57806310a5ff17146100d6578063592bd7051461010f5780638a72ea6a146101245780638dbdbe6d1461017b575b600080fd5b6100c16100bc366004610c4d565b610225565b60405190151581526020015b60405180910390f35b6101016100e4366004610bd8565b600160209081526000928352604080842090915290825290205481565b6040519081526020016100cd565b61012261011d366004610b97565b6102d8565b005b610137610132366004610c04565b610345565b6040805197885260208801969096529486019390935260608501919091526001600160a01b0390811660808501521660a083015260ff1660c082015260e0016100cd565b610122610189366004610c4d565b6103a4565b61010161019c366004610bd8565b610449565b6101226101af366004610c86565b61047a565b6101226101c2366004610bd8565b610984565b6101016101d5366004610c1d565b6001600160a01b03166000908152600160209081526040808320938352929052205490565b610101610208366004610bd8565b600260209081526000928352604080842090915290825290205481565b6004546000906001600160a01b031633146102795760405162461bcd60e51b815260206004820152600f60248201526e27b7363c9032b9b1b937bb9031b0b760891b60448201526064015b60405180910390fd5b6001600160a01b03821660009081526001602090815260408083208684529091529020546102a8908590610cfa565b6001600160a01b039290921660009081526001602081815260408084209684529590529390209190915550919050565b6005546001600160a01b031633146103235760405162461bcd60e51b815260206004820152600e60248201526d27b7363c9037bbb732b91031b0b760911b6044820152606401610270565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6000818154811061035557600080fd5b6000918252602090912060069091020180546001820154600283015460038401546004850154600590950154939550919390926001600160a01b0391821691811690600160a01b900460ff1687565b6004546001600160a01b031633146103f05760405162461bcd60e51b815260206004820152600f60248201526e27b7363c9032b9b1b937bb9031b0b760891b6044820152606401610270565b6001600160a01b038116600090815260016020908152604080832085845290915290205461041f908490610ce2565b6001600160a01b039091166000908152600160209081526040808320948352939052919091205550565b6003602052816000526040600020818154811061046557600080fd5b90600052602060002001600091509150505481565b6040516331a9108f60e11b81526004810183905233906001600160a01b03851690636352211e9060240160206040518083038186803b1580156104bc57600080fd5b505afa1580156104d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f49190610bbb565b6001600160a01b0316146105425760405162461bcd60e51b81526020600482015260156024820152742737ba103934b3b43a103a37b5b2b71037bbb732b960591b6044820152606401610270565b6001600160a01b0383166000908152600260209081526040808320858452909152812054905415806105ac575060006001600160a01b03166000828154811061058d5761058d610d27565b60009182526020909120600460069092020101546001600160a01b0316145b15610793576040805160e0810182528481526020810187815291810188815242606083019081526001600160a01b03808916608085019081523360a0860190815260ff808a1660c088019081526000805460018181018355828052995160069091027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56381019190915599517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5648b015596517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5658a015594517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56689015591517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e567880180549185166001600160a01b0319909216919091179055517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56890960180549351909116600160a01b026001600160a81b031990931695909116949094171790925590546107399190610cfa565b6001600160a01b038516600090815260026020908152604080832087845282528083209390935533825260039052908120905461077890600190610cfa565b81546001810183556000928352602090922090910155610916565b6040805160e0810182526001600160a01b03861660009081526002602090815283822087835290529182205482549192839290919081106107d6576107d6610d27565b60009182526020808320600690920290910154835282810189905260408084018b90524260608501526001600160a01b0389168352600282528083208884529091528120548154608090930192811061083157610831610d27565b60009182526020808320600460069093020191909101546001600160a01b039081168452338483015260ff871660409485015288168252600281528282208783529052908120548154811061088857610888610d27565b60009182526020918290208351600690920201908155908201516001820155604082015160028201556060820151600382015560808201516004820180546001600160a01b039283166001600160a01b031990911617905560a08301516005909201805460c09094015160ff16600160a01b026001600160a81b031990941692909116919091179190911790555b6040516323b872dd60e01b8152336004820152306024820152604481018490526001600160a01b038516906323b872dd90606401600060405180830381600087803b15801561096457600080fd5b505af1158015610978573d6000803e3d6000fd5b50505050505050505050565b6001600160a01b0382166000908152600260209081526040808320848452909152812054815482919081106109bb576109bb610d27565b600091825260208083206040805160e0810182526006949094029091018054845260018082015485850190815260028301548685018190526003840154606088015260048401546001600160a01b03908116608089015260059094015493841660a0880152600160a01b90930460ff1660c08701523387529084528286209051865290925290922054909250610a519190610cfa565b33600090815260016020818152604080842086830180518652908352818520959095558581015160a08701516001600160a01b031685529282528084209451845293905291902054610aa39190610ce2565b60a08201516001600160a01b0390811660009081526001602090815260408083208287015184528252808320949094559186168152600282528281208582529091529081205481548291908110610afc57610afc610d27565b60009182526020909120600560069092020101805460ff92909216600160a01b0260ff60a01b199092169190911790556040516323b872dd60e01b8152306004820152336024820152604481018390526001600160a01b038416906323b872dd90606401600060405180830381600087803b158015610b7a57600080fd5b505af1158015610b8e573d6000803e3d6000fd5b50505050505050565b600060208284031215610ba957600080fd5b8135610bb481610d3d565b9392505050565b600060208284031215610bcd57600080fd5b8151610bb481610d3d565b60008060408385031215610beb57600080fd5b8235610bf681610d3d565b946020939093013593505050565b600060208284031215610c1657600080fd5b5035919050565b60008060408385031215610c3057600080fd5b823591506020830135610c4281610d3d565b809150509250929050565b600080600060608486031215610c6257600080fd5b83359250602084013591506040840135610c7b81610d3d565b809150509250925092565b600080600080600060a08688031215610c9e57600080fd5b85359450602086013593506040860135610cb781610d3d565b925060608601359150608086013560ff81168114610cd457600080fd5b809150509295509295909350565b60008219821115610cf557610cf5610d11565b500190565b600082821015610d0c57610d0c610d11565b500390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0381168114610d5257600080fd5b5056fea2646970667358221220d098ae4e0cc7bdbb7de1061c03402a667836f903122c1c606ca2c65db1ab78e964736f6c63430008070033
\ No newline at end of file
addedtests/src/eth/marketplace/MarketPlaceKSM.soldiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/marketplace/MarketPlaceKSM.sol
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier:  Apache License
+pragma solidity >=0.8.0;
+
+interface IERC721 {
+    event Transfer(
+        address indexed from,
+        address indexed to,
+        uint256 indexed tokenId
+    );
+    event Approval(
+        address indexed owner,
+        address indexed approved,
+        uint256 indexed tokenId
+    );
+
+    function ownerOf(uint256 tokenId) external view returns (address owner);
+
+    function transferFrom(
+        address from,
+        address to,
+        uint256 tokenId
+    ) external;
+
+    function debug(string memory value) external;
+}
+
+interface IERC20 {
+    event Transfer(address indexed from, address indexed to, uint256 value);
+    event Approval(
+        address indexed owner,
+        address indexed spender,
+        uint256 value
+    );
+
+    function transfer(address recipient, uint256 amount)
+        external
+        returns (bool);
+
+    function transferFrom(
+        address sender,
+        address recipient,
+        uint256 amount
+    ) external returns (bool);
+}
+
+contract MarketPlaceKSM {
+    struct Offer {
+        uint256 idNFT;
+        uint256 currencyCode;
+        uint256 price;
+        uint256 time;
+        address idCollection;
+        address userAddr;
+        uint8 flagActive;
+    }
+    Offer[] public offers;
+
+    mapping(address => mapping(uint256 => uint256)) public balanceKSM; //  [userAddr] => [KSMs]
+    mapping(address => mapping(uint256 => uint256)) public asks; // [buyer][idCollection][idNFT] => idOffer
+
+    mapping(address => uint256[]) public asksbySeller; // [addressSeller] =>idOffer
+
+    address escrow;
+    address owner;
+
+    constructor(address _escrow) {
+        escrow = _escrow;
+        owner = msg.sender;
+    }
+
+    function setowner(address _newEscrow) public onlyOwner {
+        escrow = _newEscrow;
+    }
+
+    function setEscrow(address _newEscrow) public onlyOwner {
+        escrow = _newEscrow;
+    }
+
+    modifier onlyEscrow() {
+        require(msg.sender == escrow, "Only escrow can");
+        _;
+    }
+
+    modifier onlyOwner() {
+        require(msg.sender == owner, "Only owner can");
+        _;
+    }
+
+    /**
+     * Make bids (offers) to sell NFTs
+     */
+    function setAsk(
+        uint256 _price,
+        uint256 _currencyCode,
+        address _idCollection,
+        uint256 _idNFT,
+        uint8 _active
+    ) public {
+        require(
+            IERC721(_idCollection).ownerOf(_idNFT) == msg.sender,
+            "Not right token owner"
+        );
+        uint256 offerID = asks[_idCollection][_idNFT];
+        if (offers.length == 0 || offers[offerID].idCollection == address(0)) {
+            offers.push(
+                Offer(
+                    _idNFT,
+                    _currencyCode,
+                    _price,
+                    block.timestamp,
+                    _idCollection,
+                    msg.sender,
+                    _active
+                )
+            );
+            asks[_idCollection][_idNFT] = offers.length - 1;
+            asksbySeller[msg.sender].push(offers.length - 1);
+        }
+        //edit existing offer
+        else {
+            offers[asks[_idCollection][_idNFT]] = Offer(
+                offers[asks[_idCollection][_idNFT]].idNFT,
+                _currencyCode,
+                _price,
+                block.timestamp,
+                offers[asks[_idCollection][_idNFT]].idCollection,
+                msg.sender,
+                _active
+            );
+        }
+
+        IERC721(_idCollection).transferFrom(msg.sender, address(this), _idNFT);
+    }
+
+    function deposit(
+        uint256 _amount,
+        uint256 _currencyCode,
+        address _sender
+    ) public onlyEscrow {
+        balanceKSM[_sender][_currencyCode] =
+            balanceKSM[_sender][_currencyCode] +
+            _amount;
+    }
+
+    function buy(address _idCollection, uint256 _idNFT) public {
+        Offer memory offer = offers[asks[_idCollection][_idNFT]];
+        // 1. reduce balance
+        balanceKSM[msg.sender][offer.currencyCode] =
+            balanceKSM[msg.sender][offer.currencyCode] -
+            offer.price;
+        // 2. increase balance
+        balanceKSM[offer.userAddr][offer.currencyCode] =
+            balanceKSM[offer.userAddr][offer.currencyCode] +
+            offer.price;
+        // 3. close offer
+        offers[asks[_idCollection][_idNFT]].flagActive = 0;
+        // 4. transfer NFT to buyer
+        IERC721(_idCollection).transferFrom(address(this), msg.sender, _idNFT);
+    }
+
+    function withdraw(
+        uint256 _amount,
+        uint256 _currencyCode,
+        address _sender
+    ) public onlyEscrow returns (bool) {
+        balanceKSM[_sender][_currencyCode] =
+            balanceKSM[_sender][_currencyCode] -
+            _amount;
+        return true;
+    }
+
+    function escrowBalance(uint256 _currencyCode, address _sender)
+        public
+        view
+        returns (uint256)
+    {
+        return balanceKSM[_sender][_currencyCode];
+    }
+}
addedtests/src/eth/marketplace/MarketPlaceUNQ.abidiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/marketplace/MarketPlaceUNQ.abi
@@ -0,0 +1 @@
+[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"asks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"asksbySeller","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_idCollection","type":"address"},{"internalType":"uint256","name":"_idNFT","type":"uint256"},{"internalType":"address","name":"_currencyCode","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"buy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_idCollection","type":"address"},{"internalType":"uint256","name":"_idNFT","type":"uint256"}],"name":"buy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"offers","outputs":[{"internalType":"uint256","name":"idNFT","type":"uint256"},{"internalType":"address","name":"currencyCode","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"time","type":"uint256"},{"internalType":"address","name":"idCollection","type":"address"},{"internalType":"address","name":"userAddr","type":"address"},{"internalType":"uint8","name":"flagActive","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"address","name":"_currencyCode","type":"address"},{"internalType":"address","name":"_idCollection","type":"address"},{"internalType":"uint256","name":"_idNFT","type":"uint256"},{"internalType":"uint8","name":"_active","type":"uint8"}],"name":"setAsk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"setowner","outputs":[],"stateMutability":"nonpayable","type":"function"}]
\ No newline at end of file
addedtests/src/eth/marketplace/MarketPlaceUNQ.bindiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/marketplace/MarketPlaceUNQ.bin
@@ -0,0 +1 @@
+608060405234801561001057600080fd5b50600380546001600160a01b03191633179055610f2d806100326000396000f3fe6080604052600436106100705760003560e01c806399f2d4eb1161004e57806399f2d4eb14610120578063b3ffb7601461014e578063cce7ec1314610161578063e22d4f7d1461017457600080fd5b8063592bd705146100755780637b1d6001146100975780638a72ea6a146100b7575b600080fd5b34801561008157600080fd5b50610095610090366004610d2b565b6101ac565b005b3480156100a357600080fd5b506100956100b2366004610e1b565b61021e565b3480156100c357600080fd5b506100d76100d2366004610e02565b61073d565b604080519788526001600160a01b03968716602089015287019490945260608601929092528316608085015290911660a083015260ff1660c082015260e0015b60405180910390f35b34801561012c57600080fd5b5061014061013b366004610d6c565b6107a0565b604051908152602001610117565b61009561015c366004610d98565b6107d1565b61009561016f366004610d6c565b610b0b565b34801561018057600080fd5b5061014061018f366004610d6c565b600160209081526000928352604080842090915290825290205481565b6003546001600160a01b031633146101fc5760405162461bcd60e51b815260206004820152600e60248201526d27b7363c9037bbb732b91031b0b760911b60448201526064015b60405180910390fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6040516331a9108f60e11b81526004810183905233906001600160a01b03851690636352211e9060240160206040518083038186803b15801561026057600080fd5b505afa158015610274573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102989190610d4f565b6001600160a01b0316146102e65760405162461bcd60e51b81526020600482015260156024820152742737ba103934b3b43a103a37b5b2b71037bbb732b960591b60448201526064016101f3565b6001600160a01b038316600090815260016020908152604080832085845290915281205490541580610350575060006001600160a01b03166000828154811061033157610331610ec9565b60009182526020909120600460069092020101546001600160a01b0316145b15610542576040805160e0810182528481526001600160a01b03878116602083019081529282018981524260608401908152888316608085019081523360a0860190815260ff89811660c08801908152600080546001808201835582805299517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56360069092029182015599517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5648b0180546001600160a01b0319908116928b1692909217905596517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5658b015594517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5668a015592517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5678901805490961690871617909455517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56890960180549151969094166001600160a81b031990911617600160a01b959092169490940217905590546104e99190610ea4565b6001600160a01b0385166000908152600160208181526040808420888552825280842094909455338352600290529181209054909161052791610ea4565b815460018101835560009283526020909220909101556106d3565b6040805160e0810182526001600160a01b038616600090815260016020908152838220878352905291822054825491928392909190811061058557610585610ec9565b6000918252602080832060069092029091015483526001600160a01b03808a168483015260408085018c9052426060860152908916835260018252808320888452909152812054815460809093019281106105e2576105e2610ec9565b60009182526020808320600460069093020191909101546001600160a01b039081168452338483015260ff871660409485015288168252600181528282208783529052908120548154811061063957610639610ec9565b60009182526020918290208351600690920201908155908201516001820180546001600160a01b039283166001600160a01b031991821617909155604084015160028401556060840151600384015560808401516004840180549184169190921617905560a08301516005909201805460c09094015160ff16600160a01b026001600160a81b031990941692909116919091179190911790555b6040516323b872dd60e01b81526001600160a01b038516906323b872dd9061070390339030908890600401610e80565b600060405180830381600087803b15801561071d57600080fd5b505af1158015610731573d6000803e3d6000fd5b50505050505050505050565b6000818154811061074d57600080fd5b60009182526020909120600690910201805460018201546002830154600384015460048501546005909501549395506001600160a01b03928316949193909291821691811690600160a01b900460ff1687565b600260205281600052604060002081815481106107bc57600080fd5b90600052602060002001600091509150505481565b6001600160a01b03841660009081526001602090815260408083208684529091528120548154829190811061080857610808610ec9565b60009182526020918290206040805160e0810182526006939093029091018054835260018101546001600160a01b03908116948401949094526002810154918301829052600381015460608401526004810154841660808401526005015492831660a0830152600160a01b90920460ff1660c08201529150821480156108a35750826001600160a01b031681602001516001600160a01b0316145b6109245760405162461bcd60e51b815260206004820152604660248201527f4e6f7420726967687420616d6f756e74206f722063757272656e63792073656e60448201527f742c206861766520746f20626520657175616c2063757272656e637920616e6460648201526520707269636560d01b608482015260a4016101f3565b80602001516001600160a01b03166323b872dd333084604001516040518463ffffffff1660e01b815260040161095c93929190610e80565b602060405180830381600087803b15801561097657600080fd5b505af115801561098a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ae9190610de0565b50602081015160a0820151604080840151905163a9059cbb60e01b81526001600160a01b039283166004820152602481019190915291169063a9059cbb90604401602060405180830381600087803b158015610a0957600080fd5b505af1158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190610de0565b506001600160a01b038516600090815260016020908152604080832087845290915281205481548291908110610a7957610a79610ec9565b906000526020600020906006020160050160146101000a81548160ff021916908360ff160217905550846001600160a01b03166323b872dd3033876040518463ffffffff1660e01b8152600401610ad293929190610e80565b600060405180830381600087803b158015610aec57600080fd5b505af1158015610b00573d6000803e3d6000fd5b505050505050505050565b6001600160a01b038216600090815260016020908152604080832084845290915281205481548291908110610b4257610b42610ec9565b60009182526020918290206040805160e0810182526006939093029091018054835260018101546001600160a01b03908116948401949094526002810154918301829052600381015460608401526004810154841660808401526005015492831660a0830152600160a01b90920460ff1660c082015291503414610c225760405162461bcd60e51b815260206004820152603160248201527f4e6f7420726967687420616d6f756e7420554e512073656e742c206861766520604482015270746f20626520657175616c20707269636560781b60648201526084016101f3565b8060a001516001600160a01b03166108fc82604001519081150290604051600060405180830381858888f19350505050158015610c63573d6000803e3d6000fd5b506001600160a01b038316600090815260016020908152604080832085845290915281205481548291908110610c9b57610c9b610ec9565b906000526020600020906006020160050160146101000a81548160ff021916908360ff160217905550826001600160a01b03166323b872dd3033856040518463ffffffff1660e01b8152600401610cf493929190610e80565b600060405180830381600087803b158015610d0e57600080fd5b505af1158015610d22573d6000803e3d6000fd5b50505050505050565b600060208284031215610d3d57600080fd5b8135610d4881610edf565b9392505050565b600060208284031215610d6157600080fd5b8151610d4881610edf565b60008060408385031215610d7f57600080fd5b8235610d8a81610edf565b946020939093013593505050565b60008060008060808587031215610dae57600080fd5b8435610db981610edf565b9350602085013592506040850135610dd081610edf565b9396929550929360600135925050565b600060208284031215610df257600080fd5b81518015158114610d4857600080fd5b600060208284031215610e1457600080fd5b5035919050565b600080600080600060a08688031215610e3357600080fd5b853594506020860135610e4581610edf565b93506040860135610e5581610edf565b925060608601359150608086013560ff81168114610e7257600080fd5b809150509295509295909350565b6001600160a01b039384168152919092166020820152604081019190915260600190565b600082821015610ec457634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0381168114610ef457600080fd5b5056fea2646970667358221220fbf33eb1e471c428b86ad6d948b8699fd08a127b923d5fe27ec1e1ec5f59627564736f6c63430008070033
\ No newline at end of file
addedtests/src/eth/marketplace/MarketPlaceUNQ.soldiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/marketplace/MarketPlaceUNQ.sol
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier:  Apache License
+pragma solidity >=0.8.0;
+
+interface IERC721 {
+    event Transfer(
+        address indexed from,
+        address indexed to,
+        uint256 indexed tokenId
+    );
+    event Approval(
+        address indexed owner,
+        address indexed approved,
+        uint256 indexed tokenId
+    );
+
+    function ownerOf(uint256 tokenId) external view returns (address owner);
+
+    function transferFrom(
+        address from,
+        address to,
+        uint256 tokenId
+    ) external;
+
+    function debug(string memory value) external;
+}
+
+interface IERC20 {
+    event Transfer(address indexed from, address indexed to, uint256 value);
+    event Approval(
+        address indexed owner,
+        address indexed spender,
+        uint256 value
+    );
+
+    function transfer(address recipient, uint256 amount)
+        external
+        returns (bool);
+
+    function transferFrom(
+        address sender,
+        address recipient,
+        uint256 amount
+    ) external returns (bool);
+}
+
+contract MarketPlaceUNQ {
+    struct Offer {
+        uint256 idNFT;
+        address currencyCode; //address of currency  token, = address(0) for UNQ
+        uint256 price;
+        uint256 time;
+        address idCollection;
+        address userAddr;
+        uint8 flagActive;
+    }
+    Offer[] public offers;
+
+    mapping(address => mapping(uint256 => uint256)) public asks; // [idCollection][idNFT] => idOffer
+
+    mapping(address => uint256[]) public asksbySeller; // [addressSeller] =>idOffer
+
+    address owner;
+
+    constructor() {
+        owner = msg.sender;
+    }
+
+    function setowner(address _newOwner) public onlyOwner {
+        owner = _newOwner;
+    }
+
+    modifier onlyOwner() {
+        require(msg.sender == owner, "Only owner can");
+        _;
+    }
+
+    /**
+     * Make bids (offers) to sell NFTs
+     */
+    function setAsk(
+        uint256 _price,
+        address _currencyCode,
+        address _idCollection,
+        uint256 _idNFT,
+        uint8 _active
+    ) public {
+        require(
+            IERC721(_idCollection).ownerOf(_idNFT) == msg.sender,
+            "Not right token owner"
+        );
+        uint256 offerID = asks[_idCollection][_idNFT];
+        if (offers.length == 0 || offers[offerID].idCollection == address(0)) {
+            offers.push(
+                Offer(
+                    _idNFT,
+                    _currencyCode,
+                    _price,
+                    block.timestamp,
+                    _idCollection,
+                    msg.sender,
+                    _active
+                )
+            );
+            asks[_idCollection][_idNFT] = offers.length - 1;
+            asksbySeller[msg.sender].push(offers.length - 1);
+        }
+        //edit existing offer
+        else {
+            offers[asks[_idCollection][_idNFT]] = Offer(
+                offers[asks[_idCollection][_idNFT]].idNFT,
+                _currencyCode,
+                _price,
+                block.timestamp,
+                offers[asks[_idCollection][_idNFT]].idCollection,
+                msg.sender,
+                _active
+            );
+        }
+
+        IERC721(_idCollection).transferFrom(msg.sender, address(this), _idNFT);
+    }
+
+    function buy(address _idCollection, uint256 _idNFT) public payable {
+        //buing for UNQ like as ethers
+        Offer memory offer = offers[asks[_idCollection][_idNFT]];
+        //1. check sent amount and send to seller
+        require(
+            msg.value == offer.price,
+            "Not right amount UNQ sent, have to be equal price"
+        );
+        payable(offer.userAddr).transfer(offer.price);
+        // 2. close offer
+        offers[asks[_idCollection][_idNFT]].flagActive = 0;
+        // 3. transfer NFT to buyer
+        IERC721(_idCollection).transferFrom(address(this), msg.sender, _idNFT);
+    }
+
+    function buy(
+        address _idCollection,
+        uint256 _idNFT,
+        address _currencyCode,
+        uint256 _amount
+    ) public payable {
+        Offer memory offer = offers[asks[_idCollection][_idNFT]];
+        //1. check sent amount and transfer from buyer to seller
+        require(
+            offer.price == _amount && offer.currencyCode == _currencyCode,
+            "Not right amount or currency sent, have to be equal currency and price"
+        );
+        // !!! transfer have to be approved to marketplace!
+        IERC20(offer.currencyCode).transferFrom(
+            msg.sender,
+            address(this),
+            offer.price
+        );
+        //to not disclojure buyer's address
+        IERC20(offer.currencyCode).transfer(offer.userAddr, offer.price);
+        // 2. close offer
+        offers[asks[_idCollection][_idNFT]].flagActive = 0;
+        // 3. transfer NFT to buyer
+        IERC721(_idCollection).transferFrom(address(this), msg.sender, _idNFT);
+    }
+}
addedtests/src/eth/marketplace/marketplace.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/marketplace/marketplace.test.ts
@@ -0,0 +1,198 @@
+import { readFile } from 'fs/promises';
+import { getBalanceSingle, transferBalanceExpectSuccess } from '../../substrate/get-balance';
+import privateKey from '../../substrate/privateKey';
+import { createCollectionExpectSuccess, createFungibleItemExpectSuccess, createItemExpectSuccess, queryNftOwner, transferExpectSuccess, transferFromExpectSuccess } from '../../util/helpers';
+import { collectionIdToAddress, createEthAccountWithBalance, executeEthTxOnSub, GAS_ARGS, itWeb3, subToEth, subToEthLowercase } from '../util/helpers';
+import { evmToAddress } from '@polkadot/util-crypto';
+import nonFungibleAbi from '../nonFungibleAbi.json';
+import fungibleAbi from '../fungibleAbi.json';
+import waitNewBlocks from '../../substrate/wait-new-blocks';
+import { expect } from 'chai';
+
+const PRICE = 2000n;
+
+describe('Matcher contract usage', () => {
+  itWeb3('With UNQ', async ({api, web3}) => {
+    const matcherOwner = await createEthAccountWithBalance(api, web3);
+    const Matcher = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlaceUNQ.abi`)).toString()), undefined, {
+      from: matcherOwner,
+      ...GAS_ARGS,
+    });
+    const matcher = await Matcher.deploy({ data: (await readFile(`${__dirname}/MarketPlaceUNQ.bin`)).toString() }).send({ from: matcherOwner });
+
+    const alice = privateKey('//Alice');
+    const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
+    const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), { from: matcherOwner });
+
+    const seller = privateKey('//Bob');
+  
+    const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);
+
+    // To transfer item to matcher it first needs to be transfered to EVM account of bob
+    await transferExpectSuccess(collectionId, tokenId, seller, {ethereum: subToEth(seller.address)});
+    // Fees will be paid from EVM account, so we should have some balance here
+    await transferBalanceExpectSuccess(api, seller, evmToAddress(subToEth(seller.address)), 10n ** 18n);
+    await transferBalanceExpectSuccess(api, alice, evmToAddress(subToEth(alice.address)), 10n ** 18n);
+    await waitNewBlocks(api, 1);
+
+    // Token is owned by seller initially
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: subToEthLowercase(seller.address) });
+
+    // Ask
+    {
+      await executeEthTxOnSub(api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));
+      await executeEthTxOnSub(api, seller, matcher, m => m.setAsk(PRICE, '0x0000000000000000000000000000000000000000', evmCollection.options.address, tokenId, 1));
+    }
+      
+    // Token is transferred to matcher
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: matcher.options.address.toLowerCase() });
+
+    // Buy
+    {
+      const sellerBalanceBeforePurchase = await getBalanceSingle(api, seller.address);
+      // There is two functions named 'buy', so we should provide full signature
+      await executeEthTxOnSub(api, alice, matcher, m => m['buy(address,uint256)'](evmCollection.options.address, tokenId), { value: PRICE });
+      expect(await getBalanceSingle(api, seller.address) - sellerBalanceBeforePurchase === PRICE);
+    }
+
+    // Token is transferred to evm account of alice
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: subToEthLowercase(alice.address) });
+
+  
+    // Transfer token to substrate side of alice
+    await transferFromExpectSuccess(collectionId, tokenId, alice, { ethereum: subToEth(alice.address) }, { substrate: alice.address });
+    
+    // Token is transferred to substrate account of alice, seller received funds
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ substrate: alice.address });
+  });
+
+  itWeb3('With custom ERC20', async ({api, web3}) => {
+    const matcherOwner = await createEthAccountWithBalance(api, web3);
+    const Matcher = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlaceUNQ.abi`)).toString()), undefined, {
+      from: matcherOwner,
+      ...GAS_ARGS,
+    });
+    const matcher = await Matcher.deploy({ data: (await readFile(`${__dirname}/MarketPlaceUNQ.bin`)).toString() }).send({ from: matcherOwner });
+
+    const alice = privateKey('//Alice');
+    const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
+    const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), { from: matcherOwner });
+
+    const fungibleId = await createCollectionExpectSuccess({ mode: { type: 'Fungible', decimalPoints: 0 } });
+    const evmFungible = new web3.eth.Contract(fungibleAbi as any, collectionIdToAddress(fungibleId), { from: matcherOwner, ...GAS_ARGS });
+    await createFungibleItemExpectSuccess(alice, fungibleId, { Value: PRICE }, { ethereum: subToEth(alice.address) });
+
+    const seller = privateKey('//Bob');
+  
+    const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);
+
+    // To transfer item to matcher it first needs to be transfered to EVM account of bob
+    await transferExpectSuccess(collectionId, tokenId, seller, {ethereum: subToEth(seller.address)});
+    // Fees will be paid from EVM account, so we should have some balance here
+    await transferBalanceExpectSuccess(api, seller, evmToAddress(subToEth(seller.address)), 10n ** 18n);
+    await transferBalanceExpectSuccess(api, alice, evmToAddress(subToEth(alice.address)), 10n ** 18n);
+    await waitNewBlocks(api, 1);
+
+    // Token is owned by seller initially
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: subToEthLowercase(seller.address) });
+
+    // Ask
+    {
+      await executeEthTxOnSub(api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));
+      await executeEthTxOnSub(api, seller, matcher, m => m.setAsk(PRICE, evmFungible.options.address, evmCollection.options.address, tokenId, 1));
+    }
+      
+    // Token is transferred to matcher
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: matcher.options.address.toLowerCase() });
+
+    // Buy
+    {
+      const sellerBalanceBeforePurchase = BigInt(await evmFungible.methods.balanceOf(subToEth(seller.address)).call());
+      const buyerBalanceBeforePurchase = BigInt(await evmFungible.methods.balanceOf(subToEth(alice.address)).call());
+
+      await executeEthTxOnSub(api, alice, evmFungible, m => m.approve(matcher.options.address, PRICE));
+      // There is two functions named 'buy', so we should provide full signature
+      await executeEthTxOnSub(api, alice, matcher, m =>
+        m['buy(address,uint256,address,uint256)'](evmCollection.options.address, tokenId, evmFungible.options.address, PRICE));
+
+      // Approved price is removed from buyer balance, and added to seller
+      expect(BigInt(await evmFungible.methods.balanceOf(subToEth(seller.address)).call()) - sellerBalanceBeforePurchase === PRICE);
+      expect(buyerBalanceBeforePurchase - BigInt(await evmFungible.methods.balanceOf(subToEth(alice.address)).call()) === PRICE);
+    }
+
+    // Token is transferred to evm account of alice
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: subToEthLowercase(alice.address) });
+
+  
+    // Transfer token to substrate side of alice
+    await transferFromExpectSuccess(collectionId, tokenId, alice, { ethereum: subToEth(alice.address) }, { substrate: alice.address });
+    
+    // Token is transferred to substrate account of alice
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ substrate: alice.address });
+  });
+
+  itWeb3('With escrow', async ({ api, web3 }) => {
+    const matcherOwner = await createEthAccountWithBalance(api, web3);
+    const escrow = await createEthAccountWithBalance(api, web3);
+    const Matcher = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlaceKSM.abi`)).toString()), undefined, {
+      from: matcherOwner,
+      ...GAS_ARGS,
+    });
+    const matcher = await Matcher.deploy({ data: (await readFile(`${__dirname}/MarketPlaceKSM.bin`)).toString(), arguments: [escrow] }).send({ from: matcherOwner });
+    
+    const ksmToken = 11;
+
+    const alice = privateKey('//Alice');
+    const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
+    const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), { from: matcherOwner });
+
+    const seller = privateKey('//Bob');
+  
+    const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);
+
+    // To transfer item to matcher it first needs to be transfered to EVM account of bob
+    await transferExpectSuccess(collectionId, tokenId, seller, {ethereum: subToEth(seller.address)});
+    // Fees will be paid from EVM account, so we should have some balance here
+    await transferBalanceExpectSuccess(api, seller, evmToAddress(subToEth(seller.address)), 10n ** 18n);
+    await transferBalanceExpectSuccess(api, alice, evmToAddress(subToEth(alice.address)), 10n ** 18n);
+    await waitNewBlocks(api, 1);
+
+    // Token is owned by seller initially
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: subToEthLowercase(seller.address) });
+
+    // Ask
+    {
+      await executeEthTxOnSub(api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));
+      await executeEthTxOnSub(api, seller, matcher, m => m.setAsk(PRICE, ksmToken, evmCollection.options.address, tokenId, 1));
+    }
+      
+    // Token is transferred to matcher
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: matcher.options.address.toLowerCase() });
+
+    // Give buyer KSM
+    await matcher.methods.deposit(PRICE, ksmToken, subToEth(alice.address)).send({ from: escrow });
+    await waitNewBlocks(api, 1);
+  
+    // Buy
+    {
+      expect(await matcher.methods.escrowBalance(ksmToken, subToEth(seller.address)).call()).to.be.equal('0');
+      expect(await matcher.methods.escrowBalance(ksmToken, subToEth(alice.address)).call()).to.be.equal(PRICE.toString());
+
+      await executeEthTxOnSub(api, alice, matcher, m => m.buy(evmCollection.options.address, tokenId));
+      await waitNewBlocks(api, 1);
+
+      // Price is removed from buyer balance, and added to seller
+      expect(await matcher.methods.escrowBalance(ksmToken, subToEth(alice.address)).call()).to.be.equal('0');
+      expect(await matcher.methods.escrowBalance(ksmToken, subToEth(seller.address)).call()).to.be.equal(PRICE.toString());
+    }
+
+    // Token is transferred to evm account of alice
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ ethereum: subToEthLowercase(alice.address) });
+  
+    // Transfer token to substrate side of alice
+    await transferFromExpectSuccess(collectionId, tokenId, alice, { ethereum: subToEth(alice.address) }, { substrate: alice.address });
+    
+    // Token is transferred to substrate account of alice, seller received funds
+    expect(await queryNftOwner(api, collectionId, tokenId)).to.be.deep.equal({ substrate: alice.address });
+  });
+});
addedtests/src/eth/migration.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/migration.test.ts
@@ -0,0 +1,82 @@
+import { expect } from 'chai';
+import privateKey from '../substrate/privateKey';
+import { submitTransactionAsync } from '../substrate/substrate-api';
+import { createEthAccountWithBalance, GAS_ARGS, itWeb3 } from './util/helpers';
+
+describe('EVM Migrations', () => {
+  itWeb3('Deploy contract saved state', async ({ web3, api }) => {
+    /*
+      contract StatefulContract {
+        uint counter;
+        mapping (uint => uint) kv;
+
+        function inc() public {
+          counter = counter + 1;
+        }
+        function counterValue() public view returns (uint) {
+          return counter;
+        }
+
+        function set(uint key, uint value) public {
+          kv[key] = value;
+        }
+
+        function get(uint key) public view returns (uint) {
+          return kv[key];
+        }
+      }
+    */
+    const ADDRESS = '0x4956bf52ef9ed8789f21bc600e915e0d961079f6';
+    const CODE = '0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80631ab06ee514610051578063371303c01461006d5780637bfdec3b146100775780639507d39a14610095575b600080fd5b61006b60048036038101906100669190610160565b6100c5565b005b6100756100e1565b005b61007f6100f8565b60405161008c91906101af565b60405180910390f35b6100af60048036038101906100aa9190610133565b610101565b6040516100bc91906101af565b60405180910390f35b8060016000848152602001908152602001600020819055505050565b60016000546100f091906101ca565b600081905550565b60008054905090565b600060016000838152602001908152602001600020549050919050565b60008135905061012d8161025e565b92915050565b60006020828403121561014957610148610259565b5b60006101578482850161011e565b91505092915050565b6000806040838503121561017757610176610259565b5b60006101858582860161011e565b92505060206101968582860161011e565b9150509250929050565b6101a981610220565b82525050565b60006020820190506101c460008301846101a0565b92915050565b60006101d582610220565b91506101e083610220565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156102155761021461022a565b5b828201905092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b61026781610220565b811461027257600080fd5b5056fea26469706673582212206a02d2fb5c244105ab884961479c1aee3b4c1011e4b5530ab483eb22344a865664736f6c63430008060033';
+    const DATA = [
+      // counter = 10
+      ['0x0000000000000000000000000000000000000000000000000000000000000000', '0x000000000000000000000000000000000000000000000000000000000000000a'],
+      // kv = {1: 1, 2: 2, 3: 3, 4: 4},
+      ['0xcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f', '0x0000000000000000000000000000000000000000000000000000000000000001'],
+      ['0xd9d16d34ffb15ba3a3d852f0d403e2ce1d691fb54de27ac87cd2f993f3ec330f', '0x0000000000000000000000000000000000000000000000000000000000000002'],
+      ['0x7dfe757ecd65cbd7922a9c0161e935dd7fdbcc0e999689c7d31633896b1fc60b', '0x0000000000000000000000000000000000000000000000000000000000000003'],
+      ['0xedc95719e9a3b28dd8e80877cb5880a9be7de1a13fc8b05e7999683b6b567643', '0x0000000000000000000000000000000000000000000000000000000000000004'],
+    ];
+
+    const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
+
+    await submitTransactionAsync(alice, api.tx.sudo.sudo(api.tx.evmMigration.begin(ADDRESS)));
+    await submitTransactionAsync(alice, api.tx.sudo.sudo(api.tx.evmMigration.setData(ADDRESS, DATA)));
+    await submitTransactionAsync(alice, api.tx.sudo.sudo(api.tx.evmMigration.finish(ADDRESS, CODE)));
+
+    const contract = new web3.eth.Contract([
+      {
+        inputs: [],
+        name: 'counterValue',
+        outputs: [{
+          internalType: 'uint256',
+          name: '',
+          type: 'uint256',
+        }],
+        stateMutability: 'view',
+        type: 'function',
+      },
+      {
+        inputs: [{
+          internalType: 'uint256',
+          name: 'key',
+          type: 'uint256',
+        }],
+        name: 'get',
+        outputs: [{
+          internalType: 'uint256',
+          name: '',
+          type: 'uint256',
+        }],
+        stateMutability: 'view',
+        type: 'function',
+      },
+    ], ADDRESS, { from: caller, ...GAS_ARGS });
+    
+    expect(await contract.methods.counterValue().call()).to.be.equal('10');
+    for (let i = 1; i <= 4; i++) {
+      expect(await contract.methods.get(i).call()).to.be.equal(i.toString());
+    }
+  });
+});
\ No newline at end of file
modifiedtests/src/eth/util/helpers.tsdiffbeforeafterboth
--- a/tests/src/eth/util/helpers.ts
+++ b/tests/src/eth/util/helpers.ts
@@ -143,10 +143,13 @@
   return normalizeEvents(out);
 }
 
+export function subToEthLowercase(eth: string): string {
+  const bytes = addressToEvm(eth);
+  return '0x' + Buffer.from(bytes).toString('hex');
+}
+
 export function subToEth(eth: string): string {
-  const bytes = addressToEvm(eth);
-  const string = '0x' + Buffer.from(bytes).toString('hex');
-  return Web3.utils.toChecksumAddress(string);
+  return Web3.utils.toChecksumAddress(subToEthLowercase(eth));
 }
 
 export function compileContract(name: string, src: string) {
@@ -236,6 +239,20 @@
   return new web3.eth.Contract(contractHelpersAbi as any, '0x842899ECF380553E8a4de75bF534cdf6fBF64049', {from: caller, ...GAS_ARGS});
 }
 
+export async function executeEthTxOnSub(api: ApiPromise, from: IKeyringPair, to: any, mkTx: (methods: any) => any, { value = 0 }: {value?: bigint | number} = { }) {
+  const tx = api.tx.evm.call(
+    subToEth(from.address),
+    to.options.address,
+    mkTx(to.methods).encodeABI(),
+    value,
+    GAS_ARGS.gas,
+    GAS_ARGS.gasPrice,
+    null,
+  );
+  const events = await submitTransactionAsync(from, tx);
+  expect(events.find(({ event: {section, method}})=>section === 'evm' && method === 'Executed')).to.be.not.undefined;
+}
+
 export async function ethBalanceViaSub(api: ApiPromise, address: string): Promise<bigint> {
   return (await getBalance(api, [evmToAddress(address)]))[0];
 }
modifiedtests/src/util/helpers.tsdiffbeforeafterboth
--- a/tests/src/util/helpers.ts
+++ b/tests/src/util/helpers.ts
@@ -1168,3 +1168,7 @@
     return (await api.query.nft.collectionById(collectionId)).toJSON() as unknown as ICollectionInterface;
   });
 }
+
+export async function queryNftOwner(api: ApiPromise, collectionId: number, tokenId: number): Promise<CrossAccountId> {
+  return normalizeAccountId((await api.query.nft.nftItemList(collectionId, tokenId) as any).toJSON().Owner);
+}
\ No newline at end of file