Commit 389a8058 authored by Mark Tyneway's avatar Mark Tyneway

contracts-bedrock: modularize test mocks

Modularize the testing mocks some more. Breaks out work
in https://github.com/ethereum-optimism/optimism/pull/7928
to its own pull request
parent db1ef019
...@@ -731,99 +731,3 @@ contract FFIInterface is Test { ...@@ -731,99 +731,3 @@ contract FFIInterface is Test {
return (memRoot, proof); return (memRoot, proof);
} }
} }
library EIP1967Helper {
Vm internal constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
function getAdmin(address _proxy) internal view returns (address) {
return address(uint160(uint256(vm.load(address(_proxy), Constants.PROXY_OWNER_ADDRESS))));
}
function getImplementation(address _proxy) internal view returns (address) {
return address(uint160(uint256(vm.load(address(_proxy), Constants.PROXY_IMPLEMENTATION_ADDRESS))));
}
}
// Used for testing a future upgrade beyond the current implementations.
// We include some variables so that we can sanity check accessing storage values after an upgrade.
contract NextImpl is Initializable {
// Initializable occupies the zero-th slot.
bytes32 slot1;
bytes32[19] __gap;
bytes32 slot21;
bytes32 public constant slot21Init = bytes32(hex"1337");
function initialize(uint8 _init) public reinitializer(_init) {
// Slot21 is unused by an of our upgradeable contracts.
// This is used to verify that we can access this value after an upgrade.
slot21 = slot21Init;
}
}
contract Reverter {
fallback() external {
revert();
}
}
// Useful for testing reentrancy guards
contract CallerCaller {
event WhatHappened(bool success, bytes returndata);
fallback() external {
(bool success, bytes memory returndata) = msg.sender.call(msg.data);
emit WhatHappened(success, returndata);
assembly {
switch success
case 0 { revert(add(returndata, 0x20), mload(returndata)) }
default { return(add(returndata, 0x20), mload(returndata)) }
}
}
}
// Used for testing the `CrossDomainMessenger`'s per-message reentrancy guard.
contract ConfigurableCaller {
bool doRevert = true;
address target;
bytes payload;
event WhatHappened(bool success, bytes returndata);
/// @notice Call the configured target with the configured payload OR revert.
function call() external {
if (doRevert) {
revert("ConfigurableCaller: revert");
} else {
(bool success, bytes memory returndata) = address(target).call(payload);
emit WhatHappened(success, returndata);
assembly {
switch success
case 0 { revert(add(returndata, 0x20), mload(returndata)) }
default { return(add(returndata, 0x20), mload(returndata)) }
}
}
}
/// @notice Set whether or not to have `call` revert.
function setDoRevert(bool _doRevert) external {
doRevert = _doRevert;
}
/// @notice Set the target for the call made in `call`.
function setTarget(address _target) external {
target = _target;
}
/// @notice Set the payload for the call made in `call`.
function setPayload(bytes calldata _payload) external {
payload = _payload;
}
/// @notice Fallback function that reverts if `doRevert` is true.
/// Otherwise, it does nothing.
fallback() external {
if (doRevert) {
revert("ConfigurableCaller: revert");
}
}
}
...@@ -2,13 +2,16 @@ ...@@ -2,13 +2,16 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { Messenger_Initializer, Reverter, CallerCaller, CommonTest } from "test/CommonTest.t.sol"; import { Test } from "forge-std/Test.sol";
import { Messenger_Initializer, Test } from "test/CommonTest.t.sol";
import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol";
import { Reverter, CallerCaller } from "test/mocks/Callers.sol";
// Libraries // Libraries
import { Predeploys } from "../src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { Hashing } from "../src/libraries/Hashing.sol"; import { Hashing } from "src/libraries/Hashing.sol";
import { Encoding } from "../src/libraries/Encoding.sol"; import { Encoding } from "src/libraries/Encoding.sol";
// CrossDomainMessenger_Test is for testing functionality which is common to both the L1 and L2 // CrossDomainMessenger_Test is for testing functionality which is common to both the L1 and L2
// CrossDomainMessenger contracts. For simplicity, we use the L1 Messenger as the test contract. // CrossDomainMessenger contracts. For simplicity, we use the L1 Messenger as the test contract.
...@@ -39,7 +42,7 @@ contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer { ...@@ -39,7 +42,7 @@ contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer {
/// @title ExternalRelay /// @title ExternalRelay
/// @notice A mock external contract called via the SafeCall inside /// @notice A mock external contract called via the SafeCall inside
/// the CrossDomainMessenger's `relayMessage` function. /// the CrossDomainMessenger's `relayMessage` function.
contract ExternalRelay is CommonTest { contract ExternalRelay is Test {
address internal op; address internal op;
address internal fuzzedSender; address internal fuzzedSender;
L1CrossDomainMessenger internal L1Messenger; L1CrossDomainMessenger internal L1Messenger;
......
...@@ -2,8 +2,9 @@ ...@@ -2,8 +2,9 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { Messenger_Initializer, Reverter, ConfigurableCaller } from "test/CommonTest.t.sol"; import { Messenger_Initializer } from "test/CommonTest.t.sol";
import { L2OutputOracle_Initializer } from "test/L2OutputOracle.t.sol"; import { L2OutputOracle_Initializer } from "test/L2OutputOracle.t.sol";
import { Reverter, ConfigurableCaller } from "test/mocks/Callers.sol";
// Libraries // Libraries
import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol";
...@@ -12,12 +13,8 @@ import { Hashing } from "src/libraries/Hashing.sol"; ...@@ -12,12 +13,8 @@ import { Hashing } from "src/libraries/Hashing.sol";
import { Encoding } from "src/libraries/Encoding.sol"; import { Encoding } from "src/libraries/Encoding.sol";
// Target contract dependencies // Target contract dependencies
import { L2OutputOracle } from "src/L1/L2OutputOracle.sol";
import { OptimismPortal } from "src/L1/OptimismPortal.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol";
// Target contract
import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol";
contract L1CrossDomainMessenger_Test is Messenger_Initializer { contract L1CrossDomainMessenger_Test is Messenger_Initializer {
/// @dev The receiver address /// @dev The receiver address
address recipient = address(0xabbaacdc); address recipient = address(0xabbaacdc);
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { Messenger_Initializer, Reverter, ConfigurableCaller } from "test/CommonTest.t.sol"; import { Messenger_Initializer } from "test/CommonTest.t.sol";
import { Reverter, ConfigurableCaller } from "test/mocks/Callers.sol";
// Libraries // Libraries
import { Hashing } from "src/libraries/Hashing.sol"; import { Hashing } from "src/libraries/Hashing.sol";
...@@ -12,10 +13,6 @@ import { Types } from "src/libraries/Types.sol"; ...@@ -12,10 +13,6 @@ import { Types } from "src/libraries/Types.sol";
// Target contract dependencies // Target contract dependencies
import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol";
import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol";
import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol";
// Target contract
import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol";
contract L2CrossDomainMessenger_Test is Messenger_Initializer { contract L2CrossDomainMessenger_Test is Messenger_Initializer {
/// @dev Receiver address for testing /// @dev Receiver address for testing
......
...@@ -3,7 +3,9 @@ pragma solidity 0.8.15; ...@@ -3,7 +3,9 @@ pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { stdError } from "forge-std/Test.sol"; import { stdError } from "forge-std/Test.sol";
import { L2OutputOracle_Initializer, NextImpl, EIP1967Helper } from "test/CommonTest.t.sol"; import { L2OutputOracle_Initializer } from "test/CommonTest.t.sol";
import { NextImpl } from "test/mocks/NextImpl.sol";
import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
// Libraries // Libraries
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
......
...@@ -3,7 +3,8 @@ pragma solidity 0.8.15; ...@@ -3,7 +3,8 @@ pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { stdError } from "forge-std/Test.sol"; import { stdError } from "forge-std/Test.sol";
import { Portal_Initializer, CommonTest, NextImpl } from "test/CommonTest.t.sol"; import { Portal_Initializer } from "test/CommonTest.t.sol";
import { NextImpl } from "test/mocks/NextImpl.sol";
// Libraries // Libraries
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { FeeVault_Initializer, Reverter } from "test/CommonTest.t.sol"; import { FeeVault_Initializer } from "test/CommonTest.t.sol";
import { Reverter } from "test/mocks/Callers.sol";
import { StandardBridge } from "src/universal/StandardBridge.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol";
// Libraries // Libraries
......
...@@ -12,7 +12,7 @@ import { ResourceMetering } from "src/L1/ResourceMetering.sol"; ...@@ -12,7 +12,7 @@ import { ResourceMetering } from "src/L1/ResourceMetering.sol";
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import { Portal_Initializer } from "test/CommonTest.t.sol"; import { Portal_Initializer } from "test/CommonTest.t.sol";
import { EIP1967Helper } from "test/CommonTest.t.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
contract OptimismPortal_Depositor is StdUtils, ResourceMetering { contract OptimismPortal_Depositor is StdUtils, ResourceMetering {
......
...@@ -19,8 +19,75 @@ contract CallRecorder { ...@@ -19,8 +19,75 @@ contract CallRecorder {
} }
} }
/// @dev Useful for testing reentrancy guards
contract CallerCaller {
event WhatHappened(bool success, bytes returndata);
fallback() external {
(bool success, bytes memory returndata) = msg.sender.call(msg.data);
emit WhatHappened(success, returndata);
assembly {
switch success
case 0 { revert(add(returndata, 0x20), mload(returndata)) }
default { return(add(returndata, 0x20), mload(returndata)) }
}
}
}
/// @dev Used for testing the `CrossDomainMessenger`'s per-message reentrancy guard.
contract ConfigurableCaller {
bool doRevert = true;
address target;
bytes payload;
event WhatHappened(bool success, bytes returndata);
/// @notice Call the configured target with the configured payload OR revert.
function call() external {
if (doRevert) {
revert("ConfigurableCaller: revert");
} else {
(bool success, bytes memory returndata) = address(target).call(payload);
emit WhatHappened(success, returndata);
assembly {
switch success
case 0 { revert(add(returndata, 0x20), mload(returndata)) }
default { return(add(returndata, 0x20), mload(returndata)) }
}
}
}
/// @notice Set whether or not to have `call` revert.
function setDoRevert(bool _doRevert) external {
doRevert = _doRevert;
}
/// @notice Set the target for the call made in `call`.
function setTarget(address _target) external {
target = _target;
}
/// @notice Set the payload for the call made in `call`.
function setPayload(bytes calldata _payload) external {
payload = _payload;
}
/// @notice Fallback function that reverts if `doRevert` is true.
/// Otherwise, it does nothing.
fallback() external {
if (doRevert) {
revert("ConfigurableCaller: revert");
}
}
}
/// @dev Any call will revert
contract Reverter { contract Reverter {
function doRevert() public pure { function doRevert() public pure {
revert("Reverter reverted"); revert("Reverter reverted");
} }
fallback() external {
revert();
}
} }
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Vm } from "forge-std/Vm.sol";
import { Constants } from "src/libraries/Constants.sol";
/// @title EIP1967Helper
/// @dev Testing library to help with reading EIP 1967 variables from state
library EIP1967Helper {
Vm internal constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
function getAdmin(address _proxy) internal view returns (address) {
return address(uint160(uint256(vm.load(address(_proxy), Constants.PROXY_OWNER_ADDRESS))));
}
function getImplementation(address _proxy) internal view returns (address) {
return address(uint160(uint256(vm.load(address(_proxy), Constants.PROXY_IMPLEMENTATION_ADDRESS))));
}
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
/// @title NextImpl
/// @dev Used for testing a future upgrade beyond the current implementations.
// We include some variables so that we can sanity check accessing storage values after an upgrade.
contract NextImpl is Initializable {
// Initializable occupies the zero-th slot.
bytes32 slot1;
bytes32[19] __gap;
bytes32 slot21;
bytes32 public constant slot21Init = bytes32(hex"1337");
function initialize(uint8 _init) public reinitializer(_init) {
// Slot21 is unused by an of our upgradeable contracts.
// This is used to verify that we can access this value after an upgrade.
slot21 = slot21Init;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment