difftreelog
Merge branch 'develop' into feature/evm-collection-calls
in: master
26 files changed
.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
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -704,6 +704,117 @@
]
[[package]]
+name = "bp-header-chain"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "finality-grandpa",
+ "frame-support",
+ "parity-scale-codec",
+ "serde",
+ "sp-core",
+ "sp-finality-grandpa",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
+name = "bp-messages"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "bitvec 0.20.4",
+ "bp-runtime",
+ "frame-support",
+ "frame-system",
+ "impl-trait-for-tuples",
+ "parity-scale-codec",
+ "serde",
+ "sp-std",
+]
+
+[[package]]
+name = "bp-polkadot-core"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "bp-messages",
+ "bp-runtime",
+ "frame-support",
+ "frame-system",
+ "parity-scale-codec",
+ "sp-api",
+ "sp-core",
+ "sp-runtime",
+ "sp-std",
+ "sp-version",
+]
+
+[[package]]
+name = "bp-rococo"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "bp-messages",
+ "bp-polkadot-core",
+ "bp-runtime",
+ "frame-support",
+ "parity-scale-codec",
+ "smallvec 1.6.1",
+ "sp-api",
+ "sp-runtime",
+ "sp-std",
+ "sp-version",
+]
+
+[[package]]
+name = "bp-runtime"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "frame-support",
+ "hash-db",
+ "num-traits",
+ "parity-scale-codec",
+ "sp-core",
+ "sp-io",
+ "sp-runtime",
+ "sp-state-machine",
+ "sp-std",
+ "sp-trie",
+]
+
+[[package]]
+name = "bp-test-utils"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "bp-header-chain",
+ "ed25519-dalek",
+ "finality-grandpa",
+ "parity-scale-codec",
+ "sp-application-crypto",
+ "sp-finality-grandpa",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
+name = "bp-wococo"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "bp-messages",
+ "bp-polkadot-core",
+ "bp-rococo",
+ "bp-runtime",
+ "parity-scale-codec",
+ "sp-api",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
name = "bs58"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3779,6 +3890,91 @@
]
[[package]]
+name = "kusama-runtime"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "beefy-primitives",
+ "bitvec 0.20.4",
+ "frame-benchmarking",
+ "frame-election-provider-support",
+ "frame-executive",
+ "frame-support",
+ "frame-system",
+ "frame-system-benchmarking",
+ "frame-system-rpc-runtime-api",
+ "frame-try-runtime",
+ "hex-literal",
+ "log",
+ "max-encoded-len",
+ "pallet-authority-discovery",
+ "pallet-authorship",
+ "pallet-babe",
+ "pallet-balances",
+ "pallet-bounties",
+ "pallet-collective",
+ "pallet-democracy",
+ "pallet-election-provider-multi-phase",
+ "pallet-elections-phragmen",
+ "pallet-gilt",
+ "pallet-grandpa",
+ "pallet-identity",
+ "pallet-im-online",
+ "pallet-indices",
+ "pallet-membership",
+ "pallet-mmr-primitives",
+ "pallet-multisig",
+ "pallet-nicks",
+ "pallet-offences",
+ "pallet-offences-benchmarking",
+ "pallet-proxy",
+ "pallet-recovery",
+ "pallet-scheduler 3.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
+ "pallet-session",
+ "pallet-session-benchmarking",
+ "pallet-society",
+ "pallet-staking",
+ "pallet-staking-reward-fn",
+ "pallet-timestamp",
+ "pallet-tips",
+ "pallet-transaction-payment",
+ "pallet-transaction-payment-rpc-runtime-api",
+ "pallet-treasury",
+ "pallet-utility",
+ "pallet-vesting",
+ "pallet-xcm",
+ "parity-scale-codec",
+ "polkadot-primitives",
+ "polkadot-runtime-common",
+ "polkadot-runtime-parachains",
+ "rustc-hex",
+ "serde",
+ "serde_derive",
+ "smallvec 1.6.1",
+ "sp-api",
+ "sp-arithmetic",
+ "sp-authority-discovery",
+ "sp-block-builder",
+ "sp-consensus-babe",
+ "sp-core",
+ "sp-inherents",
+ "sp-io",
+ "sp-npos-elections",
+ "sp-offchain",
+ "sp-runtime",
+ "sp-session",
+ "sp-staking",
+ "sp-std",
+ "sp-transaction-pool",
+ "sp-version",
+ "static_assertions",
+ "substrate-wasm-builder 4.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
+ "xcm",
+ "xcm-builder",
+ "xcm-executor",
+]
+
+[[package]]
name = "kv-log-macro"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5019,6 +5215,7 @@
"pallet-evm",
"pallet-evm-coder-substrate",
"pallet-evm-contract-helpers",
+ "pallet-evm-migration",
"pallet-evm-transaction-payment",
"pallet-inflation",
"pallet-nft",
@@ -5321,6 +5518,7 @@
version = "3.0.0"
source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
dependencies = [
+ "frame-benchmarking",
"frame-support",
"frame-system",
"pallet-treasury",
@@ -5330,10 +5528,32 @@
]
[[package]]
+name = "pallet-bridge-grandpa"
+version = "0.1.0"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "bp-header-chain",
+ "bp-runtime",
+ "bp-test-utils",
+ "finality-grandpa",
+ "frame-support",
+ "frame-system",
+ "log",
+ "num-traits",
+ "parity-scale-codec",
+ "serde",
+ "sp-finality-grandpa",
+ "sp-runtime",
+ "sp-std",
+ "sp-trie",
+]
+
+[[package]]
name = "pallet-collective"
version = "3.0.0"
source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
dependencies = [
+ "frame-benchmarking",
"frame-support",
"frame-system",
"log",
@@ -5423,11 +5643,13 @@
version = "3.0.0"
source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
dependencies = [
+ "frame-benchmarking",
"frame-election-provider-support",
"frame-support",
"frame-system",
"log",
"parity-scale-codec",
+ "rand 0.7.3",
"sp-arithmetic",
"sp-core",
"sp-io",
@@ -5442,6 +5664,7 @@
version = "4.0.0"
source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
dependencies = [
+ "frame-benchmarking",
"frame-support",
"frame-system",
"log",
@@ -5542,6 +5765,22 @@
]
[[package]]
+name = "pallet-evm-migration"
+version = "0.1.0"
+dependencies = [
+ "fp-evm",
+ "frame-benchmarking",
+ "frame-support",
+ "frame-system",
+ "pallet-evm",
+ "parity-scale-codec",
+ "sp-core",
+ "sp-io",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
name = "pallet-evm-transaction-payment"
version = "0.1.0"
dependencies = [
@@ -5559,6 +5798,20 @@
]
[[package]]
+name = "pallet-gilt"
+version = "3.0.0"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
+dependencies = [
+ "frame-benchmarking",
+ "frame-support",
+ "frame-system",
+ "parity-scale-codec",
+ "sp-arithmetic",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
name = "pallet-grandpa"
version = "3.1.0"
source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
@@ -5600,6 +5853,7 @@
version = "3.0.0"
source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
dependencies = [
+ "frame-benchmarking",
"frame-support",
"frame-system",
"log",
@@ -5618,6 +5872,7 @@
version = "3.0.0"
source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
dependencies = [
+ "frame-benchmarking",
"frame-support",
"frame-system",
"parity-scale-codec",
@@ -5717,6 +5972,7 @@
version = "3.0.0"
source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
dependencies = [
+ "frame-benchmarking",
"frame-support",
"frame-system",
"parity-scale-codec",
@@ -5822,10 +6078,33 @@
]
[[package]]
+name = "pallet-offences-benchmarking"
+version = "3.0.0"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
+dependencies = [
+ "frame-benchmarking",
+ "frame-election-provider-support",
+ "frame-support",
+ "frame-system",
+ "pallet-babe",
+ "pallet-balances",
+ "pallet-grandpa",
+ "pallet-im-online",
+ "pallet-offences",
+ "pallet-session",
+ "pallet-staking",
+ "parity-scale-codec",
+ "sp-runtime",
+ "sp-staking",
+ "sp-std",
+]
+
+[[package]]
name = "pallet-proxy"
version = "3.0.0"
source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
dependencies = [
+ "frame-benchmarking",
"frame-support",
"frame-system",
"max-encoded-len",
@@ -5850,6 +6129,20 @@
]
[[package]]
+name = "pallet-recovery"
+version = "3.0.0"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
+dependencies = [
+ "enumflags2",
+ "frame-support",
+ "frame-system",
+ "parity-scale-codec",
+ "sp-io",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
name = "pallet-scheduler"
version = "3.0.0"
source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
@@ -5903,10 +6196,40 @@
]
[[package]]
+name = "pallet-session-benchmarking"
+version = "3.0.0"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
+dependencies = [
+ "frame-benchmarking",
+ "frame-support",
+ "frame-system",
+ "pallet-session",
+ "pallet-staking",
+ "rand 0.7.3",
+ "sp-runtime",
+ "sp-session",
+ "sp-std",
+]
+
+[[package]]
+name = "pallet-society"
+version = "3.0.0"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
+dependencies = [
+ "frame-support",
+ "frame-system",
+ "parity-scale-codec",
+ "rand_chacha 0.2.2",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
name = "pallet-staking"
version = "3.0.0"
source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
dependencies = [
+ "frame-benchmarking",
"frame-election-provider-support",
"frame-support",
"frame-system",
@@ -5915,6 +6238,7 @@
"pallet-session",
"parity-scale-codec",
"paste",
+ "rand_chacha 0.2.2",
"serde",
"sp-application-crypto",
"sp-io",
@@ -5936,6 +6260,15 @@
]
[[package]]
+name = "pallet-staking-reward-fn"
+version = "3.0.0"
+source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
+dependencies = [
+ "log",
+ "sp-arithmetic",
+]
+
+[[package]]
name = "pallet-sudo"
version = "3.0.0"
source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
@@ -5971,6 +6304,7 @@
version = "3.0.0"
source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
dependencies = [
+ "frame-benchmarking",
"frame-support",
"frame-system",
"pallet-treasury",
@@ -6029,6 +6363,7 @@
version = "3.0.0"
source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
dependencies = [
+ "frame-benchmarking",
"frame-support",
"frame-system",
"impl-trait-for-tuples",
@@ -6044,6 +6379,7 @@
version = "3.0.0"
source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
dependencies = [
+ "frame-benchmarking",
"frame-support",
"frame-system",
"parity-scale-codec",
@@ -6059,6 +6395,7 @@
source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8#74101dc21cfffb4c2d014fcc28edc166d5ca1b16"
dependencies = [
"enumflags2",
+ "frame-benchmarking",
"frame-support",
"frame-system",
"parity-scale-codec",
@@ -6074,6 +6411,7 @@
"frame-support",
"frame-system",
"parity-scale-codec",
+ "serde",
"sp-runtime",
"sp-std",
"xcm",
@@ -7149,12 +7487,15 @@
dependencies = [
"beefy-primitives",
"bitvec 0.20.4",
+ "frame-benchmarking",
"frame-election-provider-support",
"frame-executive",
"frame-support",
"frame-system",
+ "frame-system-benchmarking",
"frame-system-rpc-runtime-api",
"frame-try-runtime",
+ "hex-literal",
"log",
"max-encoded-len",
"pallet-authority-discovery",
@@ -7175,9 +7516,11 @@
"pallet-multisig",
"pallet-nicks",
"pallet-offences",
+ "pallet-offences-benchmarking",
"pallet-proxy",
"pallet-scheduler 3.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
"pallet-session",
+ "pallet-session-benchmarking",
"pallet-staking",
"pallet-staking-reward-curve",
"pallet-timestamp",
@@ -7220,12 +7563,14 @@
dependencies = [
"beefy-primitives",
"bitvec 0.20.4",
+ "frame-benchmarking",
"frame-support",
"frame-system",
"impl-trait-for-tuples",
"libsecp256k1 0.3.5",
"log",
"pallet-authorship",
+ "pallet-babe",
"pallet-balances",
"pallet-beefy",
"pallet-election-provider-multi-phase",
@@ -7263,8 +7608,10 @@
dependencies = [
"bitvec 0.20.4",
"derive_more",
+ "frame-benchmarking",
"frame-support",
"frame-system",
+ "libsecp256k1 0.3.5",
"log",
"pallet-authority-discovery",
"pallet-authorship",
@@ -7304,6 +7651,7 @@
"frame-system-rpc-runtime-api",
"futures 0.3.16",
"hex-literal",
+ "kusama-runtime",
"kvdb",
"kvdb-rocksdb",
"pallet-babe",
@@ -7339,6 +7687,7 @@
"polkadot-runtime",
"polkadot-runtime-parachains",
"polkadot-statement-distribution",
+ "rococo-runtime",
"sc-authority-discovery",
"sc-basic-authorship",
"sc-block-builder",
@@ -7380,6 +7729,7 @@
"substrate-prometheus-endpoint",
"thiserror",
"tracing",
+ "westend-runtime",
]
[[package]]
@@ -8144,6 +8494,73 @@
]
[[package]]
+name = "rococo-runtime"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "beefy-primitives",
+ "bp-rococo",
+ "bp-wococo",
+ "frame-executive",
+ "frame-support",
+ "frame-system",
+ "frame-system-rpc-runtime-api",
+ "hex-literal",
+ "log",
+ "max-encoded-len",
+ "pallet-authority-discovery",
+ "pallet-authorship",
+ "pallet-babe",
+ "pallet-balances",
+ "pallet-beefy",
+ "pallet-bridge-grandpa",
+ "pallet-collective",
+ "pallet-grandpa",
+ "pallet-im-online",
+ "pallet-indices",
+ "pallet-membership",
+ "pallet-mmr",
+ "pallet-mmr-primitives",
+ "pallet-offences",
+ "pallet-proxy",
+ "pallet-session",
+ "pallet-staking",
+ "pallet-staking-reward-curve",
+ "pallet-sudo",
+ "pallet-timestamp",
+ "pallet-transaction-payment",
+ "pallet-transaction-payment-rpc-runtime-api",
+ "pallet-utility",
+ "pallet-xcm",
+ "parity-scale-codec",
+ "polkadot-parachain",
+ "polkadot-primitives",
+ "polkadot-runtime-common",
+ "polkadot-runtime-parachains",
+ "serde",
+ "serde_derive",
+ "smallvec 1.6.1",
+ "sp-api",
+ "sp-authority-discovery",
+ "sp-block-builder",
+ "sp-consensus-babe",
+ "sp-core",
+ "sp-inherents",
+ "sp-io",
+ "sp-offchain",
+ "sp-runtime",
+ "sp-session",
+ "sp-staking",
+ "sp-std",
+ "sp-transaction-pool",
+ "sp-version",
+ "substrate-wasm-builder 4.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
+ "xcm",
+ "xcm-builder",
+ "xcm-executor",
+]
+
+[[package]]
name = "rpassword"
version = "5.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -12044,6 +12461,89 @@
]
[[package]]
+name = "westend-runtime"
+version = "0.9.8"
+source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.8#3a10ee63c0b5703a1c802db3438ab7e01344a8ce"
+dependencies = [
+ "beefy-primitives",
+ "bitvec 0.20.4",
+ "frame-benchmarking",
+ "frame-election-provider-support",
+ "frame-executive",
+ "frame-support",
+ "frame-system",
+ "frame-system-benchmarking",
+ "frame-system-rpc-runtime-api",
+ "frame-try-runtime",
+ "hex-literal",
+ "log",
+ "max-encoded-len",
+ "pallet-authority-discovery",
+ "pallet-authorship",
+ "pallet-babe",
+ "pallet-balances",
+ "pallet-collective",
+ "pallet-democracy",
+ "pallet-election-provider-multi-phase",
+ "pallet-elections-phragmen",
+ "pallet-grandpa",
+ "pallet-identity",
+ "pallet-im-online",
+ "pallet-indices",
+ "pallet-membership",
+ "pallet-mmr-primitives",
+ "pallet-multisig",
+ "pallet-nicks",
+ "pallet-offences",
+ "pallet-offences-benchmarking",
+ "pallet-proxy",
+ "pallet-recovery",
+ "pallet-scheduler 3.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
+ "pallet-session",
+ "pallet-session-benchmarking",
+ "pallet-society",
+ "pallet-staking",
+ "pallet-staking-reward-curve",
+ "pallet-sudo",
+ "pallet-timestamp",
+ "pallet-transaction-payment",
+ "pallet-transaction-payment-rpc-runtime-api",
+ "pallet-treasury",
+ "pallet-utility",
+ "pallet-vesting",
+ "pallet-xcm",
+ "parity-scale-codec",
+ "polkadot-parachain",
+ "polkadot-primitives",
+ "polkadot-runtime-common",
+ "polkadot-runtime-parachains",
+ "rustc-hex",
+ "serde",
+ "serde_derive",
+ "smallvec 1.6.1",
+ "sp-api",
+ "sp-authority-discovery",
+ "sp-block-builder",
+ "sp-consensus-babe",
+ "sp-core",
+ "sp-inherents",
+ "sp-io",
+ "sp-npos-elections",
+ "sp-offchain",
+ "sp-runtime",
+ "sp-session",
+ "sp-staking",
+ "sp-std",
+ "sp-transaction-pool",
+ "sp-version",
+ "static_assertions",
+ "substrate-wasm-builder 4.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.8)",
+ "xcm",
+ "xcm-builder",
+ "xcm-executor",
+]
+
+[[package]]
name = "which"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
Makefilediffbeforeafterboth232324evm_stubs: $(NFT_EVM_STUBS)/UniqueFungible.raw $(NFT_EVM_STUBS)/UniqueNFT.raw $(CONTRACT_HELPERS_STUBS)/ContractHelpers.raw24evm_stubs: $(NFT_EVM_STUBS)/UniqueFungible.raw $(NFT_EVM_STUBS)/UniqueNFT.raw $(CONTRACT_HELPERS_STUBS)/ContractHelpers.raw2526.PHONY: _bench27_bench:28 cargo run --release --features runtime-benchmarks -- \29 benchmark --pallet pallet-$(PALLET) \30 --wasm-execution compiled --extrinsic '*' \31 --template .maintain/frame-weight-template.hbs --steps=50 --repeat=20 \32 --output=./pallets/$(PALLET)/src/weights.rs3334.PHONY: bench-evm-migration35bench-evm-migration:36 make _bench PALLET=evm-migration3738.PHONY: bench39bench: bench-evm-migration2540crates/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;
node/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',
+]
pallets/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"]
pallets/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)
+}
pallets/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
+ }
+ }
+}
pallets/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
pallets/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
-
-}
pallets/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;
pallets/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 =
pallets/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(ð.0[0..8]);
+ let sub = u64::from_be_bytes(sub_raw);
+ Self(sub, eth)
}
fn as_eth(&self) -> &sp_core::H160 {
&self.1
runtime/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" }
runtime/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);
tests/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
+}
tests/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
tests/src/eth/marketplace/MarketPlaceKSM.bindiffbeforeafterboth--- /dev/null
+++ b/tests/src/eth/marketplace/MarketPlaceKSM.bin
@@ -0,0 +1 @@
+608060405234801561001057600080fd5b50604051610e27380380610e2783398101604081905261002f9161005d565b600480546001600160a01b039092166001600160a01b0319928316179055600580549091163317905561008d565b60006020828403121561006f57600080fd5b81516001600160a01b038116811461008657600080fd5b9392505050565b610d8b8061009c6000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c806399f2d4eb1161007157806399f2d4eb1461018e5780639df55f52146101a1578063c10c35461461010f578063cce7ec13146101b4578063db87db52146101c7578063e22d4f7d146101fa57600080fd5b80630ad58d2f146100ae57806310a5ff17146100d6578063592bd7051461010f5780638a72ea6a146101245780638dbdbe6d1461017b575b600080fd5b6100c16100bc366004610c4d565b610225565b60405190151581526020015b60405180910390f35b6101016100e4366004610bd8565b600160209081526000928352604080842090915290825290205481565b6040519081526020016100cd565b61012261011d366004610b97565b6102d8565b005b610137610132366004610c04565b610345565b6040805197885260208801969096529486019390935260608501919091526001600160a01b0390811660808501521660a083015260ff1660c082015260e0016100cd565b610122610189366004610c4d565b6103a4565b61010161019c366004610bd8565b610449565b6101226101af366004610c86565b61047a565b6101226101c2366004610bd8565b610984565b6101016101d5366004610c1d565b6001600160a01b03166000908152600160209081526040808320938352929052205490565b610101610208366004610bd8565b600260209081526000928352604080842090915290825290205481565b6004546000906001600160a01b031633146102795760405162461bcd60e51b815260206004820152600f60248201526e27b7363c9032b9b1b937bb9031b0b760891b60448201526064015b60405180910390fd5b6001600160a01b03821660009081526001602090815260408083208684529091529020546102a8908590610cfa565b6001600160a01b039290921660009081526001602081815260408084209684529590529390209190915550919050565b6005546001600160a01b031633146103235760405162461bcd60e51b815260206004820152600e60248201526d27b7363c9037bbb732b91031b0b760911b6044820152606401610270565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6000818154811061035557600080fd5b6000918252602090912060069091020180546001820154600283015460038401546004850154600590950154939550919390926001600160a01b0391821691811690600160a01b900460ff1687565b6004546001600160a01b031633146103f05760405162461bcd60e51b815260206004820152600f60248201526e27b7363c9032b9b1b937bb9031b0b760891b6044820152606401610270565b6001600160a01b038116600090815260016020908152604080832085845290915290205461041f908490610ce2565b6001600160a01b039091166000908152600160209081526040808320948352939052919091205550565b6003602052816000526040600020818154811061046557600080fd5b90600052602060002001600091509150505481565b6040516331a9108f60e11b81526004810183905233906001600160a01b03851690636352211e9060240160206040518083038186803b1580156104bc57600080fd5b505afa1580156104d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f49190610bbb565b6001600160a01b0316146105425760405162461bcd60e51b81526020600482015260156024820152742737ba103934b3b43a103a37b5b2b71037bbb732b960591b6044820152606401610270565b6001600160a01b0383166000908152600260209081526040808320858452909152812054905415806105ac575060006001600160a01b03166000828154811061058d5761058d610d27565b60009182526020909120600460069092020101546001600160a01b0316145b15610793576040805160e0810182528481526020810187815291810188815242606083019081526001600160a01b03808916608085019081523360a0860190815260ff808a1660c088019081526000805460018181018355828052995160069091027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56381019190915599517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5648b015596517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5658a015594517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56689015591517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e567880180549185166001600160a01b0319909216919091179055517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56890960180549351909116600160a01b026001600160a81b031990931695909116949094171790925590546107399190610cfa565b6001600160a01b038516600090815260026020908152604080832087845282528083209390935533825260039052908120905461077890600190610cfa565b81546001810183556000928352602090922090910155610916565b6040805160e0810182526001600160a01b03861660009081526002602090815283822087835290529182205482549192839290919081106107d6576107d6610d27565b60009182526020808320600690920290910154835282810189905260408084018b90524260608501526001600160a01b0389168352600282528083208884529091528120548154608090930192811061083157610831610d27565b60009182526020808320600460069093020191909101546001600160a01b039081168452338483015260ff871660409485015288168252600281528282208783529052908120548154811061088857610888610d27565b60009182526020918290208351600690920201908155908201516001820155604082015160028201556060820151600382015560808201516004820180546001600160a01b039283166001600160a01b031990911617905560a08301516005909201805460c09094015160ff16600160a01b026001600160a81b031990941692909116919091179190911790555b6040516323b872dd60e01b8152336004820152306024820152604481018490526001600160a01b038516906323b872dd90606401600060405180830381600087803b15801561096457600080fd5b505af1158015610978573d6000803e3d6000fd5b50505050505050505050565b6001600160a01b0382166000908152600260209081526040808320848452909152812054815482919081106109bb576109bb610d27565b600091825260208083206040805160e0810182526006949094029091018054845260018082015485850190815260028301548685018190526003840154606088015260048401546001600160a01b03908116608089015260059094015493841660a0880152600160a01b90930460ff1660c08701523387529084528286209051865290925290922054909250610a519190610cfa565b33600090815260016020818152604080842086830180518652908352818520959095558581015160a08701516001600160a01b031685529282528084209451845293905291902054610aa39190610ce2565b60a08201516001600160a01b0390811660009081526001602090815260408083208287015184528252808320949094559186168152600282528281208582529091529081205481548291908110610afc57610afc610d27565b60009182526020909120600560069092020101805460ff92909216600160a01b0260ff60a01b199092169190911790556040516323b872dd60e01b8152306004820152336024820152604481018390526001600160a01b038416906323b872dd90606401600060405180830381600087803b158015610b7a57600080fd5b505af1158015610b8e573d6000803e3d6000fd5b50505050505050565b600060208284031215610ba957600080fd5b8135610bb481610d3d565b9392505050565b600060208284031215610bcd57600080fd5b8151610bb481610d3d565b60008060408385031215610beb57600080fd5b8235610bf681610d3d565b946020939093013593505050565b600060208284031215610c1657600080fd5b5035919050565b60008060408385031215610c3057600080fd5b823591506020830135610c4281610d3d565b809150509250929050565b600080600060608486031215610c6257600080fd5b83359250602084013591506040840135610c7b81610d3d565b809150509250925092565b600080600080600060a08688031215610c9e57600080fd5b85359450602086013593506040860135610cb781610d3d565b925060608601359150608086013560ff81168114610cd457600080fd5b809150509295509295909350565b60008219821115610cf557610cf5610d11565b500190565b600082821015610d0c57610d0c610d11565b500390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0381168114610d5257600080fd5b5056fea2646970667358221220d098ae4e0cc7bdbb7de1061c03402a667836f903122c1c606ca2c65db1ab78e964736f6c63430008070033
\ No newline at end of file
tests/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];
+ }
+}
tests/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
tests/src/eth/marketplace/MarketPlaceUNQ.bindiffbeforeafterboth--- /dev/null
+++ b/tests/src/eth/marketplace/MarketPlaceUNQ.bin
@@ -0,0 +1 @@
+608060405234801561001057600080fd5b50600380546001600160a01b03191633179055610f2d806100326000396000f3fe6080604052600436106100705760003560e01c806399f2d4eb1161004e57806399f2d4eb14610120578063b3ffb7601461014e578063cce7ec1314610161578063e22d4f7d1461017457600080fd5b8063592bd705146100755780637b1d6001146100975780638a72ea6a146100b7575b600080fd5b34801561008157600080fd5b50610095610090366004610d2b565b6101ac565b005b3480156100a357600080fd5b506100956100b2366004610e1b565b61021e565b3480156100c357600080fd5b506100d76100d2366004610e02565b61073d565b604080519788526001600160a01b03968716602089015287019490945260608601929092528316608085015290911660a083015260ff1660c082015260e0015b60405180910390f35b34801561012c57600080fd5b5061014061013b366004610d6c565b6107a0565b604051908152602001610117565b61009561015c366004610d98565b6107d1565b61009561016f366004610d6c565b610b0b565b34801561018057600080fd5b5061014061018f366004610d6c565b600160209081526000928352604080842090915290825290205481565b6003546001600160a01b031633146101fc5760405162461bcd60e51b815260206004820152600e60248201526d27b7363c9037bbb732b91031b0b760911b60448201526064015b60405180910390fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6040516331a9108f60e11b81526004810183905233906001600160a01b03851690636352211e9060240160206040518083038186803b15801561026057600080fd5b505afa158015610274573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102989190610d4f565b6001600160a01b0316146102e65760405162461bcd60e51b81526020600482015260156024820152742737ba103934b3b43a103a37b5b2b71037bbb732b960591b60448201526064016101f3565b6001600160a01b038316600090815260016020908152604080832085845290915281205490541580610350575060006001600160a01b03166000828154811061033157610331610ec9565b60009182526020909120600460069092020101546001600160a01b0316145b15610542576040805160e0810182528481526001600160a01b03878116602083019081529282018981524260608401908152888316608085019081523360a0860190815260ff89811660c08801908152600080546001808201835582805299517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56360069092029182015599517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5648b0180546001600160a01b0319908116928b1692909217905596517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5658b015594517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5668a015592517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5678901805490961690871617909455517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56890960180549151969094166001600160a81b031990911617600160a01b959092169490940217905590546104e99190610ea4565b6001600160a01b0385166000908152600160208181526040808420888552825280842094909455338352600290529181209054909161052791610ea4565b815460018101835560009283526020909220909101556106d3565b6040805160e0810182526001600160a01b038616600090815260016020908152838220878352905291822054825491928392909190811061058557610585610ec9565b6000918252602080832060069092029091015483526001600160a01b03808a168483015260408085018c9052426060860152908916835260018252808320888452909152812054815460809093019281106105e2576105e2610ec9565b60009182526020808320600460069093020191909101546001600160a01b039081168452338483015260ff871660409485015288168252600181528282208783529052908120548154811061063957610639610ec9565b60009182526020918290208351600690920201908155908201516001820180546001600160a01b039283166001600160a01b031991821617909155604084015160028401556060840151600384015560808401516004840180549184169190921617905560a08301516005909201805460c09094015160ff16600160a01b026001600160a81b031990941692909116919091179190911790555b6040516323b872dd60e01b81526001600160a01b038516906323b872dd9061070390339030908890600401610e80565b600060405180830381600087803b15801561071d57600080fd5b505af1158015610731573d6000803e3d6000fd5b50505050505050505050565b6000818154811061074d57600080fd5b60009182526020909120600690910201805460018201546002830154600384015460048501546005909501549395506001600160a01b03928316949193909291821691811690600160a01b900460ff1687565b600260205281600052604060002081815481106107bc57600080fd5b90600052602060002001600091509150505481565b6001600160a01b03841660009081526001602090815260408083208684529091528120548154829190811061080857610808610ec9565b60009182526020918290206040805160e0810182526006939093029091018054835260018101546001600160a01b03908116948401949094526002810154918301829052600381015460608401526004810154841660808401526005015492831660a0830152600160a01b90920460ff1660c08201529150821480156108a35750826001600160a01b031681602001516001600160a01b0316145b6109245760405162461bcd60e51b815260206004820152604660248201527f4e6f7420726967687420616d6f756e74206f722063757272656e63792073656e60448201527f742c206861766520746f20626520657175616c2063757272656e637920616e6460648201526520707269636560d01b608482015260a4016101f3565b80602001516001600160a01b03166323b872dd333084604001516040518463ffffffff1660e01b815260040161095c93929190610e80565b602060405180830381600087803b15801561097657600080fd5b505af115801561098a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ae9190610de0565b50602081015160a0820151604080840151905163a9059cbb60e01b81526001600160a01b039283166004820152602481019190915291169063a9059cbb90604401602060405180830381600087803b158015610a0957600080fd5b505af1158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190610de0565b506001600160a01b038516600090815260016020908152604080832087845290915281205481548291908110610a7957610a79610ec9565b906000526020600020906006020160050160146101000a81548160ff021916908360ff160217905550846001600160a01b03166323b872dd3033876040518463ffffffff1660e01b8152600401610ad293929190610e80565b600060405180830381600087803b158015610aec57600080fd5b505af1158015610b00573d6000803e3d6000fd5b505050505050505050565b6001600160a01b038216600090815260016020908152604080832084845290915281205481548291908110610b4257610b42610ec9565b60009182526020918290206040805160e0810182526006939093029091018054835260018101546001600160a01b03908116948401949094526002810154918301829052600381015460608401526004810154841660808401526005015492831660a0830152600160a01b90920460ff1660c082015291503414610c225760405162461bcd60e51b815260206004820152603160248201527f4e6f7420726967687420616d6f756e7420554e512073656e742c206861766520604482015270746f20626520657175616c20707269636560781b60648201526084016101f3565b8060a001516001600160a01b03166108fc82604001519081150290604051600060405180830381858888f19350505050158015610c63573d6000803e3d6000fd5b506001600160a01b038316600090815260016020908152604080832085845290915281205481548291908110610c9b57610c9b610ec9565b906000526020600020906006020160050160146101000a81548160ff021916908360ff160217905550826001600160a01b03166323b872dd3033856040518463ffffffff1660e01b8152600401610cf493929190610e80565b600060405180830381600087803b158015610d0e57600080fd5b505af1158015610d22573d6000803e3d6000fd5b50505050505050565b600060208284031215610d3d57600080fd5b8135610d4881610edf565b9392505050565b600060208284031215610d6157600080fd5b8151610d4881610edf565b60008060408385031215610d7f57600080fd5b8235610d8a81610edf565b946020939093013593505050565b60008060008060808587031215610dae57600080fd5b8435610db981610edf565b9350602085013592506040850135610dd081610edf565b9396929550929360600135925050565b600060208284031215610df257600080fd5b81518015158114610d4857600080fd5b600060208284031215610e1457600080fd5b5035919050565b600080600080600060a08688031215610e3357600080fd5b853594506020860135610e4581610edf565b93506040860135610e5581610edf565b925060608601359150608086013560ff81168114610e7257600080fd5b809150509295509295909350565b6001600160a01b039384168152919092166020820152604081019190915260600190565b600082821015610ec457634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0381168114610ef457600080fd5b5056fea2646970667358221220fbf33eb1e471c428b86ad6d948b8699fd08a127b923d5fe27ec1e1ec5f59627564736f6c63430008070033
\ No newline at end of file
tests/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);
+ }
+}
tests/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 });
+ });
+});
tests/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
tests/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];
}
tests/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