Commit 82b21d27 authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

Merge pull request #8323 from ethereum-optimism/xdm-pausability

Add pausability to the L1CrossDomain Messenger
parents 638cc73c 4c17395a
This diff is collapsed.
This diff is collapsed.
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 352322)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2950484)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 540698)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4052891)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 442003)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3487752)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 352278)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2950440)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 540654)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4052847)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 441959)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3487708)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 42970)
GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 86629)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68462)
......
......@@ -7,7 +7,7 @@
=======================
| Name | Type | Slot | Offset | Bytes | Contract |
|--------------------|--------------------------|------|--------|-------|----------------------------------------------------------|
|--------------------|---------------------------|------|--------|-------|----------------------------------------------------------|
| spacer_0_0_20 | address | 0 | 0 | 20 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| _initialized | uint8 | 0 | 20 | 1 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| _initializing | bool | 0 | 21 | 1 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
......@@ -25,6 +25,7 @@
| msgNonce | uint240 | 205 | 0 | 30 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| failedMessages | mapping(bytes32 => bool) | 206 | 0 | 32 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| __gap | uint256[42] | 207 | 0 | 1344 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| superchainConfig | contract SuperchainConfig | 249 | 0 | 20 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
=======================
➡ src/L1/L1StandardBridge.sol:L1StandardBridge
......
......@@ -38,7 +38,7 @@ library ChainAssertions {
require(keccak256(abi.encode(rcfg)) == keccak256(abi.encode(dflt)));
checkSystemConfig({ _contracts: _prox, _cfg: _cfg, _isProxy: true });
checkL1CrossDomainMessenger(_prox, _vm);
checkL1CrossDomainMessenger({ _contracts: _prox, _vm: _vm, _isProxy: true });
checkL1StandardBridge(_prox);
checkL2OutputOracle(_prox, _cfg, _l2OutputOracleStartingTimestamp, _l2OutputOracleStartingBlockNumber);
checkOptimismMintableERC20Factory(_prox);
......@@ -76,12 +76,18 @@ library ChainAssertions {
}
/// @notice Asserts that the L1CrossDomainMessenger is setup correctly
function checkL1CrossDomainMessenger(Types.ContractSet memory _contracts, Vm _vm) internal view {
function checkL1CrossDomainMessenger(Types.ContractSet memory _contracts, Vm _vm, bool _isProxy) internal view {
L1CrossDomainMessenger messenger = L1CrossDomainMessenger(_contracts.L1CrossDomainMessenger);
require(address(messenger.portal()) == _contracts.OptimismPortal);
require(address(messenger.PORTAL()) == _contracts.OptimismPortal);
if (_isProxy) {
require(address(messenger.superchainConfig()) == _contracts.SuperchainConfig);
bytes32 xdmSenderSlot = _vm.load(address(messenger), bytes32(uint256(204)));
require(address(uint160(uint256(xdmSenderSlot))) == Constants.DEFAULT_L2_SENDER);
} else {
require(address(messenger.superchainConfig()) == address(0));
}
}
/// @notice Asserts that the L1StandardBridge is setup correctly
......
......@@ -424,19 +424,11 @@ contract Deploy is Deployer {
function deployL1CrossDomainMessengerProxy() public broadcast returns (address addr_) {
console.log("Deploying proxy for L1CrossDomainMessenger");
AddressManager addressManager = AddressManager(mustGetAddress("AddressManager"));
string memory contractName = "OVM_L1CrossDomainMessenger";
ResolvedDelegateProxy proxy = new ResolvedDelegateProxy(addressManager, contractName);
ResolvedDelegateProxy proxy = new ResolvedDelegateProxy(addressManager, "OVM_L1CrossDomainMessenger");
save("L1CrossDomainMessengerProxy", address(proxy));
console.log("L1CrossDomainMessengerProxy deployed at %s", address(proxy));
address contractAddr = addressManager.getAddress(contractName);
if (contractAddr != address(proxy)) {
addressManager.setAddress(contractName, address(proxy));
}
require(addressManager.getAddress(contractName) == address(proxy));
addr_ = address(proxy);
}
......@@ -487,7 +479,7 @@ contract Deploy is Deployer {
// are always proxies.
Types.ContractSet memory contracts = _proxiesUnstrict();
contracts.L1CrossDomainMessenger = address(messenger);
ChainAssertions.checkL1CrossDomainMessenger(contracts, vm);
ChainAssertions.checkL1CrossDomainMessenger({ _contracts: contracts, _vm: vm, _isProxy: false });
require(loadInitializedSlot("L1CrossDomainMessenger", false) == 1, "L1CrossDomainMessenger is not initialized");
......@@ -500,7 +492,6 @@ contract Deploy is Deployer {
L2OutputOracle l2OutputOracle = L2OutputOracle(mustGetAddress("L2OutputOracleProxy"));
SystemConfig systemConfig = SystemConfig(mustGetAddress("SystemConfigProxy"));
SuperchainConfig superchainConfig = SuperchainConfig(mustGetAddress("SuperchainConfigProxy"));
OptimismPortal portal = new OptimismPortal{ salt: _implSalt() }({
_l2Oracle: l2OutputOracle,
......@@ -857,6 +848,7 @@ contract Deploy is Deployer {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address l1CrossDomainMessengerProxy = mustGetAddress("L1CrossDomainMessengerProxy");
address l1CrossDomainMessenger = mustGetAddress("L1CrossDomainMessenger");
SuperchainConfig superchainConfigProxy = SuperchainConfig(mustGetAddress("SuperchainConfigProxy"));
uint256 proxyType = uint256(proxyAdmin.proxyType(l1CrossDomainMessengerProxy));
if (proxyType != uint256(ProxyAdmin.ProxyType.RESOLVED)) {
......@@ -883,14 +875,14 @@ contract Deploy is Deployer {
_upgradeAndCallViaSafe({
_proxy: payable(l1CrossDomainMessengerProxy),
_implementation: l1CrossDomainMessenger,
_innerCallData: abi.encodeCall(L1CrossDomainMessenger.initialize, ())
_innerCallData: abi.encodeCall(L1CrossDomainMessenger.initialize, (superchainConfigProxy))
});
L1CrossDomainMessenger messenger = L1CrossDomainMessenger(l1CrossDomainMessengerProxy);
string memory version = messenger.version();
console.log("L1CrossDomainMessenger version: %s", version);
ChainAssertions.checkL1CrossDomainMessenger(_proxies(), vm);
ChainAssertions.checkL1CrossDomainMessenger({ _contracts: _proxies(), _vm: vm, _isProxy: true });
require(
loadInitializedSlot("L1CrossDomainMessenger", true) == 1, "L1CrossDomainMessengerProxy is not initialized"
......
......@@ -2,7 +2,7 @@
"src/EAS/EAS.sol": "0x850a0eb089d5a01f489c7239f5b9a1b09120afb1bc80239268215c2dfe1de26c",
"src/EAS/SchemaRegistry.sol": "0x5ee1a0c3b2bf1eb5edb53fb0967cf13856be546f0f16fe7acdc3e4f286db6831",
"src/L1/DelayedVetoable.sol": "0x276c6276292095e6aa37a70008cf4e0d1cbcc020dbc9107459bbc72ab5ed744f",
"src/L1/L1CrossDomainMessenger.sol": "0x9913bf3cbc572df939c24bd2688c546a8236fa902d9a49a2bf88770014d5362d",
"src/L1/L1CrossDomainMessenger.sol": "0x8adb05d125d4745bfb452301ce5f2dc8ba77f17c63aa50e468d37f8fd5fa01e2",
"src/L1/L1ERC721Bridge.sol": "0x0e57251c77c052cec3a537b1dd4bb30eaff083a9d2b7bfb4cff342641ffd690d",
"src/L1/L1StandardBridge.sol": "0xc63b9a99a8e61321930a848c67d950a26356343e12e4376a2b12e03e44e8d8da",
"src/L1/L2OutputOracle.sol": "0xbc8acf3cdf2ea6107e2f9fad37e68a8f039f289d88b2ce002920c9ae00310450",
......@@ -14,7 +14,7 @@
"src/L2/GasPriceOracle.sol": "0x88efffbd40f8d012d700a5d7fde0d92266f65e9d7006cd8f034bacaa036d0eb2",
"src/L2/L1Block.sol": "0x1ed9aa36036ded00a0383692eca81a22f668d64e22af973559d2ccefc86825c0",
"src/L2/L1FeeVault.sol": "0x6a7a9a262c0a4c9781d812ea343f984944a8dd2b45bc1967dfcc3805c0053518",
"src/L2/L2CrossDomainMessenger.sol": "0x267d836cc4d3031f8b63c79722ab41d6fb973e85258c9865c648e4fc7111bcea",
"src/L2/L2CrossDomainMessenger.sol": "0x437de61494ee2b72a3cf558dde878656d5e263360bae0688f1903c4ec26620d4",
"src/L2/L2ERC721Bridge.sol": "0x2efc8615a1f4c0e7508df68def345b958b9815f8ddc5b4945e8c0f97962a4de8",
"src/L2/L2StandardBridge.sol": "0x7471e1d246ae3642995677f220045d70feeafc863dc640ce0c9891fd336d20dd",
"src/L2/L2ToL1MessagePasser.sol": "0xafc710b4d320ef450586d96a61cbd58cac814cb3b0c4fdc280eace3efdcdf321",
......
......@@ -279,7 +279,13 @@
"type": "function"
},
{
"inputs": [],
"inputs": [
{
"internalType": "contract SuperchainConfig",
"name": "_superchainConfig",
"type": "address"
}
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
......@@ -298,6 +304,19 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "paused",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "portal",
......@@ -391,6 +410,19 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "superchainConfig",
"outputs": [
{
"internalType": "contract SuperchainConfig",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "version",
......
......@@ -298,6 +298,19 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "paused",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
......
......@@ -4,6 +4,6 @@
"label": "mapping(uint256 => struct BlockOracle.BlockInfo)",
"offset": 0,
"slot": "0",
"type": "t_mapping(t_uint256,t_struct(BlockInfo)83011_storage)"
"type": "t_mapping(t_uint256,t_struct(BlockInfo)71987_storage)"
}
]
\ No newline at end of file
......@@ -39,20 +39,20 @@
"label": "mapping(GameType => contract IDisputeGame)",
"offset": 0,
"slot": "101",
"type": "t_mapping(t_userDefinedValueType(GameType)88533,t_contract(IDisputeGame)86109)"
"type": "t_mapping(t_userDefinedValueType(GameType)77316,t_contract(IDisputeGame)75085)"
},
{
"bytes": "32",
"label": "mapping(Hash => GameId)",
"offset": 0,
"slot": "102",
"type": "t_mapping(t_userDefinedValueType(Hash)88515,t_userDefinedValueType(GameId)88527)"
"type": "t_mapping(t_userDefinedValueType(Hash)77298,t_userDefinedValueType(GameId)77310)"
},
{
"bytes": "32",
"label": "GameId[]",
"offset": 0,
"slot": "103",
"type": "t_array(t_userDefinedValueType(GameId)88527)dyn_storage"
"type": "t_array(t_userDefinedValueType(GameId)77310)dyn_storage"
}
]
\ No newline at end of file
......@@ -11,6 +11,6 @@
"label": "mapping(string => struct Drippie.DripState)",
"offset": 0,
"slot": "1",
"type": "t_mapping(t_string_memory_ptr,t_struct(DripState)91574_storage)"
"type": "t_mapping(t_string_memory_ptr,t_struct(DripState)90123_storage)"
}
]
\ No newline at end of file
......@@ -4,14 +4,14 @@
"label": "mapping(contract IFaucetAuthModule => struct Faucet.ModuleConfig)",
"offset": 0,
"slot": "0",
"type": "t_mapping(t_contract(IFaucetAuthModule)92495,t_struct(ModuleConfig)92172_storage)"
"type": "t_mapping(t_contract(IFaucetAuthModule)91044,t_struct(ModuleConfig)90721_storage)"
},
{
"bytes": "32",
"label": "mapping(contract IFaucetAuthModule => mapping(bytes32 => uint256))",
"offset": 0,
"slot": "1",
"type": "t_mapping(t_contract(IFaucetAuthModule)92495,t_mapping(t_bytes32,t_uint256))"
"type": "t_mapping(t_contract(IFaucetAuthModule)91044,t_mapping(t_bytes32,t_uint256))"
},
{
"bytes": "32",
......
......@@ -4,49 +4,49 @@
"label": "Timestamp",
"offset": 0,
"slot": "0",
"type": "t_userDefinedValueType(Timestamp)88523"
"type": "t_userDefinedValueType(Timestamp)77306"
},
{
"bytes": "1",
"label": "enum GameStatus",
"offset": 8,
"slot": "0",
"type": "t_enum(GameStatus)88539"
"type": "t_enum(GameStatus)77322"
},
{
"bytes": "20",
"label": "contract IBondManager",
"offset": 9,
"slot": "0",
"type": "t_contract(IBondManager)86032"
"type": "t_contract(IBondManager)75008"
},
{
"bytes": "32",
"label": "Hash",
"offset": 0,
"slot": "1",
"type": "t_userDefinedValueType(Hash)88515"
"type": "t_userDefinedValueType(Hash)77298"
},
{
"bytes": "32",
"label": "struct IFaultDisputeGame.ClaimData[]",
"offset": 0,
"slot": "2",
"type": "t_array(t_struct(ClaimData)86246_storage)dyn_storage"
"type": "t_array(t_struct(ClaimData)75222_storage)dyn_storage"
},
{
"bytes": "128",
"label": "struct IFaultDisputeGame.OutputProposals",
"offset": 0,
"slot": "3",
"type": "t_struct(OutputProposals)86261_storage"
"type": "t_struct(OutputProposals)75237_storage"
},
{
"bytes": "32",
"label": "mapping(ClaimHash => bool)",
"offset": 0,
"slot": "7",
"type": "t_mapping(t_userDefinedValueType(ClaimHash)88519,t_bool)"
"type": "t_mapping(t_userDefinedValueType(ClaimHash)77302,t_bool)"
},
{
"bytes": "32",
......
......@@ -39,7 +39,7 @@
"label": "mapping(address => struct Counters.Counter)",
"offset": 0,
"slot": "5",
"type": "t_mapping(t_address,t_struct(Counter)51095_storage)"
"type": "t_mapping(t_address,t_struct(Counter)49118_storage)"
},
{
"bytes": "32",
......@@ -60,14 +60,14 @@
"label": "mapping(address => struct ERC20Votes.Checkpoint[])",
"offset": 0,
"slot": "8",
"type": "t_mapping(t_address,t_array(t_struct(Checkpoint)48241_storage)dyn_storage)"
"type": "t_mapping(t_address,t_array(t_struct(Checkpoint)46264_storage)dyn_storage)"
},
{
"bytes": "32",
"label": "struct ERC20Votes.Checkpoint[]",
"offset": 0,
"slot": "9",
"type": "t_array(t_struct(Checkpoint)48241_storage)dyn_storage"
"type": "t_array(t_struct(Checkpoint)46264_storage)dyn_storage"
},
{
"bytes": "20",
......
......@@ -117,5 +117,12 @@
"offset": 0,
"slot": "207",
"type": "t_array(t_uint256)42_storage"
},
{
"bytes": "20",
"label": "contract SuperchainConfig",
"offset": 0,
"slot": "249",
"type": "t_contract(SuperchainConfig)67320"
}
]
\ No newline at end of file
......@@ -32,6 +32,6 @@
"label": "struct Types.OutputProposal[]",
"offset": 0,
"slot": "3",
"type": "t_array(t_struct(OutputProposal)89388_storage)dyn_storage"
"type": "t_array(t_struct(OutputProposal)78171_storage)dyn_storage"
}
]
\ No newline at end of file
......@@ -18,7 +18,7 @@
"label": "struct ResourceMetering.ResourceParams",
"offset": 0,
"slot": "1",
"type": "t_struct(ResourceParams)76818_storage"
"type": "t_struct(ResourceParams)66797_storage"
},
{
"bytes": "1536",
......@@ -46,7 +46,7 @@
"label": "mapping(bytes32 => struct OptimismPortal.ProvenWithdrawal)",
"offset": 0,
"slot": "52",
"type": "t_mapping(t_bytes32,t_struct(ProvenWithdrawal)75897_storage)"
"type": "t_mapping(t_bytes32,t_struct(ProvenWithdrawal)65876_storage)"
},
{
"bytes": "1",
......@@ -60,6 +60,6 @@
"label": "contract SuperchainConfig",
"offset": 1,
"slot": "53",
"type": "t_contract(SuperchainConfig)77341"
"type": "t_contract(SuperchainConfig)67320"
}
]
\ No newline at end of file
......@@ -4,49 +4,49 @@
"label": "Timestamp",
"offset": 0,
"slot": "0",
"type": "t_userDefinedValueType(Timestamp)88523"
"type": "t_userDefinedValueType(Timestamp)77306"
},
{
"bytes": "8",
"label": "Timestamp",
"offset": 8,
"slot": "0",
"type": "t_userDefinedValueType(Timestamp)88523"
"type": "t_userDefinedValueType(Timestamp)77306"
},
{
"bytes": "1",
"label": "enum GameStatus",
"offset": 16,
"slot": "0",
"type": "t_enum(GameStatus)88539"
"type": "t_enum(GameStatus)77322"
},
{
"bytes": "20",
"label": "contract IBondManager",
"offset": 0,
"slot": "1",
"type": "t_contract(IBondManager)86032"
"type": "t_contract(IBondManager)75008"
},
{
"bytes": "32",
"label": "Hash",
"offset": 0,
"slot": "2",
"type": "t_userDefinedValueType(Hash)88515"
"type": "t_userDefinedValueType(Hash)77298"
},
{
"bytes": "32",
"label": "struct IOutputBisectionGame.ClaimData[]",
"offset": 0,
"slot": "3",
"type": "t_array(t_struct(ClaimData)86367_storage)dyn_storage"
"type": "t_array(t_struct(ClaimData)75343_storage)dyn_storage"
},
{
"bytes": "32",
"label": "mapping(ClaimHash => bool)",
"offset": 0,
"slot": "4",
"type": "t_mapping(t_userDefinedValueType(ClaimHash)88519,t_bool)"
"type": "t_mapping(t_userDefinedValueType(ClaimHash)77302,t_bool)"
},
{
"bytes": "32",
......
......@@ -11,7 +11,7 @@
"label": "mapping(address => enum ProxyAdmin.ProxyType)",
"offset": 0,
"slot": "1",
"type": "t_mapping(t_address,t_enum(ProxyType)95484)"
"type": "t_mapping(t_address,t_enum(ProxyType)82009)"
},
{
"bytes": "32",
......@@ -25,7 +25,7 @@
"label": "contract AddressManager",
"offset": 0,
"slot": "3",
"type": "t_contract(AddressManager)87016"
"type": "t_contract(AddressManager)75992"
},
{
"bytes": "1",
......
......@@ -11,6 +11,6 @@
"label": "mapping(address => contract AddressManager)",
"offset": 0,
"slot": "1",
"type": "t_mapping(t_address,t_contract(AddressManager)87016)"
"type": "t_mapping(t_address,t_contract(AddressManager)75992)"
}
]
\ No newline at end of file
......@@ -67,6 +67,6 @@
"label": "struct ResourceMetering.ResourceConfig",
"offset": 0,
"slot": "105",
"type": "t_struct(ResourceConfig)76831_storage"
"type": "t_struct(ResourceConfig)66810_storage"
}
]
\ No newline at end of file
......@@ -5,7 +5,7 @@ import { Predeploys } from "src/libraries/Predeploys.sol";
import { OptimismPortal } from "src/L1/OptimismPortal.sol";
import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol";
import { ISemver } from "src/universal/ISemver.sol";
import { Constants } from "src/libraries/Constants.sol";
import { SuperchainConfig } from "src/L1/SuperchainConfig.sol";
/// @custom:proxied
/// @title L1CrossDomainMessenger
......@@ -18,19 +18,24 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver {
/// @custom:legacy
OptimismPortal public immutable PORTAL;
/// @notice Address of the other SuperchainConfig contract.
SuperchainConfig public superchainConfig;
/// @notice Semantic version.
/// @custom:semver 1.8.0
string public constant version = "1.8.0";
/// @custom:semver 2.0.0
string public constant version = "2.0.0";
/// @notice Constructs the L1CrossDomainMessenger contract.
/// @param _portal Address of the OptimismPortal contract on this network.
constructor(OptimismPortal _portal) CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER) {
PORTAL = _portal;
initialize();
initialize({ _superchainConfig: SuperchainConfig(address(0)) });
}
/// @notice Initializes the contract.
function initialize() public initializer {
/// @param _superchainConfig Address of the SuperchainConfig contract on this network.
function initialize(SuperchainConfig _superchainConfig) public initializer {
superchainConfig = _superchainConfig;
__CrossDomainMessenger_init();
}
......@@ -53,4 +58,9 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver {
function _isUnsafeTarget(address _target) internal view override returns (bool) {
return _target == address(this) || _target == address(PORTAL);
}
/// @inheritdoc CrossDomainMessenger
function paused() public view override returns (bool) {
return superchainConfig.paused();
}
}
......@@ -219,6 +219,10 @@ abstract contract CrossDomainMessenger is
external
payable
{
// On L1 this function will check the Portal for its paused status.
// On L2 this function should be a no-op, because paused will always return false.
require(paused() == false, "CrossDomainMessenger: paused");
(, uint16 version) = Encoding.decodeVersionedNonce(_nonce);
require(version < 2, "CrossDomainMessenger: only version 0 or 1 messages are supported at this time");
......@@ -376,4 +380,12 @@ abstract contract CrossDomainMessenger is
/// @param _target Address of the contract to check.
/// @return Whether or not the address is an unsafe system address.
function _isUnsafeTarget(address _target) internal view virtual returns (bool);
/// @notice This function should return true if the contract is paused.
/// On L1 this function will check the SuperchainConfig for its paused status.
/// On L2 this function should be a no-op.
/// @return Whether or not the contract is paused.
function paused() public view virtual returns (bool) {
return false;
}
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { CommonTest } from "test/setup/CommonTest.sol";
import { SuperchainConfig } from "src/L1/SuperchainConfig.sol";
contract ExtendedPause_Test is CommonTest {
/// @dev Tests that other contracts are paused when the superchain config is paused
/// This test is somewhat redundant with tests in the SuperchainConfig and other pausable contracts, however
/// it is worthwhile to pull them into one location to ensure that the behavior is consistent.
function test_pause_fullSystem_succeeds() external {
assertFalse(superchainConfig.paused());
assertEq(l1CrossDomainMessenger.paused(), superchainConfig.paused());
vm.prank(superchainConfig.guardian());
superchainConfig.pause("identifier");
assertTrue(superchainConfig.paused());
assertEq(l1CrossDomainMessenger.paused(), superchainConfig.paused());
// The following is hacky approach which ensures that this test will fail if the paused() function is
// added to the L1StandardBridge or the L1ERC721Bridge. At that point this test should be updated to include
// those methods.
try SuperchainConfig(address(l1StandardBridge)).paused() {
revert("The L1StandardBridge has a paused() function, but is not tested as part of the ExtendedPause");
} catch (bytes memory) {
assertTrue(true);
}
try SuperchainConfig(address(l1ERC721Bridge)).paused() {
revert("The L1ERC721Bridge has a paused() function, but is not tested as part of the ExtendedPause");
} catch (bytes memory) {
assertTrue(true);
}
}
}
......@@ -47,7 +47,7 @@ contract Initializer_Test is Bridge_Initializer {
contracts.push(
InitializeableContract({
target: address(l1CrossDomainMessenger),
initCalldata: abi.encodeCall(l1CrossDomainMessenger.initialize, ()),
initCalldata: abi.encodeCall(l1CrossDomainMessenger.initialize, (superchainConfig)),
initializedSlotVal: deploy.loadInitializedSlot("L1CrossDomainMessenger", true)
})
);
......
......@@ -13,6 +13,7 @@ import { Encoding } from "src/libraries/Encoding.sol";
// Target contract dependencies
import { OptimismPortal } from "src/L1/OptimismPortal.sol";
import { SuperchainConfig } from "src/L1/SuperchainConfig.sol";
contract L1CrossDomainMessenger_Test is Bridge_Initializer {
/// @dev The receiver address
......@@ -558,4 +559,39 @@ contract L1CrossDomainMessenger_Test is Bridge_Initializer {
hex"1111"
);
}
/// @dev Tests that the relayMessage function is able to relay a message
/// successfully by calling the target contract.
function test_relayMessage_paused_reverts() external {
vm.prank(superchainConfig.guardian());
superchainConfig.pause("identifier");
vm.expectRevert("CrossDomainMessenger: paused");
l1CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce
address(0),
address(0),
0, // value
0,
hex"1111"
);
}
/// @dev Tests that the superchain config is called by the messengers paused function
function test_pause_callsSuperchainConfig_succeeds() external {
vm.expectCall(address(superchainConfig), abi.encodeWithSelector(SuperchainConfig.paused.selector));
l1CrossDomainMessenger.paused();
}
/// @dev Tests that changing the superchain config paused status changes the return value of the messenger
function test_pause_matchesSuperchainConfig_succeeds() external {
assertFalse(l1CrossDomainMessenger.paused());
assertEq(l1CrossDomainMessenger.paused(), superchainConfig.paused());
vm.prank(superchainConfig.guardian());
superchainConfig.pause("identifier");
assertTrue(l1CrossDomainMessenger.paused());
assertEq(l1CrossDomainMessenger.paused(), superchainConfig.paused());
}
}
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