Repository: gakonst/ethers-rs
Pull request #2051 (2023-01-13 10:00:28)

chore(deps): bump svm-rs
## Motivation

Earlier versions of `svm-rs` have transitive dependencies that conflict with newer Rust Crypto packages.

## Solution

Upgrade to the latest `svm-rs` version that has no conflicts with newer Rust Crypto packages.

## PR Checklist

-   [ ] Added Tests **(n/a)**
-   [ ] Added Documentation **(n/a)**
-   [x] Updated the changelog
-   [ ] Breaking changes **(n/a)**



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c82c1e7b..43f7a742 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
 
 ### Unreleased
 
+- Bump [`svm-rs`](https://github.com/roynalnaruto/svm-rs) dependency to fix conflicts with Rust Crytpo packages [#2051](https://github.com/gakonst/ethers-rs/pull/2051)
 - Avoid unnecessary allocations in `utils` [#2046](https://github.com/gakonst/ethers-rs/pull/2046)
 - Add abigen support for hardhat generated bytecode json format [#2012](https://github.com/gakonst/ethers-rs/pull/2012)
 - Fix typo in `RwClient` docs for `write_client` method.
diff --git a/Cargo.lock b/Cargo.lock
index 4d36e31c..f7bf2a35 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -69,6 +69,12 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "anes"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
+
 [[package]]
 name = "anyhow"
 version = "1.0.68"
@@ -343,18 +349,6 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
 
-[[package]]
-name = "bstr"
-version = "0.2.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
-dependencies = [
- "lazy_static",
- "memchr",
- "regex-automata",
- "serde",
-]
-
 [[package]]
 name = "build_const"
 version = "0.2.2"
@@ -508,6 +502,33 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "ciborium"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0c137568cc60b904a7724001b35ce2630fd00d5d84805fbb608ab89509d788f"
+dependencies = [
+ "ciborium-io",
+ "ciborium-ll",
+ "serde",
+]
+
+[[package]]
+name = "ciborium-io"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "346de753af073cc87b52b2083a506b38ac176a44cfb05497b622e27be899b369"
+
+[[package]]
+name = "ciborium-ll"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "213030a2b5a4e0c0892b6652260cf6ccac84827b83a85a534e178e3906c4cf1b"
+dependencies = [
+ "ciborium-io",
+ "half",
+]
+
 [[package]]
 name = "cipher"
 version = "0.3.0"
@@ -527,17 +548,6 @@ dependencies = [
  "inout",
 ]
 
-[[package]]
-name = "clap"
-version = "2.34.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
-dependencies = [
- "bitflags",
- "textwrap 0.11.0",
- "unicode-width",
-]
-
 [[package]]
 name = "clap"
 version = "3.2.23"
@@ -552,7 +562,7 @@ dependencies = [
  "once_cell",
  "strsim",
  "termcolor",
- "textwrap 0.16.0",
+ "textwrap",
 ]
 
 [[package]]
@@ -773,15 +783,16 @@ dependencies = [
 
 [[package]]
 name = "criterion"
-version = "0.3.6"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f"
+checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb"
 dependencies = [
+ "anes",
  "atty",
  "cast",
- "clap 2.34.0",
+ "ciborium",
+ "clap",
  "criterion-plot",
- "csv",
  "futures",
  "itertools",
  "lazy_static",
@@ -791,7 +802,6 @@ dependencies = [
  "rayon",
  "regex",
  "serde",
- "serde_cbor",
  "serde_derive",
  "serde_json",
  "tinytemplate",
@@ -801,9 +811,9 @@ dependencies = [
 
 [[package]]
 name = "criterion-plot"
-version = "0.4.5"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876"
+checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
 dependencies = [
  "cast",
  "itertools",
@@ -891,28 +901,6 @@ dependencies = [
  "subtle",
 ]
 
-[[package]]
-name = "csv"
-version = "1.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
-dependencies = [
- "bstr",
- "csv-core",
- "itoa 0.4.8",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "csv-core"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
-dependencies = [
- "memchr",
-]
-
 [[package]]
 name = "ctor"
 version = "0.1.26"
@@ -2148,7 +2136,7 @@ checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
 dependencies = [
  "bytes",
  "fnv",
- "itoa 1.0.5",
+ "itoa",
 ]
 
 [[package]]
@@ -2195,7 +2183,7 @@ dependencies = [
  "http-body",
  "httparse",
  "httpdate",
- "itoa 1.0.5",
+ "itoa",
  "pin-project-lite",
  "socket2",
  "tokio",
@@ -2391,12 +2379,6 @@ dependencies = [
  "either",
 ]
 
-[[package]]
-name = "itoa"
-version = "0.4.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
-
 [[package]]
 name = "itoa"
 version = "1.0.5"
@@ -3822,16 +3804,6 @@ dependencies = [
  "wasm-bindgen",
 ]
 
-[[package]]
-name = "serde_cbor"
-version = "0.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
-dependencies = [
- "half",
- "serde",
-]
-
 [[package]]
 name = "serde_derive"
 version = "1.0.152"
@@ -3849,7 +3821,7 @@ version = "1.0.91"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
 dependencies = [
- "itoa 1.0.5",
+ "itoa",
  "ryu",
  "serde",
 ]
@@ -3870,7 +3842,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
 dependencies = [
  "form_urlencoded",
- "itoa 1.0.5",
+ "itoa",
  "ryu",
  "serde",
 ]
@@ -4129,13 +4101,13 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
 
 [[package]]
 name = "svm-rs"
-version = "0.2.18"
+version = "0.2.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e4cdcf91153dc0e4e0637f26f042ada32a3b552bc8115935c7bf96f80132b0a"
+checksum = "e18bbb2b229a2cc0d8ba58603adb0e460ad49a3451b1540fd6f7a5d37fd03b80"
 dependencies = [
  "anyhow",
  "cfg-if 1.0.0",
- "clap 3.2.23",
+ "clap",
  "console 0.14.1",
  "dialoguer",
  "fs2",
@@ -4160,9 +4132,9 @@ dependencies = [
 
 [[package]]
 name = "svm-rs-builds"
-version = "0.1.10"
+version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41cdaa6adbe89c6d84c91dbf7d67bb853dd5d8f0cfe6dda42de0295a7b3c2d0b"
+checksum = "ebf4cc09b0dd1cd78bc8ca82c5e22bbcd0cca126ad0d584e2fc47d4dc0a3dd73"
 dependencies = [
  "build_const",
  "hex",
@@ -4244,15 +4216,6 @@ dependencies = [
  "winapi",
 ]
 
-[[package]]
-name = "textwrap"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
-dependencies = [
- "unicode-width",
-]
-
 [[package]]
 name = "textwrap"
 version = "0.16.0"
@@ -4294,7 +4257,7 @@ version = "0.3.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376"
 dependencies = [
- "itoa 1.0.5",
+ "itoa",
  "serde",
  "time-core",
  "time-macros",
diff --git a/ethers-contract/ethers-contract-abigen/src/contract.rs b/ethers-contract/ethers-contract-abigen/src/contract.rs
index 1d3bf00f..371861be 100644
--- a/ethers-contract/ethers-contract-abigen/src/contract.rs
+++ b/ethers-contract/ethers-contract-abigen/src/contract.rs
@@ -150,7 +150,7 @@ impl Context {
                     /// client at the given `Address`. The contract derefs to a `ethers::Contract`
                     /// object
                     pub fn new<T: Into<#ethers_core::types::Address>>(address: T, client: ::std::sync::Arc<M>) -> Self {
-                        #ethers_contract::Contract::new(address.into(), #abi_name.clone(), client).into()
+                        Self(#ethers_contract::Contract::new(address.into(), #abi_name.clone(), client))
                     }
 
                     #deployment_methods
@@ -163,7 +163,7 @@ impl Context {
 
                 impl<M : #ethers_providers::Middleware> From<#ethers_contract::Contract<M>> for #name<M> {
                     fn from(contract: #ethers_contract::Contract<M>) -> Self {
-                       Self(contract)
+                       Self::new(contract.address(), contract.client())
                     }
                 }
         };
@@ -271,7 +271,7 @@ impl Context {
         }
 
         let event_derives = args
-            .event_derives
+            .derives
             .iter()
             .map(|derive| syn::parse_str::<Path>(derive))
             .collect::<Result<Vec<_>, _>>()
diff --git a/ethers-contract/ethers-contract-abigen/src/lib.rs b/ethers-contract/ethers-contract-abigen/src/lib.rs
index cf0659b6..3be23832 100644
--- a/ethers-contract/ethers-contract-abigen/src/lib.rs
+++ b/ethers-contract/ethers-contract-abigen/src/lib.rs
@@ -1,9 +1,13 @@
-#![deny(missing_docs, unsafe_code)]
-#![deny(rustdoc::broken_intra_doc_links)]
+//! # Abigen
+//!
+//! Programmatically generate type-safe Rust bindings for Ethereum smart contracts.
+//!
+//! This crate is intended to be used either indirectly with the [`abigen` procedural macro][abigen]
+//! or directly from a build script / CLI.
+//!
+//! [abigen]: https://docs.rs/ethers/latest/ethers/contract/macro.abigen.html
 
-//! Module for generating type-safe bindings to Ethereum smart contracts. This
-//! module is intended to be used either indirectly with the `abigen` procedural
-//! macro or directly from a build script / CLI
+#![deny(rustdoc::broken_intra_doc_links, missing_docs, unsafe_code)]
 
 #[cfg(test)]
 #[allow(missing_docs)]
@@ -33,19 +37,21 @@ use eyre::Result;
 use proc_macro2::TokenStream;
 use std::{collections::HashMap, fs::File, io::Write, path::Path};
 
-/// Builder struct for generating type-safe bindings from a contract's ABI
+/// Programmatically generate type-safe Rust bindings for an Ethereum smart contract from its ABI.
 ///
-/// Note: Your contract's ABI must contain the `stateMutability` field. This is
-/// [still not supported by Vyper](https://github.com/vyperlang/vyper/issues/1931), so you must adjust your ABIs and replace
-/// `constant` functions with `view` or `pure`.
+/// For all the supported ABI sources, see [Source].
 ///
-/// To generate bindings for _multiple_ contracts at once see also [`crate::MultiAbigen`].
+/// To generate bindings for *multiple* contracts at once, see [`MultiAbigen`].
+///
+/// To generate bindings at compile time, see [the abigen! macro][abigen], or use in a `build.rs`
+/// file.
+///
+/// [abigen]: https://docs.rs/ethers/latest/ethers/contract/macro.abigen.html
 ///
 /// # Example
 ///
-/// Running the code below will generate a file called `token.rs` containing the
-/// bindings inside, which exports an `ERC20Token` struct, along with all its events. Put into a
-/// `build.rs` file this will generate the bindings during `cargo build`.
+/// Running the code below will generate a file called `token.rs` containing the bindings inside,
+/// which exports an `ERC20Token` struct, along with all its events.
 ///
 /// ```no_run
 /// # use ethers_contract_abigen::Abigen;
@@ -53,22 +59,22 @@ use std::{collections::HashMap, fs::File, io::Write, path::Path};
 /// Abigen::new("ERC20Token", "./abi.json")?.generate()?.write_to_file("token.rs")?;
 /// # Ok(())
 /// # }
-#[derive(Debug, Clone)]
+#[derive(Clone, Debug)]
+#[must_use = "Abigen does nothing unless you generate or expand it."]
 pub struct Abigen {
-    /// The source of the ABI JSON for the contract whose bindings
-    /// are being generated.
+    /// The source of the ABI JSON for the contract whose bindings are being generated.
     abi_source: Source,
 
-    /// Override the contract name to use for the generated type.
+    /// The contract's name to use for the generated type.
     contract_name: String,
 
     /// Manually specified contract method aliases.
     method_aliases: HashMap<String, String>,
 
-    /// Derives added to event structs and enums.
-    event_derives: Vec<String>,
+    /// Manually specified `derive` macros added to all structs and enums.
+    derives: Vec<String>,
 
-    /// Whether to format the code. Uses [`prettyplease`].
+    /// Whether to format the generated bindings using [`prettyplease`].
     format: bool,
 
     /// Manually specified event name aliases.
@@ -79,22 +85,21 @@ pub struct Abigen {
 }
 
 impl Abigen {
-    /// Creates a new builder with the given ABI JSON source.
-    pub fn new<S: AsRef<str>>(contract_name: &str, abi_source: S) -> Result<Self> {
+    /// Creates a new builder with the given [ABI Source][Source].
+    pub fn new<T: Into<String>, S: AsRef<str>>(contract_name: T, abi_source: S) -> Result<Self> {
         let abi_source = abi_source.as_ref().parse()?;
         Ok(Self {
             abi_source,
-            contract_name: contract_name.to_owned(),
-            method_aliases: HashMap::new(),
-            event_derives: Vec::new(),
-            event_aliases: HashMap::new(),
+            contract_name: contract_name.into(),
             format: true,
+            method_aliases: Default::default(),
+            derives: Default::default(),
+            event_aliases: Default::default(),
             error_aliases: Default::default(),
         })
     }
 
-    /// Attempts to load a new builder from an ABI JSON file at the specific
-    /// path.
+    /// Attempts to load a new builder from an ABI JSON file at the specific path.
     pub fn from_file(path: impl AsRef<Path>) -> Result<Self> {
         let name = path
             .as_ref()
@@ -110,9 +115,10 @@ impl Abigen {
         Self::new(name, std::fs::read_to_string(path.as_ref())?)
     }
 
-    /// Manually adds a solidity event alias to specify what the event struct
-    /// and function name will be in Rust.
-    #[must_use]
+    /// Manually adds a solidity event alias to specify what the event struct and function name will
+    /// be in Rust.
+    ///
+    /// For events without an alias, the `PascalCase` event name will be used.
     pub fn add_event_alias<S1, S2>(mut self, signature: S1, alias: S2) -> Self
     where
         S1: Into<String>,
@@ -122,10 +128,9 @@ impl Abigen {
         self
     }
 
-    /// Manually adds a solidity method alias to specify what the method name
-    /// will be in Rust. For solidity methods without an alias, the snake cased
-    /// method name will be used.
-    #[must_use]
+    /// Add a Solidity method error alias to specify the generated method name.
+    ///
+    /// For methods without an alias, the `snake_case` method name will be used.
     pub fn add_method_alias<S1, S2>(mut self, signature: S1, alias: S2) -> Self
     where
         S1: Into<String>,
@@ -135,8 +140,9 @@ impl Abigen {
         self
     }
 
-    /// Manually adds a solidity error alias to specify what the error struct will be in Rust.
-    #[must_use]
+    /// Add a Solidity custom error alias to specify the generated struct's name.
+    ///
+    /// For errors without an alias, the `PascalCase` error name will be used.
     pub fn add_error_alias<S1, S2>(mut self, signature: S1, alias: S2) -> Self
     where
         S1: Into<String>,
@@ -163,16 +169,18 @@ impl Abigen {
         self
     }
 
-    /// Add a custom derive to the derives for event structs and enums.
+    #[deprecated = "Use add_derive instead"]
+    #[doc(hidden)]
+    pub fn add_event_derive<S: Into<String>>(mut self, derive: S) -> Self {
+        self.derives.push(derive.into());
+        self
+    }
+
+    /// Add a custom derive to the derives for all structs and enums.
     ///
-    /// This makes it possible to for example derive serde::Serialize and
-    /// serde::Deserialize for events.
-    #[must_use]
-    pub fn add_event_derive<S>(mut self, derive: S) -> Self
-    where
-        S: Into<String>,
-    {
-        self.event_derives.push(derive.into());
+    /// For example, this makes it possible to derive serde::Serialize and serde::Deserialize.
+    pub fn add_derive<S: Into<String>>(mut self, derive: S) -> Self {
+        self.derives.push(derive.into());
         self
     }
 
@@ -253,12 +261,12 @@ impl ContractBindings {
         self.tokens
     }
 
-    /// Generate the default module name (snake case of the contract name)
+    /// Generate the default module name (snake case of the contract name).
     pub fn module_name(&self) -> String {
         util::safe_module_name(&self.name)
     }
 
-    /// Generate the default filename of the module
+    /// Generate the default file name of the module.
     pub fn module_filename(&self) -> String {
         let mut name = self.module_name();
         name.extend([".rs"]);
diff --git a/ethers-contract/ethers-contract-derive/src/abigen.rs b/ethers-contract/ethers-contract-derive/src/abigen.rs
index 8c803dbe..6d0de4b8 100644
--- a/ethers-contract/ethers-contract-derive/src/abigen.rs
+++ b/ethers-contract/ethers-contract-derive/src/abigen.rs
@@ -1,14 +1,13 @@
-//! Implementation of procedural macro for generating type-safe bindings to an
-//! ethereum smart contract.
-use crate::spanned::{ParseInner, Spanned};
-
-use ethers_contract_abigen::Abigen;
-use ethers_core::abi::{Function, FunctionExt, Param, StateMutability};
+//! Implementation of procedural macro for generating type-safe bindings to an Ethereum smart
+//! contract.
 
+use crate::spanned::{ParseInner, Spanned};
 use ethers_contract_abigen::{
     contract::{Context, ExpandedContract},
     multi::MultiExpansion,
+    Abigen,
 };
+use ethers_core::abi::{Function, FunctionExt, Param, StateMutability};
 use proc_macro2::{Span, TokenStream as TokenStream2};
 use quote::ToTokens;
 use std::{collections::HashSet, error::Error};
@@ -75,9 +74,9 @@ impl ContractArgs {
                 Parameter::Methods(methods) => methods
                     .into_iter()
                     .fold(builder, |builder, m| builder.add_method_alias(m.signature, m.alias)),
-                Parameter::EventDerives(derives) => derives
-                    .into_iter()
-                    .fold(builder, |builder, derive| builder.add_event_derive(derive)),
+                Parameter::Derives(derives) => {
+                    derives.into_iter().fold(builder, |builder, derive| builder.add_derive(derive))
+                }
             };
         }
 
@@ -133,7 +132,7 @@ impl ParseInner for ContractArgs {
 #[cfg_attr(test, derive(Debug, Eq, PartialEq))]
 enum Parameter {
     Methods(Vec<Method>),
-    EventDerives(Vec<String>),
+    Derives(Vec<String>),
 }
 
 impl Parse for Parameter {
@@ -171,7 +170,7 @@ impl Parse for Parameter {
 
                 Parameter::Methods(methods)
             }
-            "event_derives" => {
+            "derives" | "event_derives" => {
                 let content;
                 parenthesized!(content in input);
                 let derives = content
@@ -179,7 +178,7 @@ impl Parse for Parameter {
                     .into_iter()
                     .map(|path| path.to_token_stream().to_string())
                     .collect();
-                Parameter::EventDerives(derives)
+                Parameter::Derives(derives)
             }
             _ => {
                 return Err(ParseError::new(
@@ -295,7 +294,7 @@ mod tests {
                 ContractArgs {
                     name: "TestContract".to_string(),
                     abi: "path/to/abi.json".to_string(),
-                    parameters: vec![Parameter::EventDerives(vec![
+                    parameters: vec![Parameter::Derives(vec![
                         "serde :: Deserialize".into(),
                         "serde :: Serialize".into(),
                     ])],
@@ -303,7 +302,7 @@ mod tests {
                 ContractArgs {
                     name: "TestContract2".to_string(),
                     abi: "other.json".to_string(),
-                    parameters: vec![Parameter::EventDerives(vec![
+                    parameters: vec![Parameter::Derives(vec![
                         "serde :: Deserialize".into(),
                         "serde :: Serialize".into(),
                     ])],
@@ -341,7 +340,7 @@ mod tests {
                 ContractArgs {
                     name: "TestContract2".to_string(),
                     abi: "other.json".to_string(),
-                    parameters: vec![Parameter::EventDerives(vec![
+                    parameters: vec![Parameter::Derives(vec![
                         "serde :: Deserialize".into(),
                         "serde :: Serialize".into(),
                     ])],
@@ -372,7 +371,7 @@ mod tests {
                 ContractArgs {
                     name: "TestContract2".to_string(),
                     abi: "other.json".to_string(),
-                    parameters: vec![Parameter::EventDerives(vec![
+                    parameters: vec![Parameter::Derives(vec![
                         "serde :: Deserialize".into(),
                         "serde :: Serialize".into(),
                     ])],
@@ -423,7 +422,7 @@ mod tests {
                         method("myMethod(uint256,bool)", "my_renamed_method"),
                         method("myOtherMethod()", "my_other_renamed_method"),
                     ]),
-                    Parameter::EventDerives(vec![
+                    Parameter::Derives(vec![
                         "Asdf".into(),
                         "a :: B".into(),
                         "a :: b :: c :: D".into()
diff --git a/ethers-contract/src/multicall/mod.rs b/ethers-contract/src/multicall/mod.rs
index 73c67a39..76106d36 100644
--- a/ethers-contract/src/multicall/mod.rs
+++ b/ethers-contract/src/multicall/mod.rs
@@ -1,13 +1,11 @@
-use crate::{
-    call::{ContractCall, ContractError},
-    Lazy,
-};
+use crate::call::{ContractCall, ContractError};
 use ethers_core::{
     abi::{AbiDecode, Detokenize, Function, Token},
     types::{Address, BlockNumber, Bytes, Chain, NameOrAddress, H160, U256},
 };
+
 use ethers_providers::{Middleware, PendingTransaction};
-use std::{convert::TryFrom, sync::Arc};
+use std::{convert::TryFrom, fmt, sync::Arc};
 
 pub mod multicall_contract;
 use multicall_contract::multicall_3::{
@@ -26,60 +24,70 @@ pub const MULTICALL_ADDRESS: Address = H160([
 ]);
 
 /// The chain IDs that [`MULTICALL_ADDRESS`] has been deployed to.
+///
 /// Taken from: <https://github.com/mds1/multicall#multicall3-contract-addresses>
-pub static MULTICALL_SUPPORTED_CHAIN_IDS: Lazy<[U256; 48]> = Lazy::new(|| {
+pub const MULTICALL_SUPPORTED_CHAIN_IDS: &[u64] = {
     use Chain::*;
-    [
-        U256::from(Mainnet),                  // Mainnet
-        U256::from(Kovan),                    // Kovan
-        U256::from(Rinkeby),                  // Rinkeby
-        U256::from(Goerli),                   // Goerli
-        U256::from(Ropsten),                  // Ropsten
-        U256::from(Sepolia),                  // Sepolia
-        U256::from(Optimism),                 // Optimism
-        U256::from(OptimismGoerli),           // OptimismGoerli
-        U256::from(OptimismKovan),            // OptimismKovan
-        U256::from(Arbitrum),                 // Arbitrum
-        U256::from(ArbitrumGoerli),           // ArbitrumGoerli,
-        U256::from(ArbitrumTestnet),          // Arbitrum Rinkeby
-        U256::from(Polygon),                  // Polygon
-        U256::from(PolygonMumbai),            // PolygonMumbai
-        U256::from(XDai),                     // XDai
-        U256::from(Chiado),                   // ChiadoTestnet
-        U256::from(Avalanche),                // Avalanche
-        U256::from(AvalancheFuji),            // AvalancheFuji
-        U256::from(FantomTestnet),            // FantomTestnet
-        U256::from(Fantom),                   // Fantom
-        U256::from(BinanceSmartChain),        // BinanceSmartChain
-        U256::from(BinanceSmartChainTestnet), // BinanceSmartChainTestnet
-        U256::from(Moonbeam),                 // Moonbeam
-        U256::from(Moonriver),                // Moonriver
-        U256::from(Moonbase),                 // Moonbase
-        U256::from(1666600000),               // Harmony0
-        U256::from(1666600001),               // Harmony1
-        U256::from(1666600002),               // Harmony2
-        U256::from(1666600003),               // Harmony3
-        U256::from(Cronos),                   // Cronos
-        U256::from(122),                      // Fuse
-        U256::from(19),                       // Songbird
-        U256::from(16),                       // CostonTestnet
-        U256::from(288),                      // Boba
-        U256::from(Aurora),                   // Aurora
-        U256::from(592),                      // Astar
-        U256::from(66),                       // OKC
-        U256::from(128),                      // Heco
-        U256::from(1088),                     // Metis
-        U256::from(Rsk),                      // Rsk
-        U256::from(31),                       // RskTestnet
-        U256::from(Evmos),                    // Evmos
-        U256::from(EvmosTestnet),             // EvmosTestnet
-        U256::from(71402),                    // Godwoken
-        U256::from(71401),                    // GodwokenTestnet
-        U256::from(8217),                     // Klaytn
-        U256::from(2001),                     // Milkomeda
-        U256::from(321),                      // KCC
+    &[
+        Mainnet as u64,                  // Mainnet
+        Kovan as u64,                    // Kovan
+        Rinkeby as u64,                  // Rinkeby
+        Goerli as u64,                   // Görli
+        Ropsten as u64,                  // Ropsten
+        Sepolia as u64,                  // Sepolia
+        Optimism as u64,                 // Optimism
+        OptimismKovan as u64,            // Optimism Kovan
+        OptimismGoerli as u64,           // Optimism Görli
+        Arbitrum as u64,                 // Arbitrum
+        ArbitrumNova as u64,             // Arbitrum Nova
+        ArbitrumGoerli as u64,           // Arbitrum Görli
+        ArbitrumTestnet as u64,          // Arbitrum Rinkeby
+        Polygon as u64,                  // Polygon
+        PolygonMumbai as u64,            // Polygon Mumbai
+        XDai as u64,                     // Gnosis Chain
+        Avalanche as u64,                // Avalanche
+        AvalancheFuji as u64,            // Avalanche Fuji
+        FantomTestnet as u64,            // Fantom Testnet
+        Fantom as u64,                   // Fantom Opera
+        BinanceSmartChain as u64,        // BNB Smart Chain
+        BinanceSmartChainTestnet as u64, // BNB Smart Chain Testnet
+        Moonbeam as u64,                 // Moonbeam
+        Moonriver as u64,                // Moonriver
+        Moonbase as u64,                 // Moonbase
+        1666600000,                      // Harmony0
+        1666600001,                      // Harmony1
+        1666600002,                      // Harmony2
+        1666600003,                      // Harmony3
+        Cronos as u64,                   // Cronos
+        122,                             // Fuse
+        14,                              // Flare Mainnet
+        19,                              // Songbird Canary Network
+        16,                              // Coston Testnet
+        114,                             // Coston2 Testnet
+        288,                             // Boba
+        Aurora as u64,                   // Aurora
+        592,                             // Astar
+        66,                              // OKC
+        128,                             // Heco Chain
+        1088,                            // Metis
+        Rsk as u64,                      // Rsk
+        31,                              // Rsk Testnet
+        Evmos as u64,                    // Evmos
+        EvmosTestnet as u64,             // Evmos Testnet
+        Oasis as u64,                    // Oasis
+        42261,                           // Oasis Emerald ParaTime Testnet
+        42262,                           // Oasis Emerald ParaTime
+        Celo as u64,                     // Celo
+        CeloAlfajores as u64,            // Celo Alfajores Testnet
+        71402,                           // Godwoken
+        71401,                           // Godwoken Testnet
+        8217,                            // Klaytn
+        2001,                            // Milkomeda
+        321,                             // KCC
+        106,                             // Velas
+        40,                              // Telos
     ]
-});
+};
 
 #[derive(Debug, thiserror::Error)]
 pub enum MulticallError<M: Middleware> {
@@ -87,7 +95,7 @@ pub enum MulticallError<M: Middleware> {
     ContractError(#[from] ContractError<M>),
 
     #[error("Chain ID {0} is currently not supported by Multicall. Provide an address instead.")]
-    InvalidChainId(U256),
+    InvalidChainId(u64),
 
     #[error("Illegal revert: Multicall2 call reverted when it wasn't allowed to.")]
     IllegalRevert,
@@ -257,7 +265,6 @@ impl TryFrom<u8> for MulticallVersion {
 /// [`add_call`]: #method.add_call
 /// [`call`]: #method.call
 /// [`send`]: #method.send
-#[derive(Clone)]
 #[must_use = "Multicall does nothing unless you use `call` or `send`"]
 pub struct Multicall<M> {
     /// The Multicall contract interface.
@@ -268,15 +275,27 @@ pub struct Multicall<M> {
     calls: Vec<Call>,
 }
 
-// Manually implement Debug due to Middleware trait bounds.
-impl<M: Middleware> std::fmt::Debug for Multicall<M> {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+// Manually implement Clone and Debug to avoid trait bounds.
+impl<M> Clone for Multicall<M> {
+    fn clone(&self) -> Self {
+        Self {
+            contract: self.contract.clone(),
+            version: self.version,
+            legacy: self.legacy,
+            block: self.block.clone(),
+            calls: self.calls.clone(),
+        }
+    }
+}
+
+impl<M> fmt::Debug for Multicall<M> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("Multicall")
+            .field("address", &self.contract.address())
             .field("version", &self.version)
             .field("legacy", &self.legacy)
             .field("block", &self.block)
             .field("calls", &self.calls)
-            .field("contract", &self.contract)
             .finish()
     }
 }
@@ -305,7 +324,7 @@ impl<M: Middleware> Multicall<M> {
             Some(addr) => addr,
             None => {
                 let chain_id =
-                    client.get_chainid().await.map_err(ContractError::MiddlewareError)?;
+                    client.get_chainid().await.map_err(ContractError::MiddlewareError)?.as_u64();
                 if !MULTICALL_SUPPORTED_CHAIN_IDS.contains(&chain_id) {
                     return Err(MulticallError::InvalidChainId(chain_id))
                 }
@@ -341,22 +360,24 @@ impl<M: Middleware> Multicall<M> {
     pub fn new_with_chain_id(
         client: impl Into<Arc<M>>,
         address: Option<Address>,
-        chain_id: Option<impl Into<U256>>,
+        chain_id: Option<impl Into<u64>>,
     ) -> Result<Self, M> {
         // If no address is provided, check if chain_id is supported and use the default multicall
         // address.
-        let address: Address = match address {
-            Some(addr) => addr,
-            None => {
-                // Can't fetch chain_id from provider since we're not in an async function so we
-                // panic instead.
-                let chain_id =
-                    chain_id.expect("Must provide at least one of: address or chain ID.").into();
+        let address: Address = match (address, chain_id) {
+            (Some(addr), _) => addr,
+            (_, Some(chain_id)) => {
+                let chain_id = chain_id.into();
                 if !MULTICALL_SUPPORTED_CHAIN_IDS.contains(&chain_id) {
                     return Err(MulticallError::InvalidChainId(chain_id))
                 }
                 MULTICALL_ADDRESS
             }
+            _ => {
+                // Can't fetch chain_id from provider since we're not in an async function so we
+                // panic instead.
+                panic!("Must provide at least one of: address or chain ID.")
+            }
         };
 
         // Instantiate the multicall contract
diff --git a/ethers-core/src/utils/genesis.rs b/ethers-core/src/utils/genesis.rs
index 232dd7d4..77d072ee 100644
--- a/ethers-core/src/utils/genesis.rs
+++ b/ethers-core/src/utils/genesis.rs
@@ -130,11 +130,13 @@ pub struct ChainConfig {
     #[serde(skip_serializing_if = "Option::is_none")]
     pub merge_netsplit_block: Option<u64>,
 
-    /// The Shanghai hard fork block.
+    /// Shanghai switch time.
     #[serde(skip_serializing_if = "Option::is_none")]
-    pub shanghai_block: Option<u64>,
+    pub shanghai_time: Option<u64>,
 
-    /// The Cancun hard fork block.
+    // TODO: change to cancunTime when <https://github.com/ethereum/go-ethereum/pull/26481> is
+    // merged in geth
+    /// Cancun hard fork block.
     #[serde(skip_serializing_if = "Option::is_none")]
     pub cancun_block: Option<u64>,
 
diff --git a/ethers-solc/Cargo.toml b/ethers-solc/Cargo.toml
index cf98f7c2..b39a7646 100644
--- a/ethers-solc/Cargo.toml
+++ b/ethers-solc/Cargo.toml
@@ -45,17 +45,17 @@ cfg-if = "1.0.0"
 
 [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
 home = "0.5.4"
-svm = { package = "svm-rs", version = "0.2.18", default-features = false, optional = true, features = [
+svm = { package = "svm-rs", version = "0.2.19", default-features = false, optional = true, features = [
     "blocking",
 ] }
-svm-builds = { package = "svm-rs-builds", version = "0.1.8", optional = true }
+svm-builds = { package = "svm-rs-builds", version = "0.1.11", optional = true }
 
 [target.'cfg(target_arch = "wasm32")'.dependencies]
 # NOTE: this enables wasm compatibility for getrandom indirectly
 getrandom = { version = "0.2", features = ["js"] }
 
 [dev-dependencies]
-criterion = { version = "0.3", features = ["async_tokio"] }
+criterion = { version = "0.4", features = ["async_tokio"] }
 env_logger = "0.10.0"
 tracing-subscriber = { version = "0.3", default-features = false, features = ["env-filter", "fmt"] }
 rand = "0.8.5"


Test patch:
diff --git a/ethers-contract/tests/it/abigen.rs b/ethers-contract/tests/it/abigen.rs
index 41706d01..0dacb25b 100644
--- a/ethers-contract/tests/it/abigen.rs
+++ b/ethers-contract/tests/it/abigen.rs
@@ -750,3 +750,21 @@ fn can_handle_overloaded_function_with_array() {
     ]"#,
     );
 }
+
+#[test]
+fn convert_uses_correct_abi() {
+    abigen!(
+        Foo, r#"[function foo()]"#;
+        Bar, r#"[function bar()]"#;
+    );
+
+    let provider = Arc::new(Provider::new(MockProvider::new()));
+    let foo = Foo::new(Address::default(), Arc::clone(&provider));
+
+    let contract: &ethers_contract::Contract<_> = &foo;
+    let bar: Bar<Provider<MockProvider>> = contract.clone().into();
+
+    // Ensure that `bar` is using the `Bar` ABI internally (this method lookup will panic if `bar`
+    // is incorrectly using the `Foo` ABI internally).
+    bar.bar().call();
+}