Commit 6202822a authored by Maurelian's avatar Maurelian Committed by GitHub

feat(opcm): Create and use new ISystemConfigV160 (#12163)

* feat(opcm): Create and use new ISystemConfigV160

* feat(opcm): defaultSystemConfigParams in OPCM Interop

* chore: semgrep

* fix: handle different system config initializers

* chore: revert interop changes since it uses the latest systemConfig

* chore: semver lock

* chore: semver locK

---------
Co-authored-by: default avatarMatt Solomon <matt@mattsolomon.dev>
parent d83f12d3
...@@ -7,6 +7,7 @@ import { LibString } from "@solady/utils/LibString.sol"; ...@@ -7,6 +7,7 @@ import { LibString } from "@solady/utils/LibString.sol";
import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol";
import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol";
import { ISystemConfigV160 } from "src/L1/interfaces/ISystemConfigV160.sol";
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
...@@ -479,7 +480,7 @@ contract DeployImplementations is Script { ...@@ -479,7 +480,7 @@ contract DeployImplementations is Script {
// --- OP Contracts Manager --- // --- OP Contracts Manager ---
function opcmSystemConfigSetter( function opcmSystemConfigSetter(
DeployImplementationsInput, DeployImplementationsInput _dii,
DeployImplementationsOutput _dio DeployImplementationsOutput _dio
) )
internal internal
...@@ -487,9 +488,19 @@ contract DeployImplementations is Script { ...@@ -487,9 +488,19 @@ contract DeployImplementations is Script {
virtual virtual
returns (OPContractsManager.ImplementationSetter memory) returns (OPContractsManager.ImplementationSetter memory)
{ {
// When configuring OPCM during Solidity tests, we are using the latest SystemConfig.sol
// version in this repo, which contains Custom Gas Token (CGT) features. This CGT version
// has a different `initialize` signature than the SystemConfig version that was released
// as part of `op-contracts/v1.6.0`, which is no longer in the repo. When running this
// script's bytecode for a production deploy of OPCM at `op-contracts/v1.6.0`, we need to
// use the ISystemConfigV160 interface instead of ISystemConfig. Therefore the selector used
// is a function of the `release` passed in by the caller.
bytes4 selector = LibString.eq(_dii.release(), "op-contracts/v1.6.0")
? ISystemConfigV160.initialize.selector
: SystemConfig.initialize.selector;
return OPContractsManager.ImplementationSetter({ return OPContractsManager.ImplementationSetter({
name: "SystemConfig", name: "SystemConfig",
info: OPContractsManager.Implementation(address(_dio.systemConfigImpl()), SystemConfig.initialize.selector) info: OPContractsManager.Implementation(address(_dio.systemConfigImpl()), selector)
}); });
} }
......
...@@ -32,8 +32,8 @@ ...@@ -32,8 +32,8 @@
"sourceCodeHash": "0xde4df0f9633dc0cdb1c9f634003ea5b0f7c5c1aebc407bc1b2f44c0ecf938649" "sourceCodeHash": "0xde4df0f9633dc0cdb1c9f634003ea5b0f7c5c1aebc407bc1b2f44c0ecf938649"
}, },
"src/L1/OPContractsManager.sol": { "src/L1/OPContractsManager.sol": {
"initCodeHash": "0xfc35bbfe19cb5345288d314ade85538a65ad213a7163133c0044b5556b180836", "initCodeHash": "0x15ace86b1d389d02654392e10c3d444000f22e549ad2736cd5a869e4d862ddc8",
"sourceCodeHash": "0x597bb234e83560d0e120b83334e152269d5fcdba2f8743bdd7594cc79098c15f" "sourceCodeHash": "0xffb7698ab51b7ea58460146de3d094d8e2f869c1425d289832855062c77692a8"
}, },
"src/L1/OptimismPortal.sol": { "src/L1/OptimismPortal.sol": {
"initCodeHash": "0xbe2c0c81b3459014f287d8c89cdc0d27dde5d1f44e5d024fa1e4773ddc47c190", "initCodeHash": "0xbe2c0c81b3459014f287d8c89cdc0d27dde5d1f44e5d024fa1e4773ddc47c190",
......
...@@ -12,6 +12,7 @@ import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol"; ...@@ -12,6 +12,7 @@ import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol";
import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol";
import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol";
import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol";
import { ISystemConfigV160 } from "src/L1/interfaces/ISystemConfigV160.sol";
import { Proxy } from "src/universal/Proxy.sol"; import { Proxy } from "src/universal/Proxy.sol";
import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { ProxyAdmin } from "src/universal/ProxyAdmin.sol";
...@@ -126,8 +127,8 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -126,8 +127,8 @@ contract OPContractsManager is ISemver, Initializable {
// -------- Constants and Variables -------- // -------- Constants and Variables --------
/// @custom:semver 1.0.0-beta.11 /// @custom:semver 1.0.0-beta.12
string public constant version = "1.0.0-beta.11"; string public constant version = "1.0.0-beta.12";
/// @notice Represents the interface version so consumers know how to decode the DeployOutput struct /// @notice Represents the interface version so consumers know how to decode the DeployOutput struct
/// that's emitted in the `Deployed` event. Whenever that struct changes, a new version should be used. /// that's emitted in the `Deployed` event. Whenever that struct changes, a new version should be used.
...@@ -309,7 +310,10 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -309,7 +310,10 @@ contract OPContractsManager is ISemver, Initializable {
data = encodeOptimismPortalInitializer(impl.initializer, output); data = encodeOptimismPortalInitializer(impl.initializer, output);
upgradeAndCall(output.opChainProxyAdmin, address(output.optimismPortalProxy), impl.logic, data); upgradeAndCall(output.opChainProxyAdmin, address(output.optimismPortalProxy), impl.logic, data);
// First we upgrade the implementation so it's version can be retrieved, then we initialize
// it afterwards. See the comments in encodeSystemConfigInitializer to learn more.
impl = getLatestImplementation("SystemConfig"); impl = getLatestImplementation("SystemConfig");
output.opChainProxyAdmin.upgrade(payable(address(output.systemConfigProxy)), impl.logic);
data = encodeSystemConfigInitializer(impl.initializer, _input, output); data = encodeSystemConfigInitializer(impl.initializer, _input, output);
upgradeAndCall(output.opChainProxyAdmin, address(output.systemConfigProxy), impl.logic, data); upgradeAndCall(output.opChainProxyAdmin, address(output.systemConfigProxy), impl.logic, data);
...@@ -450,21 +454,48 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -450,21 +454,48 @@ contract OPContractsManager is ISemver, Initializable {
virtual virtual
returns (bytes memory) returns (bytes memory)
{ {
(ResourceMetering.ResourceConfig memory referenceResourceConfig, SystemConfig.Addresses memory opChainAddrs) = // We inspect the SystemConfig contract and determine it's signature here. This is required
defaultSystemConfigParams(_selector, _input, _output); // because this OPCM contract is being developed in a repository that no longer contains the
// SystemConfig contract that was released as part of `op-contracts/v1.6.0`, but in production
return abi.encodeWithSelector( // it needs to support that version, in addition to the version currently on develop.
_selector, string memory semver = _output.systemConfigProxy.version();
_input.roles.systemConfigOwner, if (keccak256(abi.encode(semver)) == keccak256(abi.encode(string("2.2.0")))) {
_input.basefeeScalar, // We are using the op-contracts/v1.6.0 SystemConfig contract.
_input.blobBasefeeScalar, (
bytes32(uint256(uint160(_input.roles.batcher))), // batcherHash ResourceMetering.ResourceConfig memory referenceResourceConfig,
30_000_000, // gasLimit, TODO should this be an input? ISystemConfigV160.Addresses memory opChainAddrs
_input.roles.unsafeBlockSigner, ) = defaultSystemConfigV160Params(_selector, _input, _output);
referenceResourceConfig,
chainIdToBatchInboxAddress(_input.l2ChainId), return abi.encodeWithSelector(
opChainAddrs _selector,
); _input.roles.systemConfigOwner,
_input.basefeeScalar,
_input.blobBasefeeScalar,
bytes32(uint256(uint160(_input.roles.batcher))), // batcherHash
30_000_000, // gasLimit, TODO should this be an input?
_input.roles.unsafeBlockSigner,
referenceResourceConfig,
chainIdToBatchInboxAddress(_input.l2ChainId),
opChainAddrs
);
} else {
// We are using the latest SystemConfig contract from the repo.
(ResourceMetering.ResourceConfig memory referenceResourceConfig, SystemConfig.Addresses memory opChainAddrs)
= defaultSystemConfigParams(_selector, _input, _output);
return abi.encodeWithSelector(
_selector,
_input.roles.systemConfigOwner,
_input.basefeeScalar,
_input.blobBasefeeScalar,
bytes32(uint256(uint160(_input.roles.batcher))), // batcherHash
30_000_000, // gasLimit, TODO should this be an input?
_input.roles.unsafeBlockSigner,
referenceResourceConfig,
chainIdToBatchInboxAddress(_input.l2ChainId),
opChainAddrs
);
}
} }
/// @notice Helper method for encoding the OptimismMintableERC20Factory initializer data. /// @notice Helper method for encoding the OptimismMintableERC20Factory initializer data.
...@@ -612,6 +643,45 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -612,6 +643,45 @@ contract OPContractsManager is ISemver, Initializable {
assertValidContractAddress(opChainAddrs_.optimismMintableERC20Factory); assertValidContractAddress(opChainAddrs_.optimismMintableERC20Factory);
} }
/// @notice Returns default, standard config arguments for the SystemConfig initializer.
/// This is used by subclasses to reduce code duplication.
function defaultSystemConfigV160Params(
bytes4, /* selector */
DeployInput memory, /* _input */
DeployOutput memory _output
)
internal
view
virtual
returns (
ResourceMetering.ResourceConfig memory resourceConfig_,
ISystemConfigV160.Addresses memory opChainAddrs_
)
{
// We use assembly to easily convert from IResourceMetering.ResourceConfig to ResourceMetering.ResourceConfig.
// This is required because we have not yet fully migrated the codebase to be interface-based.
IResourceMetering.ResourceConfig memory resourceConfig = Constants.DEFAULT_RESOURCE_CONFIG();
assembly ("memory-safe") {
resourceConfig_ := resourceConfig
}
opChainAddrs_ = ISystemConfigV160.Addresses({
l1CrossDomainMessenger: address(_output.l1CrossDomainMessengerProxy),
l1ERC721Bridge: address(_output.l1ERC721BridgeProxy),
l1StandardBridge: address(_output.l1StandardBridgeProxy),
disputeGameFactory: address(_output.disputeGameFactoryProxy),
optimismPortal: address(_output.optimismPortalProxy),
optimismMintableERC20Factory: address(_output.optimismMintableERC20FactoryProxy)
});
assertValidContractAddress(opChainAddrs_.l1CrossDomainMessenger);
assertValidContractAddress(opChainAddrs_.l1ERC721Bridge);
assertValidContractAddress(opChainAddrs_.l1StandardBridge);
assertValidContractAddress(opChainAddrs_.disputeGameFactory);
assertValidContractAddress(opChainAddrs_.optimismPortal);
assertValidContractAddress(opChainAddrs_.optimismMintableERC20Factory);
}
/// @notice Makes an external call to the target to initialize the proxy with the specified data. /// @notice Makes an external call to the target to initialize the proxy with the specified data.
/// First performs safety checks to ensure the target, implementation, and proxy admin are valid. /// First performs safety checks to ensure the target, implementation, and proxy admin are valid.
function upgradeAndCall( function upgradeAndCall(
......
...@@ -3,6 +3,7 @@ pragma solidity ^0.8.0; ...@@ -3,6 +3,7 @@ pragma solidity ^0.8.0;
import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol";
/// @notice This interface corresponds to the Custom Gas Token version of the SystemConfig contract.
interface ISystemConfig { interface ISystemConfig {
enum UpdateType { enum UpdateType {
BATCHER, BATCHER,
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol";
/// @notice This interface corresponds to the op-contracts/v1.6.0 release of the SystemConfig
/// contract, which has a semver of 2.2.0 as specified in
/// https://github.com/ethereum-optimism/optimism/releases/tag/op-contracts%2Fv1.6.0
interface ISystemConfigV160 {
enum UpdateType {
BATCHER,
GAS_CONFIG,
GAS_LIMIT,
UNSAFE_BLOCK_SIGNER
}
struct Addresses {
address l1CrossDomainMessenger;
address l1ERC721Bridge;
address l1StandardBridge;
address disputeGameFactory;
address optimismPortal;
address optimismMintableERC20Factory;
}
event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data);
event Initialized(uint8 version);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function BATCH_INBOX_SLOT() external view returns (bytes32);
function DISPUTE_GAME_FACTORY_SLOT() external view returns (bytes32);
function L1_CROSS_DOMAIN_MESSENGER_SLOT() external view returns (bytes32);
function L1_ERC_721_BRIDGE_SLOT() external view returns (bytes32);
function L1_STANDARD_BRIDGE_SLOT() external view returns (bytes32);
function OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT() external view returns (bytes32);
function OPTIMISM_PORTAL_SLOT() external view returns (bytes32);
function START_BLOCK_SLOT() external view returns (bytes32);
function UNSAFE_BLOCK_SIGNER_SLOT() external view returns (bytes32);
function VERSION() external view returns (uint256);
function basefeeScalar() external view returns (uint32);
function batchInbox() external view returns (address addr_);
function batcherHash() external view returns (bytes32);
function blobbasefeeScalar() external view returns (uint32);
function disputeGameFactory() external view returns (address addr_);
function gasLimit() external view returns (uint64);
function gasPayingToken() external view returns (address addr_, uint8 decimals_);
function gasPayingTokenName() external view returns (string memory name_);
function gasPayingTokenSymbol() external view returns (string memory symbol_);
function initialize(
address _owner,
uint32 _basefeeScalar,
uint32 _blobbasefeeScalar,
bytes32 _batcherHash,
uint64 _gasLimit,
address _unsafeBlockSigner,
IResourceMetering.ResourceConfig memory _config,
address _batchInbox,
Addresses memory _addresses
)
external;
function isCustomGasToken() external view returns (bool);
function l1CrossDomainMessenger() external view returns (address addr_);
function l1ERC721Bridge() external view returns (address addr_);
function l1StandardBridge() external view returns (address addr_);
function maximumGasLimit() external pure returns (uint64);
function minimumGasLimit() external view returns (uint64);
function optimismMintableERC20Factory() external view returns (address addr_);
function optimismPortal() external view returns (address addr_);
function overhead() external view returns (uint256);
function owner() external view returns (address);
function renounceOwnership() external;
function resourceConfig() external view returns (IResourceMetering.ResourceConfig memory);
function scalar() external view returns (uint256);
function setBatcherHash(bytes32 _batcherHash) external;
function setGasConfig(uint256 _overhead, uint256 _scalar) external;
function setGasConfigEcotone(uint32 _basefeeScalar, uint32 _blobbasefeeScalar) external;
function setGasLimit(uint64 _gasLimit) external;
function setUnsafeBlockSigner(address _unsafeBlockSigner) external;
function startBlock() external view returns (uint256 startBlock_);
function transferOwnership(address newOwner) external; // nosemgrep
function unsafeBlockSigner() external view returns (address addr_);
function version() external pure returns (string memory);
function __constructor__() external;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment