Skip to content

Commit 18dc1f1

Browse files
authored
test: exclude forge reserved addresses from setSlasher fuzz inputs (#23721)
## Problem The `Merge branch 'next' into merge-train/spartan` CI run ([ci.aztec-labs.com/1780091707705535](http://ci.aztec-labs.com/1780091707705535)) failed in the `cd l1-contracts && forge test` step: ``` test/staking/setSlasher.t.sol:SetSlasherTest [FAIL: unknown selector `0xbffa7f0f` for ConsoleCalls; counterexample: args=[0x000000000000000000636F6e736F6c652e6c6f67]] test_finalizeSetSlasher_appliesAfterDelay(address) (runs: 104) ``` ## Root cause `0x000000000000000000636F6e736F6c652e6c6f67` is forge-std's console address (ASCII "console.log"). The fuzzer drew it as the `_newSlasher` parameter. Foundry intercepts **every** call to that address and dispatches it to its console handler, which bypasses `vm.mockCall`. So the staking contract's `PROPOSER()` lookup (selector `0xbffa7f0f`) on the fuzzed slasher reverted with "unknown selector for ConsoleCalls" instead of returning the mocked value. Every fuzz test in this file that mocks a slasher and then calls into it shares the same latent flake — `test_finalizeSetSlasher_appliesAfterDelay` is just the one the fuzzer happened to hit this run. ## Fix Call `assumeNotForgeAddress` (forge-std, inherited via `Test`) to exclude the vm / console / Create2Deployer reserved addresses: - in the shared `_mockInitializedSlasher` helper (covers all tests that mock through it), and - in `test_queueSetSlasher_revertsWhenProposerUnset`, which mocks the slasher inline. ## Verification Reproduced the exact CI failure locally by forcing the console address through the original (unfixed) flow, then confirmed the fix: - `forge test --match-contract SetSlasherTest --fuzz-runs 512` → 12 passed, 0 failed - Full `cd l1-contracts && forge test` → **849 passed, 0 failed, 3 skipped** (was 848 passed / 1 failed before the fix) Targeting the `merge-train/spartan` branch directly per the merge-trains runbook (Option 1: direct fix). --- *Created by [claudebox](https://claudebox.work/v2/sessions/0413f464208ab06d) · group: `slackbot`*
1 parent 353ca4b commit 18dc1f1

1 file changed

Lines changed: 6 additions & 0 deletions

File tree

l1-contracts/test/staking/setSlasher.t.sol

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ contract SetSlasherTest is StakingBase {
1919
/// queueSetSlasher accepts it. Tests that want to exercise the uninitialized-slasher
2020
/// guard call queueSetSlasher directly without mocking.
2121
function _mockInitializedSlasher(address _slasher) internal {
22+
// Foundry intercepts every call to the console address and dispatches it to its console
23+
// handler, which bypasses vm.mockCall. A fuzzed slasher equal to that address therefore makes
24+
// the PROPOSER() lookup revert with "unknown selector for ConsoleCalls" instead of returning
25+
// the mocked value, so exclude the reserved forge addresses.
26+
assumeNotForgeAddress(_slasher);
2227
vm.mockCall(_slasher, abi.encodeWithSignature("PROPOSER()"), abi.encode(address(0xBEEF)));
2328
}
2429

@@ -140,6 +145,7 @@ contract SetSlasherTest is StakingBase {
140145
// Slasher.initializeProposer is permissionless and an attacker could claim the proposer
141146
// role during the 60-day delay.
142147
address owner = _owner(); // cache before expectRevert to avoid consuming it
148+
assumeNotForgeAddress(_newSlasher);
143149
vm.mockCall(_newSlasher, abi.encodeWithSignature("PROPOSER()"), abi.encode(address(0)));
144150

145151
vm.prank(owner);

0 commit comments

Comments
 (0)