Repository: gakonst/ethers-rs
Pull request #1852 (2022-11-10 04:06:48)

fix: generated crate not using generated version
<!--
Thank you for your Pull Request. Please provide a description above and review
the requirements below.

Bug fixes and new features should include tests.

Contributors guide: https://github.com/gakonst/ethers-rs/blob/master/CONTRIBUTING.md

The contributors guide includes instructions for running rustfmt and building the
documentation.
-->

## Motivation
currently when abigen generates a new crate. it uses the git version of the repo. However this is wrong as if someone set there ethers-rs dep to version 1.0.0, if they generated a crate for bindings. it would be the git version causing a dependency conflict 
<!--
Explain the context and why you're making that change. What is the problem
you're trying to solve? In some cases there is not a problem and this can be
thought of as being the motivation for your change.
-->

## Solution
to fix this problem we simply read from the cargo manifest directory and then parse what version the bindings are being generated from and use that over the default hardcoded version

<!--
Summarize the solution and provide any necessary context needed to understand
the code change.
-->

## PR Checklist

-   [ ] Added Tests
-   [x] Added Documentation
-   [x] Updated the changelog


Will-Smith11: @mattsse is this more what you had in mind?

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9de5209d..c9676bad 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
 
 ### Unreleased
 
+-   Add 'ethers_core::types::OpCode' and use in 'ethers_core::types::VMOperation' [1857](https://github.com/gakonst/ethers-rs/issues/1857)
 -   Remove rust_decimals dependency for ethers-core
 -   Add support for numbers greater than 2^96 for `ethers_core::utils::parse_units` [#1822](https://github.com/gakonst/ethers-rs/issues/1822)
 -   Add comment about safety of u8 -> u64 cast in `ethers_core::types::Signature`
@@ -93,12 +94,14 @@
 -   [#1632](https://github.com/gakonst/ethers-rs/pull/1632) Re-export `H32` from `ethabi`.
 -   [#1634](https://github.com/gakonst/ethers-rs/pull/1634) Derive missing `Clone`, `Copy` and `Debug` impls in ethers-etherscan.
 -   Bytes debug format now displays hex literals [#1658](https://github.com/gakonst/ethers-rs/pull/1658)
-- [#1451](https://github.com/gakonst/ethers-rs/issues/1451) Add Arithemtic Shift Left operation for I256 
+-   [#1451](https://github.com/gakonst/ethers-rs/issues/1451) Add Arithemtic Shift Left operation for I256
+-   [#1860](https://github.com/gakonst/ethers-rs/pull/1860)Update I256 type documentation calling out the inconsistency 
+    between its right shift operator and standard library numeric types.
 
 ## ethers-contract-abigen
 
 ### Unreleased
-
+-   Fix Cargo.toml generation issue that could cause dependency conflicts [#1852](https://github.com/gakonst/ethers-rs/pull/1852)
 -   Use corresponding rust structs for event fields if they're solidity structs [#1674](https://github.com/gakonst/ethers-rs/pull/1674)
 -   Add `ContractFilter` to filter contracts in `MultiAbigen` [#1564](https://github.com/gakonst/ethers-rs/pull/1564)
 -   generate error bindings for custom errors [#1549](https://github.com/gakonst/ethers-rs/pull/1549)
diff --git a/Cargo.lock b/Cargo.lock
index 494df0f8..a848202b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1278,6 +1278,7 @@ dependencies = [
  "serde_json",
  "syn",
  "tempfile",
+ "toml",
  "url",
  "walkdir",
 ]
@@ -1685,7 +1686,6 @@ checksum = "3eb42d4fb72227be5778429f9ef5240a38a358925a49f05b5cf702ce7c7e558a"
 dependencies = [
  "futures-channel",
  "futures-task",
- "tokio",
 ]
 
 [[package]]
@@ -4101,9 +4101,9 @@ dependencies = [
 
 [[package]]
 name = "toml"
-version = "0.5.8"
+version = "0.5.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
+checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
 dependencies = [
  "serde",
 ]
diff --git a/ethers-contract/ethers-contract-abigen/Cargo.toml b/ethers-contract/ethers-contract-abigen/Cargo.toml
index f57fd771..ec96bbae 100644
--- a/ethers-contract/ethers-contract-abigen/Cargo.toml
+++ b/ethers-contract/ethers-contract-abigen/Cargo.toml
@@ -29,6 +29,7 @@ dunce = "1.0.2"
 walkdir = "2.3.2"
 eyre = "0.6"
 regex = "1.6.0"
+toml = "0.5.9"
 
 [target.'cfg(target_arch = "wasm32")'.dependencies]
 # NOTE: this enables wasm compatibility for getrandom indirectly
diff --git a/ethers-contract/ethers-contract-abigen/src/contract/methods.rs b/ethers-contract/ethers-contract-abigen/src/contract/methods.rs
index cfda0b00..57e16d19 100644
--- a/ethers-contract/ethers-contract-abigen/src/contract/methods.rs
+++ b/ethers-contract/ethers-contract-abigen/src/contract/methods.rs
@@ -1,4 +1,4 @@
-use std::collections::{btree_map::Entry, BTreeMap, HashMap};
+use std::collections::{btree_map::Entry, BTreeMap, HashMap, HashSet};
 
 use super::{types, util, Context};
 use crate::{
@@ -534,11 +534,21 @@ impl Context {
             }
             // compare each overloaded function with the `first_fun`
             for (idx, overloaded_fun) in functions.into_iter().skip(1) {
+                // keep track of matched params
+                let mut already_matched_param_diff = HashSet::new();
                 // attempt to find diff in the input arguments
                 let mut diff = Vec::new();
                 let mut same_params = true;
                 for (idx, i1) in overloaded_fun.inputs.iter().enumerate() {
-                    if first_fun.inputs.iter().all(|i2| i1 != i2) {
+                    // Find the first param that differs and hasn't already been matched as diff
+                    if let Some((pos, _)) = first_fun
+                        .inputs
+                        .iter()
+                        .enumerate()
+                        .filter(|(pos, _)| !already_matched_param_diff.contains(pos))
+                        .find(|(_, i2)| i1 != *i2)
+                    {
+                        already_matched_param_diff.insert(pos);
                         diff.push(i1);
                         same_params = false;
                     } else {
diff --git a/ethers-contract/ethers-contract-abigen/src/multi.rs b/ethers-contract/ethers-contract-abigen/src/multi.rs
index b09a7019..10c3e3c9 100644
--- a/ethers-contract/ethers-contract-abigen/src/multi.rs
+++ b/ethers-contract/ethers-contract-abigen/src/multi.rs
@@ -1,4 +1,5 @@
 //! Generate bindings for multiple `Abigen`
+use crate::{util, Abigen, Context, ContractBindings, ContractFilter, ExpandedContract};
 use eyre::Result;
 use inflector::Inflector;
 use proc_macro2::TokenStream;
@@ -7,10 +8,9 @@ use std::{
     collections::{BTreeMap, BTreeSet, HashMap, HashSet},
     fs,
     io::Write,
-    path::Path,
+    path::{Path, PathBuf},
 };
-
-use crate::{util, Abigen, Context, ContractBindings, ContractFilter, ExpandedContract};
+use toml::Value;
 
 /// Collects Abigen structs for a series of contracts, pending generation of
 /// the contract bindings.
@@ -553,6 +553,7 @@ impl MultiBindingsInner {
         &self,
         name: impl AsRef<str>,
         version: impl AsRef<str>,
+        crate_version: String,
     ) -> Result<Vec<u8>> {
         let mut toml = vec![];
 
@@ -564,15 +565,31 @@ impl MultiBindingsInner {
         writeln!(toml, "# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html")?;
         writeln!(toml)?;
         writeln!(toml, "[dependencies]")?;
-        writeln!(
-            toml,
-            r#"
-ethers = {{ git = "https://github.com/gakonst/ethers-rs", default-features = false, features = ["abigen"] }}
-"#
-        )?;
+        writeln!(toml, r#"{}"#, crate_version)?;
         Ok(toml)
     }
 
+    /// parses the active Cargo.toml to get what version of ethers we are using
+    fn find_crate_version(&self) -> Result<String> {
+        let cargo_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("Cargo.toml");
+        let data = std::fs::read_to_string(cargo_dir)?;
+        let toml = data.parse::<Value>()?;
+
+        let Some(ethers) = toml.get("dependencies")
+            .and_then (|v| v.get("ethers").or_else(|| v.get("ethers-contract")))
+            else { eyre::bail!("couldn't find ethers or ethers-contract dependency")};
+        if let Some(rev) = ethers.get("rev") {
+            Ok(format!("ethers = {{ git = \"https://github.com/gakonst/ethers-rs\", rev = {}, default-features = false, features = [\"abigen\"] }}", rev))
+        } else if let Some(version) = ethers.get("version") {
+            Ok(format!(
+                "ethers = {{ version = {}, default-features = false, features = [\"abigen\"] }}",
+                version
+            ))
+        } else {
+            Ok("ethers = {{ git = \"https://github.com/gakonst/ethers-rs\", default-features = false, features = [\"abigen\"] }}".to_string())
+        }
+    }
+
     /// Write the contents of `Cargo.toml` to disk
     fn write_cargo_toml(
         &self,
@@ -580,7 +597,8 @@ ethers = {{ git = "https://github.com/gakonst/ethers-rs", default-features = fal
         name: impl AsRef<str>,
         version: impl AsRef<str>,
     ) -> Result<()> {
-        let contents = self.generate_cargo_toml(name, version)?;
+        let crate_version = self.find_crate_version()?;
+        let contents = self.generate_cargo_toml(name, version, crate_version)?;
 
         let mut file = fs::OpenOptions::new()
             .read(true)
@@ -717,7 +735,8 @@ ethers = {{ git = "https://github.com/gakonst/ethers-rs", default-features = fal
 
         if check_cargo_toml {
             // additionally check the contents of the cargo
-            let cargo_contents = self.generate_cargo_toml(name, version)?;
+            let crate_version = self.find_crate_version()?;
+            let cargo_contents = self.generate_cargo_toml(name, version, crate_version)?;
             check_file_in_dir(crate_path, "Cargo.toml", &cargo_contents)?;
         }
 
@@ -775,7 +794,7 @@ mod tests {
 
     use crate::{ExcludeContracts, SelectContracts};
     use ethers_solc::project_util::TempProject;
-    use std::{panic, path::PathBuf};
+    use std::{env, panic, path::PathBuf};
 
     struct Context {
         multi_gen: MultiAbigen,
@@ -1238,4 +1257,195 @@ contract Enum {
         let content = fs::read_to_string(&mod_).unwrap();
         assert!(content.contains("pub mod mod_ {"));
     }
+
+    #[test]
+    fn parse_ethers_crate() {
+        // gotta bunch these all together as we are overwriting env vars
+        run_test(|context| {
+            let Context { multi_gen, mod_root } = context;
+            let tmp = TempProject::dapptools().unwrap();
+
+            tmp.add_source(
+            "Cargo.toml",
+            r#"
+ [package]
+        name = "ethers-contract"
+        version = "1.0.0"
+        edition = "2018"
+        rust-version = "1.62"
+        authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
+        license = "MIT OR Apache-2.0"
+        description = "Smart contract bindings for the ethers-rs crate"
+        homepage = "https://docs.rs/ethers"
+        repository = "https://github.com/gakonst/ethers-rs"
+        keywords = ["ethereum", "web3", "celo", "ethers"]
+
+        [dependencies]
+        ethers-providers = { version = "^1.0.0", path = "../ethers-providers", default-features = false }
+"#,
+        )
+        .unwrap();
+
+            let _ = tmp.compile().unwrap();
+            env::set_var("CARGO_MANIFEST_DIR", tmp.root());
+            let single_file = false;
+            let name = "a-name";
+            let version = "290.3782.3";
+
+            multi_gen
+                .clone()
+                .build()
+                .unwrap()
+                .write_to_crate(name, version, mod_root, single_file)
+                .unwrap();
+
+            multi_gen
+                .clone()
+                .build()
+                .unwrap()
+                .ensure_consistent_crate(name, version, mod_root, single_file, true)
+                .expect("Inconsistent bindings");
+        });
+
+        run_test(|context| {
+            let Context { multi_gen, mod_root } = context;
+            let tmp = TempProject::dapptools().unwrap();
+
+            tmp.add_source(
+                "Cargo.toml",
+                r#"
+ [package]
+        name = "ethers-contract"
+        version = "1.0.0"
+        edition = "2018"
+        rust-version = "1.62"
+        authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
+        license = "MIT OR Apache-2.0"
+        description = "Smart contract bindings for the ethers-rs crate"
+        homepage = "https://docs.rs/ethers"
+        repository = "https://github.com/gakonst/ethers-rs"
+        keywords = ["ethereum", "web3", "celo", "ethers"]
+
+        [dependencies]
+        ethers-contracts = "0.4.0"
+"#,
+            )
+            .unwrap();
+
+            let _ = tmp.compile().unwrap();
+            env::set_var("CARGO_MANIFEST_DIR", tmp.root());
+
+            let single_file = false;
+            let name = "a-name";
+            let version = "290.3782.3";
+
+            multi_gen
+                .clone()
+                .build()
+                .unwrap()
+                .write_to_crate(name, version, mod_root, single_file)
+                .unwrap();
+
+            multi_gen
+                .clone()
+                .build()
+                .unwrap()
+                .ensure_consistent_crate(name, version, mod_root, single_file, true)
+                .expect("Inconsistent bindings");
+        });
+
+        run_test(|context| {
+            let Context { multi_gen, mod_root } = context;
+            let tmp = TempProject::dapptools().unwrap();
+
+            tmp.add_source(
+            "Cargo.toml",
+            r#"
+    [package]
+        name = "ethers-contract"
+        version = "1.0.0"
+        edition = "2018"
+        rust-version = "1.62"
+        authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
+        license = "MIT OR Apache-2.0"
+        description = "Smart contract bindings for the ethers-rs crate"
+        homepage = "https://docs.rs/ethers"
+        repository = "https://github.com/gakonst/ethers-rs"
+        keywords = ["ethereum", "web3", "celo", "ethers"]
+
+        [dependencies]
+        ethers = {git="https://github.com/gakonst/ethers-rs", rev = "fd8ebf5",features = ["ws", "rustls", "ipc"] }
+"#,
+        )
+        .unwrap();
+
+            let _ = tmp.compile().unwrap();
+            env::set_var("CARGO_MANIFEST_DIR", tmp.root());
+
+            let single_file = false;
+            let name = "a-name";
+            let version = "290.3782.3";
+
+            multi_gen
+                .clone()
+                .build()
+                .unwrap()
+                .write_to_crate(name, version, mod_root, single_file)
+                .unwrap();
+
+            multi_gen
+                .clone()
+                .build()
+                .unwrap()
+                .ensure_consistent_crate(name, version, mod_root, single_file, true)
+                .expect("Inconsistent bindings");
+        });
+
+        run_test(|context| {
+            let Context { multi_gen, mod_root } = context;
+            let tmp = TempProject::dapptools().unwrap();
+
+            tmp.add_source(
+                "Cargo.toml",
+                r#"
+    [package]
+        name = "ethers-contract"
+        version = "1.0.0"
+        edition = "2018"
+        rust-version = "1.62"
+        authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
+        license = "MIT OR Apache-2.0"
+        description = "Smart contract bindings for the ethers-rs crate"
+        homepage = "https://docs.rs/ethers"
+        repository = "https://github.com/gakonst/ethers-rs"
+        keywords = ["ethereum", "web3", "celo", "ethers"]
+
+        [dependencies]
+        ethers = {git="https://github.com/gakonst/ethers-rs" ,features = ["ws", "rustls", "ipc"] }
+"#,
+            )
+            .unwrap();
+
+            let _ = tmp.compile().unwrap();
+            env::set_var("CARGO_MANIFEST_DIR", tmp.root());
+
+            let single_file = false;
+            let name = "a-name";
+            let version = "290.3782.3";
+
+            multi_gen
+                .clone()
+                .build()
+                .unwrap()
+                .write_to_crate(name, version, mod_root, single_file)
+                .unwrap();
+
+            multi_gen
+                .clone()
+                .build()
+                .unwrap()
+                .ensure_consistent_crate(name, version, mod_root, single_file, true)
+                .expect("Inconsistent bindings");
+        });
+    }
 }
diff --git a/ethers-core/src/types/i256.rs b/ethers-core/src/types/i256.rs
index d6eec01a..b3bc4ae5 100644
--- a/ethers-core/src/types/i256.rs
+++ b/ethers-core/src/types/i256.rs
@@ -89,6 +89,12 @@ impl Sign {
 }
 
 /// Little-endian 256-bit signed integer.
+///
+/// ## Diversion from standard numeric types
+/// The right shift operator on I256 doesn't act in the same manner as standard numeric types
+/// (e.g. `i8`, `i16` etc). On standard types if the number is negative right shift will perform
+/// an arithmetic shift, whereas on I256 this will perform a bit-wise shift.
+/// Arithmetic shift on I256 is done via the [asr](I256::asr) and [asl](I256::asl) functions.
 #[derive(Clone, Copy, Default, Deserialize, Eq, Hash, PartialEq, Serialize)]
 #[serde(transparent)]
 pub struct I256(U256);
diff --git a/ethers-core/src/types/trace/example-trace-str.rs b/ethers-core/src/types/trace/example-trace-str.rs
index ab76f69d..f9520c28 100644
--- a/ethers-core/src/types/trace/example-trace-str.rs
+++ b/ethers-core/src/types/trace/example-trace-str.rs
@@ -1,1097 +1,1249 @@
 r#"{
-  "output": "0x",
-  "stateDiff": {
-    "0x01f0eb5c4b0a9d8285b67195f5f10ce22971a102": {
-      "balance": {
-        "*": {
-          "from": "0x7361af5818297800",
-          "to": "0x734a36bb22448000"
+    "output": "0x",
+    "stateDiff": {
+        "0x01f0eb5c4b0a9d8285b67195f5f10ce22971a102": {
+            "balance": {
+                "*": {
+                    "from": "0x7361af5818297800",
+                    "to": "0x734a36bb22448000"
+                }
+            },
+            "code": "=",
+            "nonce": {
+                "*": {
+                    "from": "0x1d6",
+                    "to": "0x1d7"
+                }
+            },
+            "storage": {}
+        },
+        "0xb2930b35844a230f00e51431acae96fe543a0347": {
+            "balance": {
+                "*": {
+                    "from": "0x11b39d46046d14d44e5",
+                    "to": "0x11b39d687ebea8b3ce5"
+                }
+            },
+            "code": "=",
+            "nonce": "=",
+            "storage": {}
+        },
+        "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3": {
+            "balance": {
+                "*": {
+                    "from": "0x109397d7f6f000",
+                    "to": "0x25e48fb49df000"
+                }
+            },
+            "code": "=",
+            "nonce": "=",
+            "storage": {}
         }
-      },
-      "code": "=",
-      "nonce": {
-        "*": {
-          "from": "0x1d6",
-          "to": "0x1d7"
-        }
-      },
-      "storage": {}
-    },
-    "0xb2930b35844a230f00e51431acae96fe543a0347": {
-      "balance": {
-        "*": {
-          "from": "0x11b39d46046d14d44e5",
-          "to": "0x11b39d687ebea8b3ce5"
-        }
-      },
-      "code": "=",
-      "nonce": "=",
-      "storage": {}
     },
-    "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3": {
-      "balance": {
-        "*": {
-          "from": "0x109397d7f6f000",
-          "to": "0x25e48fb49df000"
+    "trace": [
+        {
+            "action": {
+                "from": "0x01f0eb5c4b0a9d8285b67195f5f10ce22971a102",
+                "callType": "call",
+                "gas": "0xa5f8",
+                "input": "0x1a695230000000000000000000000000c227a75b32ed37d3f9d6341b9904d003dad3b1b3",
+                "to": "0x0b95993a39a363d99280ac950f5e4536ab5c5566",
+                "value": "0x1550f7dca70000"
+            },
+            "result": {
+                "gasUsed": "0x1ddf",
+                "output": "0x"
+            },
+            "subtraces": 1,
+            "traceAddress": [],
+            "type": "call"
+        },
+        {
+            "action": {
+                "from": "0x0b95993a39a363d99280ac950f5e4536ab5c5566",
+                "callType": "call",
+                "gas": "0x8fc",
+                "input": "0x",
+                "to": "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3",
+                "value": "0x1550f7dca70000"
+            },
+            "result": {
+                "gasUsed": "0x0",
+                "output": "0x"
+            },
+            "subtraces": 0,
+            "traceAddress": [
+                0
+            ],
+            "type": "call"
         }
-      },
-      "code": "=",
-      "nonce": "=",
-      "storage": {}
+    ],
+    "vmTrace": {
+        "code": "0x60606040523615610055576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680631a6952301461005e5780637362377b1461008c5780638da5cb5b146100a1575b61005c5b5b565b005b61008a600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506100f6565b005b341561009757600080fd5b61009f61013a565b005b34156100ac57600080fd5b6100b4610210565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b8073ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f19350505050151561013657600080fd5b5b50565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561019557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050151561020d57600080fd5b5b565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16815600a165627a7a7230582029eabe8a624d811f3ea09c310d65be79ddefa23e3b702541dc1687b475f091690029",
+        "ops": [
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x60"
+                    ],
+                    "store": null,
+                    "used": 42485
+                },
+                "pc": 0,
+                "sub": null,
+                "op": "PUSH1",
+                "idx": "15-0"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x40"
+                    ],
+                    "store": null,
+                    "used": 42482
+                },
+                "pc": 2,
+                "sub": null,
+                "op": "PUSH1",
+                "idx": "15-1"
+            },
+            {
+                "cost": 12,
+                "ex": {
+                    "mem": {
+                        "data": "0x0000000000000000000000000000000000000000000000000000000000000060",
+                        "off": 64
+                    },
+                    "push": [],
+                    "store": null,
+                    "used": 42470
+                },
+                "pc": 4,
+                "sub": null,
+                "op": "MSTORE",
+                "idx": "15-2"
+            },
+            {
+                "cost": 2,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x24"
+                    ],
+                    "store": null,
+                    "used": 42468
+                },
+                "pc": 5,
+                "sub": null,
+                "op": "CALLDATASIZE",
+                "idx": "15-3"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x0"
+                    ],
+                    "store": null,
+                    "used": 42465
+                },
+                "pc": 6,
+                "sub": null,
+                "op": "ISZERO",
+                "idx": "15-4"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x55"
+                    ],
+                    "store": null,
+                    "used": 42462
+                },
+                "pc": 7,
+                "sub": null,
+                "op": "PUSH2",
+                "idx": "15-5"
+            },
+            {
+                "cost": 10,
+                "ex": {
+                    "mem": null,
+                    "push": [],
+                    "store": null,
+                    "used": 42452
+                },
+                "pc": 10,
+                "sub": null,
+                "op": "JUMPI",
+                "idx": "15-6"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x0"
+                    ],
+                    "store": null,
+                    "used": 42449
+                },
+                "pc": 11,
+                "sub": null,
+                "op": "PUSH1",
+                "idx": "15-7"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x1a695230000000000000000000000000c227a75b32ed37d3f9d6341b9904d003"
+                    ],
+                    "store": null,
+                    "used": 42446
+                },
+                "pc": 13,
+                "sub": null,
+                "op": "CALLDATALOAD",
+                "idx": "15-8"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x100000000000000000000000000000000000000000000000000000000"
+                    ],
+                    "store": null,
+                    "used": 42443
+                },
+                "pc": 14,
+                "sub": null,
+                "op": "PUSH29",
+                "idx": "15-9"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x100000000000000000000000000000000000000000000000000000000",
+                        "0x1a695230000000000000000000000000c227a75b32ed37d3f9d6341b9904d003"
+                    ],
+                    "store": null,
+                    "used": 42440
+                },
+                "pc": 44,
+                "sub": null,
+                "op": "SWAP1",
+                "idx": "15-10"
+            },
+            {
+                "cost": 5,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x1a695230"
+                    ],
+                    "store": null,
+                    "used": 42435
+                },
+                "pc": 45,
+                "sub": null,
+                "op": "DIV",
+                "idx": "15-11"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0xffffffff"
+                    ],
+                    "store": null,
+                    "used": 42432
+                },
+                "pc": 46,
+                "sub": null,
+                "op": "PUSH4",
+                "idx": "15-12"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x1a695230"
+                    ],
+                    "store": null,
+                    "used": 42429
+                },
+                "pc": 51,
+                "sub": null,
+                "op": "AND",
+                "idx": "15-13"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x1a695230",
+                        "0x1a695230"
+                    ],
+                    "store": null,
+                    "used": 42426
+                },
+                "pc": 52,
+                "sub": null,
+                "op": "DUP1",
+                "idx": "15-14"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x1a695230"
+                    ],
+                    "store": null,
+                    "used": 42423
+                },
+                "pc": 53,
+                "sub": null,
+                "op": "PUSH4",
+                "idx": "15-15"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x1"
+                    ],
+                    "store": null,
+                    "used": 42420
+                },
+                "pc": 58,
+                "sub": null,
+                "op": "EQ",
+                "idx": "15-16"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x5e"
+                    ],
+                    "store": null,
+                    "used": 42417
+                },
+                "pc": 59,
+                "sub": null,
+                "op": "PUSH2",
+                "idx": "15-17"
+            },
+            {
+                "cost": 10,
+                "ex": {
+                    "mem": null,
+                    "push": [],
+                    "store": null,
+                    "used": 42407
+                },
+                "pc": 62,
+                "sub": null,
+                "op": "JUMPI",
+                "idx": "15-18"
+            },
+            {
+                "cost": 1,
+                "ex": {
+                    "mem": null,
+                    "push": [],
+                    "store": null,
+                    "used": 42406
+                },
+                "pc": 94,
+                "sub": null,
+                "op": "JUMPDEST",
+                "idx": "15-19"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x8a"
+                    ],
+                    "store": null,
+                    "used": 42403
+                },
+                "pc": 95,
+                "sub": null,
+                "op": "PUSH2",
+                "idx": "15-20"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x4"
+                    ],
+                    "store": null,
+                    "used": 42400
+                },
+                "pc": 98,
+                "sub": null,
+                "op": "PUSH1",
+                "idx": "15-21"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x4",
+                        "0x4"
+                    ],
+                    "store": null,
+                    "used": 42397
+                },
+                "pc": 100,
+                "sub": null,
+                "op": "DUP1",
+                "idx": "15-22"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x4",
+                        "0x4"
+                    ],
+                    "store": null,
+                    "used": 42394
+                },
+                "pc": 101,
+                "sub": null,
+                "op": "DUP1",
+                "idx": "15-23"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3"
+                    ],
+                    "store": null,
+                    "used": 42391
+                },
+                "pc": 102,
+                "sub": null,
+                "op": "CALLDATALOAD",
+                "idx": "15-24"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0xffffffffffffffffffffffffffffffffffffffff"
+                    ],
+                    "store": null,
+                    "used": 42388
+                },
+                "pc": 103,
+                "sub": null,
+                "op": "PUSH20",
+                "idx": "15-25"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3"
+                    ],
+                    "store": null,
+                    "used": 42385
+                },
+                "pc": 124,
+                "sub": null,
+                "op": "AND",
+                "idx": "15-26"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3",
+                        "0x4"
+                    ],
+                    "store": null,
+                    "used": 42382
+                },
+                "pc": 125,
+                "sub": null,
+                "op": "SWAP1",
+                "idx": "15-27"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x20"
+                    ],
+                    "store": null,
+                    "used": 42379
+                },
+                "pc": 126,
+                "sub": null,
+                "op": "PUSH1",
+                "idx": "15-28"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x24"
+                    ],
+                    "store": null,
+                    "used": 42376
+                },
+                "pc": 128,
+                "sub": null,
+                "op": "ADD",
+                "idx": "15-29"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x24",
+                        "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3"
+                    ],
+                    "store": null,
+                    "used": 42373
+                },
+                "pc": 129,
+                "sub": null,
+                "op": "SWAP1",
+                "idx": "15-30"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3",
+                        "0x24",
+                        "0x4"
+                    ],
+                    "store": null,
+                    "used": 42370
+                },
+                "pc": 130,
+                "sub": null,
+                "op": "SWAP2",
+                "idx": "15-31"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x4",
+                        "0x24"
+                    ],
+                    "store": null,
+                    "used": 42367
+                },
+                "pc": 131,
+                "sub": null,
+                "op": "SWAP1",
+                "idx": "15-32"
+            },
+            {
+                "cost": 2,
+                "ex": {
+                    "mem": null,
+                    "push": [],
+                    "store": null,
+                    "used": 42365
+                },
+                "pc": 132,
+                "sub": null,
+                "op": "POP",
+                "idx": "15-33"
+            },
+            {
+                "cost": 2,
+                "ex": {
+                    "mem": null,
+                    "push": [],
+                    "store": null,
+                    "used": 42363
+                },
+                "pc": 133,
+                "sub": null,
+                "op": "POP",
+                "idx": "15-34"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0xf6"
+                    ],
+                    "store": null,
+                    "used": 42360
+                },
+                "pc": 134,
+                "sub": null,
+                "op": "PUSH2",
+                "idx": "15-35"
+            },
+            {
+                "cost": 8,
+                "ex": {
+                    "mem": null,
+                    "push": [],
+                    "store": null,
+                    "used": 42352
+                },
+                "pc": 137,
+                "sub": null,
+                "op": "JUMP",
+                "idx": "15-36"
+            },
+            {
+                "cost": 1,
+                "ex": {
+                    "mem": null,
+                    "push": [],
+                    "store": null,
+                    "used": 42351
+                },
+                "pc": 246,
+                "sub": null,
+                "op": "JUMPDEST",
+                "idx": "15-37"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3",
+                        "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3"
+                    ],
+                    "store": null,
+                    "used": 42348
+                },
+                "pc": 247,
+                "sub": null,
+                "op": "DUP1",
+                "idx": "15-38"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0xffffffffffffffffffffffffffffffffffffffff"
+                    ],
+                    "store": null,
+                    "used": 42345
+                },
+                "pc": 248,
+                "sub": null,
+                "op": "PUSH20",
+                "idx": "15-39"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3"
+                    ],
+                    "store": null,
+                    "used": 42342
+                },
+                "pc": 269,
+                "sub": null,
+                "op": "AND",
+                "idx": "15-40"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x8fc"
+                    ],
+                    "store": null,
+                    "used": 42339
+                },
+                "pc": 270,
+                "sub": null,
+                "op": "PUSH2",
+                "idx": "15-41"
+            },
+            {
+                "cost": 2,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x1550f7dca70000"
+                    ],
+                    "store": null,
+                    "used": 42337
+                },
+                "pc": 273,
+                "sub": null,
+                "op": "CALLVALUE",
+                "idx": "15-42"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x1550f7dca70000",
+                        "0x8fc"
+                    ],
+                    "store": null,
+                    "used": 42334
+                },
+                "pc": 274,
+                "sub": null,
+                "op": "SWAP1",
+                "idx": "15-43"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x1550f7dca70000",
+                        "0x8fc",
+                        "0x1550f7dca70000"
+                    ],
+                    "store": null,
+                    "used": 42331
+                },
+                "pc": 275,
+                "sub": null,
+                "op": "DUP2",
+                "idx": "15-44"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x0"
+                    ],
+                    "store": null,
+                    "used": 42328
+                },
+                "pc": 276,
+                "sub": null,
+                "op": "ISZERO",
+                "idx": "15-45"
+            },
+            {
+                "cost": 5,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x0"
+                    ],
+                    "store": null,
+                    "used": 42323
+                },
+                "pc": 277,
+                "sub": null,
+                "op": "MUL",
+                "idx": "15-46"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x0",
+                        "0x1550f7dca70000"
+                    ],
+                    "store": null,
+                    "used": 42320
+                },
+                "pc": 278,
+                "sub": null,
+                "op": "SWAP1",
+                "idx": "15-47"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x40"
+                    ],
+                    "store": null,
+                    "used": 42317
+                },
+                "pc": 279,
+                "sub": null,
+                "op": "PUSH1",
+                "idx": "15-48"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": {
+                        "data": "0x0000000000000000000000000000000000000000000000000000000000000060",
+                        "off": 64
+                    },
+                    "push": [
+                        "0x60"
+                    ],
+                    "store": null,
+                    "used": 42314
+                },
+                "pc": 281,
+                "sub": null,
+                "op": "MLOAD",
+                "idx": "15-49"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x0"
+                    ],
+                    "store": null,
+                    "used": 42311
+                },
+                "pc": 282,
+                "sub": null,
+                "op": "PUSH1",
+                "idx": "15-50"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x40"
+                    ],
+                    "store": null,
+                    "used": 42308
+                },
+                "pc": 284,
+                "sub": null,
+                "op": "PUSH1",
+                "idx": "15-51"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": {
+                        "data": "0x0000000000000000000000000000000000000000000000000000000000000060",
+                        "off": 64
+                    },
+                    "push": [
+                        "0x60"
+                    ],
+                    "store": null,
+                    "used": 42305
+                },
+                "pc": 286,
+                "sub": null,
+                "op": "MLOAD",
+                "idx": "15-52"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x60",
+                        "0x60"
+                    ],
+                    "store": null,
+                    "used": 42302
+                },
+                "pc": 287,
+                "sub": null,
+                "op": "DUP1",
+                "idx": "15-53"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x60",
+                        "0x0",
+                        "0x60",
+                        "0x60",
+                        "0x60"
+                    ],
+                    "store": null,
+                    "used": 42299
+                },
+                "pc": 288,
+                "sub": null,
+                "op": "DUP4",
+                "idx": "15-54"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x0"
+                    ],
+                    "store": null,
+                    "used": 42296
+                },
+                "pc": 289,
+                "sub": null,
+                "op": "SUB",
+                "idx": "15-55"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x60",
+                        "0x0",
+                        "0x60"
+                    ],
+                    "store": null,
+                    "used": 42293
+                },
+                "pc": 290,
+                "sub": null,
+                "op": "DUP2",
+                "idx": "15-56"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x1550f7dca70000",
+                        "0x60",
+                        "0x0",
+                        "0x60",
+                        "0x0",
+                        "0x60",
+                        "0x1550f7dca70000"
+                    ],
+                    "store": null,
+                    "used": 42290
+                },
+                "pc": 291,
+                "sub": null,
+                "op": "DUP6",
+                "idx": "15-57"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3",
+                        "0x0",
+                        "0x1550f7dca70000",
+                        "0x60",
+                        "0x0",
+                        "0x60",
+                        "0x0",
+                        "0x60",
+                        "0x1550f7dca70000",
+                        "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3"
+                    ],
+                    "store": null,
+                    "used": 42287
+                },
+                "pc": 292,
+                "sub": null,
+                "op": "DUP9",
+                "idx": "15-58"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x0",
+                        "0x1550f7dca70000",
+                        "0x60",
+                        "0x0",
+                        "0x60",
+                        "0x0",
+                        "0x60",
+                        "0x1550f7dca70000",
+                        "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3",
+                        "0x0"
+                    ],
+                    "store": null,
+                    "used": 42284
+                },
+                "pc": 293,
+                "sub": null,
+                "op": "DUP9",
+                "idx": "15-59"
+            },
+            {
+                "cost": 9700,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x1"
+                    ],
+                    "store": null,
+                    "used": 34884
+                },
+                "pc": 294,
+                "sub": {
+                    "code": "0x",
+                    "ops": []
+                },
+                "op": "CALL",
+                "idx": "15-60"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x1",
+                        "0x0",
+                        "0x1550f7dca70000",
+                        "0x60",
+                        "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3"
+                    ],
+                    "store": null,
+                    "used": 34881
+                },
+                "pc": 295,
+                "sub": null,
+                "op": "SWAP4",
+                "idx": "15-61"
+            },
+            {
+                "cost": 2,
+                "ex": {
+                    "mem": null,
+                    "push": [],
+                    "store": null,
+                    "used": 34879
+                },
+                "pc": 296,
+                "sub": null,
+                "op": "POP",
+                "idx": "15-62"
+            },
+            {
+                "cost": 2,
+                "ex": {
+                    "mem": null,
+                    "push": [],
+                    "store": null,
+                    "used": 34877
+                },
+                "pc": 297,
+                "sub": null,
+                "op": "POP",
+                "idx": "15-63"
+            },
+            {
+                "cost": 2,
+                "ex": {
+                    "mem": null,
+                    "push": [],
+                    "store": null,
+                    "used": 34875
+                },
+                "pc": 298,
+                "sub": null,
+                "op": "POP",
+                "idx": "15-64"
+            },
+            {
+                "cost": 2,
+                "ex": {
+                    "mem": null,
+                    "push": [],
+                    "store": null,
+                    "used": 34873
+                },
+                "pc": 299,
+                "sub": null,
+                "op": "POP",
+                "idx": "15-65"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x0"
+                    ],
+                    "store": null,
+                    "used": 34870
+                },
+                "pc": 300,
+                "sub": null,
+                "op": "ISZERO",
+                "idx": "15-66"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x1"
+                    ],
+                    "store": null,
+                    "used": 34867
+                },
+                "pc": 301,
+                "sub": null,
+                "op": "ISZERO",
+                "idx": "15-67"
+            },
+            {
+                "cost": 3,
+                "ex": {
+                    "mem": null,
+                    "push": [
+                        "0x136"
+                    ],
+                    "store": null,
+                    "used": 34864
+                },
+                "pc": 302,
+                "sub": null,
+                "op": "PUSH2",
+                "idx": "15-68"
+            },
+            {
+                "cost": 10,
+                "ex": {
+                    "mem": null,
+                    "push": [],
+                    "store": null,
+                    "used": 34854
+                },
+                "pc": 305,
+                "sub": null,
+                "op": "JUMPI",
+                "idx": "15-69"
+            },
+            {
+                "cost": 1,
+                "ex": {
+                    "mem": null,
+                    "push": [],
+                    "store": null,
+                    "used": 34853
+                },
+                "pc": 310,
+                "sub": null,
+                "op": "JUMPDEST",
+                "idx": "15-70"
+            },
+            {
+                "cost": 1,
+                "ex": {
+                    "mem": null,
+                    "push": [],
+                    "store": null,
+                    "used": 34852
+                },
+                "pc": 311,
+                "sub": null,
+                "op": "JUMPDEST",
+                "idx": "15-71"
+            },
+            {
+                "cost": 2,
+                "ex": {
+                    "mem": null,
+                    "push": [],
+                    "store": null,
+                    "used": 34850
+                },
+                "pc": 312,
+                "sub": null,
+                "op": "POP",
+                "idx": "15-72"
+            },
+            {
+                "cost": 8,
+                "ex": {
+                    "mem": null,
+                    "push": [],
+                    "store": null,
+                    "used": 34842
+                },
+                "pc": 313,
+                "sub": null,
+                "op": "JUMP",
+                "idx": "15-73"
+            },
+            {
+                "cost": 1,
+                "ex": {
+                    "mem": null,
+                    "push": [],
+                    "store": null,
+                    "used": 34841
+                },
+                "pc": 138,
+                "sub": null,
+                "op": "JUMPDEST",
+                "idx": "15-74"
+            },
+            {
+                "cost": 0,
+                "ex": {
+                    "mem": null,
+                    "push": [],
+                    "store": null,
+                    "used": 34841
+                },
+                "pc": 139,
+                "sub": null,
+                "op": "STOP",
+                "idx": "15-75"
+            }
+        ]
     }
