git.delta.rocks / unique-network / refs/commits / 28d97cada79a

difftreelog

test add bench for nesting (#963)

Pavel Orlov2023-07-11parent: #83605d4.patch.diff
in: master
* feat: added bench for nesting

* fix: nitpicks

* fix: remove unused deps

* test(market): compilator version has been changed

* use toolchain version from .env fir codestyle wf

* fix: fmt

* chore: update `proc-macro2` dep

Updated from 1.0.59 to 1.0.63

* Fix solidity version

---------

16 files changed

modified.github/workflows/codestyle.ymldiffbeforeafterboth
--- a/.github/workflows/codestyle.yml
+++ b/.github/workflows/codestyle.yml
@@ -16,9 +16,12 @@
       - uses: actions/checkout@v3.1.0
         with:
           ref: ${{ github.head_ref }}            
-      - name: Install latest nightly
-        uses: dtolnay/rust-toolchain@nightly
+      - name: Read .env file
+        uses: xom9ikk/dotenv@v2          
+      - name: Install toolchain version from .env
+        uses: dtolnay/rust-toolchain@master
         with:
+            toolchain: ${{ env.RUST_TOOLCHAIN }}
             targets: wasm32-unknown-unknown
             components: rustfmt, clippy
       - name: Run cargo fmt
@@ -50,9 +53,12 @@
       - uses: actions/checkout@v3.1.0
       - name: Install substrate dependencies
         run: sudo apt install -y libssl-dev pkg-config libclang-dev clang protobuf-compiler
-      - name: Install latest nightly
-        uses: dtolnay/rust-toolchain@nightly
+      - name: Read .env file
+        uses: xom9ikk/dotenv@v2
+      - name: Install toolchain version from .env
+        uses: dtolnay/rust-toolchain@master
         with:
+            toolchain: ${{ env.RUST_TOOLCHAIN }}
             targets: wasm32-unknown-unknown
             components: rustfmt, clippy
       - name: Run cargo check
modified.vscode/settings.jsondiffbeforeafterboth
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,16 +1,14 @@
 {
-    "eslint.format.enable": true,
-    "[javascript]": {
-        "editor.defaultFormatter": "dbaeumer.vscode-eslint"
-    },
-    "[typescript]": {
-        "editor.defaultFormatter": "dbaeumer.vscode-eslint"
-    },
-    "rust-analyzer.cargo.extraEnv": {
-        "SKIP_WASM_BUILD": "1"
-    },
-    "rust-analyzer.cargo.features": [
-        "runtime-benchmarks",
-        "try-runtime"
-    ]
-}
\ No newline at end of file
+	"eslint.format.enable": true,
+	"[javascript]": {
+		"editor.defaultFormatter": "dbaeumer.vscode-eslint"
+	},
+	"[typescript]": {
+		"editor.defaultFormatter": "dbaeumer.vscode-eslint"
+	},
+	"rust-analyzer.cargo.extraEnv": {
+		"SKIP_WASM_BUILD": "1"
+	},
+	"rust-analyzer.cargo.features": ["runtime-benchmarks", "try-runtime"],
+	"solidity.packageDefaultDependenciesDirectory": "tests/node_modules"
+}
modifiedCargo.lockdiffbeforeafterboth
92169216
9217[[package]]9217[[package]]
9218name = "proc-macro2"9218name = "proc-macro2"
9219version = "1.0.59"9219version = "1.0.63"
9220source = "registry+https://github.com/rust-lang/crates.io-index"9220source = "registry+https://github.com/rust-lang/crates.io-index"
9221checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b"9221checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
9222dependencies = [9222dependencies = [
9223 "unicode-ident",9223 "unicode-ident",
9224]9224]
modifiedpallets/evm-coder-substrate/procedural/src/lib.rsdiffbeforeafterboth
--- a/pallets/evm-coder-substrate/procedural/src/lib.rs
+++ b/pallets/evm-coder-substrate/procedural/src/lib.rs
@@ -52,7 +52,7 @@
 		let (impl_generics, ty_generics, _where_clause) = input.generics.split_for_impl();
 		let ident = &input.ident;
 		let Data::Enum(data) = &input.data else {
-			return Err(Error::new_spanned(input, "PreDispatch input is enum"))
+			return Err(Error::new_spanned(input, "PreDispatch input is enum"));
 		};
 
 		let matching = data
modifiedpallets/structure/src/lib.rsdiffbeforeafterboth
--- a/pallets/structure/src/lib.rs
+++ b/pallets/structure/src/lib.rs
@@ -399,8 +399,9 @@
 		if is_collection(account.as_eth()) {
 			fail!(<Error<T>>::CantNestTokenUnderCollection);
 		}
-		let Some((collection, token)) = T::CrossTokenAddressMapping::address_to_token(account) else {
-			return Ok(())
+		let Some((collection, token)) = T::CrossTokenAddressMapping::address_to_token(account)
+		else {
+			return Ok(());
 		};
 
 		let dispatch = T::CollectionDispatch::dispatch(collection)?;
modifiedtests/package.jsondiffbeforeafterboth
--- a/tests/package.json
+++ b/tests/package.json
@@ -136,12 +136,15 @@
     "@polkadot/util-crypto": "12.2.1",
     "@polkadot/wasm-crypto-asmjs": "^7.2.1",
     "@polkadot/wasm-crypto-wasm": "^7.2.1",
+    "@rmrk-team/evm-contracts": "^1.2.1",
+    "@typechain/web3-v1": "^6.0.3",
     "chai-as-promised": "^7.1.1",
     "chai-like": "^1.1.1",
     "csv-writer": "^1.6.0",
     "find-process": "^1.4.7",
     "lossless-json": "^2.0.9",
-    "solc": "0.8.17",
+    "solc": "0.8.18",
+    "typechain": "^8.2.0",
     "web3": "1.10.0"
   },
   "resolutions": {
addedtests/src/benchmarks/nesting/ABIGEN/RMRKNestableMintable.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/benchmarks/nesting/ABIGEN/RMRKNestableMintable.ts
@@ -0,0 +1,355 @@
+/* Autogenerated file. Do not edit manually. */
+/* tslint:disable */
+/* eslint-disable */
+
+import type BN from "bn.js";
+import type { ContractOptions } from "web3-eth-contract";
+import type { EventLog } from "web3-core";
+import type { EventEmitter } from "events";
+import type {
+  Callback,
+  PayableTransactionObject,
+  NonPayableTransactionObject,
+  BlockType,
+  ContractEventLog,
+  BaseContract,
+} from "./types";
+
+export interface EventOptions {
+  filter?: object;
+  fromBlock?: BlockType;
+  topics?: string[];
+}
+
+export type AllChildrenRejected = ContractEventLog<{
+  tokenId: string;
+  0: string;
+}>;
+export type Approval = ContractEventLog<{
+  owner: string;
+  approved: string;
+  tokenId: string;
+  0: string;
+  1: string;
+  2: string;
+}>;
+export type ApprovalForAll = ContractEventLog<{
+  owner: string;
+  operator: string;
+  approved: boolean;
+  0: string;
+  1: string;
+  2: boolean;
+}>;
+export type ChildAccepted = ContractEventLog<{
+  tokenId: string;
+  childIndex: string;
+  childAddress: string;
+  childId: string;
+  0: string;
+  1: string;
+  2: string;
+  3: string;
+}>;
+export type ChildProposed = ContractEventLog<{
+  tokenId: string;
+  childIndex: string;
+  childAddress: string;
+  childId: string;
+  0: string;
+  1: string;
+  2: string;
+  3: string;
+}>;
+export type ChildTransferred = ContractEventLog<{
+  tokenId: string;
+  childIndex: string;
+  childAddress: string;
+  childId: string;
+  fromPending: boolean;
+  toZero: boolean;
+  0: string;
+  1: string;
+  2: string;
+  3: string;
+  4: boolean;
+  5: boolean;
+}>;
+export type NestTransfer = ContractEventLog<{
+  from: string;
+  to: string;
+  fromTokenId: string;
+  toTokenId: string;
+  tokenId: string;
+  0: string;
+  1: string;
+  2: string;
+  3: string;
+  4: string;
+}>;
+export type Transfer = ContractEventLog<{
+  from: string;
+  to: string;
+  tokenId: string;
+  0: string;
+  1: string;
+  2: string;
+}>;
+
+export interface RMRKNestableMintable extends BaseContract {
+  constructor(
+    jsonInterface: any[],
+    address?: string,
+    options?: ContractOptions
+  ): RMRKNestableMintable;
+  clone(): RMRKNestableMintable;
+  methods: {
+    RMRK_INTERFACE(): NonPayableTransactionObject<string>;
+
+    VERSION(): NonPayableTransactionObject<string>;
+
+    acceptChild(
+      parentId: number | string | BN,
+      childIndex: number | string | BN,
+      childAddress: string,
+      childId: number | string | BN
+    ): NonPayableTransactionObject<void>;
+
+    addChild(
+      parentId: number | string | BN,
+      childId: number | string | BN,
+      data: string | number[]
+    ): NonPayableTransactionObject<void>;
+
+    approve(
+      to: string,
+      tokenId: number | string | BN
+    ): NonPayableTransactionObject<void>;
+
+    balanceOf(owner: string): NonPayableTransactionObject<string>;
+
+    "burn(uint256)"(
+      tokenId: number | string | BN
+    ): NonPayableTransactionObject<void>;
+
+    "burn(uint256,uint256)"(
+      tokenId: number | string | BN,
+      maxChildrenBurns: number | string | BN
+    ): NonPayableTransactionObject<string>;
+
+    childOf(
+      parentId: number | string | BN,
+      index: number | string | BN
+    ): NonPayableTransactionObject<[string, string]>;
+
+    childrenOf(
+      parentId: number | string | BN
+    ): NonPayableTransactionObject<[string, string][]>;
+
+    directOwnerOf(tokenId: number | string | BN): NonPayableTransactionObject<{
+      0: string;
+      1: string;
+      2: boolean;
+    }>;
+
+    getApproved(
+      tokenId: number | string | BN
+    ): NonPayableTransactionObject<string>;
+
+    isApprovedForAll(
+      owner: string,
+      operator: string
+    ): NonPayableTransactionObject<boolean>;
+
+    mint(
+      to: string,
+      tokenId: number | string | BN
+    ): NonPayableTransactionObject<void>;
+
+    name(): NonPayableTransactionObject<string>;
+
+    nestMint(
+      to: string,
+      tokenId: number | string | BN,
+      destinationId: number | string | BN
+    ): NonPayableTransactionObject<void>;
+
+    nestTransfer(
+      to: string,
+      tokenId: number | string | BN,
+      destinationId: number | string | BN
+    ): NonPayableTransactionObject<void>;
+
+    nestTransferFrom(
+      from: string,
+      to: string,
+      tokenId: number | string | BN,
+      destinationId: number | string | BN,
+      data: string | number[]
+    ): NonPayableTransactionObject<void>;
+
+    onERC721Received(
+      _operator: string,
+      _from: string,
+      _tokenId: number | string | BN,
+      _data: string | number[]
+    ): NonPayableTransactionObject<string>;
+
+    ownerOf(tokenId: number | string | BN): NonPayableTransactionObject<string>;
+
+    pendingChildOf(
+      parentId: number | string | BN,
+      index: number | string | BN
+    ): NonPayableTransactionObject<[string, string]>;
+
+    pendingChildrenOf(
+      parentId: number | string | BN
+    ): NonPayableTransactionObject<[string, string][]>;
+
+    rejectAllChildren(
+      tokenId: number | string | BN,
+      maxRejections: number | string | BN
+    ): NonPayableTransactionObject<void>;
+
+    safeMint(to: string): NonPayableTransactionObject<void>;
+
+    "safeTransferFrom(address,address,uint256)"(
+      from: string,
+      to: string,
+      tokenId: number | string | BN
+    ): NonPayableTransactionObject<void>;
+
+    "safeTransferFrom(address,address,uint256,bytes)"(
+      from: string,
+      to: string,
+      tokenId: number | string | BN,
+      data: string | number[]
+    ): NonPayableTransactionObject<void>;
+
+    setApprovalForAll(
+      operator: string,
+      approved: boolean
+    ): NonPayableTransactionObject<void>;
+
+    supportsInterface(
+      interfaceId: string | number[]
+    ): NonPayableTransactionObject<boolean>;
+
+    symbol(): NonPayableTransactionObject<string>;
+
+    transfer(
+      to: string,
+      tokenId: number | string | BN
+    ): NonPayableTransactionObject<void>;
+
+    transferChild(
+      tokenId: number | string | BN,
+      to: string,
+      destinationId: number | string | BN,
+      childIndex: number | string | BN,
+      childAddress: string,
+      childId: number | string | BN,
+      isPending: boolean,
+      data: string | number[]
+    ): NonPayableTransactionObject<void>;
+
+    transferFrom(
+      from: string,
+      to: string,
+      tokenId: number | string | BN
+    ): NonPayableTransactionObject<void>;
+  };
+  events: {
+    AllChildrenRejected(cb?: Callback<AllChildrenRejected>): EventEmitter;
+    AllChildrenRejected(
+      options?: EventOptions,
+      cb?: Callback<AllChildrenRejected>
+    ): EventEmitter;
+
+    Approval(cb?: Callback<Approval>): EventEmitter;
+    Approval(options?: EventOptions, cb?: Callback<Approval>): EventEmitter;
+
+    ApprovalForAll(cb?: Callback<ApprovalForAll>): EventEmitter;
+    ApprovalForAll(
+      options?: EventOptions,
+      cb?: Callback<ApprovalForAll>
+    ): EventEmitter;
+
+    ChildAccepted(cb?: Callback<ChildAccepted>): EventEmitter;
+    ChildAccepted(
+      options?: EventOptions,
+      cb?: Callback<ChildAccepted>
+    ): EventEmitter;
+
+    ChildProposed(cb?: Callback<ChildProposed>): EventEmitter;
+    ChildProposed(
+      options?: EventOptions,
+      cb?: Callback<ChildProposed>
+    ): EventEmitter;
+
+    ChildTransferred(cb?: Callback<ChildTransferred>): EventEmitter;
+    ChildTransferred(
+      options?: EventOptions,
+      cb?: Callback<ChildTransferred>
+    ): EventEmitter;
+
+    NestTransfer(cb?: Callback<NestTransfer>): EventEmitter;
+    NestTransfer(
+      options?: EventOptions,
+      cb?: Callback<NestTransfer>
+    ): EventEmitter;
+
+    Transfer(cb?: Callback<Transfer>): EventEmitter;
+    Transfer(options?: EventOptions, cb?: Callback<Transfer>): EventEmitter;
+
+    allEvents(options?: EventOptions, cb?: Callback<EventLog>): EventEmitter;
+  };
+
+  once(event: "AllChildrenRejected", cb: Callback<AllChildrenRejected>): void;
+  once(
+    event: "AllChildrenRejected",
+    options: EventOptions,
+    cb: Callback<AllChildrenRejected>
+  ): void;
+
+  once(event: "Approval", cb: Callback<Approval>): void;
+  once(event: "Approval", options: EventOptions, cb: Callback<Approval>): void;
+
+  once(event: "ApprovalForAll", cb: Callback<ApprovalForAll>): void;
+  once(
+    event: "ApprovalForAll",
+    options: EventOptions,
+    cb: Callback<ApprovalForAll>
+  ): void;
+
+  once(event: "ChildAccepted", cb: Callback<ChildAccepted>): void;
+  once(
+    event: "ChildAccepted",
+    options: EventOptions,
+    cb: Callback<ChildAccepted>
+  ): void;
+
+  once(event: "ChildProposed", cb: Callback<ChildProposed>): void;
+  once(
+    event: "ChildProposed",
+    options: EventOptions,
+    cb: Callback<ChildProposed>
+  ): void;
+
+  once(event: "ChildTransferred", cb: Callback<ChildTransferred>): void;
+  once(
+    event: "ChildTransferred",
+    options: EventOptions,
+    cb: Callback<ChildTransferred>
+  ): void;
+
+  once(event: "NestTransfer", cb: Callback<NestTransfer>): void;
+  once(
+    event: "NestTransfer",
+    options: EventOptions,
+    cb: Callback<NestTransfer>
+  ): void;
+
+  once(event: "Transfer", cb: Callback<Transfer>): void;
+  once(event: "Transfer", options: EventOptions, cb: Callback<Transfer>): void;
+}
addedtests/src/benchmarks/nesting/ABIGEN/index.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/benchmarks/nesting/ABIGEN/index.ts
@@ -0,0 +1,4 @@
+/* Autogenerated file. Do not edit manually. */
+/* tslint:disable */
+/* eslint-disable */
+export type { RMRKNestableMintable } from "./RMRKNestableMintable";
addedtests/src/benchmarks/nesting/ABIGEN/types.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/benchmarks/nesting/ABIGEN/types.ts
@@ -0,0 +1,73 @@
+/* Autogenerated file. Do not edit manually. */
+/* tslint:disable */
+/* eslint-disable */
+import type BN from "bn.js";
+import type { EventEmitter } from "events";
+import type { EventLog, PromiEvent, TransactionReceipt } from "web3-core/types";
+import type { Contract } from "web3-eth-contract";
+
+export interface EstimateGasOptions {
+  from?: string;
+  gas?: number;
+  value?: number | string | BN;
+}
+
+export interface EventOptions {
+  filter?: object;
+  fromBlock?: BlockType;
+  topics?: string[];
+}
+
+export type Callback<T> = (error: Error, result: T) => void;
+export interface ContractEventLog<T> extends EventLog {
+  returnValues: T;
+}
+export interface ContractEventEmitter<T> extends EventEmitter {
+  on(event: "connected", listener: (subscriptionId: string) => void): this;
+  on(
+    event: "data" | "changed",
+    listener: (event: ContractEventLog<T>) => void
+  ): this;
+  on(event: "error", listener: (error: Error) => void): this;
+}
+
+export interface NonPayableTx {
+  nonce?: string | number | BN;
+  chainId?: string | number | BN;
+  from?: string;
+  to?: string;
+  data?: string;
+  gas?: string | number | BN;
+  maxPriorityFeePerGas?: string | number | BN;
+  maxFeePerGas?: string | number | BN;
+  gasPrice?: string | number | BN;
+}
+
+export interface PayableTx extends NonPayableTx {
+  value?: string | number | BN;
+}
+
+export interface NonPayableTransactionObject<T> {
+  arguments: any[];
+  call(tx?: NonPayableTx, block?: BlockType): Promise<T>;
+  send(tx?: NonPayableTx): PromiEvent<TransactionReceipt>;
+  estimateGas(tx?: NonPayableTx): Promise<number>;
+  encodeABI(): string;
+}
+
+export interface PayableTransactionObject<T> {
+  arguments: any[];
+  call(tx?: PayableTx, block?: BlockType): Promise<T>;
+  send(tx?: PayableTx): PromiEvent<TransactionReceipt>;
+  estimateGas(tx?: PayableTx): Promise<number>;
+  encodeABI(): string;
+}
+
+export type BlockType =
+  | "latest"
+  | "pending"
+  | "genesis"
+  | "earliest"
+  | number
+  | BN;
+export type BaseContract = Omit<Contract, "clone" | "once">;
addedtests/src/benchmarks/nesting/RMRKNestableMintable.soldiffbeforeafterboth
--- /dev/null
+++ b/tests/src/benchmarks/nesting/RMRKNestableMintable.sol
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.18;
+
+import "@rmrk-team/evm-contracts/contracts/RMRK/nestable/RMRKNestable.sol";
+import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
+
+contract RMRKNestableMintable is RMRKNestable, IERC721Receiver {
+	uint256 private _counter;
+
+	constructor() RMRKNestable("RMRK", "nesting") {
+		_counter = 1;
+	}
+
+	function safeMint(address to) external {
+		_safeMint(to, _counter, "");
+		_counter++;
+	}
+
+	function mint(address to, uint256 tokenId) external {
+		_mint(to, tokenId, "");
+	}
+
+	function nestMint(address to, uint256 tokenId, uint256 destinationId) external {
+		_nestMint(to, tokenId, destinationId, "");
+	}
+
+	function nestTransfer(address to, uint256 tokenId, uint256 destinationId) public virtual {
+		nestTransferFrom(_msgSender(), to, tokenId, destinationId, "");
+	}
+
+	function transfer(address to, uint256 tokenId) public virtual {
+		transferFrom(_msgSender(), to, tokenId);
+	}
+
+	function onERC721Received(
+		address _operator,
+		address _from,
+		uint256 _tokenId,
+		bytes calldata _data
+	) external returns (bytes4) {
+		return IERC721Receiver.onERC721Received.selector;
+	}
+}
addedtests/src/benchmarks/nesting/abigen.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/benchmarks/nesting/abigen.ts
@@ -0,0 +1,20 @@
+import {runTypeChain, glob, DEFAULT_FLAGS} from 'typechain';
+
+
+async function main() {
+  const cwd = process.cwd();
+
+  // find all files matching the glob
+  const allFiles = glob(cwd, ['./ABI/*.abi']);
+
+  await runTypeChain({
+    cwd,
+    filesToProcess: allFiles,
+    allFiles,
+    outDir: 'ABIGEN',
+    target: 'web3-v1',
+    flags: {...DEFAULT_FLAGS, alwaysGenerateOverloads: true, tsNocheck: false},
+  });
+}
+
+main().catch(console.error);
\ No newline at end of file
addedtests/src/benchmarks/nesting/index.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/benchmarks/nesting/index.ts
@@ -0,0 +1,227 @@
+import {EthUniqueHelper, usingEthPlaygrounds} from '../../eth/util';
+import {readFile} from 'fs/promises';
+import {
+  ICrossAccountId,
+} from '../../util/playgrounds/types';
+import {IKeyringPair} from '@polkadot/types/types';
+import {UniqueNFTCollection} from '../../util/playgrounds/unique';
+import {Contract} from 'web3-eth-contract';
+import {createObjectCsvWriter} from 'csv-writer';
+import {convertToTokens, createCollectionForBenchmarks, PERMISSIONS, PROPERTIES} from '../utils/common';
+import {makeNames} from '../../util';
+import {ContractImports} from '../../eth/util/playgrounds/types';
+import {RMRKNestableMintable} from './ABIGEN';
+import {rm} from 'fs';
+
+const {dirname} = makeNames(import.meta.url);
+
+export const CONTRACT_IMPORT: ContractImports[] = [
+  {
+    fsPath: `${dirname}/../../../node_modules/@rmrk-team/evm-contracts/contracts/RMRK/nestable/RMRKNestable.sol`,
+    solPath: '@rmrk-team/evm-contracts/contracts/RMRK/nestable/RMRKNestable.sol',
+  },
+  {
+    fsPath: `${dirname}/../../../node_modules/@rmrk-team/evm-contracts/contracts/RMRK/nestable/IERC6059.sol`,
+    solPath: '@rmrk-team/evm-contracts/contracts/RMRK/nestable/IERC6059.sol',
+  },
+  {
+    fsPath: `${dirname}/../../../node_modules/@rmrk-team/evm-contracts/contracts/RMRK/core/RMRKCore.sol`,
+    solPath: '@rmrk-team/evm-contracts/contracts/RMRK/core/RMRKCore.sol',
+  },
+  {
+    fsPath: `${dirname}/../../../node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol`,
+    solPath: '@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol',
+  },
+  {
+    fsPath: `${dirname}/../../../node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol`,
+    solPath: '@openzeppelin/contracts/token/ERC721/IERC721.sol',
+  },
+  {
+    fsPath: `${dirname}/../../../node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol`,
+    solPath: '@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol',
+  },
+  {
+    fsPath: `${dirname}/../../../node_modules/@openzeppelin/contracts/utils/Address.sol`,
+    solPath: '@openzeppelin/contracts/utils/Address.sol',
+  },
+  {
+    fsPath: `${dirname}/../../../node_modules/@openzeppelin/contracts/utils/Context.sol`,
+    solPath: '@openzeppelin/contracts/utils/Context.sol',
+  },
+  {
+    fsPath: `${dirname}/../../../node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol`,
+    solPath: '@openzeppelin/contracts/utils/introspection/IERC165.sol',
+  },
+  {
+    fsPath: `${dirname}/../../../node_modules/@rmrk-team/evm-contracts/contracts/RMRK/library/RMRKErrors.sol`,
+    solPath: '@rmrk-team/evm-contracts/contracts/RMRK/library/RMRKErrors.sol',
+  },
+  {
+    fsPath: `${dirname}/../../../node_modules/@rmrk-team/evm-contracts/contracts/RMRK/core/IRMRKCore.sol`,
+    solPath: '@rmrk-team/evm-contracts/contracts/RMRK/core/IRMRKCore.sol',
+  },
+  {
+    fsPath: `${dirname}/RMRKNestableMintable.sol`,
+    solPath: 'RMRKNestableMintable.sol',
+  },
+];
+
+
+const main = async () => {
+
+  await usingEthPlaygrounds(async (helper, privateKey) => {
+
+    const donor = await privateKey('//Alice'); // Seed from account with balance on this network
+
+    const eth = await measureEth(helper, donor);
+    const sub = await measureSub(helper, donor);
+    const rmrk = await measureRMRK(helper, donor);
+    console.table({susbtrate: sub, eth: eth, rmrk: rmrk});
+  });
+};
+
+async function measureRMRK(helper: EthUniqueHelper, donor: IKeyringPair) {
+  const CONTRACT_SOURCE = (
+    await readFile(`${dirname}/RMRKNestableMintable.sol`)
+  ).toString();
+  const RELAYER_SOURCE = (await readFile(`${dirname}/relayer.sol`)).toString();
+
+  const ethSigner = await helper.eth.createAccountWithBalance(donor);
+
+  const contract = await helper.ethContract.deployByCode(
+    ethSigner,
+    'RMRKNestableMintable',
+    CONTRACT_SOURCE,
+    CONTRACT_IMPORT,
+    5000000,
+  );
+
+  const relayer = await helper.ethContract.deployByCode(
+    ethSigner,
+    'Relayer',
+    RELAYER_SOURCE,
+    CONTRACT_IMPORT,
+    5000000,
+    [contract.options.address],
+  );
+
+  const relayerAddress = relayer.options.address;
+
+  const rmrk = contract as any as RMRKNestableMintable;
+  const createTokenFor = async (receiver: string) => {
+    const tokenReceipt = await rmrk.methods.safeMint(receiver).send({from: ethSigner});
+    return tokenReceipt.events!['Transfer'].returnValues.tokenId as number;
+  };
+
+
+  const nestId = await createTokenFor(ethSigner);
+  const outerCollectionNestedId = 10;
+  const contractOwnedNestId = await createTokenFor(relayerAddress);
+  const nextTokenId = contractOwnedNestId + 1;
+
+  const nestTransfer = await helper.arrange.calculcateFee({Ethereum: ethSigner}, async () => {
+    const addChildData = rmrk.methods.addChild(nestId, outerCollectionNestedId, []).encodeABI();
+    await relayer.methods.relay(addChildData).send({from: ethSigner});
+    await rmrk.methods.acceptChild(nestId, 0, relayerAddress, outerCollectionNestedId).send({from: ethSigner});
+  });
+
+
+  const nestMint = await helper.arrange.calculcateFee({Ethereum: ethSigner}, async () => {
+    const nestMintData = rmrk.methods.nestMint(rmrk.options.address, nextTokenId, contractOwnedNestId).encodeABI();
+    await relayer.methods.relay(nestMintData).send({from: ethSigner});
+    const acceptNestedToken = rmrk.methods.acceptChild(contractOwnedNestId, 0, rmrk.options.address, nextTokenId).encodeABI();
+    await relayer.methods.relay(acceptNestedToken).send({from: ethSigner});
+  });
+
+
+  const unnestToken = await helper.arrange.calculcateFee({Ethereum: ethSigner}, async () => {
+    const unnestData = rmrk.methods.transferChild(contractOwnedNestId, ethSigner, 0, 0, rmrk.options.address, nextTokenId, false, []).encodeABI();
+    await relayer.methods.relay(unnestData).send({from: ethSigner});
+  });
+
+  return {mint: convertToTokens(nestMint), transfer: convertToTokens(nestTransfer), unnest: convertToTokens(unnestToken)};
+}
+
+async function measureEth(helper: EthUniqueHelper, donor: IKeyringPair) {
+  const owner = await helper.eth.createAccountWithBalance(donor);
+  const {collectionId, contract} = await createNestingCollection(helper, owner);
+
+  // Create a token to be nested to
+  const mintingTargetNFTTokenIdResult = await contract.methods.mint(owner).send({from: owner});
+  const targetNFTTokenId = mintingTargetNFTTokenIdResult.events.Transfer.returnValues.tokenId;
+  const targetNftTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetNFTTokenId);
+
+  // Create a nested token
+  const nestMint = await helper.arrange.calculcateFee({Ethereum: owner}, async () => {
+    await contract.methods.mint(targetNftTokenAddress).send({from: owner});
+  });
+
+  // Create a token to be nested and nest
+  const mintingSecondTokenIdResult = await contract.methods.mint(owner).send({from: owner});
+  const nestedTokenId = mintingSecondTokenIdResult.events.Transfer.returnValues.tokenId;
+
+  const nestTransfer = await helper.arrange.calculcateFee({Ethereum: owner}, async () => {
+    await contract.methods.transfer(targetNftTokenAddress, nestedTokenId).send({from: owner});
+  });
+
+  const unnestToken = await helper.arrange.calculcateFee({Ethereum: owner}, async () => {
+    await contract.methods.transferFrom(targetNftTokenAddress, owner, nestedTokenId).send({from: owner});
+  });
+  return {mint: convertToTokens(nestMint), transfer: convertToTokens(nestTransfer), unnest: convertToTokens(unnestToken)};
+}
+
+async function measureSub(helper: EthUniqueHelper, donor: IKeyringPair) {
+
+  const [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);
+
+  const targetNFTCollection = await helper.nft.mintCollection(alice);
+  const targetTokenBob = await targetNFTCollection.mintToken(alice, {Substrate: bob.address});
+
+
+  const collectionForNesting = await helper.nft.mintCollection(bob);
+  // permissions should be set:
+  await targetNFTCollection.setPermissions(alice, {
+    nesting: {tokenOwner: true},
+  });
+
+  const nestMint = await helper.arrange.calculcateFee({Substrate: bob.address}, async () => {
+    await (collectionForNesting.mintToken(bob, targetTokenBob.nestingAccount()));
+  });
+
+  const nestedToken2 = await collectionForNesting.mintToken(bob);
+  const nestTransfer = await helper.arrange.calculcateFee({Substrate: bob.address}, async () => {
+    await nestedToken2.nest(bob, targetTokenBob);
+  });
+
+  const unnestToken = await helper.arrange.calculcateFee({Substrate: bob.address}, async () => {
+    await nestedToken2.transferFrom(bob, targetTokenBob.nestingAccount(), {Substrate: bob.address});
+  });
+
+  return {mint: convertToTokens(nestMint), transfer: convertToTokens(nestTransfer), unnest: convertToTokens(unnestToken)};
+}
+
+
+const createNestingCollection = async (
+  helper: EthUniqueHelper,
+  owner: string,
+): Promise<{ collectionId: number, collectionAddress: string, contract: Contract }> => {
+  const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
+
+  const contract =  helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
+  await contract.methods.setCollectionNesting(true).send({from: owner});
+
+  return {collectionId, collectionAddress, contract};
+};
+
+main()
+  .then(() => process.exit(0))
+  .catch((e) => {
+    console.log(e);
+    process.exit(1);
+  });
+
+
+
+
+
+
addedtests/src/benchmarks/nesting/relayer.soldiffbeforeafterboth
--- /dev/null
+++ b/tests/src/benchmarks/nesting/relayer.sol
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.18;
+
+import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
+import "./RMRKNestableMintable.sol";
+
+contract Relayer is RMRKNestableMintable {
+	address _receiver;
+
+	constructor(address recevier) {
+		_receiver = recevier;
+	}
+
+	function relay(bytes calldata payload) external {
+		(bool succes, bytes memory _returnData) = address(_receiver).call(payload);
+		require(succes);
+	}
+}
modifiedtests/src/eth/marketplace-v2/Market.soldiffbeforeafterboth
--- a/tests/src/eth/marketplace-v2/Market.sol
+++ b/tests/src/eth/marketplace-v2/Market.sol
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: UNLICENSED
-pragma solidity 0.8.17;
+pragma solidity 0.8.18;
 
 import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
 import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
