diff --git a/packages/contracts-bedrock/scripts/L2Genesis.s.sol b/packages/contracts-bedrock/scripts/L2Genesis.s.sol index 647e3222227d..2cd3da78226d 100644 --- a/packages/contracts-bedrock/scripts/L2Genesis.s.sol +++ b/packages/contracts-bedrock/scripts/L2Genesis.s.sol @@ -192,7 +192,7 @@ contract L2Genesis is Deployer { vm.etch(addr, code); EIP1967Helper.setAdmin(addr, Predeploys.PROXY_ADMIN); - if (Predeploys.isSupportedPredeploy(addr)) { + if (Predeploys.isSupportedPredeploy(addr, cfg.useInterop())) { address implementation = Predeploys.predeployToCodeNamespace(addr); console.log("Setting proxy %s implementation: %s", addr, implementation); EIP1967Helper.setImplementation(addr, implementation); @@ -231,6 +231,10 @@ contract L2Genesis is Deployer { setSchemaRegistry(); // 20 setEAS(); // 21 setGovernanceToken(); // 42: OP (not behind a proxy) + if (cfg.useInterop()) { + setCrossL2Inbox(); // 22 + setL2ToL2CrossDomainMessenger(); // 23 + } } function setProxyAdmin() public { @@ -441,6 +445,18 @@ contract L2Genesis is Deployer { vm.resetNonce(address(eas)); } + /// @notice This predeploy is following the saftey invariant #2. + /// This contract has no initializer. + function setCrossL2Inbox() internal { + _setImplementationCode(Predeploys.CROSS_L2_INBOX); + } + + /// @notice This predeploy is following the saftey invariant #2. + /// This contract has no initializer. + function setL2ToL2CrossDomainMessenger() internal { + _setImplementationCode(Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER); + } + /// @notice Sets all the preinstalls. /// Warning: the creator-accounts of the preinstall contracts have 0 nonce values. /// When performing a regular user-initiated contract-creation of a preinstall, diff --git a/packages/contracts-bedrock/src/libraries/Predeploys.sol b/packages/contracts-bedrock/src/libraries/Predeploys.sol index ed00c991ba5b..d37dbca6af11 100644 --- a/packages/contracts-bedrock/src/libraries/Predeploys.sol +++ b/packages/contracts-bedrock/src/libraries/Predeploys.sol @@ -124,13 +124,14 @@ library Predeploys { } /// @notice Returns true if the address is a defined predeploy that is embedded into new OP-Stack chains. - function isSupportedPredeploy(address _addr) internal pure returns (bool) { + function isSupportedPredeploy(address _addr, bool _useInterop) internal pure returns (bool) { return _addr == LEGACY_MESSAGE_PASSER || _addr == DEPLOYER_WHITELIST || _addr == WETH || _addr == L2_CROSS_DOMAIN_MESSENGER || _addr == GAS_PRICE_ORACLE || _addr == L2_STANDARD_BRIDGE || _addr == SEQUENCER_FEE_WALLET || _addr == OPTIMISM_MINTABLE_ERC20_FACTORY || _addr == L1_BLOCK_NUMBER || _addr == L2_ERC721_BRIDGE || _addr == L1_BLOCK_ATTRIBUTES || _addr == L2_TO_L1_MESSAGE_PASSER || _addr == OPTIMISM_MINTABLE_ERC721_FACTORY || _addr == PROXY_ADMIN || _addr == BASE_FEE_VAULT - || _addr == L1_FEE_VAULT || _addr == SCHEMA_REGISTRY || _addr == EAS || _addr == GOVERNANCE_TOKEN; + || _addr == L1_FEE_VAULT || _addr == SCHEMA_REGISTRY || _addr == EAS || _addr == GOVERNANCE_TOKEN + || (_useInterop && _addr == CROSS_L2_INBOX) || (_useInterop && _addr == L2_TO_L2_CROSS_DOMAIN_MESSENGER); } function isPredeployNamespace(address _addr) internal pure returns (bool) { diff --git a/packages/contracts-bedrock/test/L2Genesis.t.sol b/packages/contracts-bedrock/test/L2Genesis.t.sol index 68e0f559c074..551e01088947 100644 --- a/packages/contracts-bedrock/test/L2Genesis.t.sol +++ b/packages/contracts-bedrock/test/L2Genesis.t.sol @@ -121,13 +121,27 @@ contract L2GenesisTest is Test { return abi.decode(vm.ffi(commands), (uint256)); } - /// @notice Tests the genesis predeploys setup using a temp file. - function test_genesis_predeploys() external { - withTempDump(_test_genesis_predeploys); + /// @notice Tests the genesis predeploys setup using a temp file for the case where useInterop is false. + function test_genesis_predeploys_notUsingInterop() external { + string memory path = tmpfile(); + _test_genesis_predeploys(path, false); + deleteFile(path); + } + + /// @notice Tests the genesis predeploys setup using a temp file for the case where useInterop is true. + function test_genesis_predeploys_usingInterop() external { + string memory path = tmpfile(); + _test_genesis_predeploys(path, true); + deleteFile(path); } /// @notice Tests the genesis predeploys setup. - function _test_genesis_predeploys(string memory _path) internal { + function _test_genesis_predeploys(string memory _path, bool _useInterop) internal { + // Set the useInterop value + vm.mockCall( + address(genesis.cfg()), abi.encodeWithSelector(genesis.cfg().useInterop.selector), abi.encode(_useInterop) + ); + // Set the predeploy proxies into state genesis.setPredeployProxies(); genesis.writeGenesisAllocs(_path); @@ -135,8 +149,8 @@ contract L2GenesisTest is Test { // 2 predeploys do not have proxies assertEq(getCodeCount(_path, "Proxy.sol:Proxy"), Predeploys.PREDEPLOY_COUNT - 2); - // 17 proxies have the implementation set - assertEq(getPredeployCountWithSlotSet(_path, Constants.PROXY_IMPLEMENTATION_ADDRESS), 17); + // 19 proxies have the implementation set if useInterop is true and 17 if useInterop is false + assertEq(getPredeployCountWithSlotSet(_path, Constants.PROXY_IMPLEMENTATION_ADDRESS), _useInterop ? 19 : 17); // All proxies except 2 have the proxy 1967 admin slot set to the proxy admin assertEq(