-  },
-  "trace": [
-    {
-      "action": {
-        "callType": "call",
-        "from": "0x01f0eb5c4b0a9d8285b67195f5f10ce22971a102",
-        "gas": "0xa5f8",
-        "input": "0x1a695230000000000000000000000000c227a75b32ed37d3f9d6341b9904d003dad3b1b3",
-        "to": "0x0b95993a39a363d99280ac950f5e4536ab5c5566",
-        "value": "0x1550f7dca70000"
-      },
-      "result": {
-        "gasUsed": "0x1ddf",
-        "output": "0x"
-      },
-      "subtraces": 1,
-      "traceAddress": [],
-      "type": "call"
-    },
-    {
-      "action": {
-        "callType": "call",
-        "from": "0x0b95993a39a363d99280ac950f5e4536ab5c5566",
-        "gas": "0x8fc",
-        "input": "0x",
-        "to": "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3",
-        "value": "0x1550f7dca70000"
-      },
-      "result": {
-        "gasUsed": "0x0",
-        "output": "0x"
-      },
-      "subtraces": 0,
-      "traceAddress": [
-        0
-      ],
-      "type": "call"
-    }
-  ],
-  "vmTrace": {
-    "code": "0x60606040523615610055576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680631a6952301461005e5780637362377b1461008c5780638da5cb5b146100a1575b61005c5b5b565b005b61008a600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506100f6565b005b341561009757600080fd5b61009f61013a565b005b34156100ac57600080fd5b6100b4610210565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b8073ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f19350505050151561013657600080fd5b5b50565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561019557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050151561020d57600080fd5b5b565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16815600a165627a7a7230582029eabe8a624d811f3ea09c310d65be79ddefa23e3b702541dc1687b475f091690029",
-    "ops": [
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x60"
-          ],
-          "store": null,
-          "used": 42485
-        },
-        "pc": 0,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x40"
-          ],
-          "store": null,
-          "used": 42482
-        },
-        "pc": 2,
-        "sub": null
-      },
-      {
-        "cost": 12,
-        "ex": {
-          "mem": {
-            "data": "0x0000000000000000000000000000000000000000000000000000000000000060",
-            "off": 64
-          },
-          "push": [],
-          "store": null,
-          "used": 42470
-        },
-        "pc": 4,
-        "sub": null
-      },
-      {
-        "cost": 2,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x24"
-          ],
-          "store": null,
-          "used": 42468
-        },
-        "pc": 5,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x0"
-          ],
-          "store": null,
-          "used": 42465
-        },
-        "pc": 6,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x55"
-          ],
-          "store": null,
-          "used": 42462
-        },
-        "pc": 7,
-        "sub": null
-      },
-      {
-        "cost": 10,
-        "ex": {
-          "mem": null,
-          "push": [],
-          "store": null,
-          "used": 42452
-        },
-        "pc": 10,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x0"
-          ],
-          "store": null,
-          "used": 42449
-        },
-        "pc": 11,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x1a695230000000000000000000000000c227a75b32ed37d3f9d6341b9904d003"
-          ],
-          "store": null,
-          "used": 42446
-        },
-        "pc": 13,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x100000000000000000000000000000000000000000000000000000000"
-          ],
-          "store": null,
-          "used": 42443
-        },
-        "pc": 14,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x100000000000000000000000000000000000000000000000000000000",
-            "0x1a695230000000000000000000000000c227a75b32ed37d3f9d6341b9904d003"
-          ],
-          "store": null,
-          "used": 42440
-        },
-        "pc": 44,
-        "sub": null
-      },
-      {
-        "cost": 5,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x1a695230"
-          ],
-          "store": null,
-          "used": 42435
-        },
-        "pc": 45,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0xffffffff"
-          ],
-          "store": null,
-          "used": 42432
-        },
-        "pc": 46,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x1a695230"
-          ],
-          "store": null,
-          "used": 42429
-        },
-        "pc": 51,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x1a695230",
-            "0x1a695230"
-          ],
-          "store": null,
-          "used": 42426
-        },
-        "pc": 52,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x1a695230"
-          ],
-          "store": null,
-          "used": 42423
-        },
-        "pc": 53,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x1"
-          ],
-          "store": null,
-          "used": 42420
-        },
-        "pc": 58,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x5e"
-          ],
-          "store": null,
-          "used": 42417
-        },
-        "pc": 59,
-        "sub": null
-      },
-      {
-        "cost": 10,
-        "ex": {
-          "mem": null,
-          "push": [],
-          "store": null,
-          "used": 42407
-        },
-        "pc": 62,
-        "sub": null
-      },
-      {
-        "cost": 1,
-        "ex": {
-          "mem": null,
-          "push": [],
-          "store": null,
-          "used": 42406
-        },
-        "pc": 94,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x8a"
-          ],
-          "store": null,
-          "used": 42403
-        },
-        "pc": 95,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x4"
-          ],
-          "store": null,
-          "used": 42400
-        },
-        "pc": 98,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x4",
-            "0x4"
-          ],
-          "store": null,
-          "used": 42397
-        },
-        "pc": 100,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x4",
-            "0x4"
-          ],
-          "store": null,
-          "used": 42394
-        },
-        "pc": 101,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3"
-          ],
-          "store": null,
-          "used": 42391
-        },
-        "pc": 102,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0xffffffffffffffffffffffffffffffffffffffff"
-          ],
-          "store": null,
-          "used": 42388
-        },
-        "pc": 103,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3"
-          ],
-          "store": null,
-          "used": 42385
-        },
-        "pc": 124,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3",
-            "0x4"
-          ],
-          "store": null,
-          "used": 42382
-        },
-        "pc": 125,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x20"
-          ],
-          "store": null,
-          "used": 42379
-        },
-        "pc": 126,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x24"
-          ],
-          "store": null,
-          "used": 42376
-        },
-        "pc": 128,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x24",
-            "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3"
-          ],
-          "store": null,
-          "used": 42373
-        },
-        "pc": 129,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3",
-            "0x24",
-            "0x4"
-          ],
-          "store": null,
-          "used": 42370
-        },
-        "pc": 130,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x4",
-            "0x24"
-          ],
-          "store": null,
-          "used": 42367
-        },
-        "pc": 131,
-        "sub": null
-      },
-      {
-        "cost": 2,
-        "ex": {
-          "mem": null,
-          "push": [],
-          "store": null,
-          "used": 42365
-        },
-        "pc": 132,
-        "sub": null
-      },
-      {
-        "cost": 2,
-        "ex": {
-          "mem": null,
-          "push": [],
-          "store": null,
-          "used": 42363
-        },
-        "pc": 133,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0xf6"
-          ],
-          "store": null,
-          "used": 42360
-        },
-        "pc": 134,
-        "sub": null
-      },
-      {
-        "cost": 8,
-        "ex": {
-          "mem": null,
-          "push": [],
-          "store": null,
-          "used": 42352
-        },
-        "pc": 137,
-        "sub": null
-      },
-      {
-        "cost": 1,
-        "ex": {
-          "mem": null,
-          "push": [],
-          "store": null,
-          "used": 42351
-        },
-        "pc": 246,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3",
-            "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3"
-          ],
-          "store": null,
-          "used": 42348
-        },
-        "pc": 247,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0xffffffffffffffffffffffffffffffffffffffff"
-          ],
-          "store": null,
-          "used": 42345
-        },
-        "pc": 248,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3"
-          ],
-          "store": null,
-          "used": 42342
-        },
-        "pc": 269,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x8fc"
-          ],
-          "store": null,
-          "used": 42339
-        },
-        "pc": 270,
-        "sub": null
-      },
-      {
-        "cost": 2,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x1550f7dca70000"
-          ],
-          "store": null,
-          "used": 42337
-        },
-        "pc": 273,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x1550f7dca70000",
-            "0x8fc"
-          ],
-          "store": null,
-          "used": 42334
-        },
-        "pc": 274,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x1550f7dca70000",
-            "0x8fc",
-            "0x1550f7dca70000"
-          ],
-          "store": null,
-          "used": 42331
-        },
-        "pc": 275,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x0"
-          ],
-          "store": null,
-          "used": 42328
-        },
-        "pc": 276,
-        "sub": null
-      },
-      {
-        "cost": 5,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x0"
-          ],
-          "store": null,
-          "used": 42323
-        },
-        "pc": 277,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x0",
-            "0x1550f7dca70000"
-          ],
-          "store": null,
-          "used": 42320
-        },
-        "pc": 278,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x40"
-          ],
-          "store": null,
-          "used": 42317
-        },
-        "pc": 279,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": {
-            "data": "0x0000000000000000000000000000000000000000000000000000000000000060",
-            "off": 64
-          },
-          "push": [
-            "0x60"
-          ],
-          "store": null,
-          "used": 42314
-        },
-        "pc": 281,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x0"
-          ],
-          "store": null,
-          "used": 42311
-        },
-        "pc": 282,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x40"
-          ],
-          "store": null,
-          "used": 42308
-        },
-        "pc": 284,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": {
-            "data": "0x0000000000000000000000000000000000000000000000000000000000000060",
-            "off": 64
-          },
-          "push": [
-            "0x60"
-          ],
-          "store": null,
-          "used": 42305
-        },
-        "pc": 286,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x60",
-            "0x60"
-          ],
-          "store": null,
-          "used": 42302
-        },
-        "pc": 287,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x60",
-            "0x0",
-            "0x60",
-            "0x60",
-            "0x60"
-          ],
-          "store": null,
-          "used": 42299
-        },
-        "pc": 288,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x0"
-          ],
-          "store": null,
-          "used": 42296
-        },
-        "pc": 289,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x60",
-            "0x0",
-            "0x60"
-          ],
-          "store": null,
-          "used": 42293
-        },
-        "pc": 290,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x1550f7dca70000",
-            "0x60",
-            "0x0",
-            "0x60",
-            "0x0",
-            "0x60",
-            "0x1550f7dca70000"
-          ],
-          "store": null,
-          "used": 42290
-        },
-        "pc": 291,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3",
-            "0x0",
-            "0x1550f7dca70000",
-            "0x60",
-            "0x0",
-            "0x60",
-            "0x0",
-            "0x60",
-            "0x1550f7dca70000",
-            "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3"
-          ],
-          "store": null,
-          "used": 42287
-        },
-        "pc": 292,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x0",
-            "0x1550f7dca70000",
-            "0x60",
-            "0x0",
-            "0x60",
-            "0x0",
-            "0x60",
-            "0x1550f7dca70000",
-            "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3",
-            "0x0"
-          ],
-          "store": null,
-          "used": 42284
-        },
-        "pc": 293,
-        "sub": null
-      },
-      {
-        "cost": 9700,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x1"
-          ],
-          "store": null,
-          "used": 34884
-        },
-        "pc": 294,
-        "sub": {
-          "code": "0x",
-          "ops": []
-        }
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x1",
-            "0x0",
-            "0x1550f7dca70000",
-            "0x60",
-            "0xc227a75b32ed37d3f9d6341b9904d003dad3b1b3"
-          ],
-          "store": null,
-          "used": 34881
-        },
-        "pc": 295,
-        "sub": null
-      },
-      {
-        "cost": 2,
-        "ex": {
-          "mem": null,
-          "push": [],
-          "store": null,
-          "used": 34879
-        },
-        "pc": 296,
-        "sub": null
-      },
-      {
-        "cost": 2,
-        "ex": {
-          "mem": null,
-          "push": [],
-          "store": null,
-          "used": 34877
-        },
-        "pc": 297,
-        "sub": null
-      },
-      {
-        "cost": 2,
-        "ex": {
-          "mem": null,
-          "push": [],
-          "store": null,
-          "used": 34875
-        },
-        "pc": 298,
-        "sub": null
-      },
-      {
-        "cost": 2,
-        "ex": {
-          "mem": null,
-          "push": [],
-          "store": null,
-          "used": 34873
-        },
-        "pc": 299,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x0"
-          ],
-          "store": null,
-          "used": 34870
-        },
-        "pc": 300,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x1"
-          ],
-          "store": null,
-          "used": 34867
-        },
-        "pc": 301,
-        "sub": null
-      },
-      {
-        "cost": 3,
-        "ex": {
-          "mem": null,
-          "push": [
-            "0x136"
-          ],
-          "store": null,
-          "used": 34864
-        },
-        "pc": 302,
-        "sub": null
-      },
-      {
-        "cost": 10,
-        "ex": {
-          "mem": null,
-          "push": [],
-          "store": null,
-          "used": 34854
-        },
-        "pc": 305,
-        "sub": null
-      },
-      {
-        "cost": 1,
-        "ex": {
-          "mem": null,
-          "push": [],
-          "store": null,
-          "used": 34853
-        },
-        "pc": 310,
-        "sub": null
-      },
-      {
-        "cost": 1,
-        "ex": {
-          "mem": null,
-          "push": [],
-          "store": null,
-          "used": 34852
-        },
-        "pc": 311,
-        "sub": null
-      },
-      {
-        "cost": 2,
-        "ex": {
-          "mem": null,
-          "push": [],
-          "store": null,
-          "used": 34850
-        },
-        "pc": 312,
-        "sub": null
-      },
-      {
-        "cost": 8,
-        "ex": {
-          "mem": null,
-          "push": [],
-          "store": null,
-          "used": 34842
-        },
-        "pc": 313,
-        "sub": null
-      },
-      {
-        "cost": 1,
-        "ex": {
-          "mem": null,
-          "push": [],
-          "store": null,
-          "used": 34841
-        },
-        "pc": 138,
-        "sub": null
-      },
-      {
-        "cost": 0,
-        "ex": {
-          "mem": null,
-          "push": [],
-          "store": null,
-          "used": 34841
-        },
-        "pc": 139,
-        "sub": null
-      }
-    ]
-  }
 }"#
