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_0() (gas: 352278)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2950484) GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2950440)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 540698) GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 540654)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4052891) GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4052847)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 442003) GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 441959)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3487752) GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3487708)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 42970) GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 42970)
GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 86629) GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 86629)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68462) GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68462)
......
...@@ -6,25 +6,26 @@ ...@@ -6,25 +6,26 @@
➡ src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger ➡ src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger
======================= =======================
| Name | Type | Slot | Offset | Bytes | Contract | | Name | Type | Slot | Offset | Bytes | Contract |
|--------------------|--------------------------|------|--------|-------|----------------------------------------------------------| |--------------------|---------------------------|------|--------|-------|----------------------------------------------------------|
| spacer_0_0_20 | address | 0 | 0 | 20 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | | spacer_0_0_20 | address | 0 | 0 | 20 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| _initialized | uint8 | 0 | 20 | 1 | 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 | | _initializing | bool | 0 | 21 | 1 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| spacer_1_0_1600 | uint256[50] | 1 | 0 | 1600 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | | spacer_1_0_1600 | uint256[50] | 1 | 0 | 1600 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| spacer_51_0_20 | address | 51 | 0 | 20 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | | spacer_51_0_20 | address | 51 | 0 | 20 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| spacer_52_0_1568 | uint256[49] | 52 | 0 | 1568 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | | spacer_52_0_1568 | uint256[49] | 52 | 0 | 1568 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| spacer_101_0_1 | bool | 101 | 0 | 1 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | | spacer_101_0_1 | bool | 101 | 0 | 1 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| spacer_102_0_1568 | uint256[49] | 102 | 0 | 1568 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | | spacer_102_0_1568 | uint256[49] | 102 | 0 | 1568 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| spacer_151_0_32 | uint256 | 151 | 0 | 32 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | | spacer_151_0_32 | uint256 | 151 | 0 | 32 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| spacer_152_0_1568 | uint256[49] | 152 | 0 | 1568 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | | spacer_152_0_1568 | uint256[49] | 152 | 0 | 1568 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| spacer_201_0_32 | mapping(bytes32 => bool) | 201 | 0 | 32 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | | spacer_201_0_32 | mapping(bytes32 => bool) | 201 | 0 | 32 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| spacer_202_0_32 | mapping(bytes32 => bool) | 202 | 0 | 32 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | | spacer_202_0_32 | mapping(bytes32 => bool) | 202 | 0 | 32 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| successfulMessages | mapping(bytes32 => bool) | 203 | 0 | 32 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | | successfulMessages | mapping(bytes32 => bool) | 203 | 0 | 32 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| xDomainMsgSender | address | 204 | 0 | 20 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | | xDomainMsgSender | address | 204 | 0 | 20 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| msgNonce | uint240 | 205 | 0 | 30 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger | | msgNonce | uint240 | 205 | 0 | 30 | src/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| failedMessages | mapping(bytes32 => bool) | 206 | 0 | 32 | 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 | | __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 ➡ src/L1/L1StandardBridge.sol:L1StandardBridge
......
...@@ -38,7 +38,7 @@ library ChainAssertions { ...@@ -38,7 +38,7 @@ library ChainAssertions {
require(keccak256(abi.encode(rcfg)) == keccak256(abi.encode(dflt))); require(keccak256(abi.encode(rcfg)) == keccak256(abi.encode(dflt)));
checkSystemConfig({ _contracts: _prox, _cfg: _cfg, _isProxy: true }); checkSystemConfig({ _contracts: _prox, _cfg: _cfg, _isProxy: true });
checkL1CrossDomainMessenger(_prox, _vm); checkL1CrossDomainMessenger({ _contracts: _prox, _vm: _vm, _isProxy: true });
checkL1StandardBridge(_prox); checkL1StandardBridge(_prox);
checkL2OutputOracle(_prox, _cfg, _l2OutputOracleStartingTimestamp, _l2OutputOracleStartingBlockNumber); checkL2OutputOracle(_prox, _cfg, _l2OutputOracleStartingTimestamp, _l2OutputOracleStartingBlockNumber);
checkOptimismMintableERC20Factory(_prox); checkOptimismMintableERC20Factory(_prox);
...@@ -76,12 +76,18 @@ library ChainAssertions { ...@@ -76,12 +76,18 @@ library ChainAssertions {
} }
/// @notice Asserts that the L1CrossDomainMessenger is setup correctly /// @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); L1CrossDomainMessenger messenger = L1CrossDomainMessenger(_contracts.L1CrossDomainMessenger);
require(address(messenger.portal()) == _contracts.OptimismPortal); require(address(messenger.portal()) == _contracts.OptimismPortal);
require(address(messenger.PORTAL()) == _contracts.OptimismPortal); require(address(messenger.PORTAL()) == _contracts.OptimismPortal);
bytes32 xdmSenderSlot = _vm.load(address(messenger), bytes32(uint256(204))); if (_isProxy) {
require(address(uint160(uint256(xdmSenderSlot))) == Constants.DEFAULT_L2_SENDER); 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 /// @notice Asserts that the L1StandardBridge is setup correctly
......
...@@ -424,19 +424,11 @@ contract Deploy is Deployer { ...@@ -424,19 +424,11 @@ contract Deploy is Deployer {
function deployL1CrossDomainMessengerProxy() public broadcast returns (address addr_) { function deployL1CrossDomainMessengerProxy() public broadcast returns (address addr_) {
console.log("Deploying proxy for L1CrossDomainMessenger"); console.log("Deploying proxy for L1CrossDomainMessenger");
AddressManager addressManager = AddressManager(mustGetAddress("AddressManager")); AddressManager addressManager = AddressManager(mustGetAddress("AddressManager"));
string memory contractName = "OVM_L1CrossDomainMessenger"; ResolvedDelegateProxy proxy = new ResolvedDelegateProxy(addressManager, "OVM_L1CrossDomainMessenger");
ResolvedDelegateProxy proxy = new ResolvedDelegateProxy(addressManager, contractName);
save("L1CrossDomainMessengerProxy", address(proxy)); save("L1CrossDomainMessengerProxy", address(proxy));
console.log("L1CrossDomainMessengerProxy deployed at %s", 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); addr_ = address(proxy);
} }
...@@ -487,7 +479,7 @@ contract Deploy is Deployer { ...@@ -487,7 +479,7 @@ contract Deploy is Deployer {
// are always proxies. // are always proxies.
Types.ContractSet memory contracts = _proxiesUnstrict(); Types.ContractSet memory contracts = _proxiesUnstrict();
contracts.L1CrossDomainMessenger = address(messenger); 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"); require(loadInitializedSlot("L1CrossDomainMessenger", false) == 1, "L1CrossDomainMessenger is not initialized");
...@@ -500,7 +492,6 @@ contract Deploy is Deployer { ...@@ -500,7 +492,6 @@ contract Deploy is Deployer {
L2OutputOracle l2OutputOracle = L2OutputOracle(mustGetAddress("L2OutputOracleProxy")); L2OutputOracle l2OutputOracle = L2OutputOracle(mustGetAddress("L2OutputOracleProxy"));
SystemConfig systemConfig = SystemConfig(mustGetAddress("SystemConfigProxy")); SystemConfig systemConfig = SystemConfig(mustGetAddress("SystemConfigProxy"));
SuperchainConfig superchainConfig = SuperchainConfig(mustGetAddress("SuperchainConfigProxy"));
OptimismPortal portal = new OptimismPortal{ salt: _implSalt() }({ OptimismPortal portal = new OptimismPortal{ salt: _implSalt() }({
_l2Oracle: l2OutputOracle, _l2Oracle: l2OutputOracle,
...@@ -857,6 +848,7 @@ contract Deploy is Deployer { ...@@ -857,6 +848,7 @@ contract Deploy is Deployer {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin")); ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address l1CrossDomainMessengerProxy = mustGetAddress("L1CrossDomainMessengerProxy"); address l1CrossDomainMessengerProxy = mustGetAddress("L1CrossDomainMessengerProxy");
address l1CrossDomainMessenger = mustGetAddress("L1CrossDomainMessenger"); address l1CrossDomainMessenger = mustGetAddress("L1CrossDomainMessenger");
SuperchainConfig superchainConfigProxy = SuperchainConfig(mustGetAddress("SuperchainConfigProxy"));
uint256 proxyType = uint256(proxyAdmin.proxyType(l1CrossDomainMessengerProxy)); uint256 proxyType = uint256(proxyAdmin.proxyType(l1CrossDomainMessengerProxy));
if (proxyType != uint256(ProxyAdmin.ProxyType.RESOLVED)) { if (proxyType != uint256(ProxyAdmin.ProxyType.RESOLVED)) {
...@@ -883,14 +875,14 @@ contract Deploy is Deployer { ...@@ -883,14 +875,14 @@ contract Deploy is Deployer {
_upgradeAndCallViaSafe({ _upgradeAndCallViaSafe({
_proxy: payable(l1CrossDomainMessengerProxy), _proxy: payable(l1CrossDomainMessengerProxy),
_implementation: l1CrossDomainMessenger, _implementation: l1CrossDomainMessenger,
_innerCallData: abi.encodeCall(L1CrossDomainMessenger.initialize, ()) _innerCallData: abi.encodeCall(L1CrossDomainMessenger.initialize, (superchainConfigProxy))
}); });
L1CrossDomainMessenger messenger = L1CrossDomainMessenger(l1CrossDomainMessengerProxy); L1CrossDomainMessenger messenger = L1CrossDomainMessenger(l1CrossDomainMessengerProxy);
string memory version = messenger.version(); string memory version = messenger.version();
console.log("L1CrossDomainMessenger version: %s", version); console.log("L1CrossDomainMessenger version: %s", version);
ChainAssertions.checkL1CrossDomainMessenger(_proxies(), vm); ChainAssertions.checkL1CrossDomainMessenger({ _contracts: _proxies(), _vm: vm, _isProxy: true });
require( require(
loadInitializedSlot("L1CrossDomainMessenger", true) == 1, "L1CrossDomainMessengerProxy is not initialized" loadInitializedSlot("L1CrossDomainMessenger", true) == 1, "L1CrossDomainMessengerProxy is not initialized"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"src/EAS/EAS.sol": "0x850a0eb089d5a01f489c7239f5b9a1b09120afb1bc80239268215c2dfe1de26c", "src/EAS/EAS.sol": "0x850a0eb089d5a01f489c7239f5b9a1b09120afb1bc80239268215c2dfe1de26c",
"src/EAS/SchemaRegistry.sol": "0x5ee1a0c3b2bf1eb5edb53fb0967cf13856be546f0f16fe7acdc3e4f286db6831", "src/EAS/SchemaRegistry.sol": "0x5ee1a0c3b2bf1eb5edb53fb0967cf13856be546f0f16fe7acdc3e4f286db6831",
"src/L1/DelayedVetoable.sol": "0x276c6276292095e6aa37a70008cf4e0d1cbcc020dbc9107459bbc72ab5ed744f", "src/L1/DelayedVetoable.sol": "0x276c6276292095e6aa37a70008cf4e0d1cbcc020dbc9107459bbc72ab5ed744f",
"src/L1/L1CrossDomainMessenger.sol": "0x9913bf3cbc572df939c24bd2688c546a8236fa902d9a49a2bf88770014d5362d", "src/L1/L1CrossDomainMessenger.sol": "0x8adb05d125d4745bfb452301ce5f2dc8ba77f17c63aa50e468d37f8fd5fa01e2",
"src/L1/L1ERC721Bridge.sol": "0x0e57251c77c052cec3a537b1dd4bb30eaff083a9d2b7bfb4cff342641ffd690d", "src/L1/L1ERC721Bridge.sol": "0x0e57251c77c052cec3a537b1dd4bb30eaff083a9d2b7bfb4cff342641ffd690d",
"src/L1/L1StandardBridge.sol": "0xc63b9a99a8e61321930a848c67d950a26356343e12e4376a2b12e03e44e8d8da", "src/L1/L1StandardBridge.sol": "0xc63b9a99a8e61321930a848c67d950a26356343e12e4376a2b12e03e44e8d8da",
"src/L1/L2OutputOracle.sol": "0xbc8acf3cdf2ea6107e2f9fad37e68a8f039f289d88b2ce002920c9ae00310450", "src/L1/L2OutputOracle.sol": "0xbc8acf3cdf2ea6107e2f9fad37e68a8f039f289d88b2ce002920c9ae00310450",
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
"src/L2/GasPriceOracle.sol": "0x88efffbd40f8d012d700a5d7fde0d92266f65e9d7006cd8f034bacaa036d0eb2", "src/L2/GasPriceOracle.sol": "0x88efffbd40f8d012d700a5d7fde0d92266f65e9d7006cd8f034bacaa036d0eb2",
"src/L2/L1Block.sol": "0x1ed9aa36036ded00a0383692eca81a22f668d64e22af973559d2ccefc86825c0", "src/L2/L1Block.sol": "0x1ed9aa36036ded00a0383692eca81a22f668d64e22af973559d2ccefc86825c0",
"src/L2/L1FeeVault.sol": "0x6a7a9a262c0a4c9781d812ea343f984944a8dd2b45bc1967dfcc3805c0053518", "src/L2/L1FeeVault.sol": "0x6a7a9a262c0a4c9781d812ea343f984944a8dd2b45bc1967dfcc3805c0053518",
"src/L2/L2CrossDomainMessenger.sol": "0x267d836cc4d3031f8b63c79722ab41d6fb973e85258c9865c648e4fc7111bcea", "src/L2/L2CrossDomainMessenger.sol": "0x437de61494ee2b72a3cf558dde878656d5e263360bae0688f1903c4ec26620d4",
"src/L2/L2ERC721Bridge.sol": "0x2efc8615a1f4c0e7508df68def345b958b9815f8ddc5b4945e8c0f97962a4de8", "src/L2/L2ERC721Bridge.sol": "0x2efc8615a1f4c0e7508df68def345b958b9815f8ddc5b4945e8c0f97962a4de8",
"src/L2/L2StandardBridge.sol": "0x7471e1d246ae3642995677f220045d70feeafc863dc640ce0c9891fd336d20dd", "src/L2/L2StandardBridge.sol": "0x7471e1d246ae3642995677f220045d70feeafc863dc640ce0c9891fd336d20dd",
"src/L2/L2ToL1MessagePasser.sol": "0xafc710b4d320ef450586d96a61cbd58cac814cb3b0c4fdc280eace3efdcdf321", "src/L2/L2ToL1MessagePasser.sol": "0xafc710b4d320ef450586d96a61cbd58cac814cb3b0c4fdc280eace3efdcdf321",
......
...@@ -279,7 +279,13 @@ ...@@ -279,7 +279,13 @@
"type": "function" "type": "function"
}, },
{ {
"inputs": [], "inputs": [
{
"internalType": "contract SuperchainConfig",
"name": "_superchainConfig",
"type": "address"
}
],
"name": "initialize", "name": "initialize",
"outputs": [], "outputs": [],
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
...@@ -298,6 +304,19 @@ ...@@ -298,6 +304,19 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "paused",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "portal", "name": "portal",
...@@ -391,6 +410,19 @@ ...@@ -391,6 +410,19 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "superchainConfig",
"outputs": [
{
"internalType": "contract SuperchainConfig",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "version", "name": "version",
......
...@@ -298,6 +298,19 @@ ...@@ -298,6 +298,19 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "paused",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
......
...@@ -4,6 +4,6 @@ ...@@ -4,6 +4,6 @@
"label": "mapping(uint256 => struct BlockOracle.BlockInfo)", "label": "mapping(uint256 => struct BlockOracle.BlockInfo)",
"offset": 0, "offset": 0,
"slot": "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 @@ ...@@ -39,20 +39,20 @@
"label": "mapping(GameType => contract IDisputeGame)", "label": "mapping(GameType => contract IDisputeGame)",
"offset": 0, "offset": 0,
"slot": "101", "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", "bytes": "32",
"label": "mapping(Hash => GameId)", "label": "mapping(Hash => GameId)",
"offset": 0, "offset": 0,
"slot": "102", "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", "bytes": "32",
"label": "GameId[]", "label": "GameId[]",
"offset": 0, "offset": 0,
"slot": "103", "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 @@ ...@@ -11,6 +11,6 @@
"label": "mapping(string => struct Drippie.DripState)", "label": "mapping(string => struct Drippie.DripState)",
"offset": 0, "offset": 0,
"slot": "1", "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 @@ ...@@ -4,14 +4,14 @@
"label": "mapping(contract IFaucetAuthModule => struct Faucet.ModuleConfig)", "label": "mapping(contract IFaucetAuthModule => struct Faucet.ModuleConfig)",
"offset": 0, "offset": 0,
"slot": "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", "bytes": "32",
"label": "mapping(contract IFaucetAuthModule => mapping(bytes32 => uint256))", "label": "mapping(contract IFaucetAuthModule => mapping(bytes32 => uint256))",
"offset": 0, "offset": 0,
"slot": "1", "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", "bytes": "32",
......
...@@ -4,49 +4,49 @@ ...@@ -4,49 +4,49 @@
"label": "Timestamp", "label": "Timestamp",
"offset": 0, "offset": 0,
"slot": "0", "slot": "0",
"type": "t_userDefinedValueType(Timestamp)88523" "type": "t_userDefinedValueType(Timestamp)77306"
}, },
{ {
"bytes": "1", "bytes": "1",
"label": "enum GameStatus", "label": "enum GameStatus",
"offset": 8, "offset": 8,
"slot": "0", "slot": "0",
"type": "t_enum(GameStatus)88539" "type": "t_enum(GameStatus)77322"
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "contract IBondManager", "label": "contract IBondManager",
"offset": 9, "offset": 9,
"slot": "0", "slot": "0",
"type": "t_contract(IBondManager)86032" "type": "t_contract(IBondManager)75008"
}, },
{ {
"bytes": "32", "bytes": "32",
"label": "Hash", "label": "Hash",
"offset": 0, "offset": 0,
"slot": "1", "slot": "1",
"type": "t_userDefinedValueType(Hash)88515" "type": "t_userDefinedValueType(Hash)77298"
}, },
{ {
"bytes": "32", "bytes": "32",
"label": "struct IFaultDisputeGame.ClaimData[]", "label": "struct IFaultDisputeGame.ClaimData[]",
"offset": 0, "offset": 0,
"slot": "2", "slot": "2",
"type": "t_array(t_struct(ClaimData)86246_storage)dyn_storage" "type": "t_array(t_struct(ClaimData)75222_storage)dyn_storage"
}, },
{ {
"bytes": "128", "bytes": "128",
"label": "struct IFaultDisputeGame.OutputProposals", "label": "struct IFaultDisputeGame.OutputProposals",
"offset": 0, "offset": 0,
"slot": "3", "slot": "3",
"type": "t_struct(OutputProposals)86261_storage" "type": "t_struct(OutputProposals)75237_storage"
}, },
{ {
"bytes": "32", "bytes": "32",
"label": "mapping(ClaimHash => bool)", "label": "mapping(ClaimHash => bool)",
"offset": 0, "offset": 0,
"slot": "7", "slot": "7",
"type": "t_mapping(t_userDefinedValueType(ClaimHash)88519,t_bool)" "type": "t_mapping(t_userDefinedValueType(ClaimHash)77302,t_bool)"
}, },
{ {
"bytes": "32", "bytes": "32",
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
"label": "mapping(address => struct Counters.Counter)", "label": "mapping(address => struct Counters.Counter)",
"offset": 0, "offset": 0,
"slot": "5", "slot": "5",
"type": "t_mapping(t_address,t_struct(Counter)51095_storage)" "type": "t_mapping(t_address,t_struct(Counter)49118_storage)"
}, },
{ {
"bytes": "32", "bytes": "32",
...@@ -60,14 +60,14 @@ ...@@ -60,14 +60,14 @@
"label": "mapping(address => struct ERC20Votes.Checkpoint[])", "label": "mapping(address => struct ERC20Votes.Checkpoint[])",
"offset": 0, "offset": 0,
"slot": "8", "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", "bytes": "32",
"label": "struct ERC20Votes.Checkpoint[]", "label": "struct ERC20Votes.Checkpoint[]",
"offset": 0, "offset": 0,
"slot": "9", "slot": "9",
"type": "t_array(t_struct(Checkpoint)48241_storage)dyn_storage" "type": "t_array(t_struct(Checkpoint)46264_storage)dyn_storage"
}, },
{ {
"bytes": "20", "bytes": "20",
......
...@@ -117,5 +117,12 @@ ...@@ -117,5 +117,12 @@
"offset": 0, "offset": 0,
"slot": "207", "slot": "207",
"type": "t_array(t_uint256)42_storage" "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 @@ ...@@ -32,6 +32,6 @@
"label": "struct Types.OutputProposal[]", "label": "struct Types.OutputProposal[]",
"offset": 0, "offset": 0,
"slot": "3", "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 @@ ...@@ -18,7 +18,7 @@
"label": "struct ResourceMetering.ResourceParams", "label": "struct ResourceMetering.ResourceParams",
"offset": 0, "offset": 0,
"slot": "1", "slot": "1",
"type": "t_struct(ResourceParams)76818_storage" "type": "t_struct(ResourceParams)66797_storage"
}, },
{ {
"bytes": "1536", "bytes": "1536",
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
"label": "mapping(bytes32 => struct OptimismPortal.ProvenWithdrawal)", "label": "mapping(bytes32 => struct OptimismPortal.ProvenWithdrawal)",
"offset": 0, "offset": 0,
"slot": "52", "slot": "52",
"type": "t_mapping(t_bytes32,t_struct(ProvenWithdrawal)75897_storage)" "type": "t_mapping(t_bytes32,t_struct(ProvenWithdrawal)65876_storage)"
}, },
{ {
"bytes": "1", "bytes": "1",
...@@ -60,6 +60,6 @@ ...@@ -60,6 +60,6 @@
"label": "contract SuperchainConfig", "label": "contract SuperchainConfig",
"offset": 1, "offset": 1,
"slot": "53", "slot": "53",
"type": "t_contract(SuperchainConfig)77341" "type": "t_contract(SuperchainConfig)67320"
} }
] ]
\ No newline at end of file
...@@ -4,49 +4,49 @@ ...@@ -4,49 +4,49 @@
"label": "Timestamp", "label": "Timestamp",
"offset": 0, "offset": 0,
"slot": "0", "slot": "0",
"type": "t_userDefinedValueType(Timestamp)88523" "type": "t_userDefinedValueType(Timestamp)77306"
}, },
{ {
"bytes": "8", "bytes": "8",
"label": "Timestamp", "label": "Timestamp",
"offset": 8, "offset": 8,
"slot": "0", "slot": "0",
"type": "t_userDefinedValueType(Timestamp)88523" "type": "t_userDefinedValueType(Timestamp)77306"
}, },
{ {
"bytes": "1", "bytes": "1",
"label": "enum GameStatus", "label": "enum GameStatus",
"offset": 16, "offset": 16,
"slot": "0", "slot": "0",
"type": "t_enum(GameStatus)88539" "type": "t_enum(GameStatus)77322"
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "contract IBondManager", "label": "contract IBondManager",
"offset": 0, "offset": 0,
"slot": "1", "slot": "1",
"type": "t_contract(IBondManager)86032" "type": "t_contract(IBondManager)75008"
}, },
{ {
"bytes": "32", "bytes": "32",
"label": "Hash", "label": "Hash",
"offset": 0, "offset": 0,
"slot": "2", "slot": "2",
"type": "t_userDefinedValueType(Hash)88515" "type": "t_userDefinedValueType(Hash)77298"
}, },
{ {
"bytes": "32", "bytes": "32",
"label": "struct IOutputBisectionGame.ClaimData[]", "label": "struct IOutputBisectionGame.ClaimData[]",
"offset": 0, "offset": 0,
"slot": "3", "slot": "3",
"type": "t_array(t_struct(ClaimData)86367_storage)dyn_storage" "type": "t_array(t_struct(ClaimData)75343_storage)dyn_storage"
}, },
{ {
"bytes": "32", "bytes": "32",
"label": "mapping(ClaimHash => bool)", "label": "mapping(ClaimHash => bool)",
"offset": 0, "offset": 0,
"slot": "4", "slot": "4",
"type": "t_mapping(t_userDefinedValueType(ClaimHash)88519,t_bool)" "type": "t_mapping(t_userDefinedValueType(ClaimHash)77302,t_bool)"
}, },
{ {
"bytes": "32", "bytes": "32",
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
"label": "mapping(address => enum ProxyAdmin.ProxyType)", "label": "mapping(address => enum ProxyAdmin.ProxyType)",
"offset": 0, "offset": 0,
"slot": "1", "slot": "1",
"type": "t_mapping(t_address,t_enum(ProxyType)95484)" "type": "t_mapping(t_address,t_enum(ProxyType)82009)"
}, },
{ {
"bytes": "32", "bytes": "32",
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
"label": "contract AddressManager", "label": "contract AddressManager",
"offset": 0, "offset": 0,
"slot": "3", "slot": "3",
"type": "t_contract(AddressManager)87016" "type": "t_contract(AddressManager)75992"
}, },
{ {
"bytes": "1", "bytes": "1",
......
...@@ -11,6 +11,6 @@ ...@@ -11,6 +11,6 @@
"label": "mapping(address => contract AddressManager)", "label": "mapping(address => contract AddressManager)",
"offset": 0, "offset": 0,
"slot": "1", "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 @@ ...@@ -67,6 +67,6 @@
"label": "struct ResourceMetering.ResourceConfig", "label": "struct ResourceMetering.ResourceConfig",
"offset": 0, "offset": 0,
"slot": "105", "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"; ...@@ -5,7 +5,7 @@ import { Predeploys } from "src/libraries/Predeploys.sol";
import { OptimismPortal } from "src/L1/OptimismPortal.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol";
import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol";
import { ISemver } from "src/universal/ISemver.sol"; import { ISemver } from "src/universal/ISemver.sol";
import { Constants } from "src/libraries/Constants.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol";
/// @custom:proxied /// @custom:proxied
/// @title L1CrossDomainMessenger /// @title L1CrossDomainMessenger
...@@ -18,19 +18,24 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver { ...@@ -18,19 +18,24 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver {
/// @custom:legacy /// @custom:legacy
OptimismPortal public immutable PORTAL; OptimismPortal public immutable PORTAL;
/// @notice Address of the other SuperchainConfig contract.
SuperchainConfig public superchainConfig;
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 1.8.0 /// @custom:semver 2.0.0
string public constant version = "1.8.0"; string public constant version = "2.0.0";
/// @notice Constructs the L1CrossDomainMessenger contract. /// @notice Constructs the L1CrossDomainMessenger contract.
/// @param _portal Address of the OptimismPortal contract on this network. /// @param _portal Address of the OptimismPortal contract on this network.
constructor(OptimismPortal _portal) CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER) { constructor(OptimismPortal _portal) CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER) {
PORTAL = _portal; PORTAL = _portal;
initialize(); initialize({ _superchainConfig: SuperchainConfig(address(0)) });
} }
/// @notice Initializes the contract. /// @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(); __CrossDomainMessenger_init();
} }
...@@ -53,4 +58,9 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver { ...@@ -53,4 +58,9 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver {
function _isUnsafeTarget(address _target) internal view override returns (bool) { function _isUnsafeTarget(address _target) internal view override returns (bool) {
return _target == address(this) || _target == address(PORTAL); 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 ...@@ -219,6 +219,10 @@ abstract contract CrossDomainMessenger is
external external
payable 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); (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);
require(version < 2, "CrossDomainMessenger: only version 0 or 1 messages are supported at this time"); require(version < 2, "CrossDomainMessenger: only version 0 or 1 messages are supported at this time");
...@@ -376,4 +380,12 @@ abstract contract CrossDomainMessenger is ...@@ -376,4 +380,12 @@ abstract contract CrossDomainMessenger is
/// @param _target Address of the contract to check. /// @param _target Address of the contract to check.
/// @return Whether or not the address is an unsafe system address. /// @return Whether or not the address is an unsafe system address.
function _isUnsafeTarget(address _target) internal view virtual returns (bool); 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 { ...@@ -47,7 +47,7 @@ contract Initializer_Test is Bridge_Initializer {
contracts.push( contracts.push(
InitializeableContract({ InitializeableContract({
target: address(l1CrossDomainMessenger), target: address(l1CrossDomainMessenger),
initCalldata: abi.encodeCall(l1CrossDomainMessenger.initialize, ()), initCalldata: abi.encodeCall(l1CrossDomainMessenger.initialize, (superchainConfig)),
initializedSlotVal: deploy.loadInitializedSlot("L1CrossDomainMessenger", true) initializedSlotVal: deploy.loadInitializedSlot("L1CrossDomainMessenger", true)
}) })
); );
......
...@@ -13,6 +13,7 @@ import { Encoding } from "src/libraries/Encoding.sol"; ...@@ -13,6 +13,7 @@ import { Encoding } from "src/libraries/Encoding.sol";
// Target contract dependencies // Target contract dependencies
import { OptimismPortal } from "src/L1/OptimismPortal.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol";
import { SuperchainConfig } from "src/L1/SuperchainConfig.sol";
contract L1CrossDomainMessenger_Test is Bridge_Initializer { contract L1CrossDomainMessenger_Test is Bridge_Initializer {
/// @dev The receiver address /// @dev The receiver address
...@@ -558,4 +559,39 @@ contract L1CrossDomainMessenger_Test is Bridge_Initializer { ...@@ -558,4 +559,39 @@ contract L1CrossDomainMessenger_Test is Bridge_Initializer {
hex"1111" 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