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
1 change: 1 addition & 0 deletions op-chain-ops/interopgen/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ func GenesisL2(l2Host *script.Host, cfg *L2Config, deployment *L2Deployment, mul
GasPayingTokenSymbol: cfg.GasPayingTokenSymbol,
NativeAssetLiquidityAmount: cfg.NativeAssetLiquidityAmount.ToInt(),
LiquidityControllerOwner: cfg.LiquidityControllerOwner,
UseL2CM: false, // TODO(#19102): add support for L2CM
}); err != nil {
return fmt.Errorf("failed L2 genesis: %w", err)
}
Expand Down
3 changes: 3 additions & 0 deletions op-deployer/pkg/deployer/devfeatures.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ var (

// OPCMV2DevFlag enables the OPContractsManagerV2 contract.
OPCMV2DevFlag = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000010000")

// L2CMDevFlag enables L2CM.
L2CMDevFlag = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000100000")
)

// IsDevFeatureEnabled checks if a specific development feature is enabled in a feature bitmap.
Expand Down
26 changes: 26 additions & 0 deletions op-deployer/pkg/deployer/integration_test/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,32 @@ func TestEndToEndApply(t *testing.T) {
require.Equal(t, amount, account.Balance, "Native asset liquidity predeploy should have the configured balance")
})

t.Run("with L2CM", func(t *testing.T) {
intent, st := shared.NewIntent(t, l1ChainID, dk, l2ChainID1, loc, loc, testCustomGasLimit)

intent.GlobalDeployOverrides = map[string]any{
"devFeatureBitmap": deployer.L2CMDevFlag,
}

require.NoError(t, deployer.ApplyPipeline(ctx, deployer.ApplyPipelineOpts{
DeploymentTarget: deployer.DeploymentTargetLive,
L1RPCUrl: l1RPC,
DeployerPrivateKey: pk,
Intent: intent,
State: st,
Logger: lgr,
StateWriter: pipeline.NoopStateWriter(),
CacheDir: testCacheDir,
}))

// Check that the native asset liquidity predeploy has the configured amount in L2 genesis
conditionalDeployerAddr := common.HexToAddress("0x420000000000000000000000000000000000002C")
l2Genesis := st.Chains[0].Allocs.Data.Accounts
account, exists := l2Genesis[conditionalDeployerAddr]
require.True(t, exists, "Conditional deployer should exist in L2 genesis")
require.NotEmpty(t, account.Code, "Conditional deployer should have code deployed")
})

