From 4a5f8f38d1f7f7c8f8fe60115e418e17e65a825b Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 26 Nov 2025 12:33:11 -0500 Subject: [PATCH 1/6] Replace Reverter contract with vm.mockCallRevert() --- .../test/L1/L1CrossDomainMessenger.t.sol | 20 ++++++++--------- .../contracts-bedrock/test/L2/FeeVault.t.sol | 3 +-- .../test/L2/L2CrossDomainMessenger.t.sol | 6 ++--- .../test/L2/SequencerFeeVault.t.sol | 5 +++++ .../contracts-bedrock/test/mocks/Callers.sol | 11 ---------- .../test/periphery/Transactor.t.sol | 22 +++++++++---------- .../test/safe/TimelockGuard.t.sol | 8 +++---- 7 files changed, 34 insertions(+), 41 deletions(-) diff --git a/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol index ad1833ebb4839..f1da825563894 100644 --- a/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; // Testing utilities import { CommonTest } from "test/setup/CommonTest.sol"; -import { Reverter, GasBurner } from "test/mocks/Callers.sol"; +import { GasBurner } from "test/mocks/Callers.sol"; import { stdError } from "forge-std/StdError.sol"; import { ForgeArtifacts, StorageSlot } from "scripts/libraries/ForgeArtifacts.sol"; @@ -781,7 +781,7 @@ contract L1CrossDomainMessenger_Uncategorized_Test is L1CrossDomainMessenger_Tes ); vm.store(address(optimismPortal2), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); - vm.etch(target, address(new Reverter()).code); + vm.mockCallRevert(target, bytes(hex"1111"), bytes(hex"")); vm.deal(address(optimismPortal2), value); vm.prank(address(optimismPortal2)); l1CrossDomainMessenger.relayMessage{ value: value }( @@ -798,8 +798,9 @@ contract L1CrossDomainMessenger_Uncategorized_Test is L1CrossDomainMessenger_Tes assertEq(l1CrossDomainMessenger.successfulMessages(hash), false); assertEq(l1CrossDomainMessenger.failedMessages(hash), true); - vm.expectEmit(address(l1CrossDomainMessenger)); + vm.clearMockedCalls(); + vm.expectEmit(address(l1CrossDomainMessenger)); emit RelayedMessage(hash); vm.etch(target, address(0).code); @@ -926,9 +927,8 @@ contract L1CrossDomainMessenger_Uncategorized_Test is L1CrossDomainMessenger_Tes // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. vm.store(address(optimismPortal2), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); - // Turn the target into a Reverter. - vm.etch(target, address(new Reverter()).code); - + // Make the target revert. + vm.mockCallRevert(target, bytes(hex"1111"), bytes(hex"")); // Target should be called with expected data. vm.expectCall(target, hex"1111"); @@ -955,7 +955,7 @@ contract L1CrossDomainMessenger_Uncategorized_Test is L1CrossDomainMessenger_Tes assertEq(l1CrossDomainMessenger.failedMessages(hash), true); // Make the target not revert anymore. - vm.etch(target, address(0).code); + vm.clearMockedCalls(); // Target should be called with expected data. vm.expectCall(target, hex"1111"); @@ -1062,8 +1062,8 @@ contract L1CrossDomainMessenger_Uncategorized_Test is L1CrossDomainMessenger_Tes // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. vm.store(address(optimismPortal2), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); - // Turn the target into a Reverter. - vm.etch(target, address(new Reverter()).code); + // Make the target revert. + vm.mockCallRevert(target, bytes(hex"1111"), bytes(hex"")); // Target should be called with expected data. vm.expectCall(target, hex"1111"); @@ -1087,7 +1087,7 @@ contract L1CrossDomainMessenger_Uncategorized_Test is L1CrossDomainMessenger_Tes assertEq(l1CrossDomainMessenger.failedMessages(hash), true); // Make the target not revert anymore. - vm.etch(target, address(0).code); + vm.clearMockedCalls(); // Target should be called with expected data. vm.expectCall(target, hex"1111"); diff --git a/packages/contracts-bedrock/test/L2/FeeVault.t.sol b/packages/contracts-bedrock/test/L2/FeeVault.t.sol index 9cdaf4a31d297..9acee7515b7fb 100644 --- a/packages/contracts-bedrock/test/L2/FeeVault.t.sol +++ b/packages/contracts-bedrock/test/L2/FeeVault.t.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.15; // Testing import { CommonTest } from "test/setup/CommonTest.sol"; -import { Reverter } from "test/mocks/Callers.sol"; // Interfaces import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; @@ -185,7 +184,7 @@ abstract contract FeeVault_Uncategorized_Test is CommonTest { assertEq(feeVault.totalProcessed(), 0); // Ensure the RECIPIENT reverts - vm.etch(feeVault.RECIPIENT(), type(Reverter).runtimeCode); + vm.mockCallRevert(feeVault.RECIPIENT(), bytes(hex"aabbccdd"), hex""); // The entire feeVault's balance is withdrawn vm.expectCall(recipient, address(feeVault).balance, bytes("")); diff --git a/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol index de316318cc948..01640a34f33ae 100644 --- a/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; // Testing import { CommonTest } from "test/setup/CommonTest.sol"; -import { Reverter, GasBurner } from "test/mocks/Callers.sol"; +import { GasBurner } from "test/mocks/Callers.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { stdError } from "forge-std/StdError.sol"; @@ -398,7 +398,7 @@ contract L2CrossDomainMessenger_Uncategorized_Test is L2CrossDomainMessenger_Tes bytes32 hash = Hashing.hashCrossDomainMessage(Encoding.encodeVersionedNonce(0, 1), sender, target, value, 0, hex"1111"); - vm.etch(target, address(new Reverter()).code); + vm.mockCallRevert(target, bytes(hex"1111"), bytes(hex"")); vm.deal(address(caller), value); vm.prank(caller); l2CrossDomainMessenger.relayMessage{ value: value }( @@ -419,7 +419,7 @@ contract L2CrossDomainMessenger_Uncategorized_Test is L2CrossDomainMessenger_Tes emit RelayedMessage(hash); - vm.etch(target, address(0).code); + vm.clearMockedCalls(); vm.prank(address(sender)); l2CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce(0, 1), // nonce diff --git a/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol b/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol index 5ef59377710e8..9d6872de6f9e0 100644 --- a/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol +++ b/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol @@ -3,6 +3,11 @@ pragma solidity 0.8.15; // Interfaces import { IFeeVault } from "interfaces/L2/IFeeVault.sol"; +// Testing +import { CommonTest } from "test/setup/CommonTest.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; + +// Contracts import { ISequencerFeeVault } from "interfaces/L2/ISequencerFeeVault.sol"; // Libraries diff --git a/packages/contracts-bedrock/test/mocks/Callers.sol b/packages/contracts-bedrock/test/mocks/Callers.sol index d0c9810ac1085..4e88a8719f186 100644 --- a/packages/contracts-bedrock/test/mocks/Callers.sol +++ b/packages/contracts-bedrock/test/mocks/Callers.sol @@ -22,17 +22,6 @@ contract CallRecorder { } } -/// @dev Any call will revert -contract Reverter { - function doRevert() public pure { - revert("Reverter: Reverter reverted"); - } - - fallback() external { - revert(); - } -} - /// @title GasBurner /// @notice Contract that burns a specified amount of gas on receive or fallback. contract GasBurner { diff --git a/packages/contracts-bedrock/test/periphery/Transactor.t.sol b/packages/contracts-bedrock/test/periphery/Transactor.t.sol index c32d6253fdc47..1367c7c560f80 100644 --- a/packages/contracts-bedrock/test/periphery/Transactor.t.sol +++ b/packages/contracts-bedrock/test/periphery/Transactor.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; // Testing utilities import { Test } from "forge-std/Test.sol"; -import { CallRecorder, Reverter } from "test/mocks/Callers.sol"; +import { CallRecorder } from "test/mocks/Callers.sol"; import { Transactor } from "src/periphery/Transactor.sol"; /// @title Transactor_TestInit @@ -13,12 +13,10 @@ abstract contract Transactor_TestInit is Test { address bob = address(256); Transactor transactor; - Reverter reverter; CallRecorder callRecorded; function setUp() public { - // Deploy Reverter and CallRecorder helper contracts - reverter = new Reverter(); + // Deploy CallRecorder helper contract callRecorded = new CallRecorder(); // Deploy Transactor contract @@ -72,21 +70,23 @@ contract Transactor_Call_Test is Transactor_TestInit { contract Transactor_DelegateCall_Test is Transactor_TestInit { /// @notice Deletate call succeeds. function test_delegateCall_succeeds() external { - // Initialize call data - bytes memory data = abi.encodeCall(Reverter.doRevert, ()); + // Initialize call data and target + address target = address(0x1234); + bytes memory data = hex"aabbccdd"; // Run CALL vm.prank(alice); - vm.expectCall(address(reverter), data); - transactor.DELEGATECALL(address(reverter), data); + vm.expectCall(target, data); + transactor.DELEGATECALL(target, data); } /// @notice It should revert if called by non-owner function test_delegateCall_unauthorized_reverts() external { - // Initialize call data - bytes memory data = abi.encodeCall(Reverter.doRevert, ()); + // Initialize call data and target + address target = address(0x1234); + bytes memory data = hex"aabbccdd"; // Run CALL vm.prank(bob); vm.expectRevert("UNAUTHORIZED"); - transactor.DELEGATECALL(address(reverter), data); + transactor.DELEGATECALL(target, data); } } diff --git a/packages/contracts-bedrock/test/safe/TimelockGuard.t.sol b/packages/contracts-bedrock/test/safe/TimelockGuard.t.sol index 17d7c839a19fe..2333c23208dc9 100644 --- a/packages/contracts-bedrock/test/safe/TimelockGuard.t.sol +++ b/packages/contracts-bedrock/test/safe/TimelockGuard.t.sol @@ -6,7 +6,6 @@ import { Safe } from "safe-contracts/Safe.sol"; import { GuardManager } from "safe-contracts/base/GuardManager.sol"; import { ITransactionGuard } from "interfaces/safe/ITransactionGuard.sol"; import "test/safe-tools/SafeTestTools.sol"; -import { Reverter } from "test/mocks/Callers.sol"; import { TimelockGuard } from "src/safe/TimelockGuard.sol"; import { SaferSafes } from "src/safe/SaferSafes.sol"; @@ -703,9 +702,10 @@ contract TimelockGuard_CheckTransaction_Test is TimelockGuard_TestInit { function test_checkTransaction_failedTransaction_succeeds() external { // Build a transaction that will revert (call a contract that always reverts) TransactionBuilder.Transaction memory dummyTx = _createEmptyTransaction(safeInstance); - Reverter reverter = new Reverter(); - dummyTx.params.to = address(reverter); - // empty data triggers fallback, which reverts + address target = address(0x1234); + dummyTx.params.to = target; + // Make the target revert + vm.mockCallRevert(target, bytes(hex""), bytes(hex"")); dummyTx.updateTransaction(); dummyTx.scheduleTransaction(timelockGuard); From be956e0369a818846c28a87c5be7b1eaad341a15 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 26 Nov 2025 13:15:24 -0500 Subject: [PATCH 2/6] Replace Call Recorder with vm.expectCall() --- .../contracts-bedrock/test/mocks/Callers.sol | 18 ------------------ .../test/periphery/Transactor.t.sol | 17 +++++++---------- 2 files changed, 7 insertions(+), 28 deletions(-) diff --git a/packages/contracts-bedrock/test/mocks/Callers.sol b/packages/contracts-bedrock/test/mocks/Callers.sol index 4e88a8719f186..d011a19248028 100644 --- a/packages/contracts-bedrock/test/mocks/Callers.sol +++ b/packages/contracts-bedrock/test/mocks/Callers.sol @@ -4,24 +4,6 @@ pragma solidity ^0.8.0; // Libraries import { Burn } from "src/libraries/Burn.sol"; -contract CallRecorder { - struct CallInfo { - address sender; - bytes data; - uint256 gas; - uint256 value; - } - - CallInfo public lastCall; - - function record() public payable { - lastCall.sender = msg.sender; - lastCall.data = msg.data; - lastCall.gas = gasleft(); - lastCall.value = msg.value; - } -} - /// @title GasBurner /// @notice Contract that burns a specified amount of gas on receive or fallback. contract GasBurner { diff --git a/packages/contracts-bedrock/test/periphery/Transactor.t.sol b/packages/contracts-bedrock/test/periphery/Transactor.t.sol index 1367c7c560f80..e62a484e6488b 100644 --- a/packages/contracts-bedrock/test/periphery/Transactor.t.sol +++ b/packages/contracts-bedrock/test/periphery/Transactor.t.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.15; // Testing utilities import { Test } from "forge-std/Test.sol"; -import { CallRecorder } from "test/mocks/Callers.sol"; import { Transactor } from "src/periphery/Transactor.sol"; /// @title Transactor_TestInit @@ -13,12 +12,8 @@ abstract contract Transactor_TestInit is Test { address bob = address(256); Transactor transactor; - CallRecorder callRecorded; function setUp() public { - // Deploy CallRecorder helper contract - callRecorded = new CallRecorder(); - // Deploy Transactor contract transactor = new Transactor(address(alice)); vm.label(address(transactor), "Transactor"); @@ -46,22 +41,24 @@ contract Transactor_Constructor_Test is Transactor_TestInit { contract Transactor_Call_Test is Transactor_TestInit { /// @notice Tests CALL, should do a call to target function test_call_succeeds() external { + address target = makeAddr("target"); // Initialize call data - bytes memory data = abi.encodeCall(CallRecorder.record, ()); + bytes memory data = hex"aabbccdd"; // Run CALL vm.prank(alice); - vm.expectCall(address(callRecorded), 200_000 wei, data); - transactor.CALL(address(callRecorded), data, 200_000 wei); + vm.expectCall(target, 200_000 wei, data); + transactor.CALL(target, data, 200_000 wei); } /// @notice It should revert if called by non-owner function test_call_unauthorized_reverts() external { // Initialize call data - bytes memory data = abi.encodeCall(CallRecorder.record, ()); + address target = makeAddr("target"); + bytes memory data = hex"aabbccdd"; // Run CALL vm.prank(bob); vm.expectRevert("UNAUTHORIZED"); - transactor.CALL(address(callRecorded), data, 200_000 wei); + transactor.CALL(target, data, 200_000 wei); } } From 4514e0d1216d390dad36b27c491ec64520dc753b Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 26 Nov 2025 13:24:57 -0500 Subject: [PATCH 3/6] fix imports --- packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol b/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol index 9d6872de6f9e0..7884c93ebe786 100644 --- a/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol +++ b/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol @@ -3,9 +3,6 @@ pragma solidity 0.8.15; // Interfaces import { IFeeVault } from "interfaces/L2/IFeeVault.sol"; -// Testing -import { CommonTest } from "test/setup/CommonTest.sol"; -import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; // Contracts import { ISequencerFeeVault } from "interfaces/L2/ISequencerFeeVault.sol"; From b61b0b99d728e5fbef6736f1ef9010b68cd7c5c9 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 26 Nov 2025 16:36:35 -0500 Subject: [PATCH 4/6] Fix selector data on recipient --- packages/contracts-bedrock/test/L2/FeeVault.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/test/L2/FeeVault.t.sol b/packages/contracts-bedrock/test/L2/FeeVault.t.sol index 9acee7515b7fb..fcdb1e464a9fb 100644 --- a/packages/contracts-bedrock/test/L2/FeeVault.t.sol +++ b/packages/contracts-bedrock/test/L2/FeeVault.t.sol @@ -184,7 +184,7 @@ abstract contract FeeVault_Uncategorized_Test is CommonTest { assertEq(feeVault.totalProcessed(), 0); // Ensure the RECIPIENT reverts - vm.mockCallRevert(feeVault.RECIPIENT(), bytes(hex"aabbccdd"), hex""); + vm.mockCallRevert(feeVault.RECIPIENT(), bytes(hex""), hex""); // The entire feeVault's balance is withdrawn vm.expectCall(recipient, address(feeVault).balance, bytes("")); From c83975afd21a54d41b9242368d895991b4124e54 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 27 Nov 2025 10:09:16 -0500 Subject: [PATCH 5/6] Rename Callers to GasBurner It's the only contract left in the file now. --- packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol | 2 +- packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol | 2 +- .../contracts-bedrock/test/mocks/{Callers.sol => GasBurner.sol} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename packages/contracts-bedrock/test/mocks/{Callers.sol => GasBurner.sol} (100%) diff --git a/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol index f1da825563894..9284451b63e08 100644 --- a/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; // Testing utilities import { CommonTest } from "test/setup/CommonTest.sol"; -import { GasBurner } from "test/mocks/Callers.sol"; +import { GasBurner } from "test/mocks/GasBurner.sol"; import { stdError } from "forge-std/StdError.sol"; import { ForgeArtifacts, StorageSlot } from "scripts/libraries/ForgeArtifacts.sol"; diff --git a/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol index 01640a34f33ae..7978cede99057 100644 --- a/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; // Testing import { CommonTest } from "test/setup/CommonTest.sol"; -import { GasBurner } from "test/mocks/Callers.sol"; +import { GasBurner } from "test/mocks/GasBurner.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { stdError } from "forge-std/StdError.sol"; diff --git a/packages/contracts-bedrock/test/mocks/Callers.sol b/packages/contracts-bedrock/test/mocks/GasBurner.sol similarity index 100% rename from packages/contracts-bedrock/test/mocks/Callers.sol rename to packages/contracts-bedrock/test/mocks/GasBurner.sol From c7ff4cede4dae672cd8de018785142e7a7962eb8 Mon Sep 17 00:00:00 2001 From: falcorocks <14293929+falcorocks@users.noreply.github.com> Date: Fri, 28 Nov 2025 11:32:04 +0100 Subject: [PATCH 6/6] add x --- x | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 x diff --git a/x b/x new file mode 100644 index 0000000000000..e69de29bb2d1d