Repository: gakonst/ethers-rs
Pull request #1511 (2022-07-26 03:11:16)

chore(deps): bump web-sys from 0.3.58 to 0.3.59
Bumps [web-sys](https://github.com/rustwasm/wasm-bindgen) from 0.3.58 to 0.3.59.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a href="https://github.com/rustwasm/wasm-bindgen/commits">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=web-sys&package-manager=cargo&previous-version=0.3.58&new-version=0.3.59)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 47862703..fefd4112 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
 
 ### Unreleased
 
+- Added `get_erc1155_token_transfer_events` function for etherscan client [#1503](https://github.com/gakonst/ethers-rs/pull/1503)
 - Add support for Geth `debug_traceTransaction` [#1469](https://github.com/gakonst/ethers-rs/pull/1469)
 - Use correct, new transaction type for `typool_content` RPC endpoint [#1501](https://github.com/gakonst/ethers-rs/pull/1501)
 - Fix the default config for generated `BuildInfo` [#1458](https://github.com/gakonst/ethers-rs/pull/1458)
@@ -96,6 +97,8 @@
   [#1498](https://github.com/gakonst/ethers-rs/pull/1498). Note: this changes
   generated module names to snake case. For example, `MyContract` is now
   `my_contract` rather than `mycontract_mod`.
+- The `Cargo.toml` generated by bindings now includes the `abigen` feature on
+  ethers. [#1508](https://github.com/gakonst/ethers-rs/pull/1508)
 
 ### 0.6.0
 
diff --git a/Cargo.lock b/Cargo.lock
index 6e8cff3f..02e12ac6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2109,9 +2109,9 @@ dependencies = [
 
 [[package]]
 name = "js-sys"
-version = "0.3.58"
+version = "0.3.59"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27"
+checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2"
 dependencies = [
  "wasm-bindgen",
 ]
@@ -4078,9 +4078,9 @@ dependencies = [
 
 [[package]]
 name = "tracing-subscriber"
-version = "0.3.14"
+version = "0.3.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a713421342a5a666b7577783721d3117f1b69a393df803ee17bb73b1e122a59"
+checksum = "60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b"
 dependencies = [
  "ansi_term",
  "matchers",
@@ -4290,9 +4290,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.81"
+version = "0.2.82"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994"
+checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d"
 dependencies = [
  "cfg-if 1.0.0",
  "serde",
@@ -4302,13 +4302,13 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.81"
+version = "0.2.82"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a"
+checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f"
 dependencies = [
  "bumpalo",
- "lazy_static",
  "log",
+ "once_cell",
  "proc-macro2",
  "quote",
  "syn",
@@ -4329,9 +4329,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.81"
+version = "0.2.82"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa"
+checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -4339,9 +4339,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.81"
+version = "0.2.82"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048"
+checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -4352,9 +4352,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.81"
+version = "0.2.82"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be"
+checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a"
 
 [[package]]
 name = "wasm-bindgen-test"
@@ -4397,9 +4397,9 @@ dependencies = [
 
 [[package]]
 name = "web-sys"
-version = "0.3.58"
+version = "0.3.59"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90"
+checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1"
 dependencies = [
  "js-sys",
  "wasm-bindgen",
diff --git a/ethers-contract/ethers-contract-abigen/src/multi.rs b/ethers-contract/ethers-contract-abigen/src/multi.rs
index 0023f583..6266abcc 100644
--- a/ethers-contract/ethers-contract-abigen/src/multi.rs
+++ b/ethers-contract/ethers-contract-abigen/src/multi.rs
@@ -530,8 +530,7 @@ impl MultiBindingsInner {
         writeln!(
             toml,
             r#"
-ethers = {{ git = "https://github.com/gakonst/ethers-rs", default-features = false }}
-serde_json = "1.0.79"
+ethers = {{ git = "https://github.com/gakonst/ethers-rs", default-features = false, features = ["abigen"] }}
 "#
         )?;
         Ok(toml)
diff --git a/ethers-core/src/abi/codec.rs b/ethers-core/src/abi/codec.rs
index 6a888aa0..a953eef0 100644
--- a/ethers-core/src/abi/codec.rs
+++ b/ethers-core/src/abi/codec.rs
@@ -167,7 +167,11 @@ impl_abi_codec_tuple!(12, A, B, C, D, E, F, G, H, I, J, K, L);
 impl_abi_codec_tuple!(13, A, B, C, D, E, F, G, H, I, J, K, L, M);
 impl_abi_codec_tuple!(14, A, B, C, D, E, F, G, H, I, J, K, L, M, N);
 impl_abi_codec_tuple!(15, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
-impl_abi_codec_tuple!(16, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
+impl_abi_codec_tuple!(16, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q);
+impl_abi_codec_tuple!(17, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R);
+impl_abi_codec_tuple!(18, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S);
+impl_abi_codec_tuple!(19, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T);
+impl_abi_codec_tuple!(20, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U);
 
 #[cfg(test)]
 mod tests {
diff --git a/ethers-core/src/abi/mod.rs b/ethers-core/src/abi/mod.rs
index 4a332e6d..88c57f88 100644
--- a/ethers-core/src/abi/mod.rs
+++ b/ethers-core/src/abi/mod.rs
@@ -188,6 +188,11 @@ impl_abi_type_tuple!(13, A, B, C, D, E, F, G, H, I, J, K, L, M);
 impl_abi_type_tuple!(14, A, B, C, D, E, F, G, H, I, J, K, L, M, N);
 impl_abi_type_tuple!(15, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
 impl_abi_type_tuple!(16, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
+impl_abi_type_tuple!(17, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q);
+impl_abi_type_tuple!(18, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R);
+impl_abi_type_tuple!(19, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S);
+impl_abi_type_tuple!(20, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T);
+impl_abi_type_tuple!(21, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U);
 
 #[cfg(test)]
 mod tests {
diff --git a/ethers-core/src/abi/tokens.rs b/ethers-core/src/abi/tokens.rs
index e0684bb0..8839d14d 100644
--- a/ethers-core/src/abi/tokens.rs
+++ b/ethers-core/src/abi/tokens.rs
@@ -123,6 +123,11 @@ impl_tuples!(13, A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M
 impl_tuples!(14, A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, );
 impl_tuples!(15, A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, );
 impl_tuples!(16, A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, );
+impl_tuples!(17, A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16,);
+impl_tuples!(18, A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16, R:17,);
+impl_tuples!(19, A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16, R:17, S:18,);
+impl_tuples!(20, A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16, R:17, S:18, T:19,);
+impl_tuples!(21, A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16, R:17, S:18, T:19, U:20,);
 
 impl Tokenizable for Token {
     fn from_token(token: Token) -> Result<Self, InvalidOutputType> {
@@ -329,6 +334,11 @@ impl_tokenizable_item_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M,);
 impl_tokenizable_item_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N,);
 impl_tokenizable_item_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O,);
 impl_tokenizable_item_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P,);
+impl_tokenizable_item_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q,);
+impl_tokenizable_item_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R,);
+impl_tokenizable_item_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S,);
+impl_tokenizable_item_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T,);
+impl_tokenizable_item_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U,);
 
 impl Tokenizable for Vec<u8> {
     fn from_token(token: Token) -> Result<Self, InvalidOutputType> {
diff --git a/ethers-etherscan/src/account.rs b/ethers-etherscan/src/account.rs
index cc310bd8..7f01c578 100644
--- a/ethers-etherscan/src/account.rs
+++ b/ethers-etherscan/src/account.rs
@@ -203,6 +203,33 @@ pub struct ERC721TokenTransferEvent {
     pub confirmations: U64,
 }
 
+/// The raw response from the ERC1155 transfer list API endpoint
+#[derive(Debug, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct ERC1155TokenTransferEvent {
+    pub block_number: BlockNumber,
+    pub time_stamp: String,
+    pub hash: H256,
+    pub nonce: U256,
+    pub block_hash: H256,
+    pub from: Address,
+    pub contract_address: Address,
+    pub to: Option<Address>,
+    #[serde(rename = "tokenID")]
+    pub token_id: String,
+    pub token_value: String,
+    pub token_name: String,
+    pub token_symbol: String,
+    pub transaction_index: U64,
+    pub gas: U256,
+    pub gas_price: Option<U256>,
+    pub gas_used: U256,
+    pub cumulative_gas_used: U256,
+    /// deprecated
+    pub input: String,
+    pub confirmations: U64,
+}
+
 /// The raw response from the mined blocks API endpoint
 #[derive(Debug, Serialize, Deserialize)]
 #[serde(rename_all = "camelCase")]
@@ -532,6 +559,36 @@ impl Client {
         Ok(response.result)
     }
 
+    /// Returns the list of ERC-1155 ( NFT ) tokens transferred by an address, with optional
+    /// filtering by token contract.
+    ///
+    /// ```no_run
+    /// # use ethers_etherscan::{Client, account::TokenQueryOption};
+    /// # use ethers_core::types::Chain;
+    ///
+    /// # #[tokio::main]
+    /// # async fn main() {
+    ///     let client = Client::new(Chain::Mainnet, "API_KEY").unwrap();
+    ///     let txs = client
+    ///         .get_erc1155_token_transfer_events(
+    ///             TokenQueryOption::ByAddressAndContract(
+    ///                 "0x216CD350a4044e7016f14936663e2880Dd2A39d7".parse().unwrap(),
+    ///                 "0x495f947276749ce646f68ac8c248420045cb7b5e".parse().unwrap(),
+    ///          ), None).await.unwrap();
+    /// # }
+    /// ```
+    pub async fn get_erc1155_token_transfer_events(
+        &self,
+        event_query_option: TokenQueryOption,
+        params: Option<TxListParams>,
+    ) -> Result<Vec<ERC1155TokenTransferEvent>> {
+        let params = event_query_option.into_params(params.unwrap_or_default());
+        let query = self.create_query("account", "token1155tx", params);
+        let response: Response<Vec<ERC1155TokenTransferEvent>> = self.get_json(&query).await?;
+
+        Ok(response.result)
+    }
+
     /// Returns the list of blocks mined by an address.
     ///
     /// ```no_run
@@ -708,6 +765,26 @@ mod tests {
         .await
     }
 
+    #[tokio::test]
+    #[serial]
+    async fn get_erc1155_transfer_events_success() {
+        run_at_least_duration(Duration::from_millis(250), async {
+            let client = Client::new_from_env(Chain::Mainnet).unwrap();
+
+            let txs = client
+                .get_erc1155_token_transfer_events(
+                    TokenQueryOption::ByAddressAndContract(
+                        "0x216CD350a4044e7016f14936663e2880Dd2A39d7".parse().unwrap(),
+                        "0x495f947276749ce646f68ac8c248420045cb7b5e".parse().unwrap(),
+                    ),
+                    None,
+                )
+                .await;
+            assert!(txs.is_ok());
+        })
+        .await
+    }
+
     #[tokio::test]
     #[serial]
     async fn get_mined_blocks_success() {
diff --git a/ethers-signers/Cargo.toml b/ethers-signers/Cargo.toml
index 311a08d6..8e16e718 100644
--- a/ethers-signers/Cargo.toml
+++ b/ethers-signers/Cargo.toml
@@ -44,7 +44,7 @@ home = { version = "0.5.3", optional = true }
 ethers-contract = { version = "^0.13.0", path = "../ethers-contract", features = ["eip712", "abigen"]}
 ethers-derive-eip712 = { version = "^0.13.0", path = "../ethers-core/ethers-derive-eip712" }
 serde_json = { version = "1.0.64" }
-tracing-subscriber = "0.3.14"
+tracing-subscriber = "0.3.15"
 yubihsm = { version = "0.41.0-pre", features = ["secp256k1", "usb", "mockhsm"] }
 
 [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
diff --git a/ethers-solc/src/artifacts/mod.rs b/ethers-solc/src/artifacts/mod.rs
index d9005879..147bcbba 100644
--- a/ethers-solc/src/artifacts/mod.rs
+++ b/ethers-solc/src/artifacts/mod.rs
@@ -1619,6 +1619,7 @@ pub struct Ewasm {
     pub wasm: String,
 }
 
+/// Represents the `storage-layout` section of the `CompilerOutput` if selected.
 #[derive(Clone, Debug, Default, Serialize, Deserialize, Eq, PartialEq)]
 pub struct StorageLayout {
     pub storage: Vec<Storage>,
@@ -1647,9 +1648,16 @@ pub struct Storage {
 #[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
 pub struct StorageType {
     pub encoding: String,
+    #[serde(default, skip_serializing_if = "Option::is_none")]
+    pub key: Option<String>,
     pub label: String,
     #[serde(rename = "numberOfBytes")]
     pub number_of_bytes: String,
+    #[serde(default, skip_serializing_if = "Option::is_none")]
+    pub value: Option<String>,
+    /// additional fields
+    #[serde(flatten)]
+    pub other: BTreeMap<String, serde_json::Value>,
 }
 
 #[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Hash)]
@@ -2120,4 +2128,11 @@ mod tests {
         let value = serde_json::to_string(&c).unwrap();
         pretty_assertions::assert_eq!(s, value);
     }
+
+    #[test]
+    fn test_lossless_storage_layout() {
+        let input = include_str!("../../test-data/foundryissue2462.json");
+        let layout: StorageLayout = serde_json::from_str(input).unwrap();
+        pretty_assertions::assert_eq!(input, &serde_json::to_string_pretty(&layout).unwrap());
+    }
 }
diff --git a/examples/ethers-wasm/Cargo.toml b/examples/ethers-wasm/Cargo.toml
index 54759976..cbd258bc 100644
--- a/examples/ethers-wasm/Cargo.toml
+++ b/examples/ethers-wasm/Cargo.toml
@@ -40,7 +40,7 @@ wee_alloc = { version = "0.4.5", optional = true }
 
 serde = { version = "1.0.126", features = ["derive"] }
 hex = "0.4.3"
-web-sys = "0.3.58"
+web-sys = "0.3.59"
 
 [dev-dependencies]
 wasm-bindgen-test = "0.3.31"
diff --git a/examples/geth_trace_transaction.rs b/examples/geth_trace_transaction.rs
index e76266e3..dac3c62f 100644
--- a/examples/geth_trace_transaction.rs
+++ b/examples/geth_trace_transaction.rs
@@ -1,16 +1,19 @@
 use ethers::prelude::*;
 use eyre::Result;
-use std::{env, str::FromStr};
+use std::str::FromStr;
 
+/// use `debug_traceTransaction` to fetch traces
+/// requires, a valid endpoint in `RPC_URL` env var that supports `debug_traceTransaction`
 #[tokio::main]
 async fn main() -> Result<()> {
-    let rpc_url: String = env::var("RPC_URL")?;
-    let client = Provider::<Http>::try_from(rpc_url)?;
-    let tx_hash = "0x97a02abf405d36939e5b232a5d4ef5206980c5a6661845436058f30600c52df7";
-    let h: H256 = H256::from_str(tx_hash)?;
-    let options: GethDebugTracingOptions = GethDebugTracingOptions::default();
-    let traces = client.debug_trace_transaction(h, options).await?;
-    println!("{:?}", traces);
+    if let Ok(url) = std::env::var("RPC_URL") {
+        let client = Provider::<Http>::try_from(url)?;
+        let tx_hash = "0x97a02abf405d36939e5b232a5d4ef5206980c5a6661845436058f30600c52df7";
+        let h: H256 = H256::from_str(tx_hash)?;
+        let options: GethDebugTracingOptions = GethDebugTracingOptions::default();
+        let traces = client.debug_trace_transaction(h, options).await?;
+        println!("{:?}", traces);
+    }
 
     Ok(())
 }


Test patch:
diff --git a/ethers-contract/tests/it/abigen.rs b/ethers-contract/tests/it/abigen.rs
index 8256dc3a..fd661ad0 100644
--- a/ethers-contract/tests/it/abigen.rs
+++ b/ethers-contract/tests/it/abigen.rs
@@ -654,3 +654,8 @@ fn can_generate_to_string_overload() {
         ToStringCalls::ToString5(_) => {}
     };
 }
+
+#[test]
+fn can_generate_large_event() {
+    abigen!(NewSale, "ethers-contract/tests/solidity-contracts/sale.json");
+}
diff --git a/ethers-contract/tests/solidity-contracts/sale.json b/ethers-contract/tests/solidity-contracts/sale.json
new file mode 100644
index 00000000..d1192e30
--- /dev/null
+++ b/ethers-contract/tests/solidity-contracts/sale.json
@@ -0,0 +1,81 @@
+[
+  {
+    "anonymous": false,
+    "inputs": [
+      {
+        "indexed": false,
+        "internalType": "uint256",
+        "name": "marketplaceId",
+        "type": "uint256"
+      },
+      {
+        "indexed": false,
+        "internalType": "address[]",
+        "name": "nfts",
+        "type": "address[]"
+      },
+      {
+        "indexed": false,
+        "internalType": "uint256[]",
+        "name": "tokenIds",
+        "type": "uint256[]"
+      },
+      {
+        "indexed": false,
+        "internalType": "uint256[]",
+        "name": "amountBatches",
+        "type": "uint256[]"
+      },
+      {
+        "indexed": false,
+        "internalType": "uint128",
+        "name": "price",
+        "type": "uint128"
+      },
+      {
+        "indexed": false,
+        "internalType": "uint256",
+        "name": "duration",
+        "type": "uint256"
+      },
+      {
+        "indexed": false,
+        "internalType": "bool",
+        "name": "isAuction",
+        "type": "bool"
+      },
+      {
+        "indexed": false,
+        "internalType": "uint256",
+        "name": "amount",
+        "type": "uint256"
+      },
+      {
+        "indexed": false,
+        "internalType": "bool",
+        "name": "isNSFW",
+        "type": "bool"
+      },
+      {
+        "indexed": false,
+        "internalType": "string",
+        "name": "marketplaceURI",
+        "type": "string"
+      },
+      {
+        "indexed": false,
+        "internalType": "string",
+        "name": "searchKeywords",
+        "type": "string"
+      },
+      {
+        "indexed": false,
+        "internalType": "address[]",
+        "name": "addresses",
+        "type": "address[]"
+      }
+    ],
+    "name": "NewSale",
+    "type": "event"
+  }
+]
\ No newline at end of file
diff --git a/ethers-solc/test-data/foundryissue2462.json b/ethers-solc/test-data/foundryissue2462.json
new file mode 100644
index 00000000..ea9764ae
--- /dev/null
+++ b/ethers-solc/test-data/foundryissue2462.json
@@ -0,0 +1,54 @@
+{
+  "storage": [
+    {
+      "astId": 3,
+      "contract": "test-data/foundryissue2462.sol:Token",
+      "label": "x",
+      "offset": 0,
+      "slot": "0",
+      "type": "t_uint256"
+    },
+    {
+      "astId": 7,
+      "contract": "test-data/foundryissue2462.sol:Token",
+      "label": "balances",
+      "offset": 0,
+      "slot": "1",
+      "type": "t_mapping(t_address,t_uint256)"
+    },
+    {
+      "astId": 13,
+      "contract": "test-data/foundryissue2462.sol:Token",
+      "label": "allowances",
+      "offset": 0,
+      "slot": "2",
+      "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))"
+    }
+  ],
+  "types": {
+    "t_address": {
+      "encoding": "inplace",
+      "label": "address",
+      "numberOfBytes": "20"
+    },
+    "t_mapping(t_address,t_mapping(t_address,t_uint256))": {
+      "encoding": "mapping",
+      "key": "t_address",
+      "label": "mapping(address => mapping(address => uint256))",
+      "numberOfBytes": "32",
+      "value": "t_mapping(t_address,t_uint256)"
+    },
+    "t_mapping(t_address,t_uint256)": {
+      "encoding": "mapping",
+      "key": "t_address",
+      "label": "mapping(address => uint256)",
+      "numberOfBytes": "32",
+      "value": "t_uint256"
+    },
+    "t_uint256": {
+      "encoding": "inplace",
+      "label": "uint256",
+      "numberOfBytes": "32"
+    }
+  }
+}
\ No newline at end of file