t.Run("OPCMV2 deployment", func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
Expand Down
1 change: 1 addition & 0 deletions op-deployer/pkg/deployer/opcm/l2genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type L2GenesisInput struct {
GasPayingTokenSymbol string
NativeAssetLiquidityAmount *big.Int
LiquidityControllerOwner common.Address
UseL2CM bool
}

type L2GenesisScript script.DeployScriptWithoutOutput[L2GenesisInput]
Expand Down
16 changes: 12 additions & 4 deletions op-deployer/pkg/deployer/pipeline/l2genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@ import (
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum/go-ethereum/common/hexutil"

"github.com/ethereum-optimism/optimism/op-service/jsonutil"

"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/standard"

"github.com/ethereum-optimism/optimism/op-deployer/pkg/env"
"github.com/ethereum-optimism/optimism/op-service/jsonutil"

"github.com/ethereum-optimism/optimism/op-chain-ops/foundry"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/broadcaster"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/standard"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/state"

"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -85,6 +83,15 @@ func GenerateL2Genesis(pEnv *Env, intent *state.Intent, bundle ArtifactsBundle,

cgt := buildCGTConfig(thisIntent)

// Check if L2CM feature is enabled
var useL2CM bool = false
if devFeatureBitmap, ok := intent.GlobalDeployOverrides["devFeatureBitmap"].(common.Hash); ok {
l2CMFlag := common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000100000")
if isDevFeatureEnabled(devFeatureBitmap, l2CMFlag) {
useL2CM = true
}
}

if err := script.Run(opcm.L2GenesisInput{
L1ChainID: new(big.Int).SetUint64(intent.L1ChainID),
L2ChainID: chainID.Big(),
Expand Down Expand Up @@ -118,6 +125,7 @@ func GenerateL2Genesis(pEnv *Env, intent *state.Intent, bundle ArtifactsBundle,
GasPayingTokenSymbol: cgt.GasPayingTokenSymbol,
NativeAssetLiquidityAmount: cgt.NativeAssetLiquidityAmount,
LiquidityControllerOwner: cgt.LiquidityControllerOwner,
UseL2CM: useL2CM,
}); err != nil {
return fmt.Errorf("failed to call L2Genesis script: %w", err)
}
Expand Down
30 changes: 30 additions & 0 deletions packages/contracts-bedrock/interfaces/L2/IConditionalDeployer.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { ISemver } from "interfaces/universal/ISemver.sol";

/// @title IConditionalDeployer
/// @notice Interface for the ConditionalDeployer contract.
interface IConditionalDeployer is ISemver {
/// @notice Emitted when an implementation is deployed.
/// @param implementation The address of the deployed implementation.
/// @param salt The salt used for deployment.
event ImplementationDeployed(address indexed implementation, bytes32 salt);

/// @notice Emitted when deployment is skipped because implementation already exists.
/// @param implementation The address of the existing implementation.
event ImplementationExists(address indexed implementation);

/// @notice Error thrown when deployment fails.
error ConditionalDeployer_DeploymentFailed(bytes data);

/// @notice Address of the DeterministicDeploymentProxy (Nick's method).
function DETERMINISTIC_DEPLOYMENT_PROXY() external view returns (address payable);

/// @notice Deploys an implementation using CREATE2 if it doesn't already exist.
/// @param _value The amount of ETH to send with the deployment.
/// @param _salt The salt to use for CREATE2 deployment.
/// @param _code The initialization code for the contract.
/// @return implementation_ The address of the deployed or existing implementation.
function deploy(uint256 _value, bytes32 _salt, bytes memory _code) external returns (address implementation_);
}

This file was deleted.

16 changes: 14 additions & 2 deletions packages/contracts-bedrock/scripts/L2Genesis.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ contract L2Genesis is Script {
string gasPayingTokenSymbol;
uint256 nativeAssetLiquidityAmount;
address liquidityControllerOwner;
bool useL2CM;
}

using ForkUtils for Fork;
Expand Down Expand Up @@ -221,8 +222,11 @@ contract L2Genesis is Script {
vm.etch(addr, code);
EIP1967Helper.setAdmin(addr, Predeploys.PROXY_ADMIN);

if (Predeploys.isSupportedPredeploy(addr, _input.fork, _input.deployCrossL2Inbox, _input.useCustomGasToken))
{
if (
Predeploys.isSupportedPredeploy(
addr, _input.fork, _input.deployCrossL2Inbox, _input.useCustomGasToken, _input.useL2CM
)
) {
address implementation = Predeploys.predeployToCodeNamespace(addr);
EIP1967Helper.setImplementation(addr, implementation);
}
Expand Down Expand Up @@ -268,6 +272,9 @@ contract L2Genesis is Script {
setLiquidityController(_input); // 29
setNativeAssetLiquidity(_input); // 2A
}
if (_input.useL2CM) {
setConditionalDeployer(); // 2C
}
}

function setInteropPredeployProxies() internal { }
Expand Down Expand Up @@ -578,6 +585,11 @@ contract L2Genesis is Script {
vm.deal(Predeploys.NATIVE_ASSET_LIQUIDITY, _input.nativeAssetLiquidityAmount);
}

/// @notice This predeploy is following the safety invariant #1.
function setConditionalDeployer() internal {
_setImplementationCode(Predeploys.CONDITIONAL_DEPLOYER);
}

/// @notice Sets all the preinstalls.
function setPreinstalls() internal {
address tmpSetPreinstalls = address(uint160(uint256(keccak256("SetPreinstalls"))));
Expand Down
9 changes: 9 additions & 0 deletions packages/contracts-bedrock/scripts/deploy/DeployConfig.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ contract DeployConfig is Script {
uint256 public faultGameV2ClockExtension;
uint256 public faultGameV2MaxClockDuration;

bool public useL2CM;

bool public useInterop;
bool public useUpgradedFork;
bytes32 public devFeatureBitmap;
Expand Down Expand Up @@ -181,6 +183,8 @@ contract DeployConfig is Script {
daBondSize = _readOr(_json, "$.daBondSize", 1000000000);
daResolverRefundPercentage = _readOr(_json, "$.daResolverRefundPercentage", 0);

useL2CM = _readOr(_json, "$.useL2CM", false);

useInterop = _readOr(_json, "$.useInterop", false);
devFeatureBitmap = bytes32(_readOr(_json, "$.devFeatureBitmap", 0));
useUpgradedFork;
Expand Down Expand Up @@ -317,6 +321,11 @@ contract DeployConfig is Script {
operatorFeeVaultWithdrawalNetwork = _operatorFeeVaultWithdrawalNetwork;
}

/// @notice Allow the `useL2CM` config to be overridden in testing environments
function setUseL2CM(bool _useL2CM) public {
useL2CM = _useL2CM;
}

function latestGenesisFork() internal view returns (Fork) {
if (l2GenesisJovianTimeOffset == 0) {
return Fork.JOVIAN;
Expand Down
5 changes: 5 additions & 0 deletions packages/contracts-bedrock/scripts/libraries/Config.sol
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,11 @@ library Config {
return vm.envOr("DEV_FEATURE__OPCM_V2", false);
}

/// @notice Returns true if the development feature l2cm is enabled.
function devFeatureL2CM() internal view returns (bool) {
return vm.envOr("DEV_FEATURE__L2CM", false);
}

/// @notice Returns true if the system feature custom_gas_token is enabled.
function sysFeatureCustomGasToken() internal view returns (bool) {
return vm.envOr("SYS_FEATURE__CUSTOM_GAS_TOKEN", false);
Expand Down
100 changes: 100 additions & 0 deletions packages/contracts-bedrock/snapshots/abi/ConditionalDeployer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
[
{
"inputs": [],
"name": "DETERMINISTIC_DEPLOYMENT_PROXY",
"outputs": [
{
"internalType": "address payable",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_value",
"type": "uint256"
},
{
"internalType": "bytes32",
"name": "_salt",
"type": "bytes32"
},
{
"internalType": "bytes",
"name": "_code",
"type": "bytes"
}
],
"name": "deploy",
"outputs": [
{
"internalType": "address",
"name": "implementation_",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "version",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "implementation",
"type": "address"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
}
],
"name": "ImplementationDeployed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "implementation",
"type": "address"
}
],
"name": "ImplementationExists",
"type": "event"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "ConditionalDeployer_DeploymentFailed",
"type": "error"
}
]
4 changes: 4 additions & 0 deletions packages/contracts-bedrock/snapshots/semver-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@
"initCodeHash": "0x838bbd7f381e84e21887f72bd1da605bfc4588b3c39aed96cbce67c09335b3ee",
"sourceCodeHash": "0xcb329746df0baddd3dc03c6c88da5d6bdc0f0a96d30e6dc78d0891bb1e935032"
},
"src/L2/ConditionalDeployer.sol:ConditionalDeployer": {
"initCodeHash": "0x6b88fe95359f7166b90bcf9414b91cef3662be2e02b4a0540e486a5040c9e84c",
"sourceCodeHash": "0xaf67802e6fc99cb9a267bef3a736cf97e032ec215fc8fb8ca15c3f17eb978543"
},
"src/L2/CrossL2Inbox.sol:CrossL2Inbox": {
"initCodeHash": "0x56f868e561c4abe539043f98b16aad9305479e68fd03ece2233249b0c73a24ea",
"sourceCodeHash": "0x7c6d362a69a480a06a079542a7fd2ce48cb1dd80d6b9043fba60218569371349"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
Loading