diff --git a/ethers-core/src/types/trace/mod.rs b/ethers-core/src/types/trace/mod.rs
index 43bb621f..ce1e7082 100644
--- a/ethers-core/src/types/trace/mod.rs
+++ b/ethers-core/src/types/trace/mod.rs
@@ -11,6 +11,9 @@ pub use filter::*;
 mod geth;
 pub use geth::*;
 
+mod opcodes;
+pub use opcodes::*;
+
 #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
 /// Description of the type of trace to make
 pub enum TraceType {
@@ -131,6 +134,9 @@ pub struct VMOperation {
     /// Subordinate trace of the CALL/CREATE if applicable.
     // #[serde(bound="VMTrace: Deserialize")]
     pub sub: Option<VMTrace>,
+    /// The executed opcode name
+    #[serde(rename = "op")]
+    pub op: OpCode,
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Default, Deserialize, Serialize)]
diff --git a/ethers-core/src/types/trace/opcodes.rs b/ethers-core/src/types/trace/opcodes.rs
new file mode 100644
index 00000000..0c90a632
--- /dev/null
+++ b/ethers-core/src/types/trace/opcodes.rs
@@ -0,0 +1,343 @@
+use serde::{Deserialize, Serialize};
+
+// opcode descriptions taken from evm.codes https://github.com/comitylabs/evm.codes/blob/bc7f102808055d88365559d40c190c5bd6d164c3/opcodes.json
+// https://github.com/ethereum/go-ethereum/blob/2b1299b1c006077c56ecbad32e79fc16febe3dd6/core/vm/opcodes.go
+#[derive(Debug, Clone, PartialEq, Eq, Default, Deserialize, Serialize)]
+/// Name of executed EVM opcode
+pub enum OpCode {
+    // 0x0 range - arithmetic ops.
+    /// Opcode 0x0 - Halts execution
+    STOP,
+    /// Opcode 0x1 - Addition operation
+    ADD,
+    /// Opcode 0x2 - Multiplication operation
+    MUL,
+    /// Opcode 0x3 - Subtraction operation
+    SUB,
+    /// Opcode 0x4 - Integer division operation
+    DIV,
+    /// Opcode 0x5 - Signed integer division operation (truncated)
+    SDIV,
+    /// Opcode 0x6 - Modulo remainder operation
+    MOD,
+    /// Opcode 0x7 - Signed modulo remainder operation
+    SMOD,
+    /// Opcode 0x8 - Modulo addition operation
+    ADDMOD,
+    /// Opcode 0x9 - Modulo multiplication operation
+    MULMOD,
+    /// Opcode 0xA - Exponential operation
+    EXP,
+    /// Opcode 0xB - Extend length of two’s complement signed integer
+    SIGNEXTEND,
+
+    // 0x0C - 0x0F are invalid
+
+    // 0x10 range - comparison ops.
+    /// Opcode 0x10 - Less-than comparison
+    LT,
+    /// Opcode 0x11 - Greater-than comparison
+    GT,
+    /// Opcode 0x12 - Signed less-than comparison
+    SLT,
+    /// Opcode 0x13 - Signed greater-than comparison
+    SGT,
+    /// Opcode 0x14 - Equality comparison
+    EQ,
+    /// Opcode 0x15 - Simple not operator
+    ISZERO,
+    /// Opcode 0x16 - Bitwise AND operation
+    AND,
+    /// Opcode 0x17 - Bitwise OR operation
+    OR,
+    /// Opcode 0x18 - Bitwise XOR operation
+    XOR,
+    /// Opcode 0x19 - Bitwise NOT operation
+    NOT,
+    /// Opcode 0x1A - Retrieve single byte from word
+    BYTE,
+    /// Opcode 0x1B - Left shift operation
+    SHL,
+    /// Opcode 0x1C - Logical right shift operation
+    SHR,
+    /// Opcode 0x1D - Arithmetic (signed) right shift operation
+    SAR,
+
+    // 0x1E - 0x1F are invalid
+
+    // 0x20 range - crypto.
+    /// Opcode 0x20 - Compute Keccak-256 hash
+    SHA3,
+
+    // 0x21 - 0x2F are invalid
+
+    // 0x30 range - closure state.
+    /// Opcode 0x30 - Get address of currently executing account
+    ADDRESS,
+    /// Opcode 0x31 - Get address of currently executing account
+    BALANCE,
+    /// Opcode 0x32 - Get execution origination address
+    ORIGIN,
+    /// Opcode 0x33 - Get caller address
+    CALLER,
+    /// Opcode 0x34 - Get deposited value by the instruction/transaction responsible for this
+    /// execution
+    CALLVALUE,
+    /// Opcode 0x35 - Get input data of current environment
+    CALLDATALOAD,
+    /// Opcode 0x36 - Get size of input data in current environment
+    CALLDATASIZE,
+    /// Opcode 0x37 - Copy input data in current environment to memory
+    CALLDATACOPY,
+    /// Opcode 0x38 - Get size of code running in current environment
+    CODESIZE,
+    /// Opcode 0x39 - Copy code running in current environment to memory
+    CODECOPY,
+    /// Opcode 0x3A - Get price of gas in current environment
+    GASPRICE,
+    /// Opcode 0x3B - Get size of an account’s code
+    EXTCODESIZE,
+    /// Opcode 0x3C - Copy an account’s code to memory
+    EXTCODECOPY,
+    /// Opcode 0x3D - Get size of output data from the previous call from the current environment
+    RETURNDATASIZE,
+    /// Opcode 0x3E - Copy output data from the previous call to memory
+    RETURNDATACOPY,
+    /// Opcode 0x3F - Get hash of an account’s code
+    EXTCODEHASH,
+
+    // 0x40 range - block operations.
+    /// Opcode 0x40 - Get the hash of one of the 256 most recent complete blocks
+    BLOCKHASH,
+    /// Opcode 0x41 - Get the block’s beneficiary address
+    COINBASE,
+    /// Opcode 0x42 - Get the block’s timestamp
+    TIMESTAMP,
+    /// Opcode 0x43 - Get the block’s number
+    NUMBER,
+    /// Opcode 0x44 - Get the block’s difficulty
+    DIFFICULTY,
+    //RANDOM,      // 0x44 // Same as DIFFICULTY
+    //PREVRANDAO,  // 0x44 // Same as DIFFICULTY
+    /// Opcode 0x45 - Get the block’s gas limit
+    GASLIMIT,
+    /// Opcode 0x46 - Get the chain ID
+    CHAINID,
+    /// Opcode 0x47 - Get balance of currently executing account
+    SELFBALANCE,
+    /// Opcode 0x48 - Get the base fee
+    BASEFEE,
+
+    // 0x49 - 0x4F are invalid
+
+    // 0x50 range - 'storage' and execution.
+    /// Opcode 0x50 - Remove item from stack
+    POP,
+    /// Opcode 0x51 - Load word from memory
+    MLOAD,
+    /// Opcode 0x52 - Save word to memory
+    MSTORE,
+    /// Opcode 0x53 - Save byte to memory
+    MSTORE8,
+    /// Opcode 0x54 - Load word from storage
+    SLOAD,
+    /// Opcode 0x55 - Save word to storage
+    SSTORE,
+    /// Opcode 0x56 - Alter the program counter
+    JUMP,
+    /// Opcode 0x57 - Conditionally alter the program counter
+    JUMPI,
+    /// Opcode 0x58 - Get the value of the program counter prior to the increment corresponding to
+    /// this instruction
+    PC,
+    /// Opcode 0x59 - Get the size of active memory in bytes
+    MSIZE,
+    /// Opcode 0x5A - Get the amount of available gas, including the corresponding reduction for
+    /// the cost of this instruction
+    GAS,
+    /// Opcode 0x5B - Mark a valid destination for jumps
+    JUMPDEST,
+
+    // 0x5C - 0x5F are invalid
+
+    // 0x60 range - pushes.
+    // PUSH0,    // 0x5F (https://eips.ethereum.org/EIPS/eip-3855)
+    /// Opcode 0x60 - Place 1 byte item on stack
+    PUSH1,
+    /// Opcode 0x61 - Place 2 byte item on stack
+    PUSH2,
+    /// Opcode 0x62 - Place 3 byte item on stack
+    PUSH3,
+    /// Opcode 0x63 - Place 4 byte item on stack
+    PUSH4,
+    /// Opcode 0x64 - Place 5 byte item on stack
+    PUSH5,
+    /// Opcode 0x65 - Place 6 byte item on stack
+    PUSH6,
+    /// Opcode 0x66 - Place 7 byte item on stack
+    PUSH7,
+    /// Opcode 0x67 - Place 8 byte item on stack
+    PUSH8,
+    /// Opcode 0x68 - Place 9 byte item on stack
+    PUSH9,
+    /// Opcode 0x69 - Place 10 byte item on stack
+    PUSH10,
+    /// Opcode 0x6A - Place 11 byte item on stack
+    PUSH11,
+    /// Opcode 0x6B - Place 12 byte item on stack
+    PUSH12,
+    /// Opcode 0x6C - Place 13 byte item on stack
+    PUSH13,
+    /// Opcode 0x6D - Place 14 byte item on stack
+    PUSH14,
+    /// Opcode 0x6E - Place 15 byte item on stack
+    PUSH15,
+    /// Opcode 0x6F - Place 16 byte item on stack
+    PUSH16,
+    /// Opcode 0x70 - Place 17 byte item on stack
+    PUSH17,
+    /// Opcode 0x71 - Place 18 byte item on stack
+    PUSH18,
+    /// Opcode 0x72 - Place 19 byte item on stack
+    PUSH19,
+    /// Opcode 0x73 - Place 20 byte item on stack
+    PUSH20,
+    /// Opcode 0x74 - Place 21 byte item on stack
+    PUSH21,
+    /// Opcode 0x75 - Place 22 byte item on stack
+    PUSH22,
+    /// Opcode 0x76 - Place 23 byte item on stack
+    PUSH23,
+    /// Opcode 0x77 - Place 24 byte item on stack
+    PUSH24,
+    /// Opcode 0x78 - Place 25 byte item on stack
+    PUSH25,
+    /// Opcode 0x79 - Place 26 byte item on stack
+    PUSH26,
+    /// Opcode 0x7A - Place 27 byte item on stack
+    PUSH27,
+    /// Opcode 0x7B - Place 28 byte item on stack
+    PUSH28,
+    /// Opcode 0x7C - Place 29 byte item on stack
+    PUSH29,
+    /// Opcode 0x7D - Place 30 byte item on stack
+    PUSH30,
+    /// Opcode 0x7E - Place 31 byte item on stack
+    PUSH31,
+    /// Opcode 0x7F - Place 32 byte item on stack
+    PUSH32,
+
+    // 0x80 range - dups.
+    /// Opcode 0x80 - Duplicate 1st stack item
+    DUP1,
+    /// Opcode 0x81 - Duplicate 2nd stack item
+    DUP2,
+    /// Opcode 0x82 - Duplicate 3rd stack item
+    DUP3,
+    /// Opcode 0x83 - Duplicate 4th stack item
+    DUP4,
+    /// Opcode 0x84 - Duplicate 5th stack item
+    DUP5,
+    /// Opcode 0x85 - Duplicate 6th stack item
+    DUP6,
+    /// Opcode 0x86 - Duplicate 7th stack item
+    DUP7,
+    /// Opcode 0x87 - Duplicate 8th stack item
+    DUP8,
+    /// Opcode 0x88 - Duplicate 9th stack item
+    DUP9,
+    /// Opcode 0x89 - Duplicate 10th stack item
+    DUP10,
+    /// Opcode 0x8A - Duplicate 11th stack item
+    DUP11,
+    /// Opcode 0x8B - Duplicate 12th stack item
+    DUP12,
+    /// Opcode 0x8C - Duplicate 13th stack item
+    DUP13,
+    /// Opcode 0x8D - Duplicate 14th stack item
+    DUP14,
+    /// Opcode 0x8E - Duplicate 15th stack item
+    DUP15,
+    /// Opcode 0x8F - Duplicate 16th stack item
+    DUP16,
+
+    // 0x90 range - swaps.
+    /// Opcode 0x90 - Exchange 1st and 1st stack items
+    SWAP1,
+    /// Opcode 0x91 - Exchange 1st and 2nd stack items
+    SWAP2,
+    /// Opcode 0x92 - Exchange 1st and 3rd stack items
+    SWAP3,
+    /// Opcode 0x93 - Exchange 1st and 4th stack items
+    SWAP4,
+    /// Opcode 0x94 - Exchange 1st and 5th stack items
+    SWAP5,
+    /// Opcode 0x95 - Exchange 1st and 6th stack items
+    SWAP6,
+    /// Opcode 0x96 - Exchange 1st and 7th stack items
+    SWAP7,
+    /// Opcode 0x97 - Exchange 1st and 8th stack items
+    SWAP8,
+    /// Opcode 0x98 - Exchange 1st and 9th stack items
+    SWAP9,
+    /// Opcode 0x99 - Exchange 1st and 10th stack items
+    SWAP10,
+    /// Opcode 0x9A - Exchange 1st and 11th stack items
+    SWAP11,
+    /// Opcode 0x9B - Exchange 1st and 12th stack items
+    SWAP12,
+    /// Opcode 0x9C - Exchange 1st and 13th stack items
+    SWAP13,
+    /// Opcode 0x9D - Exchange 1st and 14th stack items
+    SWAP14,
+    /// Opcode 0x9E - Exchange 1st and 15th stack items
+    SWAP15,
+    /// Opcode 0x9F - Exchange 1st and 16th stack items
+    SWAP16,
+
+    // 0xA0 range - logging ops.
+    /// Opcode 0xA0 - Append log record with one topic
+    LOG0,
+    /// Opcode 0xA1 - Append log record with two topics
+    LOG1,
+    /// Opcode 0xA2 - Append log record with three topics
+    LOG2,
+    /// Opcode 0xA3 - Append log record with four topics
+    LOG3,
+    /// Opcode 0xA4 - Append log record with five topics
+    LOG4,
+
+    // 0xA5 - 0xEF are invalid
+
+    // 0xF0 range - closures.
+    /// Opcode 0xF0 - Create a new account with associated code
+    CREATE,
+    /// Opcode 0xF1 - Message-call into an account
+    CALL,
+    /// Opcode 0xF2 - Message-call into this account with alternative account’s code
+    CALLCODE,
+    /// Opcode 0xF3 - Halt execution returning output data
+    RETURN,
+    /// Opcode 0xF4 - Message-call into this account with an alternative account’s code, but
+    /// persisting the current values for sender and value
+    DELEGATECALL,
+    /// Opcode 0xF5 - Create a new account with associated code at a predictable address
+    CREATE2,
+
+    // 0xF6 - 0xF9 are invalid
+
+    // 0xFA range - closures
+    /// Opcode 0xFA - Static message-call into an account
+    STATICCALL,
+
+    // 0xFB - 0xFC are invalid
+
+    // 0xfd range - closures
+    /// Opcode 0xFD - Halt execution reverting state changes but returning data and remaining gas
+    REVERT,
+    #[default]
+    /// Opcode 0xFE - Designated invalid instruction
+    INVALID,
+    /// Opcode 0xFF - Halt execution and register account for later deletion
+    SELFDESTRUCT,
+}
diff --git a/ethers-core/src/types/transaction/response.rs b/ethers-core/src/types/transaction/response.rs
index 5ee768b4..314caf0b 100644
--- a/ethers-core/src/types/transaction/response.rs
+++ b/ethers-core/src/types/transaction/response.rs
@@ -279,8 +279,6 @@ impl Transaction {
         #[cfg(feature = "celo")]
         self.decode_celo_metadata(rlp, offset)?;
 
-        self.gas = rlp.val_at(*offset)?;
-        *offset += 1;
         self.to = Some(rlp.val_at(*offset)?);
         *offset += 1;
         self.value = rlp.val_at(*offset)?;
@@ -1069,6 +1067,30 @@ mod tests {
         .expect("unable to decode raw tx");
         decoded_tx.recover_from_mut().unwrap();
         decoded_tx.hash = decoded_tx.hash();
-        dbg!(&decoded_tx);
+        assert_eq!(
+            H256::from_str("0xeae304417079580c334ccc07e3933a906699461802a17b722034a8191c4a38ea")
+                .unwrap(),
+            decoded_tx.hash
+        );
+    }
+
+    #[test]
+    fn test_rlp_decoding_issue_1848_first() {
+        // slot 5097934, tx index 40, hash
+        // 0xf98c9f1a2f30ee316ea1db18c132ccab6383b8e4933ccf6259ca9d1f27d4a364
+        let s = "01f9012e01826c6f850737be7600830493ef940c3de458b51a11da7d4616f42f66c861e3859d3e80b8c4f5b22c2a000000000000000000000000e67b950f4b84c5b06ee36ded6727a17443fe749300000000000000000000000000000000000000000000005f344f4a335cc50000000000000000000000000000000000000000000005c2f00b834b7f0000000000000000000000000000000000000000000000000005aa64a95b4a40400000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000c3de458b51a11da7d4616f42f66c861e3859d3ec080a0c4023f0b8f7daecd7e143ef7aaa9b67bd059e643a6f2ae509a0e8483a3966e28a065a20662274cb5f7fe60a2af7dbd466244154440e73243f00b6a69bd08eacda4";
+        let b = hex::decode(s).unwrap();
+        let r = rlp::Rlp::new(b.as_slice());
+        Transaction::decode(&r).unwrap();
+    }
+
+    #[test]
+    fn test_rlp_decoding_issue_1848_second() {
+        // slot 5097936, tx index 0, hash
+        // 6d38fc8aee934858815ed41273cece3b676c368e9c6e39f172313a0685e1f175
+        let s = "01f8ee0182034c853d9f1b88158307a120940087bb802d9c0e343f00510000729031ce00bf2780b8841e1326a300000000000000000000000088e6a0c2ddd26feeb64f039a2c41296fcb3f56400000000000000000000000000000000000000000000000000000001d3b3e730000000000000000000000000000000000000000000000000596b93e53696740000000000000000000000000000000000000000000000000000000000000000001c001a0bbfd754ed51b34d0a8577f69b4c42ce6b47fee6ecf49114bb135e7e8eadbb336a0433692134eb7e7686e9aefafa9f69c601aa977c00cc85c827782f5fb1f1cff0f";
+        let b = hex::decode(s).unwrap();
+        let r = rlp::Rlp::new(b.as_slice());
+        Transaction::decode(&r).unwrap();
     }
 }
