Skip to content

Commit 0d2a1d3

Browse files
gakonstampcode-com
andauthored
fix(cheatcodes): fix vm.expectRevert for direct precompile calls (#13460)
Precompile calls don't create an interpreter frame, so `initialize_interp` never fires and `max_depth` never gets bumped beyond the cheatcode call depth. This causes the depth check in `handle_expect_revert` to fail with "call didn't revert at a lower depth than cheatcode call depth". Track `max_depth` in the `call` hook as well, accounting for the callee depth (`curr_depth + 1`). Amp-Thread-ID: https://ampcode.com/threads/T-019c63a2-2c36-7334-ab55-2931a174b59c Co-authored-by: Amp <amp@ampcode.com>
1 parent f8e3dfa commit 0d2a1d3

2 files changed

Lines changed: 19 additions & 0 deletions

File tree

crates/cheatcodes/src/inspector.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,13 @@ impl Cheatcodes {
766766
return None;
767767
}
768768

769+
// `expectRevert`: track max call depth. This is also done in `initialize_interp`, but
770+
// precompile calls don't create an interpreter frame so we must also track it here.
771+
// The callee executes at `curr_depth + 1`.
772+
if let Some(expected) = &mut self.expected_revert {
773+
expected.max_depth = max(curr_depth + 1, expected.max_depth);
774+
}
775+
769776
// Handle expected calls
770777

771778
// Grab the different calldatas expected.

testdata/default/cheats/ExpectRevert.t.sol

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,18 @@ contract ExpectRevertCountWithReverter is Test {
413413
}
414414
}
415415

416+
contract ExpectRevertPrecompileTest is Test {
417+
/// Test that vm.expectRevert works when the next external call targets a
418+
/// precompile address directly. Precompile calls don't create an interpreter
419+
/// frame (no `initialize_interp`), so depth tracking must account for them.
420+
function testExpectRevertDirectPrecompileCall() public {
421+
// BLAKE2F precompile (0x09) expects exactly 213 bytes of input.
422+
// Calling it with invalid input reverts.
423+
vm.expectRevert();
424+
address(0x09).call(hex"00");
425+
}
426+
}
427+
416428
contract ExpectRevertWithErrorTest is Test {
417429
/// Ref: <https://github.com/foundry-rs/foundry/issues/12511>
418430
function test_f() external {

0 commit comments

Comments
 (0)