diff --git a/packages/contracts-bedrock/src/L1/SystemConfig.sol b/packages/contracts-bedrock/src/L1/SystemConfig.sol index c4ad7d547168..d9e47e3fc170 100644 --- a/packages/contracts-bedrock/src/L1/SystemConfig.sol +++ b/packages/contracts-bedrock/src/L1/SystemConfig.sol @@ -367,7 +367,7 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { /// @notice Internal function for updating the gas config. /// @param _overhead New overhead value. /// @param _scalar New scalar value. - function _setGasConfig(uint256 _overhead, uint256 _scalar) internal { + function _setGasConfig(uint256 _overhead, uint256 _scalar) internal virtual { require((uint256(0xff) << 248) & _scalar == 0, "SystemConfig: scalar exceeds max."); overhead = _overhead; diff --git a/packages/contracts-bedrock/src/L1/SystemConfigHolocene.sol b/packages/contracts-bedrock/src/L1/SystemConfigHolocene.sol index cf1ecc0f8543..13e18a449c8c 100644 --- a/packages/contracts-bedrock/src/L1/SystemConfigHolocene.sol +++ b/packages/contracts-bedrock/src/L1/SystemConfigHolocene.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { OptimismPortalInterop as OptimismPortal } from "src/L1/OptimismPortalInterop.sol"; -import { SystemConfigInterop } from "src/L1/SystemConfigInterop.sol"; +import { SystemConfig } from "src/L1/SystemConfig.sol"; import { ConfigType } from "src/L2/L1BlockInterop.sol"; import { StaticConfig } from "src/libraries/StaticConfig.sol"; @@ -10,33 +10,58 @@ import { StaticConfig } from "src/libraries/StaticConfig.sol"; /// @notice The SystemConfig contract is used to manage configuration of an Optimism network. /// All configuration is stored on L1 and picked up by L2 as part of the derviation of /// the L2 chain. -contract SystemConfigHolocene is SystemConfigInterop { - /// @notice Internal setter for the batcher hash. - /// @param _batcherHash New batcher hash. - function _setBatcherHash(bytes32 _batcherHash) internal override { - if (batcherHash != _batcherHash) { - batcherHash = _batcherHash; - OptimismPortal(payable(optimismPortal())).setConfig( - ConfigType.SET_BATCHER_HASH, StaticConfig.encodeSetBatcherHash({ _batcherHash: _batcherHash }) - ); - } +contract SystemConfigHolocene is SystemConfig { + error Deprecated(); + + /// @notice Internal function for updating the gas config. + /// `setGasConfig` is deprecated, use `setFeeScalars` instead. + /// `setGasConfig` will be removed when SystemConfigHolocene is + /// pulled into SystemConfig. + function _setGasConfig(uint256, uint256) internal pure override { + revert Deprecated(); } /// @notice Internal function for updating the fee scalars as of the Ecotone upgrade. + /// Deprecated, use `setFeeScalars` instead. /// @param _basefeeScalar New basefeeScalar value. - /// @param _blobbasefeeScalar New blobbasefeeScalar value. - function _setGasConfigEcotone(uint32 _basefeeScalar, uint32 _blobbasefeeScalar) internal override { + /// @param _blobBasefeeScalar New blobBasefeeScalar value. + function _setGasConfigEcotone(uint32 _basefeeScalar, uint32 _blobBasefeeScalar) internal override { + _setFeeScalars(_basefeeScalar, _blobBasefeeScalar); + } + + /// @notice Updates the fee scalars. Can only be called by the owner. + /// @param _basefeeScalar New basefeeScalar value. + /// @param _blobBasefeeScalar New blobBasefeeScalar value. + function setFeeScalars(uint32 _basefeeScalar, uint32 _blobBasefeeScalar) external onlyOwner { + _setFeeScalars(_basefeeScalar, _blobBasefeeScalar); + } + + /// @notice Internal function for updating the fee scalars. + /// @param _basefeeScalar New basefeeScalar value. + /// @param _blobBasefeeScalar New blobBasefeeScalar value. + function _setFeeScalars(uint32 _basefeeScalar, uint32 _blobBasefeeScalar) internal { basefeeScalar = _basefeeScalar; - blobbasefeeScalar = _blobbasefeeScalar; + blobbasefeeScalar = _blobBasefeeScalar; - uint256 _scalar = (uint256(0x01) << 248) | (uint256(_blobbasefeeScalar) << 32) | _basefeeScalar; + uint256 _scalar = (uint256(0x01) << 248) | (uint256(_blobBasefeeScalar) << 32) | _basefeeScalar; scalar = _scalar; OptimismPortal(payable(optimismPortal())).setConfig( - ConfigType.SET_GAS_CONFIG_ECOTONE, StaticConfig.encodeSetGasConfigEcotone({ _scalar: _scalar }) + ConfigType.SET_FEE_SCALARS, StaticConfig.encodeSetFeeScalars({ _scalar: _scalar }) ); } + /// @notice Internal setter for the batcher hash. + /// @param _batcherHash New batcher hash. + function _setBatcherHash(bytes32 _batcherHash) internal override { + if (batcherHash != _batcherHash) { + batcherHash = _batcherHash; + OptimismPortal(payable(optimismPortal())).setConfig( + ConfigType.SET_BATCHER_HASH, StaticConfig.encodeSetBatcherHash({ _batcherHash: _batcherHash }) + ); + } + } + /// @notice Internal function for updating the L2 gas limit. /// @param _gasLimit New gas limit. function _setGasLimit(uint64 _gasLimit) internal override { diff --git a/packages/contracts-bedrock/src/L2/L1Block.sol b/packages/contracts-bedrock/src/L2/L1Block.sol index 8cfbb391f0f5..90b5f2b71c3f 100644 --- a/packages/contracts-bedrock/src/L2/L1Block.sol +++ b/packages/contracts-bedrock/src/L2/L1Block.sol @@ -6,6 +6,19 @@ import { Constants } from "src/libraries/Constants.sol"; import { GasPayingToken, IGasToken } from "src/libraries/GasPayingToken.sol"; import "src/libraries/L1BlockErrors.sol"; +/// @notice Enum representing different types of configurations that can be set on L1Block. +/// @custom:value SET_GAS_PAYING_TOKEN Represents the config type for setting the gas paying token. +/// @custom:value ADD_DEPENDENCY Represents the config type for adding a chain to the interop dependency set. +/// @custom:value REMOVE_DEPENDENCY Represents the config type for removing a chain from the interop dependency set. +enum ConfigType { + SET_GAS_PAYING_TOKEN, + ADD_DEPENDENCY, + REMOVE_DEPENDENCY, + SET_BATCHER_HASH, + SET_FEE_SCALARS, + SET_GAS_LIMIT +} + /// @custom:proxied /// @custom:predeploy 0x4200000000000000000000000000000000000015 /// @title L1Block @@ -162,4 +175,10 @@ contract L1Block is ISemver, IGasToken { emit GasPayingTokenSet({ token: _token, decimals: _decimals, name: _name, symbol: _symbol }); } + + /// @notice Sets static configuration options for the L2 system. Can only be called by the special + /// depositor account. + /// @param _type The type of configuration to set. + /// @param _value The encoded value with which to set the configuration. + function setConfig(ConfigType _type, bytes calldata _value) public virtual { } } diff --git a/packages/contracts-bedrock/src/L2/L1BlockHolocene.sol b/packages/contracts-bedrock/src/L2/L1BlockHolocene.sol index 7e0ad562a266..005bab87750c 100644 --- a/packages/contracts-bedrock/src/L2/L1BlockHolocene.sol +++ b/packages/contracts-bedrock/src/L2/L1BlockHolocene.sol @@ -1,20 +1,20 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { L1BlockInterop, ConfigType } from "src/L2/L1BlockInterop.sol"; +import { L1Block, ConfigType } from "src/L2/L1Block.sol"; import { StaticConfig } from "src/libraries/StaticConfig.sol"; import "src/libraries/L1BlockErrors.sol"; /// @custom:proxied /// @custom:predeploy 0x4200000000000000000000000000000000000015 /// @title L1BlockHolocene -/// @notice Interop extenstions of L1Block. -contract L1BlockHolocene is L1BlockInterop { +/// @notice Holocene extenstions of L1Block. +contract L1BlockHolocene is L1Block { /// @notice Event emitted when a new batcher hash is set. event BatcherHashSet(bytes32 indexed batcherHash); - /// @notice Event emitted when a new ecotone gas config is set. - event GasConfigEcotoneSet(uint32 indexed blobBaseFeeScalar, uint32 indexed baseFeeScalar); + /// @notice Event emitted when new fee scalars are set. + event FeeScalarsSet(uint32 indexed blobBasefeeScalar, uint32 indexed basefeeScalar); /// @notice Event emitted when a new gas limit is set. event GasLimitSet(uint64 indexed gasLimit); @@ -26,21 +26,17 @@ contract L1BlockHolocene is L1BlockInterop { /// depositor account. /// @param _type The type of configuration to set. /// @param _value The encoded value with which to set the configuration. - function setConfig(ConfigType _type, bytes calldata _value) external override { + function setConfig(ConfigType _type, bytes calldata _value) public override { if (msg.sender != DEPOSITOR_ACCOUNT()) revert NotDepositor(); - if (_type == ConfigType.SET_GAS_PAYING_TOKEN) { - _setGasPayingToken(_value); - } else if (_type == ConfigType.ADD_DEPENDENCY) { - _addDependency(_value); - } else if (_type == ConfigType.REMOVE_DEPENDENCY) { - _removeDependency(_value); - } else if (_type == ConfigType.SET_BATCHER_HASH) { + if (_type == ConfigType.SET_BATCHER_HASH) { _setBatcherHash(_value); - } else if (_type == ConfigType.SET_GAS_CONFIG_ECOTONE) { - _setGasConfigEcotone(_value); + } else if (_type == ConfigType.SET_FEE_SCALARS) { + _setFeeScalars(_value); } else if (_type == ConfigType.SET_GAS_LIMIT) { _setGasLimit(_value); + } else { + super.setConfig(_type, _value); } } @@ -54,17 +50,17 @@ contract L1BlockHolocene is L1BlockInterop { emit BatcherHashSet(_batcherHash); } - /// @notice Internal method to set new gas config. - /// @param _value The encoded value with which to set the new batcher hash. - function _setGasConfigEcotone(bytes calldata _value) internal { - uint256 _scalar = StaticConfig.decodeSetGasConfigEcotone(_value); + /// @notice Internal method to set new fee scalars. + /// @param _value The encoded value with which to set the new fee scalars. + function _setFeeScalars(bytes calldata _value) internal { + uint256 _scalar = StaticConfig.decodeSetFeeScalars(_value); - (uint32 _blobBaseFeeScalar, uint32 _baseFeeScalar) = _decodeScalar(_scalar); + (uint32 _blobBasefeeScalar, uint32 _basefeeScalar) = _decodeScalar(_scalar); - blobBaseFeeScalar = _blobBaseFeeScalar; - baseFeeScalar = _baseFeeScalar; + blobBaseFeeScalar = _blobBasefeeScalar; + baseFeeScalar = _basefeeScalar; - emit GasConfigEcotoneSet(_blobBaseFeeScalar, _baseFeeScalar); + emit FeeScalarsSet(_blobBasefeeScalar, _basefeeScalar); } /// @notice Internal method to decode blobBaseFeeScalar and baseFeeScalar. @@ -76,9 +72,9 @@ contract L1BlockHolocene is L1BlockInterop { require(0x01 == _scalar >> 248, "invalid _scalar"); - uint32 _blobbasefeeScalar = uint32((_scalar >> 32) & 0xffffffff); + uint32 _blobBasefeeScalar = uint32((_scalar >> 32) & 0xffffffff); uint32 _basefeeScalar = uint32(_scalar & 0xffffffff); - return (_blobbasefeeScalar, _basefeeScalar); + return (_blobBasefeeScalar, _basefeeScalar); } /// @notice Internal method to set new gas limit. @@ -109,12 +105,20 @@ contract L1BlockHolocene is L1BlockInterop { } // sequencenum (uint64) _sequenceNumber := shr(192, calldataload(4)) + } + + sequenceNumber = _sequenceNumber; + + // for each L2 block, include only the sequence number, except for L2 blocks with sequencer #0, + // and they'd have all the L1 origin related attributes following the 0 sequence number. + if (_sequenceNumber != 0) return; + + assembly { // number (uint64) and timestamp (uint64) sstore(number.slot, shr(128, calldataload(12))) sstore(basefee.slot, calldataload(28)) // uint256 sstore(blobBaseFee.slot, calldataload(60)) // uint256 sstore(hash.slot, calldataload(92)) // bytes32 } - sequenceNumber = _sequenceNumber; } } diff --git a/packages/contracts-bedrock/src/L2/L1BlockInterop.sol b/packages/contracts-bedrock/src/L2/L1BlockInterop.sol index 188655c834d3..80d39390c321 100644 --- a/packages/contracts-bedrock/src/L2/L1BlockInterop.sol +++ b/packages/contracts-bedrock/src/L2/L1BlockInterop.sol @@ -1,25 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { L1Block } from "src/L2/L1Block.sol"; +import { L1Block, ConfigType } from "src/L2/L1Block.sol"; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; import { StaticConfig } from "src/libraries/StaticConfig.sol"; import "src/libraries/L1BlockErrors.sol"; -/// @notice Enum representing different types of configurations that can be set on L1BlockInterop. -/// @custom:value SET_GAS_PAYING_TOKEN Represents the config type for setting the gas paying token. -/// @custom:value ADD_DEPENDENCY Represents the config type for adding a chain to the interop dependency set. -/// @custom:value REMOVE_DEPENDENCY Represents the config type for removing a chain from the interop dependency set. -enum ConfigType { - SET_GAS_PAYING_TOKEN, - ADD_DEPENDENCY, - REMOVE_DEPENDENCY, - SET_BATCHER_HASH, - SET_GAS_CONFIG_ECOTONE, - SET_GAS_LIMIT -} - /// @custom:proxied /// @custom:predeploy 0x4200000000000000000000000000000000000015 /// @title L1BlockInterop @@ -59,7 +46,7 @@ contract L1BlockInterop is L1Block { /// depositor account. /// @param _type The type of configuration to set. /// @param _value The encoded value with which to set the configuration. - function setConfig(ConfigType _type, bytes calldata _value) external virtual { + function setConfig(ConfigType _type, bytes calldata _value) public override { if (msg.sender != DEPOSITOR_ACCOUNT()) revert NotDepositor(); if (_type == ConfigType.SET_GAS_PAYING_TOKEN) { @@ -68,6 +55,8 @@ contract L1BlockInterop is L1Block { _addDependency(_value); } else if (_type == ConfigType.REMOVE_DEPENDENCY) { _removeDependency(_value); + } else { + super.setConfig(_type, _value); } } diff --git a/packages/contracts-bedrock/src/libraries/StaticConfig.sol b/packages/contracts-bedrock/src/libraries/StaticConfig.sol index 99ef2dbe059e..32ad2c25a8f3 100644 --- a/packages/contracts-bedrock/src/libraries/StaticConfig.sol +++ b/packages/contracts-bedrock/src/libraries/StaticConfig.sol @@ -72,16 +72,17 @@ library StaticConfig { return abi.decode(_data, (bytes32)); } - /// @notice Encodes the static configuration data for setting the gas config as of the Ecotone upgrade. + /// @notice Encodes the static configuration data for setting the fee scalars. /// @param _scalar New scalar value. - function encodeSetGasConfigEcotone(uint256 _scalar) internal pure returns (bytes memory) { + /// @return Encoded static configuration data. + function encodeSetFeeScalars(uint256 _scalar) internal pure returns (bytes memory) { return abi.encode(_scalar); } - /// @notice Decodes the static configuration data for setting the gas config as of the Ecotone upgrade. + /// @notice Decodes the static configuration data for setting the fee scalars. /// @param _data Encoded static configuration data. - /// @return Decoded gas config to set. - function decodeSetGasConfigEcotone(bytes memory _data) internal pure returns (uint256) { + /// @return Decoded fee scalars to set. + function decodeSetFeeScalars(bytes memory _data) internal pure returns (uint256) { return abi.decode(_data, (uint256)); }