diff --git a/ethers-core/src/utils/mod.rs b/ethers-core/src/utils/mod.rs
index 1a0b0c1b..e4c347af 100644
--- a/ethers-core/src/utils/mod.rs
+++ b/ethers-core/src/utils/mod.rs
@@ -493,8 +493,8 @@ mod tests {
         assert_eq!(parse_units("3_3_0", 3).unwrap(), U256::from(330000), "underscore");
         assert_eq!(parse_units("330", 0).unwrap(), U256::from(330), "zero decimals");
         assert_eq!(parse_units(".1234", 3).unwrap(), U256::from(123), "truncate too many decimals");
-        assert_eq!(parse_units("1", 80).is_err(), true, "overflow");
-        assert_eq!(parse_units("1", -1).is_err(), true, "neg units");
+        assert!(parse_units("1", 80).is_err(), "overflow");
+        assert!(parse_units("1", -1).is_err(), "neg units");
         let two_e30 = U256::from(2) * U256([0x4674edea40000000, 0xc9f2c9cd0, 0x0, 0x0]);
         assert_eq!(parse_units("2", 30).unwrap(), two_e30, "2e30");
         assert_eq!(parse_units(".33_319_2", 0).unwrap(), U256::zero(), "mix");
diff --git a/ethers-middleware/Cargo.toml b/ethers-middleware/Cargo.toml
index 0eb9990b..7a64a1ed 100644
--- a/ethers-middleware/Cargo.toml
+++ b/ethers-middleware/Cargo.toml
@@ -26,7 +26,7 @@ auto_impl = { version = "0.5.0", default-features = false }
 serde = { version = "1.0.124", default-features = false, features = ["derive"] }
 thiserror = { version = "1.0", default-features = false }
 futures-util = { version = "^0.3" }
-futures-locks = { version = "0.7" }
+futures-locks = { version = "0.7", default-features = false }
 tracing = { version = "0.1.37", default-features = false }
 tracing-futures = { version = "0.2.5", default-features = false }
 
diff --git a/ethers-providers/src/transports/retry.rs b/ethers-providers/src/transports/retry.rs
index 8112e508..947a0495 100644
--- a/ethers-providers/src/transports/retry.rs
+++ b/ethers-providers/src/transports/retry.rs
@@ -188,7 +188,7 @@ impl Default for RetryClientBuilder {
             timeout_retries: 3,
             // this should be enough to even out heavy loads
             rate_limit_retries: 10,
-            initial_backoff: Duration::from_millis(100),
+            initial_backoff: Duration::from_millis(1000),
             // alchemy max cpus <https://github.com/alchemyplatform/alchemy-docs/blob/master/documentation/compute-units.md#rate-limits-cups>
             compute_units_per_second: 330,
         }
@@ -289,13 +289,7 @@ where
                 // try to extract the requested backoff from the error or compute the next backoff
                 // based on retry count
                 let mut next_backoff = self.policy.backoff_hint(&err).unwrap_or_else(|| {
-                    // using `retry_number` for creating back pressure because
-                    // of already queued requests
-                    // this increases exponentially with retries and adds a delay based on how many
-                    // requests are currently queued
-                    Duration::from_millis(
-                        self.initial_backoff.as_millis().pow(rate_limit_retry_number) as u64,
-                    )
+                    Duration::from_millis(self.initial_backoff.as_millis() as u64)
                 });
 
                 // requests are usually weighted and can vary from 10 CU to several 100 CU, cheaper
diff --git a/ethers-solc/src/artifacts/mod.rs b/ethers-solc/src/artifacts/mod.rs
index 4e5b7fe4..e3dd5961 100644
--- a/ethers-solc/src/artifacts/mod.rs
+++ b/ethers-solc/src/artifacts/mod.rs
@@ -1733,8 +1733,9 @@ impl fmt::Display for Error {
     }
 }
 
