diff --git a/op-chain-ops/interopgen/deploy.go b/op-chain-ops/interopgen/deploy.go index b7e4fe943e4..cacec5bd490 100644 --- a/op-chain-ops/interopgen/deploy.go +++ b/op-chain-ops/interopgen/deploy.go @@ -156,6 +156,7 @@ func DeploySuperchainToL1(l1Host *script.Host, superCfg *SuperchainConfig) (*Sup Paused: superCfg.Paused, RequiredProtocolVersion: superCfg.RequiredProtocolVersion, RecommendedProtocolVersion: superCfg.RecommendedProtocolVersion, + IsInterop: superCfg.Implementations.UseInterop, }) if err != nil { return nil, fmt.Errorf("failed to deploy Superchain contracts: %w", err) @@ -187,6 +188,8 @@ func DeploySuperchainToL1(l1Host *script.Host, superCfg *SuperchainConfig) (*Sup ProtocolVersionsProxy: superDeployment.ProtocolVersionsProxy, SuperchainConfig: superDeployment.SuperchainConfigImpl, SuperchainConfigProxy: superDeployment.SuperchainConfigProxy, + SharedLockbox: superDeployment.SharedLockboxImpl, + SharedLockboxProxy: superDeployment.SharedLockboxProxy, }, nil } diff --git a/op-chain-ops/interopgen/deployments.go b/op-chain-ops/interopgen/deployments.go index a4ead545ac2..5837e38aba4 100644 --- a/op-chain-ops/interopgen/deployments.go +++ b/op-chain-ops/interopgen/deployments.go @@ -35,6 +35,9 @@ type SuperchainDeployment struct { SuperchainConfig common.Address `json:"SuperchainConfig"` SuperchainConfigProxy common.Address `json:"SuperchainConfigProxy"` + + SharedLockbox common.Address `json:"SharedLockbox"` + SharedLockboxProxy common.Address `json:"SharedLockboxProxy"` } type L2OpchainDeployment struct { diff --git a/op-deployer/pkg/deployer/opcm/implementations.go b/op-deployer/pkg/deployer/opcm/implementations.go index 4fdcc37c0a6..64eebd1e5c2 100644 --- a/op-deployer/pkg/deployer/opcm/implementations.go +++ b/op-deployer/pkg/deployer/opcm/implementations.go @@ -85,15 +85,12 @@ func DeployImplementations( } defer cleanupDeploy() - opcmContract := "OPContractsManager" - if err := host.RememberOnLabel("OPContractsManager", opcmContract+".sol", opcmContract); err != nil { - return output, fmt.Errorf("failed to link OPContractsManager label: %w", err) + optimismPortal := "OptimismPortal2" + if input.UseInterop { + optimismPortal = "OptimismPortalInterop" } - - // So we can see in detail where the SystemConfig interop initializer fails - sysConfig := "SystemConfig" - if err := host.RememberOnLabel("SystemConfigImpl", sysConfig+".sol", sysConfig); err != nil { - return output, fmt.Errorf("failed to link SystemConfig label: %w", err) + if err := host.RememberOnLabel("OptimismPortalImpl", optimismPortal+".sol", optimismPortal); err != nil { + return output, fmt.Errorf("failed to link OptimismPortal label: %w", err) } if err := deployScript.Run(inputAddr, outputAddr); err != nil { diff --git a/op-deployer/pkg/deployer/opcm/superchain.go b/op-deployer/pkg/deployer/opcm/superchain.go index 35811bd6934..c8bb0791fc8 100644 --- a/op-deployer/pkg/deployer/opcm/superchain.go +++ b/op-deployer/pkg/deployer/opcm/superchain.go @@ -19,6 +19,7 @@ type DeploySuperchainInput struct { Paused bool `toml:"paused"` RequiredProtocolVersion params.ProtocolVersion `toml:"requiredProtocolVersion"` RecommendedProtocolVersion params.ProtocolVersion `toml:"recommendedProtocolVersion"` + IsInterop bool `toml:"isInterop"` } func (dsi *DeploySuperchainInput) InputSet() bool { @@ -31,6 +32,8 @@ type DeploySuperchainOutput struct { SuperchainConfigProxy common.Address ProtocolVersionsImpl common.Address ProtocolVersionsProxy common.Address + SharedLockboxImpl common.Address + SharedLockboxProxy common.Address } func (output *DeploySuperchainOutput) CheckOutput(input common.Address) error { @@ -48,5 +51,10 @@ type DeploySuperchainOpts struct { } func DeploySuperchain(h *script.Host, input DeploySuperchainInput) (DeploySuperchainOutput, error) { - return RunScriptSingle[DeploySuperchainInput, DeploySuperchainOutput](h, input, "DeploySuperchain.s.sol", "DeploySuperchain") + implContract := "DeploySuperchain" + if input.IsInterop { + implContract = "DeploySuperchainInterop" + } + + return RunScriptSingle[DeploySuperchainInput, DeploySuperchainOutput](h, input, "DeploySuperchain.s.sol", implContract) } diff --git a/packages/contracts-bedrock/scripts/deploy/DeploySuperchain.s.sol b/packages/contracts-bedrock/scripts/deploy/DeploySuperchain.s.sol index 18f77c374b3..1327f1f392f 100644 --- a/packages/contracts-bedrock/scripts/deploy/DeploySuperchain.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/DeploySuperchain.s.sol @@ -580,6 +580,49 @@ contract DeploySuperchain is Script { /// and `deploySuperchainConfigProxy` methods to deploy the `SuperchainConfigInterop` implementation /// and proxy contracts. contract DeploySuperchainInterop is DeploySuperchain { + /// @notice This is a copy of the `computeCreateAddress` function from `CreateX.sol`. + /// This is needed because the `computeCreateAddress` function is not available in go cheatcodes. + /// TODO: Remove this function once we have `vm.computeCreateAddress` cheatcode in go. + function _computeCreateAddress(address deployer, uint256 nonce) private pure returns (address computedAddress) { + bytes memory data; + bytes1 len = bytes1(0x94); + + // The integer zero is treated as an empty byte string and therefore has only one length prefix, + // 0x80, which is calculated via 0x80 + 0. + if (nonce == 0x00) { + data = abi.encodePacked(bytes1(0xd6), len, deployer, bytes1(0x80)); + } + // A one-byte integer in the [0x00, 0x7f] range uses its own value as a length prefix, there is no + // additional "0x80 + length" prefix that precedes it. + else if (nonce <= 0x7f) { + data = abi.encodePacked(bytes1(0xd6), len, deployer, uint8(nonce)); + } + // In the case of `nonce > 0x7f` and `nonce <= type(uint8).max`, we have the following encoding scheme + // (the same calculation can be carried over for higher nonce bytes): + // 0xda = 0xc0 (short RLP prefix) + 0x1a (= the bytes length of: 0x94 + address + 0x84 + nonce, in hex), + // 0x94 = 0x80 + 0x14 (= the bytes length of an address, 20 bytes, in hex), + // 0x84 = 0x80 + 0x04 (= the bytes length of the nonce, 4 bytes, in hex). + else if (nonce <= type(uint8).max) { + data = abi.encodePacked(bytes1(0xd7), len, deployer, bytes1(0x81), uint8(nonce)); + } else if (nonce <= type(uint16).max) { + data = abi.encodePacked(bytes1(0xd8), len, deployer, bytes1(0x82), uint16(nonce)); + } else if (nonce <= type(uint24).max) { + data = abi.encodePacked(bytes1(0xd9), len, deployer, bytes1(0x83), uint24(nonce)); + } else if (nonce <= type(uint32).max) { + data = abi.encodePacked(bytes1(0xda), len, deployer, bytes1(0x84), uint32(nonce)); + } else if (nonce <= type(uint40).max) { + data = abi.encodePacked(bytes1(0xdb), len, deployer, bytes1(0x85), uint40(nonce)); + } else if (nonce <= type(uint48).max) { + data = abi.encodePacked(bytes1(0xdc), len, deployer, bytes1(0x86), uint48(nonce)); + } else if (nonce <= type(uint56).max) { + data = abi.encodePacked(bytes1(0xdd), len, deployer, bytes1(0x87), uint56(nonce)); + } else { + data = abi.encodePacked(bytes1(0xde), len, deployer, bytes1(0x88), uint64(nonce)); + } + + computedAddress = address(uint160(uint256(keccak256(data)))); + } + function deploySuperchainImplementationContracts( DeploySuperchainInput _dsi, DeploySuperchainOutput _dso @@ -600,7 +643,7 @@ contract DeploySuperchainInterop is DeploySuperchain { override { // Precalculate the SuperchainConfig address. Needed in the SharedLockbox initialization. - address _precalculatedSuperchainConfigProxy = vm.computeCreateAddress(msg.sender, vm.getNonce(msg.sender) + 2); + address _precalculatedSuperchainConfigProxy = _computeCreateAddress(msg.sender, vm.getNonce(msg.sender) + 2); deploySharedLockboxProxy(_dso, _precalculatedSuperchainConfigProxy);