Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions op-chain-ops/interopgen/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
}

Expand Down
3 changes: 3 additions & 0 deletions op-chain-ops/interopgen/deployments.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
13 changes: 5 additions & 8 deletions op-deployer/pkg/deployer/opcm/implementations.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
10 changes: 9 additions & 1 deletion op-deployer/pkg/deployer/opcm/superchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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)
}
45 changes: 44 additions & 1 deletion packages/contracts-bedrock/scripts/deploy/DeploySuperchain.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);

Expand Down