-#[derive(Clone, Debug, Eq, PartialEq, Hash)]
+#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd, Default)]
 pub enum Severity {
+    #[default]
     Error,
     Warning,
     Info,
diff --git a/ethers-solc/src/compile/output/mod.rs b/ethers-solc/src/compile/output/mod.rs
index 294c4e48..15ffaed3 100644
--- a/ethers-solc/src/compile/output/mod.rs
+++ b/ethers-solc/src/compile/output/mod.rs
@@ -3,7 +3,7 @@
 use crate::{
     artifacts::{
         contract::{CompactContractBytecode, CompactContractRef, Contract},
-        Error,
+        Error, Severity,
     },
     buildinfo::RawBuildInfo,
     info::ContractInfoRef,
@@ -31,6 +31,8 @@ pub struct ProjectCompileOutput<T: ArtifactOutput = ConfigurableArtifacts> {
     pub(crate) cached_artifacts: Artifacts<T::Artifact>,
     /// errors that should be omitted
     pub(crate) ignored_error_codes: Vec<u64>,
+    /// set minimum level of severity that is treated as an error
+    pub(crate) compiler_severity_filter: Severity,
 }
 
 impl<T: ArtifactOutput> ProjectCompileOutput<T> {
@@ -197,7 +199,7 @@ impl<T: ArtifactOutput> ProjectCompileOutput<T> {
 
     /// Whether there were errors
     pub fn has_compiler_errors(&self) -> bool {
-        self.compiler_output.has_error()
+        self.compiler_output.has_error(&self.ignored_error_codes, &self.compiler_severity_filter)
     }
 
     /// Whether there were warnings
@@ -398,7 +400,9 @@ impl<T: ArtifactOutput> fmt::Display for ProjectCompileOutput<T> {
         if self.compiler_output.is_unchanged() {
             f.write_str("Nothing to compile")
         } else {
-            self.compiler_output.diagnostics(&self.ignored_error_codes).fmt(f)
+            self.compiler_output
+                .diagnostics(&self.ignored_error_codes, self.compiler_severity_filter.clone())
+                .fmt(f)
         }
     }
 }
@@ -426,8 +430,20 @@ impl AggregatedCompilerOutput {
     }
 
     /// Whether the output contains a compiler error
-    pub fn has_error(&self) -> bool {
-        self.errors.iter().any(|err| err.severity.is_error())
+    pub fn has_error(
+        &self,
+        ignored_error_codes: &[u64],
+        compiler_severity_filter: &Severity,
+    ) -> bool {
+        self.errors.iter().any(|err| {
+            if compiler_severity_filter.ge(&err.severity) {
+                if compiler_severity_filter.is_warning() {
+                    return self.has_warning(ignored_error_codes)
+                }
+                return true
+            }
+            false
+        })
     }
 
     /// Whether the output contains a compiler warning
@@ -441,8 +457,12 @@ impl AggregatedCompilerOutput {
         })
     }
 
-    pub fn diagnostics<'a>(&'a self, ignored_error_codes: &'a [u64]) -> OutputDiagnostics {
-        OutputDiagnostics { compiler_output: self, ignored_error_codes }
+    pub fn diagnostics<'a>(
+        &'a self,
+        ignored_error_codes: &'a [u64],
+        compiler_severity_filter: Severity,
+    ) -> OutputDiagnostics {
+        OutputDiagnostics { compiler_output: self, ignored_error_codes, compiler_severity_filter }
     }
 
     pub fn is_empty(&self) -> bool {
@@ -702,12 +722,14 @@ pub struct OutputDiagnostics<'a> {
     compiler_output: &'a AggregatedCompilerOutput,
     /// the error codes to ignore
     ignored_error_codes: &'a [u64],
+    /// set minimum level of severity that is treated as an error
+    compiler_severity_filter: Severity,
 }
 
 impl<'a> OutputDiagnostics<'a> {
     /// Returns true if there is at least one error of high severity
     pub fn has_error(&self) -> bool {
-        self.compiler_output.has_error()
+        self.compiler_output.has_error(self.ignored_error_codes, &self.compiler_severity_filter)
     }
 
     /// Returns true if there is at least one warning
diff --git a/ethers-solc/src/compile/project.rs b/ethers-solc/src/compile/project.rs
index 5bcf376b..1233ba75 100644
--- a/ethers-solc/src/compile/project.rs
+++ b/ethers-solc/src/compile/project.rs
@@ -311,7 +311,8 @@ impl<'a, T: ArtifactOutput> CompiledState<'a, T> {
                 ctx,
                 &project.paths,
             )
-        } else if output.has_error() {
+        } else if output.has_error(&project.ignored_error_codes, &project.compiler_severity_filter)
+        {
             trace!("skip writing cache file due to solc errors: {:?}", output.errors);
             project.artifacts_handler().output_to_artifacts(
                 &output.contracts,
@@ -358,14 +359,18 @@ impl<'a, T: ArtifactOutput> ArtifactsState<'a, T> {
     fn write_cache(self) -> Result<ProjectCompileOutput<T>> {
         trace!("write cache");
         let ArtifactsState { output, cache, compiled_artifacts } = self;
-        let ignored_error_codes = cache.project().ignored_error_codes.clone();
-        let skip_write_to_disk = cache.project().no_artifacts || output.has_error();
+        let project = cache.project();
+        let ignored_error_codes = project.ignored_error_codes.clone();
+        let compiler_severity_filter = project.compiler_severity_filter.clone();
+        let skip_write_to_disk = project.no_artifacts ||
+            output.has_error(&ignored_error_codes, &compiler_severity_filter);
         let cached_artifacts = cache.consume(&compiled_artifacts, !skip_write_to_disk)?;
         Ok(ProjectCompileOutput {
             compiler_output: output,
             compiled_artifacts,
             cached_artifacts,
             ignored_error_codes,
+            compiler_severity_filter,
         })
     }
 }
diff --git a/ethers-solc/src/lib.rs b/ethers-solc/src/lib.rs
index 94805ca6..9d2947f7 100644
--- a/ethers-solc/src/lib.rs
+++ b/ethers-solc/src/lib.rs
@@ -42,7 +42,7 @@ use crate::{
     error::{SolcError, SolcIoError},
     sources::{VersionedSourceFile, VersionedSourceFiles},
 };
-use artifacts::contract::Contract;
+use artifacts::{contract::Contract, Severity};
 use compile::output::contracts::VersionedContracts;
 use error::Result;
 use semver::Version;
@@ -73,6 +73,8 @@ pub struct Project<T: ArtifactOutput = ConfigurableArtifacts> {
     pub artifacts: T,
     /// Errors/Warnings which match these error codes are not going to be logged
     pub ignored_error_codes: Vec<u64>,
+    /// The minimum severity level that is treated as a compiler error
+    pub compiler_severity_filter: Severity,
     /// The paths which will be allowed for library inclusion
     pub allowed_paths: AllowedLibPaths,
     /// The paths which will be used with solc's `--include-path` attribute
@@ -569,6 +571,8 @@ pub struct ProjectBuilder<T: ArtifactOutput = ConfigurableArtifacts> {
     artifacts: T,
     /// Which error codes to ignore
     pub ignored_error_codes: Vec<u64>,
+    /// The minimum severity level that is treated as a compiler error
+    compiler_severity_filter: Severity,
     /// All allowed paths for solc's `--allowed-paths`
     allowed_paths: AllowedLibPaths,
     /// Paths to use for solc's `--include-path`
@@ -591,6 +595,7 @@ impl<T: ArtifactOutput> ProjectBuilder<T> {
             slash_paths: true,
             artifacts,
             ignored_error_codes: Vec::new(),
+            compiler_severity_filter: Severity::Error,
             allowed_paths: Default::default(),
             include_paths: Default::default(),
             solc_jobs: None,
@@ -629,6 +634,12 @@ impl<T: ArtifactOutput> ProjectBuilder<T> {
         self
     }
 
+    #[must_use]
+    pub fn set_compiler_severity_filter(mut self, compiler_severity_filter: Severity) -> Self {
+        self.compiler_severity_filter = compiler_severity_filter;
+        self
+    }
+
     /// Disables cached builds
     #[must_use]
     pub fn ephemeral(self) -> Self {
@@ -727,6 +738,7 @@ impl<T: ArtifactOutput> ProjectBuilder<T> {
             no_artifacts,
             auto_detect,
             ignored_error_codes,
+            compiler_severity_filter,
             allowed_paths,
             include_paths,
             solc_jobs,
@@ -746,6 +758,7 @@ impl<T: ArtifactOutput> ProjectBuilder<T> {
             slash_paths,
             artifacts,
             ignored_error_codes,
+            compiler_severity_filter,
             allowed_paths,
             include_paths,
             solc_jobs,
@@ -803,6 +816,7 @@ impl<T: ArtifactOutput> ProjectBuilder<T> {
             auto_detect,
             artifacts,
             ignored_error_codes,
+            compiler_severity_filter,
             mut allowed_paths,
             include_paths,
             solc_jobs,
@@ -834,6 +848,7 @@ impl<T: ArtifactOutput> ProjectBuilder<T> {
             auto_detect,
             artifacts,
             ignored_error_codes,
+            compiler_severity_filter,
             allowed_paths,
             include_paths,
             solc_jobs: solc_jobs.unwrap_or_else(num_cpus::get),
diff --git a/ethers-solc/src/utils.rs b/ethers-solc/src/utils.rs
index b39053ce..71c10c37 100644
--- a/ethers-solc/src/utils.rs
+++ b/ethers-solc/src/utils.rs
@@ -43,7 +43,7 @@ pub static RE_THREE_OR_MORE_NEWLINES: Lazy<Regex> = Lazy::new(|| Regex::new("\n{
 
 /// Create a regex that matches any library or contract name inside a file
 pub fn create_contract_or_lib_name_regex(name: &str) -> Regex {
-    Regex::new(&format!(r#"(?:using\s+(?P<n1>{name})\s+|is\s+(?:\w+\s*,\s*)*(?P<n2>{name})(?:\s*,\s*\w+)*|(?:(?P<ignore>(?:function|error|as)\s+|\n[^\n]*(?:"([^"\n]|\\")*|'([^'\n]|\\')*))|\W+)(?P<n3>{name})name.|\(| ))"#)).unwrap()
+    Regex::new(&format!(r#"(?:using\s+(?P<n1>{name})\s+|is\s+(?:\w+\s*,\s*)*(?P<n2>{name})(?:\s*,\s*\w+)*|(?:(?P<ignore>(?:function|error|as)\s+|\n[^\n]*(?:"([^"\n]|\\")*|'([^'\n]|\\')*))|\W+)(?P<n3>{name})(?:\.|\(| ))"#)).unwrap()
 }
 
 /// Move a range by a specified offset
diff --git a/examples/paginated_logs.rs b/examples/paginated_logs.rs
index 9dbe8ae9..0a58a9b8 100644
--- a/examples/paginated_logs.rs
+++ b/examples/paginated_logs.rs
@@ -14,7 +14,7 @@ async fn main() -> Result<()> {
 
     let erc20_transfer_filter = Filter::new()
         .from_block(last_block - 10000)
-        .topic0(ValueOrArray::Value(H256::from(keccak256("Transfer(address,address,uint256)"))));
+        .event("Transfer(address,address,uint256)");
 
     let mut stream = client.get_logs_paginated(&erc20_transfer_filter, 10);
 
diff --git a/examples/subscribe_logs.rs b/examples/subscribe_logs.rs
index 02788a9c..c35cd62a 100644
--- a/examples/subscribe_logs.rs
+++ b/examples/subscribe_logs.rs
@@ -16,7 +16,7 @@ async fn main() -> Result<()> {
 
     let erc20_transfer_filter = Filter::new()
         .from_block(last_block - 25)
-        .topic0(ValueOrArray::Value(H256::from(keccak256("Transfer(address,address,uint256)"))));
+        .event("Transfer(address,address,uint256)");
 
     let mut stream = client.subscribe_logs(&erc20_transfer_filter).await?;
 


Test patch:
diff --git a/ethers-contract/tests/it/abigen.rs b/ethers-contract/tests/it/abigen.rs
index f38f9538..41706d01 100644
--- a/ethers-contract/tests/it/abigen.rs
+++ b/ethers-contract/tests/it/abigen.rs
@@ -737,3 +737,16 @@ fn can_generate_event_with_structs() {
     assert_eq!("MyEvent((uint256,uint256),uint256)", MyEventFilter::abi_signature());
     assert_event::<MyEventFilter>();
 }
+
+#[test]
+fn can_handle_overloaded_function_with_array() {
+    abigen!(
+        Test,
+        r#"[
+         serializeString(string calldata, string calldata, string calldata) external returns (string memory)
+         serializeString(string calldata, string calldata, string[] calldata) external returns (string memory)
+         serializeBool(string calldata, string calldata, bool) external returns (string memory)
+         serializeBool(string calldata, string calldata, bool[] calldata) external returns (string memory)
+    ]"#,
+    );
+}
diff --git a/ethers-solc/test-data/test-contract-warnings/LicenseWarning.sol b/ethers-solc/test-data/test-contract-warnings/LicenseWarning.sol
new file mode 100644
index 00000000..aeaa7a51
--- /dev/null
+++ b/ethers-solc/test-data/test-contract-warnings/LicenseWarning.sol
@@ -0,0 +1,3 @@
+pragma solidity 0.8.6;
+
+contract LicenseWarning {}
diff --git a/ethers-solc/tests/project.rs b/ethers-solc/tests/project.rs
index 1814610f..84bc9bfb 100644
--- a/ethers-solc/tests/project.rs
+++ b/ethers-solc/tests/project.rs
@@ -1618,6 +1618,81 @@ fn can_compile_model_checker_sample() {
     assert!(compiled.has_compiler_warnings());
 }
 
+#[test]
+fn test_compiler_severity_filter() {
+    fn gen_test_data_warning_path() -> ProjectPathsConfig {
+        let root =
+            PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("test-data/test-contract-warnings");
+
+        ProjectPathsConfig::builder().sources(root).build().unwrap()
+    }
+
+    let project = Project::builder()
+        .no_artifacts()
+        .paths(gen_test_data_warning_path())
+        .ephemeral()
+        .build()
+        .unwrap();
+    let compiled = project.compile().unwrap();
+    assert!(compiled.has_compiler_warnings());
+    assert!(!compiled.has_compiler_errors());
+
+    let project = Project::builder()
+        .no_artifacts()
+        .paths(gen_test_data_warning_path())
+        .ephemeral()
+        .set_compiler_severity_filter(ethers_solc::artifacts::Severity::Warning)
+        .build()
+        .unwrap();
+    let compiled = project.compile().unwrap();
+    assert!(compiled.has_compiler_warnings());
+    assert!(compiled.has_compiler_errors());
+}
+
+#[test]
+fn test_compiler_severity_filter_and_ignored_error_codes() {
+    fn gen_test_data_licensing_warning() -> ProjectPathsConfig {
+        let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
+            .join("test-data/test-contract-warnings/LicenseWarning.sol");
+
+        ProjectPathsConfig::builder().sources(root).build().unwrap()
+    }
+
+    let missing_license_error_code = 1878;
+
+    let project = Project::builder()
+        .no_artifacts()
+        .paths(gen_test_data_licensing_warning())
+        .ephemeral()
+        .build()
+        .unwrap();
+    let compiled = project.compile().unwrap();
+    assert!(compiled.has_compiler_warnings());
+
+    let project = Project::builder()
+        .no_artifacts()
+        .paths(gen_test_data_licensing_warning())
+        .ephemeral()
+        .ignore_error_code(missing_license_error_code)
+        .build()
+        .unwrap();
+    let compiled = project.compile().unwrap();
+    assert!(!compiled.has_compiler_warnings());
+    assert!(!compiled.has_compiler_errors());
+
+    let project = Project::builder()
+        .no_artifacts()
+        .paths(gen_test_data_licensing_warning())
+        .ephemeral()
+        .ignore_error_code(missing_license_error_code)
+        .set_compiler_severity_filter(ethers_solc::artifacts::Severity::Warning)
+        .build()
+        .unwrap();
+    let compiled = project.compile().unwrap();
+    assert!(!compiled.has_compiler_warnings());
+    assert!(!compiled.has_compiler_errors());
+}
+
 fn remove_solc_if_exists(version: &Version) {
     if Solc::find_svm_installed_version(version.to_string()).unwrap().is_some() {
         svm::remove_version(version).expect("failed to remove version")