modifiedtests/src/eth/transferValue.test.tsdiffbeforeafterboth
--- a/tests/src/eth/transferValue.test.ts
+++ b/tests/src/eth/transferValue.test.ts
@@ -36,7 +36,7 @@
       'Test',
       `
       // SPDX-License-Identifier: UNLICENSED
-      pragma solidity 0.8.17;
+      pragma solidity 0.8.18;
       
       contract Test {
         function send() public payable {
modifiedtests/yarn.lockdiffbeforeafterboth
--- a/tests/yarn.lock
+++ b/tests/yarn.lock
@@ -339,6 +339,11 @@
     "@nodelib/fs.scandir" "2.1.5"
     fastq "^1.6.0"
 
+"@openzeppelin/contracts@^4.6.0":
+  version "4.9.2"
+  resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.2.tgz#1cb2d5e4d3360141a17dbc45094a8cad6aac16c1"
+  integrity sha512-mO+y6JaqXjWeMh9glYVzVu8HYPGknAAnWyxTRhGeckOruyXQMNnlcW6w/Dx9ftLeIQk6N+ZJFuVmTwF7lEIFrg==
+
 "@openzeppelin/contracts@^4.9.0":
   version "4.9.1"
   resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.1.tgz#afa804d2c68398704b0175acc94d91a54f203645"
@@ -1015,6 +1020,13 @@
   resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
   integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
 
+"@rmrk-team/evm-contracts@^1.2.1":
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/@rmrk-team/evm-contracts/-/evm-contracts-1.2.1.tgz#5397958eb83b2d8cfebc88138811c65a90770ae5"
+  integrity sha512-jFElzC/B3VHDbvidNhAJkAOYUGXbm288zFOVM5OUyLZFcagipBZawwz2pb40XMM4HVVsw/BVUSd+L/fOWXWvpw==
+  dependencies:
+    "@openzeppelin/contracts" "^4.6.0"
+
 "@scure/base@1.1.1":
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938"
@@ -1083,6 +1095,14 @@
   resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9"
   integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==
 
+"@typechain/web3-v1@^6.0.3":
+  version "6.0.3"
+  resolved "https://registry.yarnpkg.com/@typechain/web3-v1/-/web3-v1-6.0.3.tgz#e9ea16811168677ae14dcaba719ffcc4933c8369"
+  integrity sha512-bFBYiA/Wh9XSoPtZ0nnrvg0a0brAHXhL/nCsPnPS999f9EUD9MOwkdOh8zhvY5oNzi6GMD5+KEmwE7A/eTqgeQ==
+  dependencies:
+    lodash "^4.17.15"
+    ts-essentials "^7.0.1"
+
 "@types/bn.js@^5.1.0", "@types/bn.js@^5.1.1":
   version "5.1.1"
   resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682"
@@ -1175,6 +1195,11 @@
   dependencies:
     "@types/node" "*"
 
+"@types/prettier@^2.1.1":
+  version "2.7.3"
+  resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f"
+  integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==
+
 "@types/responselike@^1.0.0":
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29"
@@ -1398,6 +1423,13 @@
   resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
   integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
 
+ansi-styles@^3.2.1:
+  version "3.2.1"
+  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
+  integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
+  dependencies:
+    color-convert "^1.9.0"
+
 ansi-styles@^4.0.0, ansi-styles@^4.1.0:
   version "4.3.0"
   resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
@@ -1423,6 +1455,16 @@
   resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
   integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
 
+array-back@^3.0.1, array-back@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0"
+  integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==
+
+array-back@^4.0.1, array-back@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e"
+  integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==
+
 array-flatten@1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
@@ -1741,6 +1783,15 @@
     pathval "^1.1.1"
     type-detect "^4.0.5"
 
+chalk@^2.4.2:
+  version "2.4.2"
+  resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
+  integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
+  dependencies:
+    ansi-styles "^3.2.1"
+    escape-string-regexp "^1.0.5"
+    supports-color "^5.3.0"
+
 chalk@^4.0.0, chalk@^4.1.0:
   version "4.1.2"
   resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
@@ -1832,6 +1883,13 @@
   dependencies:
     mimic-response "^1.0.0"
 
+color-convert@^1.9.0:
+  version "1.9.3"
+  resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
+  integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
+  dependencies:
+    color-name "1.1.3"
+
 color-convert@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
@@ -1839,6 +1897,11 @@
   dependencies:
     color-name "~1.1.4"
 
+color-name@1.1.3:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
+  integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
+
 color-name@~1.1.4:
   version "1.1.4"
   resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
@@ -1856,6 +1919,26 @@
   resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69"
   integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==
 
+command-line-args@^5.1.1:
+  version "5.2.1"
+  resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e"
+  integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==
+  dependencies:
+    array-back "^3.1.0"
+    find-replace "^3.0.0"
+    lodash.camelcase "^4.3.0"
+    typical "^4.0.0"
+
+command-line-usage@^6.1.0:
+  version "6.1.3"
+  resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.3.tgz#428fa5acde6a838779dfa30e44686f4b6761d957"
+  integrity sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==
+  dependencies:
+    array-back "^4.0.2"
+    chalk "^2.4.2"
+    table-layout "^1.0.2"
+    typical "^5.2.0"
+
 commander@^5.1.0:
   version "5.1.0"
   resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
@@ -2012,7 +2095,7 @@
   dependencies:
     ms "2.0.0"
 
-debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
+debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4:
   version "4.3.4"
   resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
   integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@@ -2055,6 +2138,11 @@
   dependencies:
     type-detect "^4.0.0"
 
+deep-extend@~0.6.0:
+  version "0.6.0"
+  resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
+  integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
+
 deep-is@^0.1.3:
   version "0.1.4"
   resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
@@ -2215,6 +2303,11 @@
   resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
   integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
 
+escape-string-regexp@^1.0.5:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
+  integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
+
 eslint-plugin-mocha@^10.1.0:
   version "10.1.0"
   resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-10.1.0.tgz#69325414f875be87fb2cb00b2ef33168d4eb7c8d"
@@ -2599,6 +2692,13 @@
     commander "^5.1.0"
     debug "^4.1.1"
 
+find-replace@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38"
+  integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==
+  dependencies:
+    array-back "^3.0.1"
+
 find-up@5.0.0, find-up@^5.0.0:
   version "5.0.0"
   resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
@@ -2700,6 +2800,15 @@
     jsonfile "^4.0.0"
     universalify "^0.1.0"
 
+fs-extra@^7.0.0:
+  version "7.0.1"
+  resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9"
+  integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==
+  dependencies:
+    graceful-fs "^4.1.2"
+    jsonfile "^4.0.0"
+    universalify "^0.1.0"
+
 fs-minipass@^1.2.7:
   version "1.2.7"
   resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"
@@ -2775,6 +2884,18 @@
   dependencies:
     is-glob "^4.0.3"
 
+glob@7.1.7:
+  version "7.1.7"
+  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90"
+  integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==
+  dependencies:
+    fs.realpath "^1.0.0"
+    inflight "^1.0.4"
+    inherits "2"
+    minimatch "^3.0.4"
+    once "^1.3.0"
+    path-is-absolute "^1.0.0"
+
 glob@7.2.0:
   version "7.2.0"
   resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
@@ -2909,6 +3030,11 @@
     ajv "^6.12.3"
     har-schema "^2.0.0"
 
+has-flag@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
+  integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
+
 has-flag@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
@@ -3383,12 +3509,17 @@
   dependencies:
     p-locate "^5.0.0"
 
+lodash.camelcase@^4.3.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
+  integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==
+
 lodash.merge@^4.6.2:
   version "4.6.2"
   resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
   integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
 
-lodash@^4.17.21:
+lodash@^4.17.15, lodash@^4.17.21:
   version "4.17.21"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
   integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -3596,6 +3727,11 @@
   dependencies:
     minimist "^1.2.6"
 
+mkdirp@^1.0.4:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
+  integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
+
 mocha@^10.1.0, mocha@^10.2.0:
   version "10.2.0"
   resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8"
@@ -4023,6 +4159,11 @@
   resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
   integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
 
+prettier@^2.3.1:
+  version "2.8.8"
+  resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da"
+  integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==
+
 process@^0.11.10:
   version "0.11.10"
   resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
@@ -4172,6 +4313,11 @@
   dependencies:
     picomatch "^2.2.1"
 
+reduce-flatten@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27"
+  integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==
+
 request@^2.79.0:
   version "2.88.2"
   resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
@@ -4437,10 +4583,10 @@
     pako "^2.0.4"
     ws "^8.8.1"
 
-solc@0.8.17:
-  version "0.8.17"
-  resolved "https://registry.yarnpkg.com/solc/-/solc-0.8.17.tgz#c748fec6a64bf029ec406aa9b37e75938d1115ae"
-  integrity sha512-Dtidk2XtTTmkB3IKdyeg6wLYopJnBVxdoykN8oP8VY3PQjN16BScYoUJTXFm2OP7P0hXNAqWiJNmmfuELtLf8g==
+solc@0.8.18:
+  version "0.8.18"
+  resolved "https://registry.yarnpkg.com/solc/-/solc-0.8.18.tgz#a05ce8918540eda5f10aa91f0f52f239b9645dad"
+  integrity sha512-wVAa2Y3BYd64Aby5LsgS3g6YC2NvZ3bJ+A8TAIAukfVuQb3AjyGrLZpyxQk5YLn14G35uZtSnIgHEpab9klOLQ==
   dependencies:
     command-exists "^1.2.8"
     commander "^8.1.0"
@@ -4480,6 +4626,11 @@
   resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
   integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==
 
+string-format@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b"
+  integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==
+
 string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
   version "4.2.3"
   resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
@@ -4527,6 +4678,13 @@
   dependencies:
     has-flag "^4.0.0"
 
+supports-color@^5.3.0:
+  version "5.5.0"
+  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
+  integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
+  dependencies:
+    has-flag "^3.0.0"
+
 supports-color@^7.1.0:
   version "7.2.0"
   resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
@@ -4556,6 +4714,16 @@
   resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
   integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
 
+table-layout@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04"
+  integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==
+  dependencies:
+    array-back "^4.0.1"
+    deep-extend "~0.6.0"
+    typical "^5.2.0"
+    wordwrapjs "^4.0.0"
+
 tar@^4.0.2:
   version "4.4.19"
   resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3"
@@ -4652,6 +4820,21 @@
   resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
   integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
 
+ts-command-line-args@^2.2.0:
+  version "2.5.1"
+  resolved "https://registry.yarnpkg.com/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz#e64456b580d1d4f6d948824c274cf6fa5f45f7f0"
+  integrity sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==
+  dependencies:
+    chalk "^4.1.0"
+    command-line-args "^5.1.1"
+    command-line-usage "^6.1.0"
+    string-format "^2.0.0"
+
+ts-essentials@^7.0.1:
+  version "7.0.3"
+  resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38"
+  integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==
+
 ts-node@^10.9.1:
   version "10.9.1"
   resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b"
@@ -4740,6 +4923,22 @@
   resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0"
   integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==
 
+typechain@^8.2.0:
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.2.0.tgz#bd4fc8f111d4405e36858bae6f744604617b60f3"
+  integrity sha512-tZqhqjxJ9xAS/Lh32jccTjMkpx7sTdUVVHAy5Bf0TIer5QFNYXotiX74oCvoVYjyxUKDK3MXHtMFzMyD3kE+jg==
+  dependencies:
+    "@types/prettier" "^2.1.1"
+    debug "^4.3.1"
+    fs-extra "^7.0.0"
+    glob "7.1.7"
+    js-sha3 "^0.8.0"
+    lodash "^4.17.15"
+    mkdirp "^1.0.4"
+    prettier "^2.3.1"
+    ts-command-line-args "^2.2.0"
+    ts-essentials "^7.0.1"
+
 typedarray-to-buffer@^3.1.5:
   version "3.1.5"
   resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
@@ -4757,6 +4956,16 @@
   resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.3.tgz#8d84219244a6b40b6fb2b33cc1c062f715b9e826"
   integrity sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==
 
+typical@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4"
+  integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==
+
+typical@^5.2.0:
+  version "5.2.0"
+  resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066"
+  integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==
+
 uglify-js@^3.1.4:
   version "3.17.4"
   resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c"
@@ -5201,6 +5410,14 @@
   resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
   integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
 
+wordwrapjs@^4.0.0:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.1.tgz#d9790bccfb110a0fc7836b5ebce0937b37a8b98f"
+  integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==
+  dependencies:
+    reduce-flatten "^2.0.0"
+    typical "^5.2.0"
+
 workerpool@6.2.1:
   version "6.2.1"
   resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"