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 @@ -254,6 +254,7 @@ func DeployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme
AllowCustomDisputeParameters: true,
OperatorFeeScalar: cfg.GasPriceOracleOperatorFeeScalar,
OperatorFeeConstant: cfg.GasPriceOracleOperatorFeeConstant,
SuperchainConfig: superDeployment.SuperchainConfigProxy,
UseCustomGasToken: cfg.UseCustomGasToken,
})
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions op-deployer/pkg/deployer/integration_test/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,8 @@ func TestEndToEndApply(t *testing.T) {
require.True(t, exists, "Native asset liquidity predeploy should exist in L2 genesis")
require.Equal(t, amount, account.Balance, "Native asset liquidity predeploy should have the configured balance")
})

// TODO: Add tests for OPCMV2
}

func TestGlobalOverrides(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions op-deployer/pkg/deployer/opcm/opchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type DeployOPChainInput struct {

OperatorFeeScalar uint32
OperatorFeeConstant uint64
SuperchainConfig common.Address

UseCustomGasToken bool
}
Expand Down
1 change: 1 addition & 0 deletions op-deployer/pkg/deployer/pipeline/opchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ func makeDCI(intent *state.Intent, thisIntent *state.ChainIntent, chainID common
AllowCustomDisputeParameters: proofParams.DangerouslyAllowCustomDisputeParameters,
OperatorFeeScalar: thisIntent.OperatorFeeScalar,
OperatorFeeConstant: thisIntent.OperatorFeeConstant,
SuperchainConfig: st.SuperchainDeployment.SuperchainConfigProxy,
UseCustomGasToken: thisIntent.IsCustomGasTokenEnabled(),
}, nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ interface IOPContractsManagerV2 {
uint256 l2ChainId;
IResourceMetering.ResourceConfig resourceConfig;
DisputeGameConfig[] disputeGameConfigs;
bool useCustomGasToken;
Comment thread
0xniha marked this conversation as resolved.
}

struct ExtraInstruction {
Expand Down Expand Up @@ -135,9 +136,7 @@ interface IOPContractsManagerV2 {
function version() external view returns (string memory);

/// @notice Upgrades Superchain-wide contracts.
function upgradeSuperchain(SuperchainUpgradeInput memory _inp)
external
returns (SuperchainContracts memory);
function upgradeSuperchain(SuperchainUpgradeInput memory _inp) external returns (SuperchainContracts memory);

/// @notice Deploys and wires a complete OP Chain per the provided configuration.
function deploy(FullConfig memory _cfg) external returns (ChainContracts memory);
Expand Down
3 changes: 2 additions & 1 deletion packages/contracts-bedrock/scripts/deploy/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,8 @@ contract Deploy is Deployer {
gasLimit: uint64(cfg.l2GenesisBlockGasLimit()),
l2ChainId: cfg.l2ChainID(),
resourceConfig: Constants.DEFAULT_RESOURCE_CONFIG(),
disputeGameConfigs: disputeGameConfigs
disputeGameConfigs: disputeGameConfigs,
useCustomGasToken: cfg.useCustomGasToken()
});
}
}
19 changes: 9 additions & 10 deletions packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,7 @@ contract DeployOPChain is Script {

config_ = IOPContractsManagerV2.FullConfig({
saltMixer: _input.saltMixer,
// TODO: Add superchain config to OPCM v2.
superchainConfig: ISuperchainConfig(address(0)),
superchainConfig: _input.superchainConfig,
proxyAdminOwner: _input.opChainProxyAdminOwner,
systemConfigOwner: _input.systemConfigOwner,
unsafeBlockSigner: _input.unsafeBlockSigner,
Expand All @@ -214,7 +213,8 @@ contract DeployOPChain is Script {
gasLimit: _input.gasLimit,
l2ChainId: _input.l2ChainId,
resourceConfig: Constants.DEFAULT_RESOURCE_CONFIG(),
disputeGameConfigs: disputeGameConfigs
disputeGameConfigs: disputeGameConfigs,
useCustomGasToken: _input.useCustomGasToken
});
}

Expand Down Expand Up @@ -318,7 +318,10 @@ contract DeployOPChain is Script {
address(_o.ethLockboxProxy)
);

if (!isDevFeatureV2DisputeGamesEnabled(_i.opcm)) {
// OPCM v2 always uses v2 dispute games, so only check v1 feature flag if v2 is not enabled
bool useV2Games = isDevFeatureOpcmV2Enabled(_i.opcm)
|| (!isDevFeatureOpcmV2Enabled(_i.opcm) && isDevFeatureV2DisputeGamesEnabled(_i.opcm));
if (!useV2Games) {
// Only check dispute game contracts if v2 dispute games are not enabled.
// When v2 contracts are enabled, we no longer deploy dispute games per chain
addrs2 = Solarray.extend(addrs2, Solarray.addresses(address(_o.permissionedDisputeGame)));
Expand Down Expand Up @@ -347,27 +350,23 @@ contract DeployOPChain is Script {
SystemConfig: address(_o.systemConfigProxy),
L1ERC721Bridge: address(_o.l1ERC721BridgeProxy),
ProtocolVersions: address(0),
SuperchainConfig: address(0)
SuperchainConfig: address(_i.superchainConfig)
});

// Check dispute games and get superchain config
address expectedPDGImpl = address(_o.permissionedDisputeGame);
ISuperchainConfig superchainConfig;

if (isDevFeatureOpcmV2Enabled(_i.opcm)) {
// OPCM v2: use implementations from v2 contract
IOPContractsManagerV2 opcmV2 = IOPContractsManagerV2(_i.opcm);
expectedPDGImpl = opcmV2.implementations().permissionedDisputeGameV2Impl;
// TODO: Add superchain config to OPCM v2.
superchainConfig = ISuperchainConfig(address(0));
} else {
// OPCM v1: use implementations from v1 contract
IOPContractsManager opcm = IOPContractsManager(_i.opcm);
if (isDevFeatureV2DisputeGamesEnabled(_i.opcm)) {
// With v2 game contracts enabled, we use the predeployed pdg implementation
expectedPDGImpl = opcm.implementations().permissionedDisputeGameV2Impl;
}
superchainConfig = opcm.superchainConfig();
}

ChainAssertions.checkDisputeGameFactory(
Expand All @@ -378,7 +377,7 @@ contract DeployOPChain is Script {
ChainAssertions.checkL1CrossDomainMessenger(_o.l1CrossDomainMessengerProxy, vm, true);
ChainAssertions.checkOptimismPortal2({
_contracts: proxies,
_superchainConfig: superchainConfig,
_superchainConfig: _i.superchainConfig,
_opChainProxyAdminOwner: _i.opChainProxyAdminOwner,
_isProxy: true
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ contract ReadImplementationAddresses is Script {
output_.l1StandardBridge = IStaticL1ChugSplashProxy(_input.l1StandardBridgeProxy).getImplementation();

// Get implementations from OPCM
// TODO: Adapt to OPCMV2 interface when feature enabled
IOPContractsManager opcm = IOPContractsManager(_input.opcm);
output_.opcmGameTypeAdder = address(opcm.opcmGameTypeAdder());
output_.opcmDeployer = address(opcm.opcmDeployer());
Expand Down
3 changes: 3 additions & 0 deletions packages/contracts-bedrock/scripts/libraries/Types.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity ^0.8.0;

import { Claim, Duration, GameType } from "src/dispute/lib/Types.sol";
import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol";

library Types {
/// @notice Represents a set of L1 contracts. Used to represent a set of proxies.
Expand Down Expand Up @@ -49,6 +50,8 @@ library Types {
// Fee params
uint32 operatorFeeScalar;
uint64 operatorFeeConstant;
// Superchain contracts
ISuperchainConfig superchainConfig;
// Whether to use the custom gas token.
bool useCustomGasToken;
}
Expand Down
30 changes: 23 additions & 7 deletions packages/contracts-bedrock/src/L1/opcm/OPContractsManagerV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ contract OPContractsManagerV2 is ISemver {
IResourceMetering.ResourceConfig resourceConfig;
// Dispute game configuration.
DisputeGameConfig[] disputeGameConfigs;
// Feature flags.
bool useCustomGasToken;
}

/// @notice Partial input required for an upgrade.
Expand Down Expand Up @@ -598,7 +600,16 @@ contract OPContractsManagerV2 is ISemver {
),
(GameType)
),
disputeGameConfigs: _upgradeInput.disputeGameConfigs
disputeGameConfigs: _upgradeInput.disputeGameConfigs,
useCustomGasToken: abi.decode(
_loadBytes(
address(_chainContracts.systemConfig),
_chainContracts.systemConfig.isCustomGasToken.selector,
"overrides.cfg.useCustomGasToken",
_upgradeInput.extraInstructions
),
(bool)
)
});
}

Expand Down Expand Up @@ -802,6 +813,11 @@ contract OPContractsManagerV2 is ISemver {
);
}

// If the custom gas token feature was requested, enable it in the SystemConfig.
if (_cfg.useCustomGasToken) {
_cts.systemConfig.setFeature(Features.CUSTOM_GAS_TOKEN, true);
}

// If critical transfer is allowed, tranfer ownership of the DisputeGameFactory and
// ProxyAdmin to the PAO. During deployments, this means transferring ownership from the
// OPCM contract to the target PAO. During upgrades, this would theoretically mean
Expand Down Expand Up @@ -855,7 +871,7 @@ contract OPContractsManagerV2 is ISemver {
_cfg.gasLimit,
_cfg.unsafeBlockSigner,
_cfg.resourceConfig,
_chainIdToBatchInboxAddress(_cfg.l2ChainId),
chainIdToBatchInboxAddress(_cfg.l2ChainId),
addrs,
_cfg.l2ChainId,
_cfg.superchainConfig
Expand Down Expand Up @@ -945,24 +961,24 @@ contract OPContractsManagerV2 is ISemver {
return contractsContainer.isDevFeatureEnabled(_feature);
}

///////////////////////////////////////////////////////////////////////////
// INTERNAL UTILITY FUNCTIONS //
///////////////////////////////////////////////////////////////////////////

/// @notice Maps an L2 chain ID to an L1 batch inbox address as defined by the standard
/// configuration's convention. This convention is
/// `versionByte || keccak256(bytes32(chainId))[:19]`, where || denotes concatenation,
/// versionByte is 0x00, and chainId is a uint256.
/// https://specs.optimism.io/protocol/configurability.html#consensus-parameters
/// @param _l2ChainId The L2 chain ID to map to an L1 batch inbox address.
/// @return Chain ID mapped to an L1 batch inbox address.
function _chainIdToBatchInboxAddress(uint256 _l2ChainId) internal pure returns (address) {
function chainIdToBatchInboxAddress(uint256 _l2ChainId) public pure returns (address) {
bytes1 versionByte = 0x00;
bytes32 hashedChainId = keccak256(bytes.concat(bytes32(_l2ChainId)));
bytes19 first19Bytes = bytes19(hashedChainId);
return address(uint160(bytes20(bytes.concat(versionByte, first19Bytes))));
}

///////////////////////////////////////////////////////////////////////////
// INTERNAL UTILITY FUNCTIONS //
///////////////////////////////////////////////////////////////////////////

/// @notice Computes a unique salt for a contract deployment.
/// @param _l2ChainId The L2 chain ID of the chain being deployed to.
/// @param _saltMixer The salt mixer to use for the deployment.
Expand Down
10 changes: 5 additions & 5 deletions packages/contracts-bedrock/test/L1/OPContractsManager.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2377,29 +2377,29 @@ contract OPContractsManager_Deploy_Test is DeployOPChain_TestBase, DisputeGames
input.l2ChainId = 0;

vm.expectRevert(IOPContractsManager.InvalidChainId.selector);
opcm.deploy(input);
IOPContractsManager(opcmAddr).deploy(input);
}

function test_deploy_l2ChainIdEqualsCurrentChainId_reverts() public {
IOPContractsManager.DeployInput memory input = toOPCMDeployInput(deployOPChainInput);
input.l2ChainId = block.chainid;

vm.expectRevert(IOPContractsManager.InvalidChainId.selector);
opcm.deploy(input);
IOPContractsManager(opcmAddr).deploy(input);
}

function test_deploy_succeeds() public {
vm.expectEmit(true, true, true, false); // TODO precompute the expected `deployOutput`.
emit Deployed(deployOPChainInput.l2ChainId, address(this), bytes(""));
opcm.deploy(toOPCMDeployInput(deployOPChainInput));
IOPContractsManager(opcmAddr).deploy(toOPCMDeployInput(deployOPChainInput));
}

/// @notice Test that deploy sets the permissioned dispute game implementation
function test_deployPermissioned_succeeds() public {
bool isV2 = isDevFeatureEnabled(DevFeatures.DEPLOY_V2_DISPUTE_GAMES);

// Sanity-check setup is consistent with devFeatures flag
IOPContractsManager.Implementations memory impls = opcm.implementations();
IOPContractsManager.Implementations memory impls = IOPContractsManager(opcmAddr).implementations();
address pdgImpl = address(impls.permissionedDisputeGameV2Impl);
address fdgImpl = address(impls.faultDisputeGameV2Impl);
if (isV2) {
Expand All @@ -2412,7 +2412,7 @@ contract OPContractsManager_Deploy_Test is DeployOPChain_TestBase, DisputeGames

// Run OPCM.deploy
IOPContractsManager.DeployInput memory opcmInput = toOPCMDeployInput(deployOPChainInput);
IOPContractsManager.DeployOutput memory opcmOutput = opcm.deploy(opcmInput);
IOPContractsManager.DeployOutput memory opcmOutput = IOPContractsManager(opcmAddr).deploy(opcmInput);

// Verify that the DisputeGameFactory has registered an implementation for the PERMISSIONED_CANNON game type
address expectedPDGAddress = isV2 ? pdgImpl : address(opcmOutput.permissionedDisputeGame);
Expand Down
Loading