From 70827aecd395bbe54d093cdb3e9c957e79a9201e Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Mon, 19 May 2025 15:16:50 +0200
Subject: [PATCH 01/21] wip: eip712 cheacode
---
crates/cheatcodes/assets/cheatcodes.json | 20 +++++++++
crates/cheatcodes/spec/src/vm.rs | 4 ++
crates/cheatcodes/src/utils.rs | 54 +++++++++++++++++++++-
crates/forge/tests/cli/eip712.rs | 57 +++++++++++++++++-------
testdata/cheats/Vm.sol | 1 +
5 files changed, 120 insertions(+), 16 deletions(-)
diff --git a/crates/cheatcodes/assets/cheatcodes.json b/crates/cheatcodes/assets/cheatcodes.json
index eb541e269a888..4d5d35ab05953 100644
--- a/crates/cheatcodes/assets/cheatcodes.json
+++ b/crates/cheatcodes/assets/cheatcodes.json
@@ -4294,6 +4294,26 @@
"status": "stable",
"safety": "unsafe"
},
+ {
+ "func": {
+ "id": "eip712HashType",
+ "description": "Randomly shuffles an array.",
+ "declaration": "function eip712HashType(string memory typeDefinition) external pure returns (bytes32 typeHash);",
+ "visibility": "external",
+ "mutability": "pure",
+ "signature": "eip712HashType(string)",
+ "selector": "0x6792e9e2",
+ "selectorBytes": [
+ 103,
+ 146,
+ 233,
+ 226
+ ]
+ },
+ "group": "utilities",
+ "status": "stable",
+ "safety": "safe"
+ },
{
"func": {
"id": "ensNamehash",
diff --git a/crates/cheatcodes/spec/src/vm.rs b/crates/cheatcodes/spec/src/vm.rs
index a75217eaa4742..3e1aa2dba1b26 100644
--- a/crates/cheatcodes/spec/src/vm.rs
+++ b/crates/cheatcodes/spec/src/vm.rs
@@ -2889,6 +2889,10 @@ interface Vm {
/// catch (bytes memory interceptedInitcode) { initcode = interceptedInitcode; }
#[cheatcode(group = Utilities, safety = Unsafe)]
function interceptInitcode() external;
+
+ /// Randomly shuffles an array.
+ #[cheatcode(group = Utilities)]
+ function eip712HashType(string memory typeDefinition) external pure returns (bytes32 typeHash);
}
}
diff --git a/crates/cheatcodes/src/utils.rs b/crates/cheatcodes/src/utils.rs
index 4735ffaa41087..229d85629d0f1 100644
--- a/crates/cheatcodes/src/utils.rs
+++ b/crates/cheatcodes/src/utils.rs
@@ -4,7 +4,8 @@ use crate::{Cheatcode, Cheatcodes, CheatcodesExecutor, CheatsCtxt, Result, Vm::*
use alloy_dyn_abi::{DynSolType, DynSolValue};
use alloy_primitives::{aliases::B32, map::HashMap, B64, U256};
use alloy_sol_types::SolValue;
-use foundry_common::ens::namehash;
+use foundry_common::{ens::namehash, fs};
+use foundry_config::fs_permissions::FsAccessKind;
use foundry_evm_core::constants::DEFAULT_CREATE2_DEPLOYER;
use proptest::prelude::Strategy;
use rand::{seq::SliceRandom, Rng, RngCore};
@@ -313,3 +314,54 @@ fn random_int(state: &mut Cheatcodes, bits: Option) -> Result {
.current()
.abi_encode())
}
+
+// `string contant schema_Foo = "Foo(bar uin256)";`
+const TYPE_BINDING_PREFIX: &str = "string constant schema_";
+
+impl Cheatcode for eip712HashTypeCall {
+ fn apply(&self, state: &mut Cheatcodes) -> Result {
+ let Self { typeDefinition } = self;
+
+ let type_def = if typeDefinition.contains('(') {
+ &get_type_def_from_bindings(typeDefinition, state)?
+ } else {
+ typeDefinition
+ };
+
+ todo!()
+ }
+}
+
+fn get_type_def_from_bindings(name: &String, state: &mut Cheatcodes) -> Result {
+ let path = state.config.ensure_path_allowed(
+ &state.config.root.join("utils").join("JsonBindings.sol"),
+ FsAccessKind::Read,
+ )?;
+
+ let content = fs::read_to_string(path)?;
+
+ let mut type_defs = HashMap::new();
+ for line in content.lines() {
+ let line = line.trim();
+ if !line.starts_with(TYPE_BINDING_PREFIX) {
+ continue;
+ }
+
+ let relevant = &line[TYPE_BINDING_PREFIX.len()..];
+ if let Some(idx) = relevant.find('=') {
+ let name = relevant[..idx].trim();
+
+ // relevant value chars are " \"Foo(bar uint256)\";"
+ let def = relevant[idx + 1..].trim();
+ if def.len() > 3 && def.starts_with('"') && def.ends_with("\";") {
+ let value = &def[1..def.len() - 2];
+ type_defs.insert(name, value);
+ }
+ }
+ }
+
+ match type_defs.get(name.as_str()) {
+ Some(value) => Ok(value.to_string()),
+ None => bail!(format!("'{name}' not found in 'utils/JsonBindings.sol'\n{:#?}", type_defs)),
+ }
+}
diff --git a/crates/forge/tests/cli/eip712.rs b/crates/forge/tests/cli/eip712.rs
index 62aa63079eb4e..8708c034caf96 100644
--- a/crates/forge/tests/cli/eip712.rs
+++ b/crates/forge/tests/cli/eip712.rs
@@ -1,27 +1,21 @@
-forgetest!(test_eip712, |prj, cmd| {
- let path = prj
- .add_source(
- "Structs",
- r#"
+use foundry_config::fs_permissions::PathPermission;
+
+const STRUCTS: &str = r#"
library Structs {
struct Foo {
Bar bar;
}
-
struct Bar {
Art art;
}
-
struct Art {
uint256 id;
}
-
struct Complex {
Structs2.Foo foo2;
Foo[] foos;
Rec[][] recs;
}
-
struct Rec {
Rec[] rec;
}
@@ -31,15 +25,12 @@ library Structs2 {
struct Foo {
uint256 id;
}
-
struct Rec {
Bar[] bar;
}
-
struct Bar {
Rec rec;
}
-
struct FooBar {
Foo[] foos;
Bar[] bars;
@@ -49,9 +40,10 @@ library Structs2 {
Structs.Rec rec;
}
}
-"#,
- )
- .unwrap();
+"#;
+
+forgetest!(test_eip712, |prj, cmd| {
+ let path = prj.add_source("Structs", STRUCTS).unwrap();
cmd.forge_fuse().args(["eip712", path.to_string_lossy().as_ref()]).assert_success().stdout_eq(
str![[r#"
@@ -77,3 +69,38 @@ FooBar(Foo[] foos,Bar[] bars,Foo_1 foo,Bar_1 bar,Rec[] recs,Rec_1 rec)Art(uint25
"#]],
);
});
+
+forgetest!(test_eip712_cheacode, |prj, cmd| {
+ prj.add_source("Structs", STRUCTS).unwrap();
+ prj.insert_ds_test();
+ prj.insert_vm();
+
+ prj.add_source(
+ "Eip712Cheat.sol",
+ r#"
+// Note Used in forge-cli tests to assert failures.
+// SPDX-License-Identifier: MIT OR Apache-2.0
+pragma solidity ^0.8.18;
+
+import "./test.sol";
+import "./Vm.sol";
+
+contract Eip712Test is DSTest {
+ Vm constant vm = Vm(HEVM_ADDRESS);
+
+ function testReadUtils() public pure {
+ vm.eip712HashType("Foo_0");
+ }
+}
+"#,
+ )
+ .unwrap();
+
+ cmd.forge_fuse().args(["bind-json"]).assert_success();
+
+ let bindings = prj.root().join("utils").join("JsonBindings.sol");
+ assert!(bindings.exists(), "JsonBindings.sol was not generated at {:?}", bindings);
+
+ prj.update_config(|config| config.fs_permissions.add(PathPermission::read(bindings)));
+ cmd.forge_fuse().args(["test", "--mc", "Eip712Test", "-vvvv"]).assert_success();
+});
diff --git a/testdata/cheats/Vm.sol b/testdata/cheats/Vm.sol
index 6d054abbfc6ec..538ff290733f8 100644
--- a/testdata/cheats/Vm.sol
+++ b/testdata/cheats/Vm.sol
@@ -208,6 +208,7 @@ interface Vm {
function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index, string calldata language) external pure returns (uint256 privateKey);
function difficulty(uint256 newDifficulty) external;
function dumpState(string calldata pathToStateJson) external;
+ function eip712HashType(string memory typeDefinition) external pure returns (bytes32 typeHash);
function ensNamehash(string calldata name) external pure returns (bytes32);
function envAddress(string calldata name) external view returns (address value);
function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value);
From ef3c1b968b3cb5740d9f1d7fa3c517cd779b5a94 Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Tue, 20 May 2025 08:44:39 -0500
Subject: [PATCH 02/21] wip: integrate json-bind
---
crates/cheatcodes/src/utils.rs | 12 +++--
crates/forge/tests/cli/eip712.rs | 85 +++++++++++++++++++-------------
2 files changed, 59 insertions(+), 38 deletions(-)
diff --git a/crates/cheatcodes/src/utils.rs b/crates/cheatcodes/src/utils.rs
index 229d85629d0f1..fc11095f2e6db 100644
--- a/crates/cheatcodes/src/utils.rs
+++ b/crates/cheatcodes/src/utils.rs
@@ -1,8 +1,8 @@
//! Implementations of [`Utilities`](spec::Group::Utilities) cheatcodes.
use crate::{Cheatcode, Cheatcodes, CheatcodesExecutor, CheatsCtxt, Result, Vm::*};
-use alloy_dyn_abi::{DynSolType, DynSolValue};
-use alloy_primitives::{aliases::B32, map::HashMap, B64, U256};
+use alloy_dyn_abi::{eip712_parser::EncodeType, DynSolType, DynSolValue, Resolver};
+use alloy_primitives::{aliases::B32, keccak256, map::HashMap, B64, U256};
use alloy_sol_types::SolValue;
use foundry_common::{ens::namehash, fs};
use foundry_config::fs_permissions::FsAccessKind;
@@ -322,13 +322,17 @@ impl Cheatcode for eip712HashTypeCall {
fn apply(&self, state: &mut Cheatcodes) -> Result {
let Self { typeDefinition } = self;
- let type_def = if typeDefinition.contains('(') {
+ let type_def = if !typeDefinition.contains('(') {
&get_type_def_from_bindings(typeDefinition, state)?
} else {
typeDefinition
+ // let canonical = EncodeType::parse(typeDefinition).and_then(|parsed|
+ // parsed.canonicalize())?;
};
- todo!()
+ // let hash = keccak256(type_def.as_bytes());
+ // bail!("type: {type_def}, hash: {hash}");
+ Ok(keccak256(type_def.as_bytes()).to_vec())
}
}
diff --git a/crates/forge/tests/cli/eip712.rs b/crates/forge/tests/cli/eip712.rs
index 8708c034caf96..f7bea4ffbca8b 100644
--- a/crates/forge/tests/cli/eip712.rs
+++ b/crates/forge/tests/cli/eip712.rs
@@ -1,36 +1,26 @@
use foundry_config::fs_permissions::PathPermission;
-const STRUCTS: &str = r#"
+forgetest!(test_eip712, |prj, cmd| {
+ let path = prj
+ .add_source(
+ "Structs",
+ r#"
library Structs {
- struct Foo {
- Bar bar;
- }
- struct Bar {
- Art art;
- }
- struct Art {
- uint256 id;
- }
+ struct Foo { Bar bar; }
+ struct Bar { Art art; }
+ struct Art { uint256 id; }
struct Complex {
Structs2.Foo foo2;
Foo[] foos;
Rec[][] recs;
}
- struct Rec {
- Rec[] rec;
- }
+ struct Rec { Rec[] rec; }
}
library Structs2 {
- struct Foo {
- uint256 id;
- }
- struct Rec {
- Bar[] bar;
- }
- struct Bar {
- Rec rec;
- }
+ struct Foo { uint256 id; }
+ struct Rec { Bar[] bar; }
+ struct Bar { Rec rec; }
struct FooBar {
Foo[] foos;
Bar[] bars;
@@ -40,10 +30,9 @@ library Structs2 {
Structs.Rec rec;
}
}
-"#;
-
-forgetest!(test_eip712, |prj, cmd| {
- let path = prj.add_source("Structs", STRUCTS).unwrap();
+ "#,
+ )
+ .unwrap();
cmd.forge_fuse().args(["eip712", path.to_string_lossy().as_ref()]).assert_success().stdout_eq(
str![[r#"
@@ -65,31 +54,59 @@ Bar(Rec rec)Rec(Bar[] bar)
FooBar(Foo[] foos,Bar[] bars,Foo_1 foo,Bar_1 bar,Rec[] recs,Rec_1 rec)Art(uint256 id)Bar(Rec rec)Bar_1(Art art)Foo(uint256 id)Foo_1(Bar_1 bar)Rec(Bar[] bar)Rec_1(Rec_1[] rec)
-
"#]],
);
});
-forgetest!(test_eip712_cheacode, |prj, cmd| {
- prj.add_source("Structs", STRUCTS).unwrap();
+forgetest!(test_eip712_cheatcode, |prj, cmd| {
+ prj.add_source(
+ "Eip712",
+ r#"
+contract Eip712 {
+ struct Transaction {
+ Person from;
+ Person to;
+ Asset tx;
+ }
+ struct Person {
+ address wallet;
+ string name;
+ }
+ struct Asset {
+ address token;
+ uint256 amount;
+ }
+}
+ "#,
+ )
+ .unwrap();
prj.insert_ds_test();
prj.insert_vm();
+ prj.insert_console();
- prj.add_source(
- "Eip712Cheat.sol",
- r#"
+ prj.add_source("Eip712Cheat.sol", r#"
// Note Used in forge-cli tests to assert failures.
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.18;
import "./test.sol";
import "./Vm.sol";
+import "./console.sol";
+
+string constant CANONICAL = "Transaction(Person from,Person to,Asset tx)Asset(address token,uint256 amount)Person(address wallet,string name)";
+string constant MESSY = "Person(address wallet, string name) Asset(address token, uint256 amount) Transaction(Person from, Person to, Asset tx)";
contract Eip712Test is DSTest {
Vm constant vm = Vm(HEVM_ADDRESS);
- function testReadUtils() public pure {
- vm.eip712HashType("Foo_0");
+ function testEip712HashType() public {
+ bytes32 hashCanonical = keccak256(bytes(CANONICAL));
+
+ bytes32 hashTypeName = vm.eip712HashType("Transaction");
+ assertEq(hashTypeName, hashCanonical);
+
+ bytes32 hashTypeDef = vm.eip712HashType(MESSY);
+ assertEq(hashTypeDef, hashCanonical);
}
}
"#,
From d1e1512d6696e1f324660c4e02a6793129e350b2 Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Tue, 20 May 2025 10:01:02 -0500
Subject: [PATCH 03/21] finish cheatcode impl + unit tests
---
Cargo.lock | 352 ++++++++++++++---------------
Cargo.toml | 2 +-
crates/cheatcodes/src/utils.rs | 68 +++---
crates/forge/tests/cli/eip712.rs | 66 ------
crates/forge/tests/cli/test_cmd.rs | 73 ++++++
5 files changed, 280 insertions(+), 281 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 4772a785080e2..c056d8e2a05fc 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -62,7 +62,7 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5848366a4f08dca1caca0a6151294a4799fe2e59ba25df100491d92e0b921b1c"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"num_enum",
"serde",
"strum 0.27.1",
@@ -75,7 +75,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "681eabb77176be186f3786795a94e6d2465bef9e117b6700ec0e62d39811cc54"
dependencies = [
"alloy-eips 1.0.4",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rlp",
"alloy-serde 1.0.4",
"alloy-trie",
@@ -100,7 +100,7 @@ checksum = "aec7fdaa4f0e4e1ca7e9271ca7887fdd467ca3b9e101582dc6c2bbd1645eae1c"
dependencies = [
"alloy-consensus",
"alloy-eips 1.0.4",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rlp",
"alloy-serde 1.0.4",
"serde",
@@ -113,15 +113,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e85622f88139f5da7b5a960ebf4309baf7ccf2a3825fc470e419522231da2eda"
dependencies = [
"alloy-consensus",
- "alloy-dyn-abi 1.1.0",
- "alloy-json-abi 1.1.0",
+ "alloy-dyn-abi 1.1.2",
+ "alloy-json-abi 1.1.2",
"alloy-network",
"alloy-network-primitives",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-provider",
"alloy-pubsub",
"alloy-rpc-types-eth",
- "alloy-sol-types 1.1.0",
+ "alloy-sol-types 1.1.2",
"alloy-transport",
"futures",
"futures-util",
@@ -147,16 +147,15 @@ dependencies = [
[[package]]
name = "alloy-dyn-abi"
-version = "1.1.0"
+version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f90b63261b7744642f6075ed17db6de118eecbe9516ea6c6ffd444b80180b75"
+checksum = "18cc14d832bc3331ca22a1c7819de1ede99f58f61a7d123952af7dde8de124a6"
dependencies = [
- "alloy-json-abi 1.1.0",
- "alloy-primitives 1.1.0",
- "alloy-sol-type-parser 1.1.0",
- "alloy-sol-types 1.1.0",
+ "alloy-json-abi 1.1.2",
+ "alloy-primitives 1.1.2",
+ "alloy-sol-type-parser 1.1.2",
+ "alloy-sol-types 1.1.2",
"arbitrary",
- "const-hex",
"derive_arbitrary",
"derive_more 2.0.1",
"itoa",
@@ -172,7 +171,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "741bdd7499908b3aa0b159bba11e71c8cddd009a2c2eb7a06e825f1ec87900a5"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rlp",
"crc",
"serde",
@@ -185,7 +184,7 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b82752a889170df67bbb36d42ca63c531eb16274f0d7299ae2a680facba17bd"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rlp",
"serde",
]
@@ -196,7 +195,7 @@ version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d4769c6ffddca380b0070d71c8b7f30bed375543fe76bb2f74ec0acf4b7cd16"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rlp",
"k256",
"serde",
@@ -212,7 +211,7 @@ dependencies = [
"alloy-eip2124",
"alloy-eip2930",
"alloy-eip7702",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rlp",
"alloy-serde 0.14.0",
"auto_impl",
@@ -232,7 +231,7 @@ dependencies = [
"alloy-eip2124",
"alloy-eip2930",
"alloy-eip7702",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rlp",
"alloy-serde 1.0.4",
"auto_impl",
@@ -252,8 +251,8 @@ dependencies = [
"alloy-consensus",
"alloy-eips 1.0.4",
"alloy-hardforks",
- "alloy-primitives 1.1.0",
- "alloy-sol-types 1.1.0",
+ "alloy-primitives 1.1.2",
+ "alloy-sol-types 1.1.2",
"auto_impl",
"derive_more 2.0.1",
"op-alloy-consensus",
@@ -269,7 +268,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eacc2e22a26b6b5c90bc8db22ca41c4fcd11b1bb2ec6eb47f88299d04d19b1aa"
dependencies = [
"alloy-eips 1.0.4",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-serde 1.0.4",
"alloy-trie",
"serde",
@@ -283,7 +282,7 @@ checksum = "b40cc82a2283e3ce6317bc1f0134ea50d20e8c1965393045ee952fb28a65ddbd"
dependencies = [
"alloy-chains",
"alloy-eip2124",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"auto_impl",
"dyn-clone",
]
@@ -302,12 +301,12 @@ dependencies = [
[[package]]
name = "alloy-json-abi"
-version = "1.1.0"
+version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0068ae277f5ee3153a95eaea8ff10e188ed8ccde9b7f9926305415a2c0ab2442"
+checksum = "3ccaa79753d7bf15f06399ea76922afbfaf8d18bebed9e8fc452984b4a90dcc9"
dependencies = [
- "alloy-primitives 1.1.0",
- "alloy-sol-type-parser 1.1.0",
+ "alloy-primitives 1.1.2",
+ "alloy-sol-type-parser 1.1.2",
"serde",
"serde_json",
]
@@ -318,8 +317,8 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e8c28ad7af5ae99b0f1983eb601390fa2a972ddaec2b24017d3bdbd4a905bfc"
dependencies = [
- "alloy-primitives 1.1.0",
- "alloy-sol-types 1.1.0",
+ "alloy-primitives 1.1.2",
+ "alloy-sol-types 1.1.2",
"serde",
"serde_json",
"thiserror 2.0.12",
@@ -337,12 +336,12 @@ dependencies = [
"alloy-eips 1.0.4",
"alloy-json-rpc",
"alloy-network-primitives",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rpc-types-any",
"alloy-rpc-types-eth",
"alloy-serde 1.0.4",
"alloy-signer",
- "alloy-sol-types 1.1.0",
+ "alloy-sol-types 1.1.2",
"async-trait",
"auto_impl",
"derive_more 2.0.1",
@@ -360,7 +359,7 @@ checksum = "5630ce8552579d1393383b27fe4bfe7c700fb7480189a82fc054da24521947aa"
dependencies = [
"alloy-consensus",
"alloy-eips 1.0.4",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-serde 1.0.4",
"serde",
]
@@ -375,7 +374,7 @@ dependencies = [
"alloy-eips 1.0.4",
"alloy-evm",
"alloy-op-hardforks",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"auto_impl",
"op-alloy-consensus",
"op-revm",
@@ -421,9 +420,9 @@ dependencies = [
[[package]]
name = "alloy-primitives"
-version = "1.1.0"
+version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a12fe11d0b8118e551c29e1a67ccb6d01cc07ef08086df30f07487146de6fa1"
+checksum = "18c35fc4b03ace65001676358ffbbaefe2a2b27ee50fe777c345082c7c888be8"
dependencies = [
"alloy-rlp",
"arbitrary",
@@ -462,7 +461,7 @@ dependencies = [
"alloy-json-rpc",
"alloy-network",
"alloy-network-primitives",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-pubsub",
"alloy-rpc-client",
"alloy-rpc-types-debug",
@@ -470,7 +469,7 @@ dependencies = [
"alloy-rpc-types-trace",
"alloy-rpc-types-txpool",
"alloy-signer",
- "alloy-sol-types 1.1.0",
+ "alloy-sol-types 1.1.2",
"alloy-transport",
"alloy-transport-http",
"alloy-transport-ipc",
@@ -502,7 +501,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78a527d71966a2589c32a555c49ea8919f621c8d85d36bc98bd5a26a66c28163"
dependencies = [
"alloy-json-rpc",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-transport",
"bimap",
"futures",
@@ -545,7 +544,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e685b0c1a853afdaf794d634b3f0771be6dcd6539377366239e391e68e1f115"
dependencies = [
"alloy-json-rpc",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-pubsub",
"alloy-transport",
"alloy-transport-http",
@@ -572,7 +571,7 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9052f908df9ffd6e830a841e9a35cb280e27ccc87a493f5621a517c77345153"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rpc-types-anvil",
"alloy-rpc-types-engine",
"alloy-rpc-types-eth",
@@ -588,7 +587,7 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ebe3dcbc6c85678f29c205b2fcf6b110b32287bf6b72bbee37ed9011404e926"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rpc-types-eth",
"alloy-serde 1.0.4",
"serde",
@@ -611,7 +610,7 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7913c67b874db23446a4cdd020da1bbc828513bd83536ccabfca403b71cdeaf9"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"serde",
]
@@ -623,7 +622,7 @@ checksum = "63b70151dc3282ce4bbde31b80a7f0f1e53b9dec9b187f528394e8f0a0411975"
dependencies = [
"alloy-consensus",
"alloy-eips 1.0.4",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rlp",
"alloy-serde 1.0.4",
"derive_more 2.0.1",
@@ -643,10 +642,10 @@ dependencies = [
"alloy-consensus-any",
"alloy-eips 1.0.4",
"alloy-network-primitives",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rlp",
"alloy-serde 1.0.4",
- "alloy-sol-types 1.1.0",
+ "alloy-sol-types 1.1.2",
"itertools 0.14.0",
"serde",
"serde_json",
@@ -659,7 +658,7 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcf555fe777cf7d11b8ebe837aca0b0ceb74f1ed9937f938b8c9fbd1460994cf"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rpc-types-eth",
"alloy-serde 1.0.4",
"serde",
@@ -673,7 +672,7 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87c69ea401ce851b52c9b07d838173cd3c23c11a552a5e5ddde3ffd834647a46"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rpc-types-eth",
"alloy-serde 1.0.4",
"serde",
@@ -685,7 +684,7 @@ version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4dba6ff08916bc0a9cbba121ce21f67c0b554c39cf174bc7b9df6c651bd3c3b"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"serde",
"serde_json",
]
@@ -696,7 +695,7 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e22b9437fededfd5371968129381e9a00c3d2d8fff9846b1de3d1625fd307c"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"serde",
"serde_json",
]
@@ -707,9 +706,9 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c32a4ee33852817fe852c856d68f326980b3776e0d55d51ff9535b5a5945e68"
dependencies = [
- "alloy-dyn-abi 1.1.0",
- "alloy-primitives 1.1.0",
- "alloy-sol-types 1.1.0",
+ "alloy-dyn-abi 1.1.2",
+ "alloy-primitives 1.1.2",
+ "alloy-sol-types 1.1.2",
"async-trait",
"auto_impl",
"either",
@@ -726,7 +725,7 @@ checksum = "0946c9082fe664b5a60f8451a75aafb04e6d5893c99ae92446fbba45d2d5dc09"
dependencies = [
"alloy-consensus",
"alloy-network",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-signer",
"async-trait",
"aws-sdk-kms",
@@ -744,7 +743,7 @@ checksum = "be3bd4d17c3e59ac664f215369b6d2d4ee51fe2f31aae6015bf220ce2ffd03d9"
dependencies = [
"alloy-consensus",
"alloy-network",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-signer",
"async-trait",
"gcloud-sdk",
@@ -761,11 +760,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fcb32ccedb85055969c8161a3abc2e73b0af7b1f9e800ff494dfc4a663b24b"
dependencies = [
"alloy-consensus",
- "alloy-dyn-abi 1.1.0",
+ "alloy-dyn-abi 1.1.2",
"alloy-network",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-signer",
- "alloy-sol-types 1.1.0",
+ "alloy-sol-types 1.1.2",
"async-trait",
"coins-ledger",
"futures-util",
@@ -782,7 +781,7 @@ checksum = "838b02f438365a5fecca1a736968680cedf2b309fcb96dfcc5ab2560d74533da"
dependencies = [
"alloy-consensus",
"alloy-network",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-signer",
"async-trait",
"coins-bip32",
@@ -801,7 +800,7 @@ checksum = "b97e3d7211e1abcc3fd4e5e7dfe90eb6ff733efc3102386341c121a75cd179b5"
dependencies = [
"alloy-consensus",
"alloy-network",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-signer",
"async-trait",
"semver 1.0.26",
@@ -826,12 +825,12 @@ dependencies = [
[[package]]
name = "alloy-sol-macro"
-version = "1.1.0"
+version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d3ef8e0d622453d969ba3cded54cf6800efdc85cb929fe22c5bdf8335666757"
+checksum = "8612e0658964d616344f199ab251a49d48113992d81b92dab93ed855faa66383"
dependencies = [
- "alloy-sol-macro-expander 1.1.0",
- "alloy-sol-macro-input 1.1.0",
+ "alloy-sol-macro-expander 1.1.2",
+ "alloy-sol-macro-input 1.1.2",
"proc-macro-error2",
"proc-macro2",
"quote",
@@ -858,12 +857,12 @@ dependencies = [
[[package]]
name = "alloy-sol-macro-expander"
-version = "1.1.0"
+version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0e84bd0693c69a8fbe3ec0008465e029c6293494df7cb07580bf4a33eff52e1"
+checksum = "7a384edac7283bc4c010a355fb648082860c04b826bb7a814c45263c8f304c74"
dependencies = [
- "alloy-json-abi 1.1.0",
- "alloy-sol-macro-input 1.1.0",
+ "alloy-json-abi 1.1.2",
+ "alloy-sol-macro-input 1.1.2",
"const-hex",
"heck",
"indexmap 2.9.0",
@@ -871,7 +870,7 @@ dependencies = [
"proc-macro2",
"quote",
"syn 2.0.101",
- "syn-solidity 1.1.0",
+ "syn-solidity 1.1.2",
"tiny-keccak",
]
@@ -893,11 +892,11 @@ dependencies = [
[[package]]
name = "alloy-sol-macro-input"
-version = "1.1.0"
+version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3de663412dadf9b64f4f92f507f78deebcc92339d12cf15f88ded65d41c7935"
+checksum = "0dd588c2d516da7deb421b8c166dc60b7ae31bca5beea29ab6621fcfa53d6ca5"
dependencies = [
- "alloy-json-abi 1.1.0",
+ "alloy-json-abi 1.1.2",
"const-hex",
"dunce",
"heck",
@@ -906,7 +905,7 @@ dependencies = [
"quote",
"serde_json",
"syn 2.0.101",
- "syn-solidity 1.1.0",
+ "syn-solidity 1.1.2",
]
[[package]]
@@ -921,9 +920,9 @@ dependencies = [
[[package]]
name = "alloy-sol-type-parser"
-version = "1.1.0"
+version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "251273c5aa1abb590852f795c938730fa641832fc8fa77b5478ed1bf11b6097e"
+checksum = "e86ddeb70792c7ceaad23e57d52250107ebbb86733e52f4a25d8dc1abc931837"
dependencies = [
"serde",
"winnow",
@@ -944,14 +943,13 @@ dependencies = [
[[package]]
name = "alloy-sol-types"
-version = "1.1.0"
+version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5460a975434ae594fe2b91586253c1beb404353b78f0a55bf124abcd79557b15"
+checksum = "584cb97bfc5746cb9dcc4def77da11694b5d6d7339be91b7480a6a68dc129387"
dependencies = [
- "alloy-json-abi 1.1.0",
- "alloy-primitives 1.1.0",
- "alloy-sol-macro 1.1.0",
- "const-hex",
+ "alloy-json-abi 1.1.2",
+ "alloy-primitives 1.1.2",
+ "alloy-sol-macro 1.1.2",
"serde",
]
@@ -962,7 +960,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efc04c8732bae7f87bc4483fd377045a4295eccaf253860a8c6660a896e2befc"
dependencies = [
"alloy-json-rpc",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"base64 0.22.1",
"derive_more 2.0.1",
"futures",
@@ -1037,7 +1035,7 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "983d99aa81f586cef9dae38443245e585840fcf0fc58b09aee0b1f27aed1d500"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rlp",
"arrayvec",
"derive_more 2.0.1",
@@ -1165,13 +1163,13 @@ dependencies = [
"alloy-chains",
"alloy-consensus",
"alloy-contract",
- "alloy-dyn-abi 1.1.0",
+ "alloy-dyn-abi 1.1.2",
"alloy-eips 1.0.4",
"alloy-evm",
"alloy-genesis",
"alloy-network",
"alloy-op-evm",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-provider",
"alloy-pubsub",
"alloy-rlp",
@@ -1179,7 +1177,7 @@ dependencies = [
"alloy-serde 1.0.4",
"alloy-signer",
"alloy-signer-local",
- "alloy-sol-types 1.1.0",
+ "alloy-sol-types 1.1.2",
"alloy-transport",
"alloy-trie",
"anvil-core",
@@ -1227,10 +1225,10 @@ name = "anvil-core"
version = "1.2.0"
dependencies = [
"alloy-consensus",
- "alloy-dyn-abi 1.1.0",
+ "alloy-dyn-abi 1.1.2",
"alloy-eips 1.0.4",
"alloy-network",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rlp",
"alloy-rpc-types",
"alloy-serde 1.0.4",
@@ -2463,18 +2461,18 @@ dependencies = [
"alloy-chains",
"alloy-consensus",
"alloy-contract",
- "alloy-dyn-abi 1.1.0",
- "alloy-json-abi 1.1.0",
+ "alloy-dyn-abi 1.1.2",
+ "alloy-json-abi 1.1.2",
"alloy-json-rpc",
"alloy-network",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-provider",
"alloy-rlp",
"alloy-rpc-types",
"alloy-serde 1.0.4",
"alloy-signer",
"alloy-signer-local",
- "alloy-sol-types 1.1.0",
+ "alloy-sol-types 1.1.2",
"alloy-transport",
"anvil",
"aws-sdk-kms",
@@ -2558,9 +2556,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
name = "chisel"
version = "1.2.0"
dependencies = [
- "alloy-dyn-abi 1.1.0",
- "alloy-json-abi 1.1.0",
- "alloy-primitives 1.1.0",
+ "alloy-dyn-abi 1.1.2",
+ "alloy-json-abi 1.1.2",
+ "alloy-primitives 1.1.2",
"clap",
"dirs",
"eyre",
@@ -3658,7 +3656,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18"
dependencies = [
"libc",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -3864,10 +3862,10 @@ name = "forge"
version = "1.2.0"
dependencies = [
"alloy-chains",
- "alloy-dyn-abi 1.1.0",
- "alloy-json-abi 1.1.0",
+ "alloy-dyn-abi 1.1.2",
+ "alloy-json-abi 1.1.2",
"alloy-network",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-provider",
"alloy-rpc-types",
"alloy-serde 1.0.4",
@@ -3947,7 +3945,7 @@ dependencies = [
name = "forge-doc"
version = "1.2.0"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"derive_more 2.0.1",
"eyre",
"forge-fmt",
@@ -3970,7 +3968,7 @@ dependencies = [
name = "forge-fmt"
version = "1.2.0"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"ariadne",
"foundry-config",
"foundry-solang-parser",
@@ -3988,11 +3986,11 @@ version = "1.2.0"
dependencies = [
"alloy-chains",
"alloy-consensus",
- "alloy-dyn-abi 1.1.0",
+ "alloy-dyn-abi 1.1.2",
"alloy-eips 1.0.4",
- "alloy-json-abi 1.1.0",
+ "alloy-json-abi 1.1.2",
"alloy-network",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-provider",
"alloy-rpc-types",
"alloy-serde 1.0.4",
@@ -4032,7 +4030,7 @@ name = "forge-script-sequence"
version = "1.2.0"
dependencies = [
"alloy-network",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"eyre",
"foundry-common",
"foundry-compilers",
@@ -4047,8 +4045,8 @@ dependencies = [
name = "forge-sol-macro-gen"
version = "1.2.0"
dependencies = [
- "alloy-sol-macro-expander 1.1.0",
- "alloy-sol-macro-input 1.1.0",
+ "alloy-sol-macro-expander 1.1.2",
+ "alloy-sol-macro-input 1.1.2",
"eyre",
"foundry-common",
"prettyplease",
@@ -4062,9 +4060,9 @@ dependencies = [
name = "forge-verify"
version = "1.2.0"
dependencies = [
- "alloy-dyn-abi 1.1.0",
- "alloy-json-abi 1.1.0",
- "alloy-primitives 1.1.0",
+ "alloy-dyn-abi 1.1.2",
+ "alloy-json-abi 1.1.2",
+ "alloy-primitives 1.1.2",
"alloy-provider",
"alloy-rpc-types",
"async-trait",
@@ -4108,8 +4106,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6129df264d2bd245ade4ed21a92f605bfd592dca8fb8e6e1adde1b9bd4288681"
dependencies = [
"alloy-chains",
- "alloy-json-abi 1.1.0",
- "alloy-primitives 1.1.0",
+ "alloy-json-abi 1.1.2",
+ "alloy-primitives 1.1.2",
"foundry-compilers",
"reqwest",
"semver 1.0.26",
@@ -4125,18 +4123,18 @@ version = "1.2.0"
dependencies = [
"alloy-chains",
"alloy-consensus",
- "alloy-dyn-abi 1.1.0",
+ "alloy-dyn-abi 1.1.2",
"alloy-evm",
"alloy-genesis",
- "alloy-json-abi 1.1.0",
+ "alloy-json-abi 1.1.2",
"alloy-network",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-provider",
"alloy-rlp",
"alloy-rpc-types",
"alloy-signer",
"alloy-signer-local",
- "alloy-sol-types 1.1.0",
+ "alloy-sol-types 1.1.2",
"base64 0.22.1",
"dialoguer",
"ecdsa",
@@ -4173,7 +4171,7 @@ dependencies = [
name = "foundry-cheatcodes-spec"
version = "1.2.0"
dependencies = [
- "alloy-sol-types 1.1.0",
+ "alloy-sol-types 1.1.2",
"foundry-macros",
"schemars",
"serde",
@@ -4185,10 +4183,10 @@ name = "foundry-cli"
version = "1.2.0"
dependencies = [
"alloy-chains",
- "alloy-dyn-abi 1.1.0",
+ "alloy-dyn-abi 1.1.2",
"alloy-eips 1.0.4",
- "alloy-json-abi 1.1.0",
- "alloy-primitives 1.1.0",
+ "alloy-json-abi 1.1.2",
+ "alloy-primitives 1.1.2",
"alloy-provider",
"alloy-rlp",
"cfg-if",
@@ -4233,18 +4231,18 @@ version = "1.2.0"
dependencies = [
"alloy-consensus",
"alloy-contract",
- "alloy-dyn-abi 1.1.0",
+ "alloy-dyn-abi 1.1.2",
"alloy-eips 1.0.4",
- "alloy-json-abi 1.1.0",
+ "alloy-json-abi 1.1.2",
"alloy-json-rpc",
"alloy-network",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-provider",
"alloy-pubsub",
"alloy-rpc-client",
"alloy-rpc-types",
"alloy-serde 1.0.4",
- "alloy-sol-types 1.1.0",
+ "alloy-sol-types 1.1.2",
"alloy-transport",
"alloy-transport-http",
"alloy-transport-ipc",
@@ -4289,9 +4287,9 @@ name = "foundry-common-fmt"
version = "1.2.0"
dependencies = [
"alloy-consensus",
- "alloy-dyn-abi 1.1.0",
+ "alloy-dyn-abi 1.1.2",
"alloy-network",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rpc-types",
"alloy-serde 1.0.4",
"chrono",
@@ -4310,8 +4308,8 @@ version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6154e503612a175a88ff342592f0a44664dda54a508d9443121b62b1701f91"
dependencies = [
- "alloy-json-abi 1.1.0",
- "alloy-primitives 1.1.0",
+ "alloy-json-abi 1.1.2",
+ "alloy-primitives 1.1.2",
"auto_impl",
"derive_more 1.0.0",
"dirs",
@@ -4357,8 +4355,8 @@ version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a3ffc93f94d2c4ae0ff0f7a12cdeaa5fbb043ced0c558cabd05631e32ac508a"
dependencies = [
- "alloy-json-abi 1.1.0",
- "alloy-primitives 1.1.0",
+ "alloy-json-abi 1.1.2",
+ "alloy-primitives 1.1.2",
"foundry-compilers-core",
"futures-util",
"path-slash",
@@ -4380,8 +4378,8 @@ version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f077777aa33f933f9f01e90f9ed78e4a40ed60a6380798b528681ca9519a577"
dependencies = [
- "alloy-json-abi 1.1.0",
- "alloy-primitives 1.1.0",
+ "alloy-json-abi 1.1.2",
+ "alloy-primitives 1.1.2",
"foundry-compilers-artifacts-solc",
"foundry-compilers-core",
"path-slash",
@@ -4395,7 +4393,7 @@ version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ff92d5831075077fe64391dcbbe4a1518bce0439f97ab6a940fa1b9c1f3eaa2"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"cfg-if",
"dunce",
"fs_extra",
@@ -4417,7 +4415,7 @@ name = "foundry-config"
version = "1.2.0"
dependencies = [
"alloy-chains",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"dirs",
"dunce",
"eyre",
@@ -4453,7 +4451,7 @@ dependencies = [
name = "foundry-debugger"
version = "1.2.0"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"crossterm",
"eyre",
"foundry-common",
@@ -4471,11 +4469,11 @@ dependencies = [
name = "foundry-evm"
version = "1.2.0"
dependencies = [
- "alloy-dyn-abi 1.1.0",
+ "alloy-dyn-abi 1.1.2",
"alloy-evm",
- "alloy-json-abi 1.1.0",
- "alloy-primitives 1.1.0",
- "alloy-sol-types 1.1.0",
+ "alloy-json-abi 1.1.2",
+ "alloy-primitives 1.1.2",
+ "alloy-sol-types 1.1.2",
"eyre",
"foundry-cheatcodes",
"foundry-common",
@@ -4499,8 +4497,8 @@ dependencies = [
name = "foundry-evm-abi"
version = "1.2.0"
dependencies = [
- "alloy-primitives 1.1.0",
- "alloy-sol-types 1.1.0",
+ "alloy-primitives 1.1.2",
+ "alloy-sol-types 1.1.2",
"derive_more 2.0.1",
"foundry-common-fmt",
"foundry-macros",
@@ -4512,16 +4510,16 @@ name = "foundry-evm-core"
version = "1.2.0"
dependencies = [
"alloy-consensus",
- "alloy-dyn-abi 1.1.0",
+ "alloy-dyn-abi 1.1.2",
"alloy-evm",
"alloy-genesis",
- "alloy-json-abi 1.1.0",
+ "alloy-json-abi 1.1.2",
"alloy-network",
"alloy-op-evm",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-provider",
"alloy-rpc-types",
- "alloy-sol-types 1.1.0",
+ "alloy-sol-types 1.1.2",
"auto_impl",
"eyre",
"foundry-cheatcodes-spec",
@@ -4548,7 +4546,7 @@ dependencies = [
name = "foundry-evm-coverage"
version = "1.2.0"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"eyre",
"foundry-common",
"foundry-compilers",
@@ -4563,9 +4561,9 @@ dependencies = [
name = "foundry-evm-fuzz"
version = "1.2.0"
dependencies = [
- "alloy-dyn-abi 1.1.0",
- "alloy-json-abi 1.1.0",
- "alloy-primitives 1.1.0",
+ "alloy-dyn-abi 1.1.2",
+ "alloy-json-abi 1.1.2",
+ "alloy-primitives 1.1.2",
"eyre",
"foundry-common",
"foundry-compilers",
@@ -4587,10 +4585,10 @@ dependencies = [
name = "foundry-evm-traces"
version = "1.2.0"
dependencies = [
- "alloy-dyn-abi 1.1.0",
- "alloy-json-abi 1.1.0",
- "alloy-primitives 1.1.0",
- "alloy-sol-types 1.1.0",
+ "alloy-dyn-abi 1.1.2",
+ "alloy-json-abi 1.1.2",
+ "alloy-primitives 1.1.2",
+ "alloy-sol-types 1.1.2",
"eyre",
"foundry-block-explorers",
"foundry-common",
@@ -4618,7 +4616,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c99831be91edd8a025fa60443b5404ad407708bc337d2e20440d498b5806fab8"
dependencies = [
"alloy-consensus",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-provider",
"alloy-rpc-types",
"eyre",
@@ -4637,7 +4635,7 @@ dependencies = [
name = "foundry-linking"
version = "1.2.0"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"foundry-compilers",
"semver 1.0.26",
"thiserror 2.0.12",
@@ -4671,7 +4669,7 @@ dependencies = [
name = "foundry-test-utils"
version = "1.2.0"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-provider",
"eyre",
"fd-lock",
@@ -4697,16 +4695,16 @@ name = "foundry-wallets"
version = "1.2.0"
dependencies = [
"alloy-consensus",
- "alloy-dyn-abi 1.1.0",
+ "alloy-dyn-abi 1.1.2",
"alloy-network",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-signer",
"alloy-signer-aws",
"alloy-signer-gcp",
"alloy-signer-ledger",
"alloy-signer-local",
"alloy-signer-trezor",
- "alloy-sol-types 1.1.0",
+ "alloy-sol-types 1.1.2",
"async-trait",
"aws-config",
"aws-sdk-kms",
@@ -5532,7 +5530,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
dependencies = [
"hermit-abi 0.5.1",
"libc",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -5595,7 +5593,7 @@ dependencies = [
"portable-atomic",
"portable-atomic-util",
"serde",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -6525,7 +6523,7 @@ checksum = "6f318b09e24148f07392c5e011bae047a0043851f9041145df5f3b01e4fedd1e"
dependencies = [
"alloy-consensus",
"alloy-eips 1.0.4",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rlp",
"alloy-serde 1.0.4",
"derive_more 2.0.1",
@@ -6542,7 +6540,7 @@ dependencies = [
"alloy-consensus",
"alloy-eips 1.0.4",
"alloy-network-primitives",
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rpc-types-eth",
"alloy-serde 1.0.4",
"derive_more 2.0.1",
@@ -7296,7 +7294,7 @@ dependencies = [
"once_cell",
"socket2",
"tracing",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -7694,10 +7692,10 @@ version = "0.22.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f847f5e88a09ac84b36529fbe2fee80b3d8bbf91e9a7ae3ea856c4125d0d232"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"alloy-rpc-types-eth",
"alloy-rpc-types-trace",
- "alloy-sol-types 1.1.0",
+ "alloy-sol-types 1.1.2",
"anstyle",
"colorchoice",
"revm",
@@ -7746,7 +7744,7 @@ name = "revm-primitives"
version = "19.0.0"
source = "git+https://github.com/bluealloy/revm.git?rev=b5808253#b580825320708f0c47d3734ceab03d90c0b11ba1"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"num_enum",
"serde",
]
@@ -7934,7 +7932,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.4.15",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -7947,7 +7945,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.9.4",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -8605,7 +8603,7 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7960f42b73c63b78df9e223ea88ca87b7aaef91e3b5084b89d79ec31ad9fc8e3"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"bumpalo",
"either",
"num-bigint",
@@ -8665,7 +8663,7 @@ dependencies = [
"solar-config",
"solar-data-structures",
"solar-macros",
- "thiserror 1.0.69",
+ "thiserror 2.0.12",
"tracing",
"unicode-width 0.2.0",
]
@@ -8687,7 +8685,7 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7965e27a45ca85135ffd45839f9623131175fb43d2ad3526d32de0946f250f1b"
dependencies = [
- "alloy-primitives 1.1.0",
+ "alloy-primitives 1.1.2",
"bitflags 2.9.1",
"bumpalo",
"itertools 0.14.0",
@@ -8708,8 +8706,8 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7e695824aaf984aa01493ebd5e7e83ddf84629d4a2667a0adf25cb6b65fa63e"
dependencies = [
- "alloy-json-abi 1.1.0",
- "alloy-primitives 1.1.0",
+ "alloy-json-abi 1.1.2",
+ "alloy-primitives 1.1.2",
"bitflags 2.9.1",
"bumpalo",
"derive_more 2.0.1",
@@ -8991,7 +8989,7 @@ dependencies = [
"serde_json",
"sha2 0.10.9",
"tempfile",
- "thiserror 1.0.69",
+ "thiserror 2.0.12",
"url",
"zip",
]
@@ -9044,9 +9042,9 @@ dependencies = [
[[package]]
name = "syn-solidity"
-version = "1.1.0"
+version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d0f0d4760f4c2a0823063b2c70e97aa2ad185f57be195172ccc0e23c4b787c4"
+checksum = "1b5d879005cc1b5ba4e18665be9e9501d9da3a9b95f625497c4cb7ee082b532e"
dependencies = [
"paste",
"proc-macro2",
@@ -10283,7 +10281,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
index febe1911fd141..b9eed6076d38c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -229,7 +229,7 @@ alloy-transport-ipc = { version = "1.0.3", default-features = false }
alloy-transport-ws = { version = "1.0.3", default-features = false }
## alloy-core
-alloy-dyn-abi = "1.0"
+alloy-dyn-abi = "1.1.2"
alloy-json-abi = "1.0"
alloy-primitives = { version = "1.0", features = [
"getrandom",
diff --git a/crates/cheatcodes/src/utils.rs b/crates/cheatcodes/src/utils.rs
index ea9a3163b7053..3f03f6ccd792d 100644
--- a/crates/cheatcodes/src/utils.rs
+++ b/crates/cheatcodes/src/utils.rs
@@ -1,7 +1,7 @@
//! Implementations of [`Utilities`](spec::Group::Utilities) cheatcodes.
use crate::{Cheatcode, Cheatcodes, CheatcodesExecutor, CheatsCtxt, Result, Vm::*};
-use alloy_dyn_abi::{eip712_parser::EncodeType, DynSolType, DynSolValue, Resolver};
+use alloy_dyn_abi::{eip712_parser::EncodeType, DynSolType, DynSolValue};
use alloy_primitives::{aliases::B32, keccak256, map::HashMap, B64, U256};
use alloy_sol_types::SolValue;
use foundry_common::{ens::namehash, fs};
@@ -316,57 +316,51 @@ fn random_int(state: &mut Cheatcodes, bits: Option) -> Result {
.abi_encode())
}
-// `string contant schema_Foo = "Foo(bar uin256)";`
-const TYPE_BINDING_PREFIX: &str = "string constant schema_";
-
impl Cheatcode for eip712HashTypeCall {
fn apply(&self, state: &mut Cheatcodes) -> Result {
let Self { typeDefinition } = self;
let type_def = if !typeDefinition.contains('(') {
- &get_type_def_from_bindings(typeDefinition, state)?
+ get_type_def_from_bindings(typeDefinition, state)?
} else {
- typeDefinition
- // let canonical = EncodeType::parse(typeDefinition).and_then(|parsed|
- // parsed.canonicalize())?;
+ EncodeType::parse(&typeDefinition).and_then(|parsed| parsed.canonicalize())?
};
- // let hash = keccak256(type_def.as_bytes());
- // bail!("type: {type_def}, hash: {hash}");
Ok(keccak256(type_def.as_bytes()).to_vec())
}
}
fn get_type_def_from_bindings(name: &String, state: &mut Cheatcodes) -> Result {
- let path = state.config.ensure_path_allowed(
- &state.config.root.join("utils").join("JsonBindings.sol"),
- FsAccessKind::Read,
- )?;
-
- let content = fs::read_to_string(path)?;
-
- let mut type_defs = HashMap::new();
- for line in content.lines() {
- let line = line.trim();
- if !line.starts_with(TYPE_BINDING_PREFIX) {
- continue;
- }
-
- let relevant = &line[TYPE_BINDING_PREFIX.len()..];
- if let Some(idx) = relevant.find('=') {
- let name = relevant[..idx].trim();
-
- // relevant value chars are " \"Foo(bar uint256)\";"
- let def = relevant[idx + 1..].trim();
- if def.len() > 3 && def.starts_with('"') && def.ends_with("\";") {
- let value = &def[1..def.len() - 2];
- type_defs.insert(name, value);
- }
- }
- }
+ const TYPE_BINDING_PREFIX: &str = "string constant schema_";
+
+ let path = state.config.root.join("utils").join("JsonBindings.sol");
+ let path = state.config.ensure_path_allowed(&path, FsAccessKind::Read)?;
+ let content = fs::read_to_string(&path)?;
+
+ let type_defs: HashMap<&str, &str> = content
+ .lines()
+ .filter_map(|line| {
+ let relevant = line.trim().strip_prefix(TYPE_BINDING_PREFIX)?;
+ let (name, def) = relevant.split_once('=')?;
+ Some((name.trim(), def.trim().strip_prefix('"')?.strip_suffix("\";")?))
+ })
+ .collect();
match type_defs.get(name.as_str()) {
Some(value) => Ok(value.to_string()),
- None => bail!(format!("'{name}' not found in 'utils/JsonBindings.sol'\n{:#?}", type_defs)),
+ None => {
+ let bindings =
+ type_defs.keys().map(|k| format!(" - {k}")).collect::>().join("\n");
+
+ bail!(
+ "'{}' not found in 'utils/JsonBindings.sol'.{}",
+ name,
+ if bindings.is_empty() {
+ String::new()
+ } else {
+ format!("\nAvailable bindings:\n{}\n", bindings)
+ }
+ );
+ }
}
}
diff --git a/crates/forge/tests/cli/eip712.rs b/crates/forge/tests/cli/eip712.rs
index f7bea4ffbca8b..55d40474e3d81 100644
--- a/crates/forge/tests/cli/eip712.rs
+++ b/crates/forge/tests/cli/eip712.rs
@@ -1,5 +1,3 @@
-use foundry_config::fs_permissions::PathPermission;
-
forgetest!(test_eip712, |prj, cmd| {
let path = prj
.add_source(
@@ -57,67 +55,3 @@ FooBar(Foo[] foos,Bar[] bars,Foo_1 foo,Bar_1 bar,Rec[] recs,Rec_1 rec)Art(uint25
"#]],
);
});
-
-forgetest!(test_eip712_cheatcode, |prj, cmd| {
- prj.add_source(
- "Eip712",
- r#"
-contract Eip712 {
- struct Transaction {
- Person from;
- Person to;
- Asset tx;
- }
- struct Person {
- address wallet;
- string name;
- }
- struct Asset {
- address token;
- uint256 amount;
- }
-}
- "#,
- )
- .unwrap();
- prj.insert_ds_test();
- prj.insert_vm();
- prj.insert_console();
-
- prj.add_source("Eip712Cheat.sol", r#"
-// Note Used in forge-cli tests to assert failures.
-// SPDX-License-Identifier: MIT OR Apache-2.0
-pragma solidity ^0.8.18;
-
-import "./test.sol";
-import "./Vm.sol";
-import "./console.sol";
-
-string constant CANONICAL = "Transaction(Person from,Person to,Asset tx)Asset(address token,uint256 amount)Person(address wallet,string name)";
-string constant MESSY = "Person(address wallet, string name) Asset(address token, uint256 amount) Transaction(Person from, Person to, Asset tx)";
-
-contract Eip712Test is DSTest {
- Vm constant vm = Vm(HEVM_ADDRESS);
-
- function testEip712HashType() public {
- bytes32 hashCanonical = keccak256(bytes(CANONICAL));
-
- bytes32 hashTypeName = vm.eip712HashType("Transaction");
- assertEq(hashTypeName, hashCanonical);
-
- bytes32 hashTypeDef = vm.eip712HashType(MESSY);
- assertEq(hashTypeDef, hashCanonical);
- }
-}
-"#,
- )
- .unwrap();
-
- cmd.forge_fuse().args(["bind-json"]).assert_success();
-
- let bindings = prj.root().join("utils").join("JsonBindings.sol");
- assert!(bindings.exists(), "JsonBindings.sol was not generated at {:?}", bindings);
-
- prj.update_config(|config| config.fs_permissions.add(PathPermission::read(bindings)));
- cmd.forge_fuse().args(["test", "--mc", "Eip712Test", "-vvvv"]).assert_success();
-});
diff --git a/crates/forge/tests/cli/test_cmd.rs b/crates/forge/tests/cli/test_cmd.rs
index 6a75e4478bf3d..ebbee81af738f 100644
--- a/crates/forge/tests/cli/test_cmd.rs
+++ b/crates/forge/tests/cli/test_cmd.rs
@@ -2,6 +2,7 @@
use alloy_primitives::U256;
use anvil::{spawn, NodeConfig};
+use foundry_config::fs_permissions::PathPermission;
use foundry_test_utils::{
rpc, str,
util::{OutputExt, OTHER_SOLC_VERSION, SOLC_VERSION},
@@ -3649,3 +3650,75 @@ Encountered a total of 1 failing tests, 0 tests succeeded
"#]]);
});
+
+forgetest!(test_eip712_cheatcode, |prj, cmd| {
+ prj.add_source(
+ "Eip712",
+ r#"
+contract Eip712Structs {
+ struct Transaction {
+ Person from;
+ Person to;
+ Asset tx;
+ }
+ struct Person {
+ address wallet;
+ string name;
+ }
+ struct Asset {
+ address token;
+ uint256 amount;
+ }
+}
+ "#,
+ )
+ .unwrap();
+ prj.insert_ds_test();
+ prj.insert_vm();
+ prj.insert_console();
+
+ prj.add_source("Eip712Cheat.sol", r#"
+// Note Used in forge-cli tests to assert failures.
+// SPDX-License-Identifier: MIT OR Apache-2.0
+pragma solidity ^0.8.18;
+
+import "./test.sol";
+import "./Vm.sol";
+import "./console.sol";
+
+string constant CANONICAL = "Transaction(Person from,Person to,Asset tx)Asset(address token,uint256 amount)Person(address wallet,string name)";
+
+contract Eip712Test is DSTest {
+ Vm constant vm = Vm(HEVM_ADDRESS);
+
+ function testEip712HashType() public {
+ bytes32 canonicalHash = keccak256(bytes(CANONICAL));
+
+ // Can figure out the canonical type from a messy string representation of the type,
+ // with an invalid order and extra whitespaces
+ bytes32 fromTypeDef = vm.eip712HashType(
+ "Person(address wallet, string name) Asset(address token, uint256 amount) Transaction(Person from, Person to, Asset tx)"
+ );
+ assertEq(fromTypeDef, canonicalHash);
+
+ // Can figure out the canonical type from the previously generated bindings
+ bytes32 fromTypeName = vm.eip712HashType("Transaction");
+ assertEq(fromTypeName, canonicalHash);
+
+ // Reverts if the input type is not found in the bindings
+ vm._expectCheatcodeRevert();
+ fromTypeName = vm.eip712HashType("InvalidTypeName");
+ }
+}
+"#,
+ )
+ .unwrap();
+
+ cmd.forge_fuse().args(["bind-json"]).assert_success();
+
+ let bindings = prj.root().join("utils").join("JsonBindings.sol");
+ assert!(bindings.exists(), "'JsonBindings.sol' was not generated at {:?}", bindings);
+
+ prj.update_config(|config| config.fs_permissions.add(PathPermission::read(bindings)));
+ cmd.forge_fuse().args(["test", "--mc", "Eip712Test", "-vvvv"]).assert_success();
+});
From cf67c2cc4c0089383a1efc5e78b75f6e11724c81 Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Tue, 20 May 2025 11:15:36 -0500
Subject: [PATCH 04/21] style: clippy + fmt
---
crates/cheatcodes/src/utils.rs | 4 ++--
crates/forge/tests/cli/eip712.rs | 32 +++++++++++++++++++++---------
crates/forge/tests/cli/test_cmd.rs | 2 +-
3 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/crates/cheatcodes/src/utils.rs b/crates/cheatcodes/src/utils.rs
index 3f03f6ccd792d..4ca22fb9ada3a 100644
--- a/crates/cheatcodes/src/utils.rs
+++ b/crates/cheatcodes/src/utils.rs
@@ -323,7 +323,7 @@ impl Cheatcode for eip712HashTypeCall {
let type_def = if !typeDefinition.contains('(') {
get_type_def_from_bindings(typeDefinition, state)?
} else {
- EncodeType::parse(&typeDefinition).and_then(|parsed| parsed.canonicalize())?
+ EncodeType::parse(typeDefinition).and_then(|parsed| parsed.canonicalize())?
};
Ok(keccak256(type_def.as_bytes()).to_vec())
@@ -358,7 +358,7 @@ fn get_type_def_from_bindings(name: &String, state: &mut Cheatcodes) -> Result
Date: Tue, 20 May 2025 12:32:29 -0500
Subject: [PATCH 05/21] fix: simple example + bump alloy core + docs
---
Cargo.toml | 11 ++--
crates/cheatcodes/spec/src/vm.rs | 7 ++-
crates/forge/tests/cli/test_cmd.rs | 81 +++++++++++++++++++++++++++---
3 files changed, 86 insertions(+), 13 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
index 4c36858f48ec4..3f6b61fe09bdd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -196,7 +196,6 @@ foundry-wallets = { path = "crates/wallets" }
foundry-linking = { path = "crates/linking" }
# solc & compilation utilities
-
foundry-block-explorers = { version = "0.17.0", default-features = false }
foundry-compilers = { version = "0.16.1", default-features = false }
foundry-fork-db = "0.14"
@@ -230,16 +229,16 @@ alloy-transport-ws = { version = "1.0.5", default-features = false }
## alloy-core
alloy-dyn-abi = "1.1.2"
-alloy-json-abi = "1.0"
-alloy-primitives = { version = "1.0", features = [
+alloy-json-abi = "1.1.2"
+alloy-primitives = { version = "1.1.2", features = [
"getrandom",
"rand",
"map-fxhash",
"map-foldhash",
] }
-alloy-sol-macro-expander = "1.0"
-alloy-sol-macro-input = "1.0"
-alloy-sol-types = "1.0"
+alloy-sol-macro-expander = "1.1.2"
+alloy-sol-macro-input = "1.1.2"
+alloy-sol-types = "1.1.2"
alloy-chains = "0.2"
alloy-rlp = "0.3"
diff --git a/crates/cheatcodes/spec/src/vm.rs b/crates/cheatcodes/spec/src/vm.rs
index 2d9a61d9c829e..0ffa5259afbd2 100644
--- a/crates/cheatcodes/spec/src/vm.rs
+++ b/crates/cheatcodes/spec/src/vm.rs
@@ -2889,7 +2889,12 @@ interface Vm {
#[cheatcode(group = Utilities, safety = Unsafe)]
function interceptInitcode() external;
- /// Randomly shuffles an array.
+ /// Generates the hash of the canonical EIP-712 type representation.
+ ///
+ /// Supports 2 different inputs:
+ /// * Name of the type (i.e. "Transaction") --> requires previous binding generation with `forge bind-json`
+ /// * String representation of the type (i.e. "Foo(Bar bar) Bar(uint256 baz)") --> the cheatcode
+ /// will output the canonical type even if the input is malformated (wrong order or whitespaces)
#[cheatcode(group = Utilities)]
function eip712HashType(string memory typeDefinition) external pure returns (bytes32 typeHash);
}
diff --git a/crates/forge/tests/cli/test_cmd.rs b/crates/forge/tests/cli/test_cmd.rs
index 24df946ddb8a5..9a4e0e76d0190 100644
--- a/crates/forge/tests/cli/test_cmd.rs
+++ b/crates/forge/tests/cli/test_cmd.rs
@@ -3651,7 +3651,81 @@ Encountered a total of 1 failing tests, 0 tests succeeded
"#]]);
});
-forgetest!(test_eip712_cheatcode, |prj, cmd| {
+forgetest!(test_eip712_cheatcode_simple, |prj, cmd| {
+ prj.add_source(
+ "Eip712",
+ r#"
+contract Eip712Structs {
+ struct EIP712Domain {
+ string name;
+ string version;
+ uint256 chainId;
+ address verifyingContract;
+ }
+}
+ "#,
+ )
+ .unwrap();
+ prj.insert_ds_test();
+ prj.insert_vm();
+ prj.insert_console();
+
+ prj.add_source("Eip712Cheat.sol", r#"
+import "./test.sol";
+import "./Vm.sol";
+import "./console.sol";
+
+string constant CANONICAL = "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)";
+
+contract Eip712Test is DSTest {
+ Vm constant vm = Vm(HEVM_ADDRESS);
+
+ function testEip712HashType() public {
+ bytes32 canonicalHash = keccak256(bytes(CANONICAL));
+ console.logBytes32(canonicalHash);
+
+ // Can figure out the canonical type from a messy string representation of the type,
+ // with an invalid order and extra whitespaces
+ bytes32 fromTypeDef = vm.eip712HashType(
+ "EIP712Domain(string name, string version, uint256 chainId, address verifyingContract)"
+ );
+ assertEq(fromTypeDef, canonicalHash);
+
+ // Can figure out the canonical type from the previously generated bindings
+ bytes32 fromTypeName = vm.eip712HashType("EIP712Domain");
+ assertEq(fromTypeName, canonicalHash);
+ }
+}
+"#,
+ )
+ .unwrap();
+
+ cmd.forge_fuse().args(["bind-json"]).assert_success();
+
+ let bindings = prj.root().join("utils").join("JsonBindings.sol");
+ assert!(bindings.exists(), "'JsonBindings.sol' was not generated at {bindings:?}");
+
+ prj.update_config(|config| config.fs_permissions.add(PathPermission::read(bindings)));
+ cmd.forge_fuse().args(["test", "--mc", "Eip712Test", "-vv"]).assert_success().stdout_eq(str![
+ [r#"
+[COMPILING_FILES] with [SOLC_VERSION]
+[SOLC_VERSION] [ELAPSED]
+Compiler run successful!
+
+Ran 1 test for src/Eip712Cheat.sol:Eip712Test
+[PASS] testEip712HashType() ([GAS])
+Logs:
+ 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f
+
+Suite result: ok. 1 passed; 0 failed; 0 skipped; [ELAPSED]
+
+Ran 1 test suite [ELAPSED]: 1 tests passed, 0 failed, 0 skipped (1 total tests)
+
+"#]
+ ]);
+});
+
+forgetest!(test_eip712_cheatcode_nested, |prj, cmd| {
prj.add_source(
"Eip712",
r#"
@@ -3678,13 +3752,8 @@ contract Eip712Structs {
prj.insert_console();
prj.add_source("Eip712Cheat.sol", r#"
-// Note Used in forge-cli tests to assert failures.
-// SPDX-License-Identifier: MIT OR Apache-2.0
-pragma solidity ^0.8.18;
-
import "./test.sol";
import "./Vm.sol";
-import "./console.sol";
string constant CANONICAL = "Transaction(Person from,Person to,Asset tx)Asset(address token,uint256 amount)Person(address wallet,string name)";
From a6cca9a47360fbdc75c0583bfdeba99494da7227 Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Tue, 20 May 2025 15:08:24 -0500
Subject: [PATCH 06/21] fix: cheats spec
---
crates/cheatcodes/assets/cheatcodes.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/crates/cheatcodes/assets/cheatcodes.json b/crates/cheatcodes/assets/cheatcodes.json
index 4d5d35ab05953..595c6d23ad581 100644
--- a/crates/cheatcodes/assets/cheatcodes.json
+++ b/crates/cheatcodes/assets/cheatcodes.json
@@ -4297,7 +4297,7 @@
{
"func": {
"id": "eip712HashType",
- "description": "Randomly shuffles an array.",
+ "description": "Generates the hash of the canonical EIP-712 type representation.\nSupports 2 different inputs:\n * Name of the type (i.e. \"Transaction\") --> requires previous binding generation with `forge bind-json`\n * String representation of the type (i.e. \"Foo(Bar bar) Bar(uint256 baz)\") --> the cheatcode\n will output the canonical type even if the input is malformated (wrong order or whitespaces)",
"declaration": "function eip712HashType(string memory typeDefinition) external pure returns (bytes32 typeHash);",
"visibility": "external",
"mutability": "pure",
From 4395b32669dca0e61c875dab2575c5275f2d9f2a Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Thu, 22 May 2025 09:11:56 -0500
Subject: [PATCH 07/21] load json bindings from foundry.toml + allow custom
path + extend tests
---
crates/cheatcodes/assets/cheatcodes.json | 26 +++++++++++--
crates/cheatcodes/spec/src/vm.rs | 21 +++++++++--
crates/cheatcodes/src/config.rs | 4 ++
crates/cheatcodes/src/utils.rs | 38 +++++++++++++------
crates/common/src/constants.rs | 3 ++
crates/forge/src/cmd/bind_json.rs | 6 +--
crates/forge/tests/cli/test_cmd.rs | 48 +++++++++++++++++++++---
testdata/cheats/Vm.sol | 3 +-
8 files changed, 122 insertions(+), 27 deletions(-)
diff --git a/crates/cheatcodes/assets/cheatcodes.json b/crates/cheatcodes/assets/cheatcodes.json
index 595c6d23ad581..7e903135a897a 100644
--- a/crates/cheatcodes/assets/cheatcodes.json
+++ b/crates/cheatcodes/assets/cheatcodes.json
@@ -4296,9 +4296,9 @@
},
{
"func": {
- "id": "eip712HashType",
- "description": "Generates the hash of the canonical EIP-712 type representation.\nSupports 2 different inputs:\n * Name of the type (i.e. \"Transaction\") --> requires previous binding generation with `forge bind-json`\n * String representation of the type (i.e. \"Foo(Bar bar) Bar(uint256 baz)\") --> the cheatcode\n will output the canonical type even if the input is malformated (wrong order or whitespaces)",
- "declaration": "function eip712HashType(string memory typeDefinition) external pure returns (bytes32 typeHash);",
+ "id": "eip712HashType_0",
+ "description": "Generates the hash of the canonical EIP-712 type representation.\nSupports 2 different inputs:\n 1. Name of the type (i.e. \"Transaction\"):\n * requires previous binding generation with `forge bind-json`.\n * bindings will be retrieved from the path configured in `foundry.toml`.\n 2. String representation of the type (i.e. \"Foo(Bar bar) Bar(uint256 baz)\").\n * Note: the cheatcode will output the canonical type even if the input is malformated\n with the wrong order of elements or with extra whitespaces.",
+ "declaration": "function eip712HashType(string memory typeNameOrDefinition) external pure returns (bytes32 typeHash);",
"visibility": "external",
"mutability": "pure",
"signature": "eip712HashType(string)",
@@ -4314,6 +4314,26 @@
"status": "stable",
"safety": "safe"
},
+ {
+ "func": {
+ "id": "eip712HashType_1",
+ "description": "Generates the hash of the canonical EIP-712 type representation.\nRequires previous binding generation with `forge bind-json`.\nParams:\n * `bindingsPath`: path where the output of `forge bind-json` is stored.\n * `typeName`: Name of the type (i.e. \"Transaction\").",
+ "declaration": "function eip712HashType(string calldata bindingsPath, string memory typeName) external pure returns (bytes32 typeHash);",
+ "visibility": "external",
+ "mutability": "pure",
+ "signature": "eip712HashType(string,string)",
+ "selector": "0x18fb6406",
+ "selectorBytes": [
+ 24,
+ 251,
+ 100,
+ 6
+ ]
+ },
+ "group": "utilities",
+ "status": "stable",
+ "safety": "safe"
+ },
{
"func": {
"id": "ensNamehash",
diff --git a/crates/cheatcodes/spec/src/vm.rs b/crates/cheatcodes/spec/src/vm.rs
index 0ffa5259afbd2..025311768e67c 100644
--- a/crates/cheatcodes/spec/src/vm.rs
+++ b/crates/cheatcodes/spec/src/vm.rs
@@ -2892,11 +2892,24 @@ interface Vm {
/// Generates the hash of the canonical EIP-712 type representation.
///
/// Supports 2 different inputs:
- /// * Name of the type (i.e. "Transaction") --> requires previous binding generation with `forge bind-json`
- /// * String representation of the type (i.e. "Foo(Bar bar) Bar(uint256 baz)") --> the cheatcode
- /// will output the canonical type even if the input is malformated (wrong order or whitespaces)
+ /// 1. Name of the type (i.e. "Transaction"):
+ /// * requires previous binding generation with `forge bind-json`.
+ /// * bindings will be retrieved from the path configured in `foundry.toml`.
+ ///
+ /// 2. String representation of the type (i.e. "Foo(Bar bar) Bar(uint256 baz)").
+ /// * Note: the cheatcode will output the canonical type even if the input is malformated
+ /// with the wrong order of elements or with extra whitespaces.
+ #[cheatcode(group = Utilities)]
+ function eip712HashType(string memory typeNameOrDefinition) external pure returns (bytes32 typeHash);
+
+ /// Generates the hash of the canonical EIP-712 type representation.
+ /// Requires previous binding generation with `forge bind-json`.
+ ///
+ /// Params:
+ /// * `bindingsPath`: path where the output of `forge bind-json` is stored.
+ /// * `typeName`: Name of the type (i.e. "Transaction").
#[cheatcode(group = Utilities)]
- function eip712HashType(string memory typeDefinition) external pure returns (bytes32 typeHash);
+ function eip712HashType(string calldata bindingsPath, string memory typeName) external pure returns (bytes32 typeHash);
}
}
diff --git a/crates/cheatcodes/src/config.rs b/crates/cheatcodes/src/config.rs
index 210c76553cba7..1ad98cd93e92b 100644
--- a/crates/cheatcodes/src/config.rs
+++ b/crates/cheatcodes/src/config.rs
@@ -33,6 +33,8 @@ pub struct CheatsConfig {
pub rpc_endpoints: ResolvedRpcEndpoints,
/// Project's paths as configured
pub paths: ProjectPathsConfig,
+ /// Path to the directory that contains the bindings generated by `forge bind-json`.
+ pub bind_json_path: PathBuf,
/// Filesystem permissions for cheatcodes like `writeFile`, `readFile`
pub fs_permissions: FsPermissions,
/// Project root
@@ -98,6 +100,7 @@ impl CheatsConfig {
no_storage_caching: config.no_storage_caching,
rpc_endpoints,
paths: config.project_paths(),
+ bind_json_path: config.bind_json.out.clone(),
fs_permissions: config.fs_permissions.clone().joined(config.root.as_ref()),
root: config.root.clone(),
broadcast: config.root.clone().join(&config.broadcast),
@@ -303,6 +306,7 @@ impl Default for CheatsConfig {
paths: ProjectPathsConfig::builder().build_with_root("./"),
fs_permissions: Default::default(),
root: Default::default(),
+ bind_json_path: PathBuf::default().join("utils").join("jsonBindings.sol"),
broadcast: Default::default(),
allowed_paths: vec![],
evm_opts: Default::default(),
diff --git a/crates/cheatcodes/src/utils.rs b/crates/cheatcodes/src/utils.rs
index 4ca22fb9ada3a..8f0ebb44f6293 100644
--- a/crates/cheatcodes/src/utils.rs
+++ b/crates/cheatcodes/src/utils.rs
@@ -4,12 +4,13 @@ use crate::{Cheatcode, Cheatcodes, CheatcodesExecutor, CheatsCtxt, Result, Vm::*
use alloy_dyn_abi::{eip712_parser::EncodeType, DynSolType, DynSolValue};
use alloy_primitives::{aliases::B32, keccak256, map::HashMap, B64, U256};
use alloy_sol_types::SolValue;
-use foundry_common::{ens::namehash, fs};
+use foundry_common::{ens::namehash, fs, TYPE_BINDING_PREFIX};
use foundry_config::fs_permissions::FsAccessKind;
use foundry_evm_core::constants::DEFAULT_CREATE2_DEPLOYER;
use proptest::prelude::Strategy;
use rand::{seq::SliceRandom, Rng, RngCore};
use revm::context::JournalTr;
+use std::path::PathBuf;
/// Contains locations of traces ignored via cheatcodes.
///
@@ -316,25 +317,39 @@ fn random_int(state: &mut Cheatcodes, bits: Option) -> Result {
.abi_encode())
}
-impl Cheatcode for eip712HashTypeCall {
+impl Cheatcode for eip712HashType_0Call {
fn apply(&self, state: &mut Cheatcodes) -> Result {
- let Self { typeDefinition } = self;
+ let Self { typeNameOrDefinition } = self;
- let type_def = if !typeDefinition.contains('(') {
- get_type_def_from_bindings(typeDefinition, state)?
+ let type_def = if typeNameOrDefinition.contains('(') {
+ // If the input contains '(', it must be the type definition
+ EncodeType::parse(typeNameOrDefinition).and_then(|parsed| parsed.canonicalize())?
} else {
- EncodeType::parse(typeDefinition).and_then(|parsed| parsed.canonicalize())?
+ // Otherwise, it must be the type name
+ let path = state
+ .config
+ .ensure_path_allowed(&state.config.bind_json_path, FsAccessKind::Read)?;
+ get_type_def_from_bindings(typeNameOrDefinition, path, &state.config.root)?
};
Ok(keccak256(type_def.as_bytes()).to_vec())
}
}
-fn get_type_def_from_bindings(name: &String, state: &mut Cheatcodes) -> Result {
- const TYPE_BINDING_PREFIX: &str = "string constant schema_";
+impl Cheatcode for eip712HashType_1Call {
+ fn apply(&self, state: &mut Cheatcodes) -> Result {
+ let Self { bindingsPath, typeName } = self;
+
+ let path = state.config.ensure_path_allowed(bindingsPath, FsAccessKind::Read)?;
+ let type_def = get_type_def_from_bindings(typeName, path, &state.config.root)?;
+
+ Ok(keccak256(type_def.as_bytes()).to_vec())
+ }
+}
- let path = state.config.root.join("utils").join("JsonBindings.sol");
- let path = state.config.ensure_path_allowed(&path, FsAccessKind::Read)?;
+/// Gets the type definition from the bindings in the provided path. Assumes that read validation
+/// for the path has already been checked.
+fn get_type_def_from_bindings(name: &String, path: PathBuf, root: &PathBuf) -> Result {
let content = fs::read_to_string(&path)?;
let type_defs: HashMap<&str, &str> = content
@@ -353,8 +368,9 @@ fn get_type_def_from_bindings(name: &String, state: &mut Cheatcodes) -> Result>().join("\n");
bail!(
- "'{}' not found in 'utils/JsonBindings.sol'.{}",
+ "'{}' not found in '{}'.{}",
name,
+ path.strip_prefix(root).unwrap_or(&path).to_string_lossy(),
if bindings.is_empty() {
String::new()
} else {
diff --git a/crates/common/src/constants.rs b/crates/common/src/constants.rs
index b8fcdc7f6fd44..425dad204b1a2 100644
--- a/crates/common/src/constants.rs
+++ b/crates/common/src/constants.rs
@@ -45,6 +45,9 @@ pub const SYSTEM_TRANSACTION_TYPE: u8 = 126;
/// Default user agent set as the header for requests that don't specify one.
pub const DEFAULT_USER_AGENT: &str = concat!("foundry/", env!("CARGO_PKG_VERSION"));
+/// Prefix for auto-generated type bindings using `forge bind-json`.
+pub const TYPE_BINDING_PREFIX: &str = "string constant schema_";
+
/// Returns whether the sender is a known L2 system sender that is the first tx in every block.
///
/// Transactions from these senders usually don't have a any fee information.
diff --git a/crates/forge/src/cmd/bind_json.rs b/crates/forge/src/cmd/bind_json.rs
index b82adb50c64dc..ecb76515b16a3 100644
--- a/crates/forge/src/cmd/bind_json.rs
+++ b/crates/forge/src/cmd/bind_json.rs
@@ -5,7 +5,7 @@ use foundry_cli::{
opts::{solar_pcx_from_solc_project, BuildOpts},
utils::LoadConfig,
};
-use foundry_common::fs;
+use foundry_common::{fs, TYPE_BINDING_PREFIX};
use foundry_compilers::{
artifacts::{Source, Sources},
multi::{MultiCompilerLanguage, MultiCompilerParsedSource},
@@ -487,8 +487,8 @@ library JsonBindings {
for struct_to_write in &self.structs_to_write {
writeln!(
result,
- " string constant schema_{} = \"{}\";",
- struct_to_write.name_in_fns, struct_to_write.schema
+ " {}{} = \"{}\";",
+ TYPE_BINDING_PREFIX, struct_to_write.name_in_fns, struct_to_write.schema
)?;
}
diff --git a/crates/forge/tests/cli/test_cmd.rs b/crates/forge/tests/cli/test_cmd.rs
index 9a4e0e76d0190..8f9b838003618 100644
--- a/crates/forge/tests/cli/test_cmd.rs
+++ b/crates/forge/tests/cli/test_cmd.rs
@@ -3760,7 +3760,7 @@ string constant CANONICAL = "Transaction(Person from,Person to,Asset tx)Asset(ad
contract Eip712Test is DSTest {
Vm constant vm = Vm(HEVM_ADDRESS);
- function testEip712HashType() public {
+ function testEip712HashType_byDefinition() public {
bytes32 canonicalHash = keccak256(bytes(CANONICAL));
// Can figure out the canonical type from a messy string representation of the type,
@@ -3769,25 +3769,63 @@ contract Eip712Test is DSTest {
"Person(address wallet, string name) Asset(address token, uint256 amount) Transaction(Person from, Person to, Asset tx)"
);
assertEq(fromTypeDef, canonicalHash);
+ }
+
+ function testEip712HashType_byTypeName() public {
+ bytes32 canonicalHash = keccak256(bytes(CANONICAL));
// Can figure out the canonical type from the previously generated bindings
bytes32 fromTypeName = vm.eip712HashType("Transaction");
assertEq(fromTypeName, canonicalHash);
+ }
+ function testReverts_Eip712HashType_invalidName() public {
// Reverts if the input type is not found in the bindings
vm._expectCheatcodeRevert();
- fromTypeName = vm.eip712HashType("InvalidTypeName");
+ bytes32 fromTypeName = vm.eip712HashType("InvalidTypeName");
}
}
"#,
)
.unwrap();
- cmd.forge_fuse().args(["bind-json"]).assert_success();
+ // cheatcode by type definition can run without bindings
+ cmd.forge_fuse()
+ .args(["test", "--mc", "Eip712Test", "--match-test", "testEip712HashType_byDefinition"])
+ .assert_success();
let bindings = prj.root().join("utils").join("JsonBindings.sol");
+ prj.update_config(|config| config.fs_permissions.add(PathPermission::read(&bindings)));
+
+ // cheatcode by type name fails if bindings haven't been generated
+ cmd.forge_fuse()
+ .args([
+ "test",
+ "--mc",
+ "Eip712Test",
+ "--match-test",
+ "testEip712HashType_byTypeName",
+ ])
+ .assert_failure()
+ .stdout_eq(str![[r#"
+...
+Ran 1 test for src/Eip712Cheat.sol:Eip712Test
+[FAIL: vm.eip712HashType: failed to read from [..] No such file or directory (os error 2)] testEip712HashType_byTypeName() ([GAS])
+Suite result: FAILED. 0 passed; 1 failed; 0 skipped; [ELAPSED]
+
+Ran 1 test suite [ELAPSED]: 0 tests passed, 1 failed, 0 skipped (1 total tests)
+
+Failing tests:
+Encountered 1 failing test in src/Eip712Cheat.sol:Eip712Test
+[FAIL: vm.eip712HashType: failed to read from [..] No such file or directory (os error 2)] testEip712HashType_byTypeName() ([GAS])
+
+Encountered a total of 1 failing tests, 0 tests succeeded
+
+"#]]);
+
+ cmd.forge_fuse().args(["bind-json"]).assert_success();
assert!(bindings.exists(), "'JsonBindings.sol' was not generated at {bindings:?}");
- prj.update_config(|config| config.fs_permissions.add(PathPermission::read(bindings)));
- cmd.forge_fuse().args(["test", "--mc", "Eip712Test", "-vvvv"]).assert_success();
+ // with generated bindings, everything works
+ cmd.forge_fuse().args(["test", "--mc", "Eip712Test"]).assert_success();
});
diff --git a/testdata/cheats/Vm.sol b/testdata/cheats/Vm.sol
index 538ff290733f8..6cbfa37b88d97 100644
--- a/testdata/cheats/Vm.sol
+++ b/testdata/cheats/Vm.sol
@@ -208,7 +208,8 @@ interface Vm {
function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index, string calldata language) external pure returns (uint256 privateKey);
function difficulty(uint256 newDifficulty) external;
function dumpState(string calldata pathToStateJson) external;
- function eip712HashType(string memory typeDefinition) external pure returns (bytes32 typeHash);
+ function eip712HashType(string memory typeNameOrDefinition) external pure returns (bytes32 typeHash);
+ function eip712HashType(string calldata bindingsPath, string memory typeName) external pure returns (bytes32 typeHash);
function ensNamehash(string calldata name) external pure returns (bytes32);
function envAddress(string calldata name) external view returns (address value);
function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value);
From cbabab38e9dd1a8f456d251e87f9449a32587160 Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Thu, 22 May 2025 09:20:54 -0500
Subject: [PATCH 08/21] style: fmt
---
crates/forge/tests/cli/eip712.rs | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/crates/forge/tests/cli/eip712.rs b/crates/forge/tests/cli/eip712.rs
index dc0bfd4367caa..62aa63079eb4e 100644
--- a/crates/forge/tests/cli/eip712.rs
+++ b/crates/forge/tests/cli/eip712.rs
@@ -7,31 +7,39 @@ library Structs {
struct Foo {
Bar bar;
}
+
struct Bar {
Art art;
}
+
struct Art {
uint256 id;
}
+
struct Complex {
Structs2.Foo foo2;
Foo[] foos;
Rec[][] recs;
}
+
struct Rec {
Rec[] rec;
}
}
+
library Structs2 {
struct Foo {
uint256 id;
}
+
struct Rec {
Bar[] bar;
}
+
struct Bar {
Rec rec;
}
+
struct FooBar {
Foo[] foos;
Bar[] bars;
From 7f64f723b58974e8cb6f09579facf045ea8fc87c Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Thu, 22 May 2025 09:45:18 -0500
Subject: [PATCH 09/21] fix: test assertion for win
---
crates/forge/tests/cli/test_cmd.rs | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)
diff --git a/crates/forge/tests/cli/test_cmd.rs b/crates/forge/tests/cli/test_cmd.rs
index 8f9b838003618..a0760d96f8c03 100644
--- a/crates/forge/tests/cli/test_cmd.rs
+++ b/crates/forge/tests/cli/test_cmd.rs
@@ -3799,25 +3799,19 @@ contract Eip712Test is DSTest {
// cheatcode by type name fails if bindings haven't been generated
cmd.forge_fuse()
- .args([
- "test",
- "--mc",
- "Eip712Test",
- "--match-test",
- "testEip712HashType_byTypeName",
- ])
+ .args(["test", "--mc", "Eip712Test", "--match-test", "testEip712HashType_byTypeName"])
.assert_failure()
.stdout_eq(str![[r#"
...
Ran 1 test for src/Eip712Cheat.sol:Eip712Test
-[FAIL: vm.eip712HashType: failed to read from [..] No such file or directory (os error 2)] testEip712HashType_byTypeName() ([GAS])
+[FAIL: vm.eip712HashType: failed to read from [..] testEip712HashType_byTypeName() ([GAS])
Suite result: FAILED. 0 passed; 1 failed; 0 skipped; [ELAPSED]
Ran 1 test suite [ELAPSED]: 0 tests passed, 1 failed, 0 skipped (1 total tests)
Failing tests:
Encountered 1 failing test in src/Eip712Cheat.sol:Eip712Test
-[FAIL: vm.eip712HashType: failed to read from [..] No such file or directory (os error 2)] testEip712HashType_byTypeName() ([GAS])
+[FAIL: vm.eip712HashType: failed to read from [..] testEip712HashType_byTypeName() ([GAS])
Encountered a total of 1 failing tests, 0 tests succeeded
From 7ff2758621e13353c486cf7a43ea9382bd5895ec Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Thu, 22 May 2025 10:00:49 -0500
Subject: [PATCH 10/21] test: custom path
---
crates/forge/tests/cli/test_cmd.rs | 65 +++++++++++++++++++++++++++++-
1 file changed, 63 insertions(+), 2 deletions(-)
diff --git a/crates/forge/tests/cli/test_cmd.rs b/crates/forge/tests/cli/test_cmd.rs
index a0760d96f8c03..fb7c974d045c7 100644
--- a/crates/forge/tests/cli/test_cmd.rs
+++ b/crates/forge/tests/cli/test_cmd.rs
@@ -3784,6 +3784,14 @@ contract Eip712Test is DSTest {
vm._expectCheatcodeRevert();
bytes32 fromTypeName = vm.eip712HashType("InvalidTypeName");
}
+
+ function testEip712HashType_byCustomPathAndTypeName() public {
+ bytes32 canonicalHash = keccak256(bytes(CANONICAL));
+
+ // Can figure out the canonical type from the previously generated bindings
+ bytes32 fromTypeName = vm.eip712HashType("utils/CustomJsonBindings.sol", "Transaction");
+ assertEq(fromTypeName, canonicalHash);
+ }
}
"#,
)
@@ -3820,6 +3828,59 @@ Encountered a total of 1 failing tests, 0 tests succeeded
cmd.forge_fuse().args(["bind-json"]).assert_success();
assert!(bindings.exists(), "'JsonBindings.sol' was not generated at {bindings:?}");
- // with generated bindings, everything works
- cmd.forge_fuse().args(["test", "--mc", "Eip712Test"]).assert_success();
+ // with generated bindings, cheatcode by type name works
+ cmd.forge_fuse()
+ .args(["test", "--mc", "Eip712Test", "--match-test", "testEip712HashType_byTypeName"])
+ .assert_success();
+
+ // even with generated bindings, cheatcode by type name fails if name is not present
+ cmd.forge_fuse()
+ .args([
+ "test",
+ "--mc",
+ "Eip712Test",
+ "--match-test",
+ "testReverts_Eip712HashType_invalidName",
+ ])
+ .assert_success();
+
+ let bindings_2 = prj.root().join("utils").join("CustomJsonBindings.sol");
+ prj.update_config(|config| {
+ config.fs_permissions.add(PathPermission::read(&bindings_2));
+ config.bind_json.out = bindings_2.clone();
+ });
+
+ // cheatcode by custom path and type name fails if bindings haven't been generated for that path
+ cmd.forge_fuse()
+ .args(["test", "--mc", "Eip712Test", "--match-test", "testEip712HashType_byCustomPathAndTypeName"])
+ .assert_failure()
+ .stdout_eq(str![[r#"
+...
+Ran 1 test for src/Eip712Cheat.sol:Eip712Test
+[FAIL: vm.eip712HashType: failed to read from [..] testEip712HashType_byCustomPathAndTypeName() ([GAS])
+Suite result: FAILED. 0 passed; 1 failed; 0 skipped; [ELAPSED]
+
+Ran 1 test suite [ELAPSED]: 0 tests passed, 1 failed, 0 skipped (1 total tests)
+
+Failing tests:
+Encountered 1 failing test in src/Eip712Cheat.sol:Eip712Test
+[FAIL: vm.eip712HashType: failed to read from [..] testEip712HashType_byCustomPathAndTypeName() ([GAS])
+
+Encountered a total of 1 failing tests, 0 tests succeeded
+
+"#]]);
+
+ cmd.forge_fuse().args(["bind-json"]).assert_success();
+ assert!(bindings_2.exists(), "'CustomJsonBindings.sol' was not generated at {bindings_2:?}");
+
+ // with generated bindings, cheatcode by custom path and type name works
+ cmd.forge_fuse()
+ .args([
+ "test",
+ "--mc",
+ "Eip712Test",
+ "--match-test",
+ "testEip712HashType_byCustomPathAndTypeName",
+ ])
+ .assert_success();
});
From c0579023d85c96e1160abd6593c1cb9eef40fb82 Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Thu, 22 May 2025 10:04:32 -0500
Subject: [PATCH 11/21] fix: custom path without being the configured one in
`foundry.toml`
---
crates/forge/tests/cli/test_cmd.rs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/crates/forge/tests/cli/test_cmd.rs b/crates/forge/tests/cli/test_cmd.rs
index fb7c974d045c7..fba03905afd8c 100644
--- a/crates/forge/tests/cli/test_cmd.rs
+++ b/crates/forge/tests/cli/test_cmd.rs
@@ -3847,7 +3847,6 @@ Encountered a total of 1 failing tests, 0 tests succeeded
let bindings_2 = prj.root().join("utils").join("CustomJsonBindings.sol");
prj.update_config(|config| {
config.fs_permissions.add(PathPermission::read(&bindings_2));
- config.bind_json.out = bindings_2.clone();
});
// cheatcode by custom path and type name fails if bindings haven't been generated for that path
@@ -3870,7 +3869,7 @@ Encountered a total of 1 failing tests, 0 tests succeeded
"#]]);
- cmd.forge_fuse().args(["bind-json"]).assert_success();
+ cmd.forge_fuse().args(["bind-json", "utils/CustomJsonBindings.sol"]).assert_success();
assert!(bindings_2.exists(), "'CustomJsonBindings.sol' was not generated at {bindings_2:?}");
// with generated bindings, cheatcode by custom path and type name works
From c6f037dc37c322e295eb9ad3c73079a89197307d Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Thu, 22 May 2025 10:38:49 -0500
Subject: [PATCH 12/21] fix: use calldata instead of memory in cheatcode fns
---
crates/cheatcodes/assets/cheatcodes.json | 4 ++--
crates/cheatcodes/spec/src/vm.rs | 4 ++--
testdata/cheats/Vm.sol | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/crates/cheatcodes/assets/cheatcodes.json b/crates/cheatcodes/assets/cheatcodes.json
index 7e903135a897a..e00c1f2125891 100644
--- a/crates/cheatcodes/assets/cheatcodes.json
+++ b/crates/cheatcodes/assets/cheatcodes.json
@@ -4298,7 +4298,7 @@
"func": {
"id": "eip712HashType_0",
"description": "Generates the hash of the canonical EIP-712 type representation.\nSupports 2 different inputs:\n 1. Name of the type (i.e. \"Transaction\"):\n * requires previous binding generation with `forge bind-json`.\n * bindings will be retrieved from the path configured in `foundry.toml`.\n 2. String representation of the type (i.e. \"Foo(Bar bar) Bar(uint256 baz)\").\n * Note: the cheatcode will output the canonical type even if the input is malformated\n with the wrong order of elements or with extra whitespaces.",
- "declaration": "function eip712HashType(string memory typeNameOrDefinition) external pure returns (bytes32 typeHash);",
+ "declaration": "function eip712HashType(string calldata typeNameOrDefinition) external pure returns (bytes32 typeHash);",
"visibility": "external",
"mutability": "pure",
"signature": "eip712HashType(string)",
@@ -4318,7 +4318,7 @@
"func": {
"id": "eip712HashType_1",
"description": "Generates the hash of the canonical EIP-712 type representation.\nRequires previous binding generation with `forge bind-json`.\nParams:\n * `bindingsPath`: path where the output of `forge bind-json` is stored.\n * `typeName`: Name of the type (i.e. \"Transaction\").",
- "declaration": "function eip712HashType(string calldata bindingsPath, string memory typeName) external pure returns (bytes32 typeHash);",
+ "declaration": "function eip712HashType(string calldata bindingsPath, string calldata typeName) external pure returns (bytes32 typeHash);",
"visibility": "external",
"mutability": "pure",
"signature": "eip712HashType(string,string)",
diff --git a/crates/cheatcodes/spec/src/vm.rs b/crates/cheatcodes/spec/src/vm.rs
index 025311768e67c..f9ed82ee4550e 100644
--- a/crates/cheatcodes/spec/src/vm.rs
+++ b/crates/cheatcodes/spec/src/vm.rs
@@ -2900,7 +2900,7 @@ interface Vm {
/// * Note: the cheatcode will output the canonical type even if the input is malformated
/// with the wrong order of elements or with extra whitespaces.
#[cheatcode(group = Utilities)]
- function eip712HashType(string memory typeNameOrDefinition) external pure returns (bytes32 typeHash);
+ function eip712HashType(string calldata typeNameOrDefinition) external pure returns (bytes32 typeHash);
/// Generates the hash of the canonical EIP-712 type representation.
/// Requires previous binding generation with `forge bind-json`.
@@ -2909,7 +2909,7 @@ interface Vm {
/// * `bindingsPath`: path where the output of `forge bind-json` is stored.
/// * `typeName`: Name of the type (i.e. "Transaction").
#[cheatcode(group = Utilities)]
- function eip712HashType(string calldata bindingsPath, string memory typeName) external pure returns (bytes32 typeHash);
+ function eip712HashType(string calldata bindingsPath, string calldata typeName) external pure returns (bytes32 typeHash);
}
}
diff --git a/testdata/cheats/Vm.sol b/testdata/cheats/Vm.sol
index 6cbfa37b88d97..ac5928158b647 100644
--- a/testdata/cheats/Vm.sol
+++ b/testdata/cheats/Vm.sol
@@ -208,8 +208,8 @@ interface Vm {
function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index, string calldata language) external pure returns (uint256 privateKey);
function difficulty(uint256 newDifficulty) external;
function dumpState(string calldata pathToStateJson) external;
- function eip712HashType(string memory typeNameOrDefinition) external pure returns (bytes32 typeHash);
- function eip712HashType(string calldata bindingsPath, string memory typeName) external pure returns (bytes32 typeHash);
+ function eip712HashType(string calldata typeNameOrDefinition) external pure returns (bytes32 typeHash);
+ function eip712HashType(string calldata bindingsPath, string calldata typeName) external pure returns (bytes32 typeHash);
function ensNamehash(string calldata name) external pure returns (bytes32);
function envAddress(string calldata name) external view returns (address value);
function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value);
From 4b23502cb68226ce8650981f4d05d29659299bc9 Mon Sep 17 00:00:00 2001
From: 0xrusowsky <90208954+0xrusowsky@users.noreply.github.com>
Date: Thu, 29 May 2025 14:22:21 +0200
Subject: [PATCH 13/21] chore(forge): cheat eip712 struct hash (#10626)
---
crates/cheatcodes/assets/cheatcodes.json | 40 +++
crates/cheatcodes/spec/src/vm.rs | 23 ++
crates/cheatcodes/src/utils.rs | 97 ++++++--
crates/forge/tests/cli/test_cmd.rs | 303 +++++++++++++++++++++++
testdata/cheats/Vm.sol | 2 +
5 files changed, 451 insertions(+), 14 deletions(-)
diff --git a/crates/cheatcodes/assets/cheatcodes.json b/crates/cheatcodes/assets/cheatcodes.json
index e00c1f2125891..1cfbab6382cf5 100644
--- a/crates/cheatcodes/assets/cheatcodes.json
+++ b/crates/cheatcodes/assets/cheatcodes.json
@@ -4294,6 +4294,46 @@
"status": "stable",
"safety": "unsafe"
},
+ {
+ "func": {
+ "id": "eip712HashStruct_0",
+ "description": "Generates the struct hash of the canonical EIP-712 type representation and its abi-encoded data.\nSupports 2 different inputs:\n 1. Name of the type (i.e. \"PermitSingle\"):\n * requires previous binding generation with `forge bind-json`.\n * bindings will be retrieved from the path configured in `foundry.toml`.\n 2. String representation of the type (i.e. \"Foo(Bar bar) Bar(uint256 baz)\").\n * Note: the cheatcode will use the canonical type even if the input is malformated\n with the wrong order of elements or with extra whitespaces.",
+ "declaration": "function eip712HashStruct(string calldata typeNameOrDefinition, bytes calldata abiEncodedData) external pure returns (bytes32 typeHash);",
+ "visibility": "external",
+ "mutability": "pure",
+ "signature": "eip712HashStruct(string,bytes)",
+ "selector": "0xaedeaebc",
+ "selectorBytes": [
+ 174,
+ 222,
+ 174,
+ 188
+ ]
+ },
+ "group": "utilities",
+ "status": "stable",
+ "safety": "safe"
+ },
+ {
+ "func": {
+ "id": "eip712HashStruct_1",
+ "description": "Generates the struct hash of the canonical EIP-712 type representation and its abi-encoded data.\nRequires previous binding generation with `forge bind-json`.\nParams:\n * `bindingsPath`: path where the output of `forge bind-json` is stored.\n * `typeName`: Name of the type (i.e. \"PermitSingle\").\n * `abiEncodedData`: ABI-encoded data for the struct that is being hashed.",
+ "declaration": "function eip712HashStruct(string calldata bindingsPath, string calldata typeName, bytes calldata abiEncodedData) external pure returns (bytes32 typeHash);",
+ "visibility": "external",
+ "mutability": "pure",
+ "signature": "eip712HashStruct(string,string,bytes)",
+ "selector": "0x6d06c57c",
+ "selectorBytes": [
+ 109,
+ 6,
+ 197,
+ 124
+ ]
+ },
+ "group": "utilities",
+ "status": "stable",
+ "safety": "safe"
+ },
{
"func": {
"id": "eip712HashType_0",
diff --git a/crates/cheatcodes/spec/src/vm.rs b/crates/cheatcodes/spec/src/vm.rs
index f9ed82ee4550e..75efabfd53302 100644
--- a/crates/cheatcodes/spec/src/vm.rs
+++ b/crates/cheatcodes/spec/src/vm.rs
@@ -2910,6 +2910,29 @@ interface Vm {
/// * `typeName`: Name of the type (i.e. "Transaction").
#[cheatcode(group = Utilities)]
function eip712HashType(string calldata bindingsPath, string calldata typeName) external pure returns (bytes32 typeHash);
+
+ /// Generates the struct hash of the canonical EIP-712 type representation and its abi-encoded data.
+ ///
+ /// Supports 2 different inputs:
+ /// 1. Name of the type (i.e. "PermitSingle"):
+ /// * requires previous binding generation with `forge bind-json`.
+ /// * bindings will be retrieved from the path configured in `foundry.toml`.
+ ///
+ /// 2. String representation of the type (i.e. "Foo(Bar bar) Bar(uint256 baz)").
+ /// * Note: the cheatcode will use the canonical type even if the input is malformated
+ /// with the wrong order of elements or with extra whitespaces.
+ #[cheatcode(group = Utilities)]
+ function eip712HashStruct(string calldata typeNameOrDefinition, bytes calldata abiEncodedData) external pure returns (bytes32 typeHash);
+
+ /// Generates the struct hash of the canonical EIP-712 type representation and its abi-encoded data.
+ /// Requires previous binding generation with `forge bind-json`.
+ ///
+ /// Params:
+ /// * `bindingsPath`: path where the output of `forge bind-json` is stored.
+ /// * `typeName`: Name of the type (i.e. "PermitSingle").
+ /// * `abiEncodedData`: ABI-encoded data for the struct that is being hashed.
+ #[cheatcode(group = Utilities)]
+ function eip712HashStruct(string calldata bindingsPath, string calldata typeName, bytes calldata abiEncodedData) external pure returns (bytes32 typeHash);
}
}
diff --git a/crates/cheatcodes/src/utils.rs b/crates/cheatcodes/src/utils.rs
index 8f0ebb44f6293..8cc78a5d91057 100644
--- a/crates/cheatcodes/src/utils.rs
+++ b/crates/cheatcodes/src/utils.rs
@@ -1,8 +1,8 @@
//! Implementations of [`Utilities`](spec::Group::Utilities) cheatcodes.
use crate::{Cheatcode, Cheatcodes, CheatcodesExecutor, CheatsCtxt, Result, Vm::*};
-use alloy_dyn_abi::{eip712_parser::EncodeType, DynSolType, DynSolValue};
-use alloy_primitives::{aliases::B32, keccak256, map::HashMap, B64, U256};
+use alloy_dyn_abi::{eip712_parser::EncodeType, DynSolType, DynSolValue, Resolver};
+use alloy_primitives::{aliases::B32, keccak256, map::HashMap, Bytes, B64, U256};
use alloy_sol_types::SolValue;
use foundry_common::{ens::namehash, fs, TYPE_BINDING_PREFIX};
use foundry_config::fs_permissions::FsAccessKind;
@@ -321,16 +321,7 @@ impl Cheatcode for eip712HashType_0Call {
fn apply(&self, state: &mut Cheatcodes) -> Result {
let Self { typeNameOrDefinition } = self;
- let type_def = if typeNameOrDefinition.contains('(') {
- // If the input contains '(', it must be the type definition
- EncodeType::parse(typeNameOrDefinition).and_then(|parsed| parsed.canonicalize())?
- } else {
- // Otherwise, it must be the type name
- let path = state
- .config
- .ensure_path_allowed(&state.config.bind_json_path, FsAccessKind::Read)?;
- get_type_def_from_bindings(typeNameOrDefinition, path, &state.config.root)?
- };
+ let type_def = get_canonical_type_def(typeNameOrDefinition, state, None)?;
Ok(keccak256(type_def.as_bytes()).to_vec())
}
@@ -347,8 +338,49 @@ impl Cheatcode for eip712HashType_1Call {
}
}
-/// Gets the type definition from the bindings in the provided path. Assumes that read validation
-/// for the path has already been checked.
+impl Cheatcode for eip712HashStruct_0Call {
+ fn apply(&self, state: &mut Cheatcodes) -> Result {
+ let Self { typeNameOrDefinition, abiEncodedData } = self;
+
+ let type_def = get_canonical_type_def(typeNameOrDefinition, state, None)?;
+ let primary = &type_def[..type_def.find('(').unwrap_or(type_def.len())];
+
+ get_struct_hash(primary, &type_def, abiEncodedData)
+ }
+}
+
+impl Cheatcode for eip712HashStruct_1Call {
+ fn apply(&self, state: &mut Cheatcodes) -> Result {
+ let Self { bindingsPath, typeName, abiEncodedData } = self;
+
+ let path = state.config.ensure_path_allowed(bindingsPath, FsAccessKind::Read)?;
+ let type_def = get_type_def_from_bindings(typeName, path, &state.config.root)?;
+
+ get_struct_hash(typeName, &type_def, abiEncodedData)
+ }
+}
+
+fn get_canonical_type_def(
+ name_or_def: &String,
+ state: &mut Cheatcodes,
+ path: Option,
+) -> Result {
+ let type_def = if name_or_def.contains('(') {
+ // If the input contains '(', it must be the type definition
+ EncodeType::parse(name_or_def).and_then(|parsed| parsed.canonicalize())?
+ } else {
+ // Otherwise, it must be the type name
+ let path = path.as_ref().unwrap_or(&state.config.bind_json_path);
+ let path = state.config.ensure_path_allowed(path, FsAccessKind::Read)?;
+ get_type_def_from_bindings(name_or_def, path, &state.config.root)?
+ };
+
+ Ok(type_def)
+}
+
+/// Gets the type definition from the bindings in the provided path.
+///
+/// Assumes that read validation for the path has already been checked.
fn get_type_def_from_bindings(name: &String, path: PathBuf, root: &PathBuf) -> Result {
let content = fs::read_to_string(&path)?;
@@ -380,3 +412,40 @@ fn get_type_def_from_bindings(name: &String, path: PathBuf, root: &PathBuf) -> R
}
}
}
+
+fn get_struct_hash(primary: &str, type_def: &String, abi_encoded_data: &Bytes) -> Result {
+ let mut resolver = Resolver::default();
+
+ // Populate the resolver by ingesting the canonical type definition, and then get the
+ // corresponding `DynSolType` of the primary type.
+ resolver
+ .ingest_string(type_def)
+ .map_err(|e| fmt_err!("Resolver failed to ingest type definition: {e}"))?;
+
+ let resolved_sol_type = resolver
+ .resolve(primary)
+ .map_err(|e| fmt_err!("Failed to resolve EIP-712 primary type '{primary}': {e}"))?;
+
+ // ABI-decode the bytes into `DynSolValue::CustomStruct`.
+ let sol_value = resolved_sol_type.abi_decode(abi_encoded_data.as_ref()).map_err(|e| {
+ fmt_err!("Failed to ABI decode using resolved_sol_type directly for '{primary}': {e}.")
+ })?;
+
+ // Use the resolver to properly encode the data.
+ let encoded_data: Vec = resolver
+ .encode_data(&sol_value)
+ .map_err(|e| fmt_err!("Failed to EIP-712 encode data for struct '{primary}': {e}"))?
+ .ok_or_else(|| fmt_err!("EIP-712 data encoding returned 'None' for struct '{primary}'"))?;
+
+ // Compute the type hash of the primary type.
+ let type_hash = resolver
+ .type_hash(primary)
+ .map_err(|e| fmt_err!("Failed to compute typeHash for EIP712 type '{primary}': {e}"))?;
+
+ // Compute the struct hash of the concatenated type hash and encoded data.
+ let mut bytes_to_hash = Vec::with_capacity(32 + encoded_data.len());
+ bytes_to_hash.extend_from_slice(type_hash.as_slice());
+ bytes_to_hash.extend_from_slice(&encoded_data);
+
+ Ok(keccak256(&bytes_to_hash).to_vec())
+}
diff --git a/crates/forge/tests/cli/test_cmd.rs b/crates/forge/tests/cli/test_cmd.rs
index fba03905afd8c..c3c52d117a7c2 100644
--- a/crates/forge/tests/cli/test_cmd.rs
+++ b/crates/forge/tests/cli/test_cmd.rs
@@ -3883,3 +3883,306 @@ Encountered a total of 1 failing tests, 0 tests succeeded
])
.assert_success();
});
+
+forgetest!(test_eip712_hash_struct_simple, |prj, cmd| {
+ prj.insert_ds_test();
+ prj.insert_vm();
+ prj.insert_console();
+
+ prj.add_source(
+ "Eip712HashStructDomainTest.sol",
+ r#"
+import "./Vm.sol";
+import "./test.sol";
+import "./console.sol";
+
+struct EIP712Domain {
+ string name;
+ string version;
+ uint256 chainId;
+ address verifyingContract;
+}
+
+string constant _EIP712_DOMAIN_TYPE_DEF = "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)";
+bytes32 constant _EIP712_DOMAIN_TYPE_HASH = keccak256(bytes(_EIP712_DOMAIN_TYPE_DEF));
+
+contract Eip712HashStructDomainTest is DSTest {
+ Vm constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code")))));
+
+ function testHashEIP712Domain() public {
+ EIP712Domain memory domain = EIP712Domain({
+ name: "Foo",
+ version: "Bar",
+ chainId: 1,
+ verifyingContract: 0xdEADBEeF00000000000000000000000000000000
+ });
+
+ // simulate user-computed domain hash
+ bytes memory encodedData = abi.encode(
+ keccak256(bytes(domain.name)),
+ keccak256(bytes(domain.version)),
+ bytes32(domain.chainId),
+ bytes32(uint256(uint160(domain.verifyingContract)))
+ );
+ bytes32 userStructHash = keccak256(abi.encodePacked(_EIP712_DOMAIN_TYPE_HASH, encodedData));
+
+ // cheatcode-computed domain hash
+ bytes32 cheatStructHash = vm.eip712HashStruct(_EIP712_DOMAIN_TYPE_DEF, abi.encode(domain));
+ console.log("EIP712Domain struct hash from cheatcode:");
+ console.logBytes32(cheatStructHash);
+
+ assertEq(cheatStructHash, userStructHash, "EIP712Domain struct hash mismatch");
+ }
+}
+"#,
+ )
+ .unwrap();
+
+ cmd.forge_fuse().args(["test", "--mc", "Eip712HashStructDomainTest", "-vvvv"]).assert_success();
+});
+
+forgetest!(test_eip712_hash_struct_complex, |prj, cmd| {
+ prj.add_source(
+ "Eip712Permit.sol",
+ r#"
+struct PermitDetails {
+ address token;
+ uint160 amount;
+ uint48 expiration;
+ uint48 nonce;
+}
+
+bytes32 constant _PERMIT_DETAILS_TYPEHASH = keccak256(
+ "PermitDetails(address token,uint160 amount,uint48 expiration,uint48 nonce)"
+);
+
+struct PermitSingle {
+ PermitDetails details;
+ address spender;
+ uint256 sigDeadline;
+}
+
+bytes32 constant _PERMIT_SINGLE_TYPEHASH = keccak256(
+ "PermitSingle(PermitDetails details,address spender,uint256 sigDeadline)PermitDetails(address token,uint160 amount,uint48 expiration,uint48 nonce)"
+);
+
+// borrowed from https://github.com/Uniswap/permit2/blob/main/src/libraries/PermitHash.sol
+library PermitHash {
+ function hash(PermitSingle memory permitSingle) internal pure returns (bytes32) {
+ bytes32 permitHash = _hashDetails(permitSingle.details);
+ return
+ keccak256(abi.encode(_PERMIT_SINGLE_TYPEHASH, permitHash, permitSingle.spender, permitSingle.sigDeadline));
+ }
+
+ function _hashDetails(PermitDetails memory details) internal pure returns (bytes32) {
+ return keccak256(abi.encode(_PERMIT_DETAILS_TYPEHASH, details));
+ }
+}
+"#,
+ )
+ .unwrap();
+
+ prj.add_source(
+ "Eip712Transaction.sol",
+ r#"
+struct Asset {
+ address token;
+ uint256 amount;
+}
+
+bytes32 constant _ASSET_TYPEHASH = keccak256(
+ "Asset(address token,uint256 amount)"
+);
+
+struct Person {
+ address wallet;
+ string name;
+}
+
+bytes32 constant _PERSON_TYPEHASH = keccak256(
+ "Person(address wallet,string name)"
+);
+
+struct Transaction {
+ Person from;
+ Person to;
+ Asset tx;
+}
+
+bytes32 constant _TRANSACTION_TYPEHASH = keccak256(
+ "Transaction(Person from,Person to,Asset tx)Asset(address token,uint256 amount)Person(address wallet,string name)"
+);
+
+
+library TransactionHash {
+ function hash(Transaction memory t) internal pure returns (bytes32) {
+ bytes32 fromHash = _hashPerson(t.from);
+ bytes32 toHash = _hashPerson(t.to);
+ bytes32 assetHash = _hashAsset(t.tx);
+ return
+ keccak256(abi.encode(_TRANSACTION_TYPEHASH, fromHash, toHash, assetHash));
+ }
+
+ function _hashPerson(Person memory person) internal pure returns (bytes32) {
+ return keccak256(
+ abi.encode(_PERSON_TYPEHASH, person.wallet, keccak256(bytes(person.name)))
+ );
+
+ }
+
+ function _hashAsset(Asset memory asset) internal pure returns (bytes32) {
+ return keccak256(abi.encode(_ASSET_TYPEHASH, asset));
+ }
+}
+ "#,
+ )
+ .unwrap();
+
+ let bindings = prj.root().join("utils").join("JsonBindings.sol");
+ prj.update_config(|config| config.fs_permissions.add(PathPermission::read(&bindings)));
+ cmd.forge_fuse().args(["bind-json"]).assert_success();
+
+ prj.insert_ds_test();
+ prj.insert_vm();
+ prj.insert_console();
+ prj.add_source(
+ "Eip712HashStructTest.sol",
+ r#"
+import "./Vm.sol";
+import "./test.sol";
+import "./console.sol";
+import "./Eip712Permit.sol";
+import "./Eip712Transaction.sol";
+
+contract Eip712HashStructTest is DSTest {
+ Vm constant vm = Vm(HEVM_ADDRESS);
+
+ function testHashPermitSingle_withTypeName() public {
+ PermitDetails memory details = PermitDetails({
+ token: 0x1111111111111111111111111111111111111111,
+ amount: 1000 ether,
+ expiration: 12345,
+ nonce: 1
+ });
+
+ // user-computed permit (using uniswap hash library)
+ bytes32 userStructHash = PermitHash._hashDetails(details);
+
+ // cheatcode-computed permit
+ bytes32 cheatStructHash = vm.eip712HashStruct("PermitDetails", abi.encode(details));
+
+ assertEq(cheatStructHash, userStructHash, "details struct hash mismatch");
+
+ PermitSingle memory permit = PermitSingle({
+ details: details,
+ spender: 0x2222222222222222222222222222222222222222,
+ sigDeadline: 12345
+ });
+
+ // user-computed permit (using uniswap hash library)
+ userStructHash = PermitHash.hash(permit);
+
+ // cheatcode-computed permit
+ cheatStructHash = vm.eip712HashStruct("PermitSingle", abi.encode(permit));
+ console.log("PermitSingle struct hash from cheatcode:");
+ console.logBytes32(cheatStructHash);
+
+ assertEq(cheatStructHash, userStructHash, "permit struct hash mismatch");
+ }
+
+ function testHashPermitSingle_withTypeDefinion() public {
+ PermitDetails memory details = PermitDetails({
+ token: 0x1111111111111111111111111111111111111111,
+ amount: 1000 ether,
+ expiration: 12345,
+ nonce: 1
+ });
+
+ // user-computed permit (using uniswap hash library)
+ bytes32 userStructHash = PermitHash._hashDetails(details);
+
+ // cheatcode-computed permit
+ bytes32 cheatStructHash = vm.eip712HashStruct("PermitDetails(address token, uint160 amount, uint48 expiration, uint48 nonce)", abi.encode(details));
+
+ assertEq(cheatStructHash, userStructHash, "details struct hash mismatch");
+
+ PermitSingle memory permit = PermitSingle({
+ details: details,
+ spender: 0x2222222222222222222222222222222222222222,
+ sigDeadline: 12345
+ });
+
+ // user-computed permit (using uniswap hash library)
+ userStructHash = PermitHash.hash(permit);
+
+ // cheatcode-computed permit (previously encoding)
+ cheatStructHash = vm.eip712HashStruct("PermitDetails(address token, uint160 amount, uint48 expiration, uint48 nonce) PermitSingle(PermitDetails details,address spender,uint256 sigDeadline)", abi.encode(permit));
+ console.log("PermitSingle struct hash from cheatcode:");
+ console.logBytes32(cheatStructHash);
+
+ assertEq(cheatStructHash, userStructHash, "permit struct hash mismatch");
+ }
+
+ function testHashTransaction_withTypeName() public {
+ Asset memory asset = Asset ({ token: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, amount: 100 ether });
+
+ bytes32 user = TransactionHash._hashAsset(asset);
+ bytes32 cheat = vm.eip712HashStruct("Asset", abi.encode(asset));
+ assertEq(user, cheat, "asset struct hash mismatch");
+
+ Person memory from = Person ({ wallet: 0x0000000000000000000000000000000000000001, name: "alice" });
+ Person memory to = Person ({ wallet: 0x0000000000000000000000000000000000000002, name: "bob" });
+
+ user = TransactionHash._hashPerson(from);
+ cheat = vm.eip712HashStruct("Person", abi.encode(from));
+ assertEq(user, cheat, "person struct hash mismatch");
+
+ Transaction memory t = Transaction ({ from: from, to: to, tx: asset });
+
+ user = TransactionHash.hash(t);
+ cheat = vm.eip712HashStruct("Transaction", abi.encode(t));
+ assertEq(user, cheat, "transaction struct hash mismatch");
+ }
+
+ function testHashTransaction_withTypeDefinition() public {
+ Asset memory asset = Asset ({ token: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, amount: 100 ether });
+
+ bytes32 user = TransactionHash._hashAsset(asset);
+ bytes32 cheat = vm.eip712HashStruct("Asset(address token, uint256 amount)", abi.encode(asset));
+ assertEq(user, cheat, "asset struct hash mismatch");
+
+ Person memory from = Person ({ wallet: 0x0000000000000000000000000000000000000001, name: "alice" });
+ Person memory to = Person ({ wallet: 0x0000000000000000000000000000000000000002, name: "bob" });
+
+ user = TransactionHash._hashPerson(from);
+ cheat = vm.eip712HashStruct("Person(address wallet, string name)", abi.encode(from));
+ assertEq(user, cheat, "person struct hash mismatch");
+
+ Transaction memory t = Transaction ({ from: from, to: to, tx: asset });
+
+ user = TransactionHash.hash(t);
+ cheat = vm.eip712HashStruct("Person(address wallet, string name) Asset(address token, uint256 amount) Transaction(Person from, Person to, Asset tx)", abi.encode(t));
+ assertEq(user, cheat, "transaction struct hash mismatch");
+ }
+}
+"#,
+ )
+ .unwrap();
+
+ cmd.forge_fuse()
+ .args(["test", "--mc", "Eip712HashStructTest", "-vv"])
+ .assert_success()
+ .stdout_eq(str![[r#"
+...
+[PASS] testHashPermitSingle_withTypeDefinion() ([GAS])
+Logs:
+ PermitSingle struct hash from cheatcode:
+ 0x3ed744fdcea02b6b9ad45a9db6e648bf6f18c221909f9ee425191f2a02f9e4a8
+
+[PASS] testHashPermitSingle_withTypeName() ([GAS])
+Logs:
+ PermitSingle struct hash from cheatcode:
+ 0x3ed744fdcea02b6b9ad45a9db6e648bf6f18c221909f9ee425191f2a02f9e4a8
+...
+"#]]);
+});
diff --git a/testdata/cheats/Vm.sol b/testdata/cheats/Vm.sol
index ac5928158b647..9a62a45254576 100644
--- a/testdata/cheats/Vm.sol
+++ b/testdata/cheats/Vm.sol
@@ -208,6 +208,8 @@ interface Vm {
function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index, string calldata language) external pure returns (uint256 privateKey);
function difficulty(uint256 newDifficulty) external;
function dumpState(string calldata pathToStateJson) external;
+ function eip712HashStruct(string calldata typeNameOrDefinition, bytes calldata abiEncodedData) external pure returns (bytes32 typeHash);
+ function eip712HashStruct(string calldata bindingsPath, string calldata typeName, bytes calldata abiEncodedData) external pure returns (bytes32 typeHash);
function eip712HashType(string calldata typeNameOrDefinition) external pure returns (bytes32 typeHash);
function eip712HashType(string calldata bindingsPath, string calldata typeName) external pure returns (bytes32 typeHash);
function ensNamehash(string calldata name) external pure returns (bytes32);
From 876b7ba9ceaffa4629ef5f27af86fc22dd64c323 Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Thu, 29 May 2025 11:22:24 -0500
Subject: [PATCH 14/21] new cheat: eip712 hash typed data
---
crates/cheatcodes/assets/cheatcodes.json | 20 +++++++++++++++
crates/cheatcodes/spec/src/vm.rs | 4 +++
crates/cheatcodes/src/utils.rs | 12 ++++++++-
crates/forge/tests/cli/test_cmd.rs | 31 ++++++++++++++++++++++++
testdata/cheats/Vm.sol | 1 +
5 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/crates/cheatcodes/assets/cheatcodes.json b/crates/cheatcodes/assets/cheatcodes.json
index 1cfbab6382cf5..f1d2b617e3a5f 100644
--- a/crates/cheatcodes/assets/cheatcodes.json
+++ b/crates/cheatcodes/assets/cheatcodes.json
@@ -4374,6 +4374,26 @@
"status": "stable",
"safety": "safe"
},
+ {
+ "func": {
+ "id": "eip712HashTypedData",
+ "description": "Generates a ready-to-sign digest of human-readable typed data following the EIP-712 standard.",
+ "declaration": "function eip712HashTypedData(string calldata jsonData) external pure returns (bytes32 digest);",
+ "visibility": "external",
+ "mutability": "pure",
+ "signature": "eip712HashTypedData(string)",
+ "selector": "0xea25e615",
+ "selectorBytes": [
+ 234,
+ 37,
+ 230,
+ 21
+ ]
+ },
+ "group": "utilities",
+ "status": "stable",
+ "safety": "safe"
+ },
{
"func": {
"id": "ensNamehash",
diff --git a/crates/cheatcodes/spec/src/vm.rs b/crates/cheatcodes/spec/src/vm.rs
index 75efabfd53302..a734c7a033ef1 100644
--- a/crates/cheatcodes/spec/src/vm.rs
+++ b/crates/cheatcodes/spec/src/vm.rs
@@ -2933,6 +2933,10 @@ interface Vm {
/// * `abiEncodedData`: ABI-encoded data for the struct that is being hashed.
#[cheatcode(group = Utilities)]
function eip712HashStruct(string calldata bindingsPath, string calldata typeName, bytes calldata abiEncodedData) external pure returns (bytes32 typeHash);
+
+ /// Generates a ready-to-sign digest of human-readable typed data following the EIP-712 standard.
+ #[cheatcode(group = Utilities)]
+ function eip712HashTypedData(string calldata jsonData) external pure returns (bytes32 digest);
}
}
diff --git a/crates/cheatcodes/src/utils.rs b/crates/cheatcodes/src/utils.rs
index 8cc78a5d91057..dcdbc5497921c 100644
--- a/crates/cheatcodes/src/utils.rs
+++ b/crates/cheatcodes/src/utils.rs
@@ -1,7 +1,7 @@
//! Implementations of [`Utilities`](spec::Group::Utilities) cheatcodes.
use crate::{Cheatcode, Cheatcodes, CheatcodesExecutor, CheatsCtxt, Result, Vm::*};
-use alloy_dyn_abi::{eip712_parser::EncodeType, DynSolType, DynSolValue, Resolver};
+use alloy_dyn_abi::{eip712_parser::EncodeType, DynSolType, DynSolValue, Resolver, TypedData};
use alloy_primitives::{aliases::B32, keccak256, map::HashMap, Bytes, B64, U256};
use alloy_sol_types::SolValue;
use foundry_common::{ens::namehash, fs, TYPE_BINDING_PREFIX};
@@ -360,6 +360,16 @@ impl Cheatcode for eip712HashStruct_1Call {
}
}
+impl Cheatcode for eip712HashTypedDataCall {
+ fn apply(&self, _state: &mut Cheatcodes) -> Result {
+ let Self { jsonData } = self;
+ let typed_data: TypedData = serde_json::from_str(jsonData)?;
+ let digest = typed_data.eip712_signing_hash()?;
+
+ Ok(digest.to_vec())
+ }
+}
+
fn get_canonical_type_def(
name_or_def: &String,
state: &mut Cheatcodes,
diff --git a/crates/forge/tests/cli/test_cmd.rs b/crates/forge/tests/cli/test_cmd.rs
index c3c52d117a7c2..a36742266251a 100644
--- a/crates/forge/tests/cli/test_cmd.rs
+++ b/crates/forge/tests/cli/test_cmd.rs
@@ -4186,3 +4186,34 @@ Logs:
...
"#]]);
});
+
+forgetest!(test_eip712_hash_typed_data, |prj, cmd| {
+ prj.insert_ds_test();
+ prj.insert_vm();
+ prj.insert_console();
+
+ prj.add_source(
+ "Eip712HashTypedData.sol",
+ r#"
+import "./Vm.sol";
+import "./test.sol";
+import "./console.sol";
+contract Eip712HashTypedDataTest is DSTest {
+ Vm constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code")))));
+
+ function testHashEIP712Message() public {
+ string memory jsonData =
+ '{"types":{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"},{"name":"salt","type":"bytes32"}]},"primaryType":"EIP712Domain","domain":{"name":"example.metamask.io","version":"1","chainId":1,"verifyingContract":"0x0000000000000000000000000000000000000000"},"message":{}}';
+
+ // since this cheatcode simply exposes an alloy fn, the test has been borrowed from:
+ //
+ bytes32 expectedHash = hex"122d1c8ef94b76dad44dcb03fa772361e20855c63311a15d5afe02d1b38f6077";
+ assertEq(vm.eip712HashTypedData(jsonData), expectedHash, "EIP712Domain struct hash mismatch");
+ }
+}
+"#,
+ )
+ .unwrap();
+
+ cmd.forge_fuse().args(["test", "--mc", "Eip712HashTypedDataTest"]).assert_success();
+});
diff --git a/testdata/cheats/Vm.sol b/testdata/cheats/Vm.sol
index 9a62a45254576..b439cf9b6f883 100644
--- a/testdata/cheats/Vm.sol
+++ b/testdata/cheats/Vm.sol
@@ -212,6 +212,7 @@ interface Vm {
function eip712HashStruct(string calldata bindingsPath, string calldata typeName, bytes calldata abiEncodedData) external pure returns (bytes32 typeHash);
function eip712HashType(string calldata typeNameOrDefinition) external pure returns (bytes32 typeHash);
function eip712HashType(string calldata bindingsPath, string calldata typeName) external pure returns (bytes32 typeHash);
+ function eip712HashTypedData(string calldata jsonData) external pure returns (bytes32 digest);
function ensNamehash(string calldata name) external pure returns (bytes32);
function envAddress(string calldata name) external view returns (address value);
function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value);
From f8dddb6b0eae2c8a2f972b3cba34aa8a0451db46 Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Thu, 29 May 2025 12:14:22 -0500
Subject: [PATCH 15/21] bump solar and compilers
---
Cargo.lock | 59 ++++++++++++++++++++++++++++++------------------------
Cargo.toml | 13 ++++--------
2 files changed, 37 insertions(+), 35 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index b63184bd63615..b06a7b9b8542b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4303,9 +4303,9 @@ dependencies = [
[[package]]
name = "foundry-compilers"
-version = "0.16.1"
+version = "0.16.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d6154e503612a175a88ff342592f0a44664dda54a508d9443121b62b1701f91"
+checksum = "fe41ab4be8c70e139241dfa4c8b4f30f905a1c92fa13123255e2eeedc5ffa63d"
dependencies = [
"alloy-json-abi 1.1.2",
"alloy-primitives 1.1.2",
@@ -4340,9 +4340,9 @@ dependencies = [
[[package]]
name = "foundry-compilers-artifacts"
-version = "0.16.1"
+version = "0.16.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "efca59ffe52914a8ff4ae4e8e97e9fa5d782031d2f5a2d1fb109fa6aac26653d"
+checksum = "afd39a92e4cf1ea15b283a8ad2c55af4ec05f5f9334601d62afd1a05abe78e84"
dependencies = [
"foundry-compilers-artifacts-solc",
"foundry-compilers-artifacts-vyper",
@@ -4350,9 +4350,9 @@ dependencies = [
[[package]]
name = "foundry-compilers-artifacts-solc"
-version = "0.16.1"
+version = "0.16.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a3ffc93f94d2c4ae0ff0f7a12cdeaa5fbb043ced0c558cabd05631e32ac508a"
+checksum = "5a3999266fe758acc25725f649d964c7ddf77b38fd00ac9423b74e65901c687d"
dependencies = [
"alloy-json-abi 1.1.2",
"alloy-primitives 1.1.2",
@@ -4373,9 +4373,9 @@ dependencies = [
[[package]]
name = "foundry-compilers-artifacts-vyper"
-version = "0.16.1"
+version = "0.16.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f077777aa33f933f9f01e90f9ed78e4a40ed60a6380798b528681ca9519a577"
+checksum = "b1b7b83ebff9bdb25b35070152169a6ea720d21b7d201debf527b4b11569ea62"
dependencies = [
"alloy-json-abi 1.1.2",
"alloy-primitives 1.1.2",
@@ -4388,9 +4388,9 @@ dependencies = [
[[package]]
name = "foundry-compilers-core"
-version = "0.16.1"
+version = "0.16.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ff92d5831075077fe64391dcbbe4a1518bce0439f97ab6a940fa1b9c1f3eaa2"
+checksum = "80f3bb9ac0bc9f509b3ed080092b4c0e8fa1ff58243d89454e96fa0cc4599d1e"
dependencies = [
"alloy-primitives 1.1.2",
"cfg-if",
@@ -8598,8 +8598,9 @@ dependencies = [
[[package]]
name = "solar-ast"
-version = "0.1.3"
-source = "git+https://github.com/paradigmxyz/solar.git?branch=dani%2Fresolver-absolute-paths#97e8dd947e20b5530edbad1422393ef9ca5678d2"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acb0d9abd88c1325e5c0f9bb153ebfb02ed40bc9639067d0ad120f5d29ee8777"
dependencies = [
"alloy-primitives 1.1.2",
"bumpalo",
@@ -8616,16 +8617,18 @@ dependencies = [
[[package]]
name = "solar-config"
-version = "0.1.3"
-source = "git+https://github.com/paradigmxyz/solar.git?branch=dani%2Fresolver-absolute-paths#97e8dd947e20b5530edbad1422393ef9ca5678d2"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "908d455bb7c04acd783bd157b63791bf010cf6a495a845e48f7aee334aad319f"
dependencies = [
"strum 0.27.1",
]
[[package]]
name = "solar-data-structures"
-version = "0.1.3"
-source = "git+https://github.com/paradigmxyz/solar.git?branch=dani%2Fresolver-absolute-paths#97e8dd947e20b5530edbad1422393ef9ca5678d2"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8b5a697cab81241c4623b4546c69e57182202847a75d7c0047c0dd10b923d8c"
dependencies = [
"bumpalo",
"index_vec",
@@ -8638,8 +8641,9 @@ dependencies = [
[[package]]
name = "solar-interface"
-version = "0.1.3"
-source = "git+https://github.com/paradigmxyz/solar.git?branch=dani%2Fresolver-absolute-paths#97e8dd947e20b5530edbad1422393ef9ca5678d2"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33e49e5a714ec80d7f9c8942584e5e86add1c5e824aa175d0681e9ac7a10e5cc"
dependencies = [
"annotate-snippets",
"anstream",
@@ -8648,7 +8652,7 @@ dependencies = [
"derive_builder",
"derive_more 2.0.1",
"dunce",
- "itertools 0.10.5",
+ "itertools 0.14.0",
"itoa",
"lasso",
"match_cfg",
@@ -8665,8 +8669,9 @@ dependencies = [
[[package]]
name = "solar-macros"
-version = "0.1.3"
-source = "git+https://github.com/paradigmxyz/solar.git?branch=dani%2Fresolver-absolute-paths#97e8dd947e20b5530edbad1422393ef9ca5678d2"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e17f8b99f28f358b41acb6efe4d7b8f326541b3c58a15dd1931d6fe581feefef"
dependencies = [
"proc-macro2",
"quote",
@@ -8675,13 +8680,14 @@ dependencies = [
[[package]]
name = "solar-parse"
-version = "0.1.3"
-source = "git+https://github.com/paradigmxyz/solar.git?branch=dani%2Fresolver-absolute-paths#97e8dd947e20b5530edbad1422393ef9ca5678d2"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6982ef2ecfb1338c774c743ab7166ce8c3dcc92089ab77fad58eeb632b201e9"
dependencies = [
"alloy-primitives 1.1.2",
"bitflags 2.9.1",
"bumpalo",
- "itertools 0.10.5",
+ "itertools 0.14.0",
"memchr",
"num-bigint",
"num-rational",
@@ -8695,8 +8701,9 @@ dependencies = [
[[package]]
name = "solar-sema"
-version = "0.1.3"
-source = "git+https://github.com/paradigmxyz/solar.git?branch=dani%2Fresolver-absolute-paths#97e8dd947e20b5530edbad1422393ef9ca5678d2"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe8e0a3a6dfc7f4987bfb93f9b56079150407ef55c459964a1541c669554b74d"
dependencies = [
"alloy-json-abi 1.1.2",
"alloy-primitives 1.1.2",
diff --git a/Cargo.toml b/Cargo.toml
index 615f85eadfeb8..fdefa17aad45f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -197,12 +197,12 @@ foundry-linking = { path = "crates/linking" }
# solc & compilation utilities
foundry-block-explorers = { version = "0.17.0", default-features = false }
-foundry-compilers = { version = "0.16.1", default-features = false }
+foundry-compilers = { version = "0.16.4", default-features = false }
foundry-fork-db = "0.14"
solang-parser = { version = "=0.3.8", package = "foundry-solang-parser" }
-solar-parse = { version = "=0.1.3", default-features = false }
-solar-sema = { version = "=0.1.3", default-features = false }
-solar-interface = { version = "=0.1.3", default-features = false }
+solar-parse = { version = "=0.1.4", default-features = false }
+solar-sema = { version = "=0.1.4", default-features = false }
+solar-interface = { version = "=0.1.4", default-features = false }
## alloy
alloy-consensus = { version = "1.0.5", default-features = false }
@@ -392,10 +392,5 @@ revm = { git = "https://github.com/bluealloy/revm.git", rev = "b5808253" }
op-revm = { git = "https://github.com/bluealloy/revm.git", rev = "b5808253" }
# revm-inspectors = { git = "https://github.com/paradigmxyz/revm-inspectors.git", rev = "a625c04" }
-## solar
-solar-parse = { git = "https://github.com/paradigmxyz/solar.git", branch = "dani/resolver-absolute-paths" }
-solar-sema = { git = "https://github.com/paradigmxyz/solar.git", branch = "dani/resolver-absolute-paths" }
-solar-interface = { git = "https://github.com/paradigmxyz/solar.git", branch = "dani/resolver-absolute-paths" }
-
## foundry
# foundry-fork-db = { git = "https://github.com/foundry-rs/foundry-fork-db", rev = "811a61a" }
From 2c0780894f9dd5babb1a0cef1814fec3a8d39dc4 Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Thu, 29 May 2025 12:31:59 -0500
Subject: [PATCH 16/21] fix: failing compiler test
---
crates/forge/tests/cli/compiler.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/crates/forge/tests/cli/compiler.rs b/crates/forge/tests/cli/compiler.rs
index 0b58221f2a1d0..ae07aec6d0225 100644
--- a/crates/forge/tests/cli/compiler.rs
+++ b/crates/forge/tests/cli/compiler.rs
@@ -242,7 +242,7 @@ Solidity:
Vyper:
-0.4.0 (<= cancun):
+0.4.0 (<= prague):
├── src/Counter.vy
└── src/ICounter.vyi
From cac75c3618c4c033ba43a29b40a2a5c9422da86f Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Thu, 29 May 2025 13:40:43 -0500
Subject: [PATCH 17/21] bump compiler and explorers + patch vyper prague ->
cancun
---
Cargo.lock | 438 +++++++++++++++--------------
Cargo.toml | 4 +-
crates/forge/src/cmd/compiler.rs | 6 +
crates/forge/tests/cli/compiler.rs | 2 +-
4 files changed, 240 insertions(+), 210 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index b06a7b9b8542b..ffb91c44d1464 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -58,9 +58,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "alloy-chains"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5848366a4f08dca1caca0a6151294a4799fe2e59ba25df100491d92e0b921b1c"
+checksum = "517e5acbd38b6d4c59da380e8bbadc6d365bf001903ce46cf5521c53c647e07b"
dependencies = [
"alloy-primitives 1.1.2",
"num_enum",
@@ -70,14 +70,14 @@ dependencies = [
[[package]]
name = "alloy-consensus"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e9835a7b6216cb8118323581e58a18b1a5014fce55ce718635aaea7fa07bd700"
+checksum = "ad451f9a70c341d951bca4e811d74dbe1e193897acd17e9dbac1353698cc430b"
dependencies = [
- "alloy-eips 1.0.5",
+ "alloy-eips 1.0.9",
"alloy-primitives 1.1.2",
"alloy-rlp",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"alloy-trie",
"auto_impl",
"c-kzg",
@@ -94,23 +94,23 @@ dependencies = [
[[package]]
name = "alloy-consensus-any"
-version = "1.0.4"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aec7fdaa4f0e4e1ca7e9271ca7887fdd467ca3b9e101582dc6c2bbd1645eae1c"
+checksum = "142daffb15d5be1a2b20d2cd540edbcef03037b55d4ff69dc06beb4d06286dba"
dependencies = [
"alloy-consensus",
- "alloy-eips 1.0.5",
+ "alloy-eips 1.0.9",
"alloy-primitives 1.1.2",
"alloy-rlp",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"serde",
]
[[package]]
name = "alloy-contract"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e810f27a4162190b50cdf4dabedee3ad9028772bd7e370fdfc0f63b8bc116d3"
+checksum = "ebf25443920ecb9728cb087fe4dc04a0b290bd6ac85638c58fe94aba70f1a44e"
dependencies = [
"alloy-consensus",
"alloy-dyn-abi 1.1.2",
@@ -224,16 +224,16 @@ dependencies = [
[[package]]
name = "alloy-eips"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90fc566136b705991072f8f79762525e14f0ca39c38d45b034944770cb6c6b67"
+checksum = "3056872f6da48046913e76edb5ddced272861f6032f09461aea1a2497be5ae5d"
dependencies = [
"alloy-eip2124",
"alloy-eip2930",
"alloy-eip7702",
"alloy-primitives 1.1.2",
"alloy-rlp",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"auto_impl",
"c-kzg",
"derive_more 2.0.1",
@@ -249,7 +249,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de0210f2d5854895b376f7fbbf78f3e33eb4f0e59abc503502cc0ed8d295a837"
dependencies = [
"alloy-consensus",
- "alloy-eips 1.0.5",
+ "alloy-eips 1.0.9",
"alloy-hardforks",
"alloy-primitives 1.1.2",
"alloy-sol-types 1.1.2",
@@ -263,22 +263,22 @@ dependencies = [
[[package]]
name = "alloy-genesis"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "765c0124a3174f136171df8498e4700266774c9de1008a0b987766cf215d08f6"
+checksum = "c98fb40f07997529235cc474de814cd7bd9de561e101716289095696c0e4639d"
dependencies = [
- "alloy-eips 1.0.5",
+ "alloy-eips 1.0.9",
"alloy-primitives 1.1.2",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"alloy-trie",
"serde",
]
[[package]]
name = "alloy-hardforks"
-version = "0.2.2"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b40cc82a2283e3ce6317bc1f0134ea50d20e8c1965393045ee952fb28a65ddbd"
+checksum = "fbff8445282ec080c2673692062bd4930d7a0d6bda257caf138cfc650c503000"
dependencies = [
"alloy-chains",
"alloy-eip2124",
@@ -313,9 +313,9 @@ dependencies = [
[[package]]
name = "alloy-json-rpc"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1590f44abdfe98686827a4e083b711ad17f843bf6ed8a50b78d3242f12a00ada"
+checksum = "dc08b31ebf9273839bd9a01f9333cbb7a3abb4e820c312ade349dd18bdc79581"
dependencies = [
"alloy-primitives 1.1.2",
"alloy-sol-types 1.1.2",
@@ -327,19 +327,19 @@ dependencies = [
[[package]]
name = "alloy-network"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "049a9022caa0c0a2dcd2bc2ea23fa098508f4a81d5dda774d753570a41e6acdb"
+checksum = "ed117b08f0cc190312bf0c38c34cf4f0dabfb4ea8f330071c587cd7160a88cb2"
dependencies = [
"alloy-consensus",
"alloy-consensus-any",
- "alloy-eips 1.0.5",
+ "alloy-eips 1.0.9",
"alloy-json-rpc",
"alloy-network-primitives",
"alloy-primitives 1.1.2",
"alloy-rpc-types-any",
"alloy-rpc-types-eth",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"alloy-signer",
"alloy-sol-types 1.1.2",
"async-trait",
@@ -353,14 +353,14 @@ dependencies = [
[[package]]
name = "alloy-network-primitives"
-version = "1.0.4"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5630ce8552579d1393383b27fe4bfe7c700fb7480189a82fc054da24521947aa"
+checksum = "c7162ff7be8649c0c391f4e248d1273e85c62076703a1f3ec7daf76b283d886d"
dependencies = [
"alloy-consensus",
- "alloy-eips 1.0.5",
+ "alloy-eips 1.0.9",
"alloy-primitives 1.1.2",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"serde",
]
@@ -371,7 +371,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee0165cc5f92d8866c0a21320ee6f089a7e1d0cebbf7008c37a6380a912ebe2"
dependencies = [
"alloy-consensus",
- "alloy-eips 1.0.5",
+ "alloy-eips 1.0.9",
"alloy-evm",
"alloy-op-hardforks",
"alloy-primitives 1.1.2",
@@ -383,9 +383,9 @@ dependencies = [
[[package]]
name = "alloy-op-hardforks"
-version = "0.2.2"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a79617217008626a24fb52b02d532bf4554ac9b184a2d22bd6c5df628c151601"
+checksum = "9ddfbb5cc9f614efa5d56e0d7226214bb67b29271d44b6ddfcbbe25eb0ff898b"
dependencies = [
"alloy-hardforks",
"auto_impl",
@@ -451,13 +451,13 @@ dependencies = [
[[package]]
name = "alloy-provider"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "959aedfc417737e2a59961c95e92c59726386748d85ef516a0d0687b440d3184"
+checksum = "d84eba1fd8b6fe8b02f2acd5dd7033d0f179e304bd722d11e817db570d1fa6c4"
dependencies = [
"alloy-chains",
"alloy-consensus",
- "alloy-eips 1.0.5",
+ "alloy-eips 1.0.9",
"alloy-json-rpc",
"alloy-network",
"alloy-network-primitives",
@@ -496,9 +496,9 @@ dependencies = [
[[package]]
name = "alloy-pubsub"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf694cd1494284e73e23b62568bb5df6777f99eaec6c0a4705ac5a5c61707208"
+checksum = "8550f7306e0230fc835eb2ff4af0a96362db4b6fc3f25767d161e0ad0ac765bf"
dependencies = [
"alloy-json-rpc",
"alloy-primitives 1.1.2",
@@ -539,9 +539,9 @@ dependencies = [
[[package]]
name = "alloy-rpc-client"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f20436220214938c4fe223244f00fbd618dda80572b8ffe7839d382a6c54f1c"
+checksum = "518a699422a3eab800f3dac2130d8f2edba8e4fff267b27a9c7dc6a2b0d313ee"
dependencies = [
"alloy-json-rpc",
"alloy-primitives 1.1.2",
@@ -567,9 +567,9 @@ dependencies = [
[[package]]
name = "alloy-rpc-types"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88d2981f41486264b2e254bc51b2691bbef9ed87d0545d11f31cb26af3109cc4"
+checksum = "c000cab4ec26a4b3e29d144e999e1c539c2fa0abed871bf90311eb3466187ca8"
dependencies = [
"alloy-primitives 1.1.2",
"alloy-rpc-types-anvil",
@@ -577,38 +577,38 @@ dependencies = [
"alloy-rpc-types-eth",
"alloy-rpc-types-trace",
"alloy-rpc-types-txpool",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"serde",
]
[[package]]
name = "alloy-rpc-types-anvil"
-version = "1.0.4"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ebe3dcbc6c85678f29c205b2fcf6b110b32287bf6b72bbee37ed9011404e926"
+checksum = "8abecc34549a208b5f91bc7f02df3205c36e2aa6586f1d9375c3382da1066b3b"
dependencies = [
"alloy-primitives 1.1.2",
"alloy-rpc-types-eth",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"serde",
]
[[package]]
name = "alloy-rpc-types-any"
-version = "1.0.4"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c583654aab419fe9e553ba86ab503e1cda0b855509ac95210c4ca6df84724255"
+checksum = "508b2fbe66d952089aa694e53802327798806498cd29ff88c75135770ecaabfc"
dependencies = [
"alloy-consensus-any",
"alloy-rpc-types-eth",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
]
[[package]]
name = "alloy-rpc-types-debug"
-version = "1.0.4"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7913c67b874db23446a4cdd020da1bbc828513bd83536ccabfca403b71cdeaf9"
+checksum = "8c832f2e851801093928dbb4b7bd83cd22270faf76b2e080646b806a285c8757"
dependencies = [
"alloy-primitives 1.1.2",
"serde",
@@ -616,15 +616,15 @@ dependencies = [
[[package]]
name = "alloy-rpc-types-engine"
-version = "1.0.4"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "63b70151dc3282ce4bbde31b80a7f0f1e53b9dec9b187f528394e8f0a0411975"
+checksum = "cab52691970553d84879d777419fa7b6a2e92e9fe8641f9324cc071008c2f656"
dependencies = [
"alloy-consensus",
- "alloy-eips 1.0.5",
+ "alloy-eips 1.0.9",
"alloy-primitives 1.1.2",
"alloy-rlp",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"derive_more 2.0.1",
"jsonwebtoken",
"rand 0.8.5",
@@ -634,17 +634,17 @@ dependencies = [
[[package]]
name = "alloy-rpc-types-eth"
-version = "1.0.4"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c4496ab5f898c88e9153b88fcb6738e2d58b2ba6d7d85c3144ee83c990316a3"
+checksum = "fcaf7dff0fdd756a714d58014f4f8354a1706ebf9fa2cf73431e0aeec3c9431e"
dependencies = [
"alloy-consensus",
"alloy-consensus-any",
- "alloy-eips 1.0.5",
+ "alloy-eips 1.0.9",
"alloy-network-primitives",
"alloy-primitives 1.1.2",
"alloy-rlp",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"alloy-sol-types 1.1.2",
"itertools 0.14.0",
"serde",
@@ -654,13 +654,13 @@ dependencies = [
[[package]]
name = "alloy-rpc-types-trace"
-version = "1.0.4"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bcf555fe777cf7d11b8ebe837aca0b0ceb74f1ed9937f938b8c9fbd1460994cf"
+checksum = "6e3507a04e868dd83219ad3cd6a8c58aefccb64d33f426b3934423a206343e84"
dependencies = [
"alloy-primitives 1.1.2",
"alloy-rpc-types-eth",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"serde",
"serde_json",
"thiserror 2.0.12",
@@ -668,13 +668,13 @@ dependencies = [
[[package]]
name = "alloy-rpc-types-txpool"
-version = "1.0.4"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87c69ea401ce851b52c9b07d838173cd3c23c11a552a5e5ddde3ffd834647a46"
+checksum = "eec36272621c3ac82b47dd77f0508346687730b1c2e3e10d3715705c217c0a05"
dependencies = [
"alloy-primitives 1.1.2",
"alloy-rpc-types-eth",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"serde",
]
@@ -691,9 +691,9 @@ dependencies = [
[[package]]
name = "alloy-serde"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8c34ffc38f543bfdceed8c1fa5253fa5131455bb3654976be4cc3a4ae6d61f4"
+checksum = "730e8f2edf2fc224cabd1c25d090e1655fa6137b2e409f92e5eec735903f1507"
dependencies = [
"alloy-primitives 1.1.2",
"serde",
@@ -702,9 +702,9 @@ dependencies = [
[[package]]
name = "alloy-signer"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59245704a5dbd20b93913f4a20aa41b45c4c134f82e119bb54de4b627e003955"
+checksum = "6b0d2428445ec13edc711909e023d7779618504c4800be055a5b940025dbafe3"
dependencies = [
"alloy-dyn-abi 1.1.2",
"alloy-primitives 1.1.2",
@@ -719,9 +719,9 @@ dependencies = [
[[package]]
name = "alloy-signer-aws"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a24ea892abc29582dce6df5a1266ddf620fe93a04eb0265a3072c68c8b0ea10"
+checksum = "6be3d371299b62eac5aa459fa58e8d1c761aabdc637573ae258ab744457fcc88"
dependencies = [
"alloy-consensus",
"alloy-network",
@@ -737,9 +737,9 @@ dependencies = [
[[package]]
name = "alloy-signer-gcp"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f07be333cf6b3f06475d86b5fe39e5f94285714fffaf961173ff87448180f346"
+checksum = "df298e47bbb7d0a8e06b603046b91062c11ba70d22f8a6c9bab1c1468bd856d0"
dependencies = [
"alloy-consensus",
"alloy-network",
@@ -755,9 +755,9 @@ dependencies = [
[[package]]
name = "alloy-signer-ledger"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04ad29d22519ce6fcf85edb8fb0d335216e8522c4458cdd92792f06c2173f9f2"
+checksum = "3b0e049299cc7e131a438a904f89a493bcea45cd92bbed3e50116a28bc27987c"
dependencies = [
"alloy-consensus",
"alloy-dyn-abi 1.1.2",
@@ -775,9 +775,9 @@ dependencies = [
[[package]]
name = "alloy-signer-local"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eae78644ab0945e95efa2dc0cfac8f53aa1226fe85c294a0d8ad82c5cc9f09a2"
+checksum = "e14fe6fedb7fe6e0dfae47fe020684f1d8e063274ef14bca387ddb7a6efa8ec1"
dependencies = [
"alloy-consensus",
"alloy-network",
@@ -794,9 +794,9 @@ dependencies = [
[[package]]
name = "alloy-signer-trezor"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52a384f096c65ec6f9c541dd8a0d1217f38ff7aa0d2565254d03d9a51c23b5c6"
+checksum = "26c7df3624131eeecf74c18e5cd59bcc125633bad407b1938161edf89eb71485"
dependencies = [
"alloy-consensus",
"alloy-network",
@@ -955,9 +955,9 @@ dependencies = [
[[package]]
name = "alloy-transport"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a56afd0561a291e84de9d5616fa3def4c4925a09117ea3b08d4d5d207c4f7083"
+checksum = "a712bdfeff42401a7dd9518f72f617574c36226a9b5414537fedc34350b73bf9"
dependencies = [
"alloy-json-rpc",
"alloy-primitives 1.1.2",
@@ -978,9 +978,9 @@ dependencies = [
[[package]]
name = "alloy-transport-http"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90770711e649bb3df0a8a666ae7b80d1d77eff5462eaf6bb4d3eaf134f6e636e"
+checksum = "7ea5a76d7f2572174a382aedf36875bedf60bcc41116c9f031cf08040703a2dc"
dependencies = [
"alloy-json-rpc",
"alloy-transport",
@@ -993,9 +993,9 @@ dependencies = [
[[package]]
name = "alloy-transport-ipc"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "983693379572a06e2bc1050116d975395604b357e1f2ac4420dd385d9ee18c11"
+checksum = "606af17a7e064d219746f6d2625676122c79d78bf73dfe746d6db9ecd7dbcb85"
dependencies = [
"alloy-json-rpc",
"alloy-pubsub",
@@ -1013,9 +1013,9 @@ dependencies = [
[[package]]
name = "alloy-transport-ws"
-version = "1.0.5"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90569cc2e13f5cdf53f42d5b3347cf4a89fccbcf9978cf08b165b4a1c6447672"
+checksum = "e0c6f9b37cd8d44aab959613966cc9d4d7a9b429c575cec43b3e5b46ea109a79"
dependencies = [
"alloy-pubsub",
"alloy-transport",
@@ -1147,12 +1147,12 @@ dependencies = [
[[package]]
name = "anstyle-wincon"
-version = "3.0.7"
+version = "3.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
+checksum = "6680de5231bd6ee4c6191b8a1325daa282b415391ec9d3a37bd34f2060dc73fa"
dependencies = [
"anstyle",
- "once_cell",
+ "once_cell_polyfill",
"windows-sys 0.59.0",
]
@@ -1164,7 +1164,7 @@ dependencies = [
"alloy-consensus",
"alloy-contract",
"alloy-dyn-abi 1.1.2",
- "alloy-eips 1.0.5",
+ "alloy-eips 1.0.9",
"alloy-evm",
"alloy-genesis",
"alloy-network",
@@ -1174,7 +1174,7 @@ dependencies = [
"alloy-pubsub",
"alloy-rlp",
"alloy-rpc-types",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"alloy-signer",
"alloy-signer-local",
"alloy-sol-types 1.1.2",
@@ -1226,12 +1226,12 @@ version = "1.2.0"
dependencies = [
"alloy-consensus",
"alloy-dyn-abi 1.1.2",
- "alloy-eips 1.0.5",
+ "alloy-eips 1.0.9",
"alloy-network",
"alloy-primitives 1.1.2",
"alloy-rlp",
"alloy-rpc-types",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"bytes",
"foundry-common",
"foundry-evm",
@@ -1812,14 +1812,14 @@ dependencies = [
"percent-encoding",
"pin-project-lite",
"tracing",
- "uuid 1.16.0",
+ "uuid 1.17.0",
]
[[package]]
name = "aws-sdk-kms"
-version = "1.69.0"
+version = "1.72.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c64c93b24f98760979113386e444886fc812632d4d84910b802d69a2bdbb5349"
+checksum = "0eef6a94141a43ee28404bf135828ad9bdd4936bfa2a84ad8dea355c94646a35"
dependencies = [
"aws-credential-types",
"aws-runtime",
@@ -1839,9 +1839,9 @@ dependencies = [
[[package]]
name = "aws-sdk-sso"
-version = "1.68.0"
+version = "1.71.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd5f01ea61fed99b5fe4877abff6c56943342a56ff145e9e0c7e2494419008be"
+checksum = "95a4fd09d6e863655d99cd2260f271c6d1030dc6bfad68e19e126d2e4c8ceb18"
dependencies = [
"aws-credential-types",
"aws-runtime",
@@ -1861,9 +1861,9 @@ dependencies = [
[[package]]
name = "aws-sdk-ssooidc"
-version = "1.69.0"
+version = "1.72.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27454e4c55aaa4ef65647e3a1cf095cb834ca6d54e959e2909f1fef96ad87860"
+checksum = "3224ab02ebb3074467a33d57caf6fcb487ca36f3697fdd381b0428dc72380696"
dependencies = [
"aws-credential-types",
"aws-runtime",
@@ -1883,9 +1883,9 @@ dependencies = [
[[package]]
name = "aws-sdk-sts"
-version = "1.69.0"
+version = "1.72.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffd6ef5d00c94215960fabcdf2d9fe7c090eed8be482d66d47b92d4aba1dd4aa"
+checksum = "f6933f189ed1255e78175fbd73fb200c0aae7240d220ed3346f567b0ddca3083"
dependencies = [
"aws-credential-types",
"aws-runtime",
@@ -2469,7 +2469,7 @@ dependencies = [
"alloy-provider",
"alloy-rlp",
"alloy-rpc-types",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"alloy-signer",
"alloy-signer-local",
"alloy-sol-types 1.1.2",
@@ -2522,9 +2522,9 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.2.23"
+version = "1.2.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766"
+checksum = "16595d3be041c03b09d08d0858631facccee9221e579704070e6e9e4915d3bc7"
dependencies = [
"jobserver",
"libc",
@@ -2649,9 +2649,9 @@ dependencies = [
[[package]]
name = "clap"
-version = "4.5.38"
+version = "4.5.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000"
+checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f"
dependencies = [
"clap_builder",
"clap_derive",
@@ -2659,9 +2659,9 @@ dependencies = [
[[package]]
name = "clap-verbosity-flag"
-version = "3.0.2"
+version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2678fade3b77aa3a8ff3aae87e9c008d3fb00473a41c71fbf74e91c8c7b37e84"
+checksum = "eeab6a5cdfc795a05538422012f20a5496f050223c91be4e5420bfd13c641fb1"
dependencies = [
"clap",
"log",
@@ -2669,9 +2669,9 @@ dependencies = [
[[package]]
name = "clap_builder"
-version = "4.5.38"
+version = "4.5.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120"
+checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51"
dependencies = [
"anstream",
"anstyle",
@@ -2684,9 +2684,9 @@ dependencies = [
[[package]]
name = "clap_complete"
-version = "4.5.50"
+version = "4.5.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c91d3baa3bcd889d60e6ef28874126a0b384fd225ab83aa6d8a801c519194ce1"
+checksum = "8d2267df7f3c8e74e38268887ea5235d4dfadd39bfff2d56ab82d61776be355e"
dependencies = [
"clap",
]
@@ -2994,9 +2994,9 @@ dependencies = [
[[package]]
name = "core-foundation"
-version = "0.10.0"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63"
+checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
dependencies = [
"core-foundation-sys",
"libc",
@@ -3868,7 +3868,7 @@ dependencies = [
"alloy-primitives 1.1.2",
"alloy-provider",
"alloy-rpc-types",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"alloy-signer",
"alloy-signer-local",
"alloy-transport",
@@ -3907,7 +3907,7 @@ dependencies = [
"inferno",
"itertools 0.14.0",
"mockall",
- "opener",
+ "opener 0.7.2",
"parking_lot",
"paste",
"path-slash",
@@ -3987,13 +3987,13 @@ dependencies = [
"alloy-chains",
"alloy-consensus",
"alloy-dyn-abi 1.1.2",
- "alloy-eips 1.0.5",
+ "alloy-eips 1.0.9",
"alloy-json-abi 1.1.2",
"alloy-network",
"alloy-primitives 1.1.2",
"alloy-provider",
"alloy-rpc-types",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"alloy-signer",
"clap",
"dialoguer",
@@ -4101,9 +4101,9 @@ dependencies = [
[[package]]
name = "foundry-block-explorers"
-version = "0.17.0"
+version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6129df264d2bd245ade4ed21a92f605bfd592dca8fb8e6e1adde1b9bd4288681"
+checksum = "7dd57f39a860475780c0b001167b2bb9039e78d8d09323c6949897f5351ffae6"
dependencies = [
"alloy-chains",
"alloy-json-abi 1.1.2",
@@ -4184,7 +4184,7 @@ version = "1.2.0"
dependencies = [
"alloy-chains",
"alloy-dyn-abi 1.1.2",
- "alloy-eips 1.0.5",
+ "alloy-eips 1.0.9",
"alloy-json-abi 1.1.2",
"alloy-primitives 1.1.2",
"alloy-provider",
@@ -4232,7 +4232,7 @@ dependencies = [
"alloy-consensus",
"alloy-contract",
"alloy-dyn-abi 1.1.2",
- "alloy-eips 1.0.5",
+ "alloy-eips 1.0.9",
"alloy-json-abi 1.1.2",
"alloy-json-rpc",
"alloy-network",
@@ -4241,7 +4241,7 @@ dependencies = [
"alloy-pubsub",
"alloy-rpc-client",
"alloy-rpc-types",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"alloy-sol-types 1.1.2",
"alloy-transport",
"alloy-transport-http",
@@ -4291,7 +4291,7 @@ dependencies = [
"alloy-network",
"alloy-primitives 1.1.2",
"alloy-rpc-types",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"chrono",
"foundry-macros",
"revm",
@@ -4303,9 +4303,9 @@ dependencies = [
[[package]]
name = "foundry-compilers"
-version = "0.16.4"
+version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe41ab4be8c70e139241dfa4c8b4f30f905a1c92fa13123255e2eeedc5ffa63d"
+checksum = "6e3e990fb891b4f7caa49271c842d8eaece61431106b33c52f9d511dc7270eee"
dependencies = [
"alloy-json-abi 1.1.2",
"alloy-primitives 1.1.2",
@@ -4340,9 +4340,9 @@ dependencies = [
[[package]]
name = "foundry-compilers-artifacts"
-version = "0.16.4"
+version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afd39a92e4cf1ea15b283a8ad2c55af4ec05f5f9334601d62afd1a05abe78e84"
+checksum = "8234ce9c22e8e5047dcae2acd10cb0ccd448dd5058d4e341310bb9dabcec4aa6"
dependencies = [
"foundry-compilers-artifacts-solc",
"foundry-compilers-artifacts-vyper",
@@ -4350,9 +4350,9 @@ dependencies = [
[[package]]
name = "foundry-compilers-artifacts-solc"
-version = "0.16.4"
+version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a3999266fe758acc25725f649d964c7ddf77b38fd00ac9423b74e65901c687d"
+checksum = "2d46c321c7a688810301c8efa1d020ee876b6bcf4a327c6a50bf807845b94c41"
dependencies = [
"alloy-json-abi 1.1.2",
"alloy-primitives 1.1.2",
@@ -4373,9 +4373,9 @@ dependencies = [
[[package]]
name = "foundry-compilers-artifacts-vyper"
-version = "0.16.4"
+version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1b7b83ebff9bdb25b35070152169a6ea720d21b7d201debf527b4b11569ea62"
+checksum = "2f2e6f66303fe27dbd3123db706f9f25bae1b46ddcb97191e0f5ac199db94403"
dependencies = [
"alloy-json-abi 1.1.2",
"alloy-primitives 1.1.2",
@@ -4388,9 +4388,9 @@ dependencies = [
[[package]]
name = "foundry-compilers-core"
-version = "0.16.4"
+version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80f3bb9ac0bc9f509b3ed080092b4c0e8fa1ff58243d89454e96fa0cc4599d1e"
+checksum = "34dd4424b0bcbbf6ad9e6f80377136b84edcfcbb4234a0c59afa78a89d5a9ee8"
dependencies = [
"alloy-primitives 1.1.2",
"cfg-if",
@@ -5235,11 +5235,10 @@ dependencies = [
[[package]]
name = "hyper-rustls"
-version = "0.27.5"
+version = "0.27.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2"
+checksum = "03a01595e11bdcec50946522c32dde3fc6914743000a68b93000965f2f02406d"
dependencies = [
- "futures-util",
"http 1.3.1",
"hyper",
"hyper-util",
@@ -5249,7 +5248,7 @@ dependencies = [
"tokio",
"tokio-rustls",
"tower-service",
- "webpki-roots 0.26.11",
+ "webpki-roots 1.0.0",
]
[[package]]
@@ -5267,22 +5266,28 @@ dependencies = [
[[package]]
name = "hyper-util"
-version = "0.1.11"
+version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2"
+checksum = "b1c293b6b3d21eca78250dc7dbebd6b9210ec5530e038cbfe0661b5c47ab06e8"
dependencies = [
+ "base64 0.22.1",
"bytes",
"futures-channel",
+ "futures-core",
"futures-util",
"http 1.3.1",
"http-body 1.0.1",
"hyper",
+ "ipnet",
"libc",
+ "percent-encoding",
"pin-project-lite",
"socket2",
+ "system-configuration",
"tokio",
"tower-service",
"tracing",
+ "windows-registry",
]
[[package]]
@@ -5521,6 +5526,16 @@ version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
+[[package]]
+name = "iri-string"
+version = "0.7.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2"
+dependencies = [
+ "memchr",
+ "serde",
+]
+
[[package]]
name = "is-terminal"
version = "0.4.16"
@@ -5582,9 +5597,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "jiff"
-version = "0.2.13"
+version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f02000660d30638906021176af16b17498bd0d12813dbfe7b276d8bc7f3c0806"
+checksum = "a194df1107f33c79f4f93d02c80798520551949d59dfad22b6157048a88cca93"
dependencies = [
"jiff-static",
"jiff-tzdb-platform",
@@ -5597,9 +5612,9 @@ dependencies = [
[[package]]
name = "jiff-static"
-version = "0.2.13"
+version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3c30758ddd7188629c6713fc45d1188af4f44c90582311d0c8d8c9907f60c48"
+checksum = "6c6e1db7ed32c6c71b759497fae34bf7933636f75a251b9e736555da426f6442"
dependencies = [
"proc-macro2",
"quote",
@@ -5723,9 +5738,9 @@ dependencies = [
[[package]]
name = "lalrpop"
-version = "0.22.1"
+version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7047a26de42016abf8f181b46b398aef0b77ad46711df41847f6ed869a2a1d5b"
+checksum = "ba4ebbd48ce411c1d10fb35185f5a51a7bfa3d8b24b4e330d30c9e3a34129501"
dependencies = [
"ascii-canvas",
"bit-set",
@@ -5744,9 +5759,9 @@ dependencies = [
[[package]]
name = "lalrpop-util"
-version = "0.22.1"
+version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8d05b3fe34b8bd562c338db725dfa9beb9451a48f65f129ccb9538b48d2c93b"
+checksum = "b5baa5e9ff84f1aefd264e6869907646538a52147a755d494517a8007fb48733"
dependencies = [
"regex-automata 0.4.9",
"rustversion",
@@ -5792,9 +5807,9 @@ dependencies = [
[[package]]
name = "libloading"
-version = "0.8.7"
+version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a793df0d7afeac54f95b471d3af7f0d4fb975699f972341a4b76988d49cdf0c"
+checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
dependencies = [
"cfg-if",
"windows-targets 0.53.0",
@@ -6042,9 +6057,9 @@ checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
[[package]]
name = "mdbook"
-version = "0.4.49"
+version = "0.4.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1daacee059634081dee4250d2814763a365b92dfe14bfdef964bc27835209d4"
+checksum = "a87e65420ab45ca9c1b8cdf698f95b710cc826d373fa550f0f7fad82beac9328"
dependencies = [
"ammonia",
"anyhow",
@@ -6057,8 +6072,7 @@ dependencies = [
"hex",
"log",
"memchr",
- "once_cell",
- "opener",
+ "opener 0.8.2",
"pulldown-cmark",
"regex",
"serde",
@@ -6160,14 +6174,14 @@ dependencies = [
[[package]]
name = "mio"
-version = "1.0.3"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
+checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
dependencies = [
"libc",
"log",
"wasi 0.11.0+wasi-snapshot-preview1",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -6204,11 +6218,11 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]]
name = "newtype-uuid"
-version = "1.2.1"
+version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee3224f0e8be7c2a1ebc77ef9c3eecb90f55c6594399ee825de964526b3c9056"
+checksum = "a8ba303c7a8f8fdee1fe1513cfd918f50f1c69bf65c91b39217bfc2b2af5c081"
dependencies = [
- "uuid 1.16.0",
+ "uuid 1.17.0",
]
[[package]]
@@ -6502,6 +6516,12 @@ version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
+[[package]]
+name = "once_cell_polyfill"
+version = "1.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
+
[[package]]
name = "once_map"
version = "0.4.21"
@@ -6521,10 +6541,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f318b09e24148f07392c5e011bae047a0043851f9041145df5f3b01e4fedd1e"
dependencies = [
"alloy-consensus",
- "alloy-eips 1.0.5",
+ "alloy-eips 1.0.9",
"alloy-primitives 1.1.2",
"alloy-rlp",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"derive_more 2.0.1",
"serde",
"thiserror 2.0.12",
@@ -6537,11 +6557,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15ede8322c10c21249de4fced204e2af4978972e715afee34b6fe684d73880cf"
dependencies = [
"alloy-consensus",
- "alloy-eips 1.0.5",
+ "alloy-eips 1.0.9",
"alloy-network-primitives",
"alloy-primitives 1.1.2",
"alloy-rpc-types-eth",
- "alloy-serde 1.0.5",
+ "alloy-serde 1.0.9",
"derive_more 2.0.1",
"op-alloy-consensus",
"serde",
@@ -6578,6 +6598,17 @@ dependencies = [
"windows-sys 0.59.0",
]
+[[package]]
+name = "opener"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "771b9704f8cd8b424ec747a320b30b47517a6966ba2c7da90047c16f4a962223"
+dependencies = [
+ "bstr",
+ "normpath",
+ "windows-sys 0.59.0",
+]
+
[[package]]
name = "openssl-probe"
version = "0.1.6"
@@ -6622,9 +6653,9 @@ dependencies = [
[[package]]
name = "parity-scale-codec"
-version = "3.7.4"
+version = "3.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9fde3d0718baf5bc92f577d652001da0f8d54cd03a7974e118d04fc888dc23d"
+checksum = "799781ae679d79a948e13d4824a40970bfa500058d245760dd857301059810fa"
dependencies = [
"arrayvec",
"bitvec",
@@ -6638,9 +6669,9 @@ dependencies = [
[[package]]
name = "parity-scale-codec-derive"
-version = "3.7.4"
+version = "3.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "581c837bb6b9541ce7faa9377c20616e4fb7650f6b0f68bc93c827ee504fb7b3"
+checksum = "34b4653168b563151153c9e4c08ebed57fb8262bebfa79711552fa983c623e7a"
dependencies = [
"proc-macro-crate",
"proc-macro2",
@@ -7220,7 +7251,7 @@ dependencies = [
"quick-xml 0.37.5",
"strip-ansi-escapes",
"thiserror 2.0.12",
- "uuid 1.16.0",
+ "uuid 1.17.0",
]
[[package]]
@@ -7517,9 +7548,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "reqwest"
-version = "0.12.15"
+version = "0.12.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb"
+checksum = "e98ff6b0dbbe4d5a37318f433d4fc82babd21631f194d370409ceb2e40b2f0b5"
dependencies = [
"async-compression",
"base64 0.22.1",
@@ -7546,26 +7577,24 @@ dependencies = [
"quinn",
"rustls",
"rustls-native-certs",
- "rustls-pemfile",
"rustls-pki-types",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
- "system-configuration",
"tokio",
"tokio-rustls",
"tokio-socks",
"tokio-util",
"tower",
+ "tower-http",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-streams",
"web-sys",
- "webpki-roots 0.26.11",
- "windows-registry",
+ "webpki-roots 1.0.0",
]
[[package]]
@@ -7834,9 +7863,9 @@ dependencies = [
[[package]]
name = "ruint"
-version = "1.14.0"
+version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78a46eb779843b2c4f21fac5773e25d6d5b7c8f0922876c91541790d2ca27eef"
+checksum = "11256b5fe8c68f56ac6f39ef0720e592f33d2367a4782740d9c9142e889c7fb4"
dependencies = [
"alloy-rlp",
"arbitrary",
@@ -7975,15 +8004,6 @@ dependencies = [
"security-framework",
]
-[[package]]
-name = "rustls-pemfile"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
-dependencies = [
- "rustls-pki-types",
-]
-
[[package]]
name = "rustls-pki-types"
version = "1.12.0"
@@ -8008,9 +8028,9 @@ dependencies = [
[[package]]
name = "rustversion"
-version = "1.0.20"
+version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
+checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
[[package]]
name = "rusty-fork"
@@ -8192,7 +8212,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316"
dependencies = [
"bitflags 2.9.1",
- "core-foundation 0.10.0",
+ "core-foundation 0.10.1",
"core-foundation-sys",
"libc",
"security-framework-sys",
@@ -8588,9 +8608,9 @@ dependencies = [
[[package]]
name = "socket2"
-version = "0.5.9"
+version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef"
+checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
dependencies = [
"libc",
"windows-sys 0.52.0",
@@ -8772,7 +8792,7 @@ dependencies = [
"thiserror 2.0.12",
"tokio",
"toml_edit",
- "uuid 1.16.0",
+ "uuid 1.17.0",
"zip",
"zip-extract",
]
@@ -9298,9 +9318,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.45.0"
+version = "1.45.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165"
+checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779"
dependencies = [
"backtrace",
"bytes",
@@ -9509,12 +9529,14 @@ dependencies = [
"http-body-util",
"http-range-header",
"httpdate",
+ "iri-string",
"mime",
"mime_guess",
"percent-encoding",
"pin-project-lite",
"tokio",
"tokio-util",
+ "tower",
"tower-layer",
"tower-service",
"tracing",
@@ -9893,12 +9915,14 @@ dependencies = [
[[package]]
name = "uuid"
-version = "1.16.0"
+version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"
+checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d"
dependencies = [
"getrandom 0.3.3",
+ "js-sys",
"serde",
+ "wasm-bindgen",
]
[[package]]
@@ -10313,15 +10337,15 @@ dependencies = [
[[package]]
name = "windows-core"
-version = "0.61.1"
+version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46ec44dc15085cea82cf9c78f85a9114c463a369786585ad2882d1ff0b0acf40"
+checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
dependencies = [
"windows-implement",
"windows-interface",
"windows-link",
"windows-result",
- "windows-strings 0.4.1",
+ "windows-strings 0.4.2",
]
[[package]]
@@ -10386,9 +10410,9 @@ dependencies = [
[[package]]
name = "windows-result"
-version = "0.3.3"
+version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b895b5356fc36103d0f64dd1e94dfa7ac5633f1c9dd6e80fe9ec4adef69e09d"
+checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
dependencies = [
"windows-link",
]
@@ -10404,9 +10428,9 @@ dependencies = [
[[package]]
name = "windows-strings"
-version = "0.4.1"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a7ab927b2637c19b3dbe0965e75d8f2d30bdd697a1516191cad2ec4df8fb28a"
+checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
dependencies = [
"windows-link",
]
diff --git a/Cargo.toml b/Cargo.toml
index fdefa17aad45f..6e5bafa630107 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -196,8 +196,8 @@ foundry-wallets = { path = "crates/wallets" }
foundry-linking = { path = "crates/linking" }
# solc & compilation utilities
-foundry-block-explorers = { version = "0.17.0", default-features = false }
-foundry-compilers = { version = "0.16.4", default-features = false }
+foundry-block-explorers = { version = "0.18.0", default-features = false }
+foundry-compilers = { version = "0.17.0", default-features = false }
foundry-fork-db = "0.14"
solang-parser = { version = "=0.3.8", package = "foundry-solang-parser" }
solar-parse = { version = "=0.1.4", default-features = false }
diff --git a/crates/forge/src/cmd/compiler.rs b/crates/forge/src/cmd/compiler.rs
index 19e4354ca9cb4..50aebf969f252 100644
--- a/crates/forge/src/cmd/compiler.rs
+++ b/crates/forge/src/cmd/compiler.rs
@@ -139,6 +139,12 @@ impl ResolveArgs {
0 => sh_println!("- {version}")?,
_ => {
if let Some(evm) = &resolved_compiler.evm_version {
+ if let Some(path) = &resolved_compiler.paths.last() {
+ if path.ends_with(".vy") && evm == &EvmVersion::Prague {
+ sh_println!("{version} (<= {evm}):", evm = EvmVersion::Cancun)?;
+ continue;
+ }
+ };
sh_println!("{version} (<= {evm}):")?
} else {
sh_println!("{version}:")?
diff --git a/crates/forge/tests/cli/compiler.rs b/crates/forge/tests/cli/compiler.rs
index ae07aec6d0225..0b58221f2a1d0 100644
--- a/crates/forge/tests/cli/compiler.rs
+++ b/crates/forge/tests/cli/compiler.rs
@@ -242,7 +242,7 @@ Solidity:
Vyper:
-0.4.0 (<= prague):
+0.4.0 (<= cancun):
├── src/Counter.vy
└── src/ICounter.vyi
From b998d0e2b97a3d7afab38edc62444c944d745710 Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Thu, 29 May 2025 13:54:47 -0500
Subject: [PATCH 18/21] style: clippy
---
crates/anvil/core/src/eth/mod.rs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/crates/anvil/core/src/eth/mod.rs b/crates/anvil/core/src/eth/mod.rs
index bca300cac6cd8..be38aa4ad45e3 100644
--- a/crates/anvil/core/src/eth/mod.rs
+++ b/crates/anvil/core/src/eth/mod.rs
@@ -35,6 +35,7 @@ pub struct Params {
/// Represents ethereum JSON-RPC API
#[derive(Clone, Debug, serde::Deserialize)]
#[serde(tag = "method", content = "params")]
+#[allow(clippy::large_enum_variant)]
pub enum EthRequest {
#[serde(rename = "web3_clientVersion", with = "empty_params")]
Web3ClientVersion(()),
@@ -640,7 +641,7 @@ pub enum EthRequest {
/// Add an address to the [`DelegationCapability`] of the wallet
///
- /// [`DelegationCapability`]: wallet::DelegationCapability
+ /// [`DelegationCapability`]: wallet::DelegationCapability
#[serde(rename = "anvil_addCapability", with = "sequence")]
AnvilAddCapability(Address),
From 452cbcea15d83ec84de3dc1378829955afa2f69a Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Thu, 29 May 2025 14:48:13 -0500
Subject: [PATCH 19/21] fix: check for `.vyi` paths
---
crates/forge/src/cmd/compiler.rs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/crates/forge/src/cmd/compiler.rs b/crates/forge/src/cmd/compiler.rs
index 50aebf969f252..d631f3ea3fd44 100644
--- a/crates/forge/src/cmd/compiler.rs
+++ b/crates/forge/src/cmd/compiler.rs
@@ -140,7 +140,9 @@ impl ResolveArgs {
_ => {
if let Some(evm) = &resolved_compiler.evm_version {
if let Some(path) = &resolved_compiler.paths.last() {
- if path.ends_with(".vy") && evm == &EvmVersion::Prague {
+ if (path.ends_with(".vy") || path.ends_with(".vyi")) &&
+ evm == &EvmVersion::Prague
+ {
sh_println!("{version} (<= {evm}):", evm = EvmVersion::Cancun)?;
continue;
}
From ce7948f29ffdec807448a7956c39058cd6da2496 Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Thu, 29 May 2025 15:17:28 -0500
Subject: [PATCH 20/21] style: simplify
---
crates/forge/src/cmd/compiler.rs | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/crates/forge/src/cmd/compiler.rs b/crates/forge/src/cmd/compiler.rs
index d631f3ea3fd44..b8612ec58a801 100644
--- a/crates/forge/src/cmd/compiler.rs
+++ b/crates/forge/src/cmd/compiler.rs
@@ -139,17 +139,19 @@ impl ResolveArgs {
0 => sh_println!("- {version}")?,
_ => {
if let Some(evm) = &resolved_compiler.evm_version {
- if let Some(path) = &resolved_compiler.paths.last() {
- if (path.ends_with(".vy") || path.ends_with(".vyi")) &&
- evm == &EvmVersion::Prague
- {
- sh_println!("{version} (<= {evm}):", evm = EvmVersion::Cancun)?;
- continue;
- }
- };
- sh_println!("{version} (<= {evm}):")?
+ // Vyper does not yet support Prague, so we normalize it to Cancun.
+ if evm == &EvmVersion::Prague &&
+ resolved_compiler
+ .paths
+ .last()
+ .is_some_and(|p| p.ends_with(".vy") || p.ends_with(".vyi"))
+ {
+ sh_println!("{version} (<= {evm}):", evm = EvmVersion::Cancun)?;
+ } else {
+ sh_println!("{version} (<= {evm}):")?;
+ }
} else {
- sh_println!("{version}:")?
+ sh_println!("{version}:")?;
}
}
}
From d35f49897829a0e6620e6c7600cfe38dc7ffcc7b Mon Sep 17 00:00:00 2001
From: 0xrusowsky <0xrusowsky@proton.me>
Date: Thu, 29 May 2025 15:17:41 -0500
Subject: [PATCH 21/21] style: simplify
---
crates/forge/src/cmd/compiler.rs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/crates/forge/src/cmd/compiler.rs b/crates/forge/src/cmd/compiler.rs
index b8612ec58a801..27e7aabcf972d 100644
--- a/crates/forge/src/cmd/compiler.rs
+++ b/crates/forge/src/cmd/compiler.rs
@@ -146,12 +146,12 @@ impl ResolveArgs {
.last()
.is_some_and(|p| p.ends_with(".vy") || p.ends_with(".vyi"))
{
- sh_println!("{version} (<= {evm}):", evm = EvmVersion::Cancun)?;
+ sh_println!("{version} (<= {evm}):", evm = EvmVersion::Cancun)?
} else {
- sh_println!("{version} (<= {evm}):")?;
+ sh_println!("{version} (<= {evm}):")?
}
} else {
- sh_println!("{version}:")?;
+ sh_println!("{version}:")?
}
}
}