diff --git a/packages/contracts-bedrock/interfaces/L2/IL2ContractsManager.sol b/packages/contracts-bedrock/interfaces/L2/IL2ContractsManager.sol new file mode 100644 index 00000000000..0f0212d399c --- /dev/null +++ b/packages/contracts-bedrock/interfaces/L2/IL2ContractsManager.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +// Interfaces +import { ISemver } from "interfaces/universal/ISemver.sol"; + +// Libraries +import { L2ContractsManagerTypes } from "src/libraries/L2ContractsManagerTypes.sol"; + +/// @title IL2ContractsManager +/// @notice Interface for the L2ContractsManager contract. +interface IL2ContractsManager is ISemver { + /// @notice Executes the upgrade for all predeploys. + /// @dev This function MUST be called via DELEGATECALL from the L2ProxyAdmin. + function upgrade() external; + + /// @notice Constructor for the L2ContractsManager contract. + /// @param _implementations The implementation struct containing the new implementation addresses for the L2 + /// predeploys. + function __constructor__(L2ContractsManagerTypes.Implementations memory _implementations) external; +} diff --git a/packages/contracts-bedrock/interfaces/L2/IXForkL2ContractsManager.sol b/packages/contracts-bedrock/interfaces/L2/IXForkL2ContractsManager.sol deleted file mode 100644 index f3b7f5d573f..00000000000 --- a/packages/contracts-bedrock/interfaces/L2/IXForkL2ContractsManager.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import { XForkL2CMTypes } from "src/libraries/XForkL2CMTypes.sol"; - -/// @title IXForkL2ContractsManager -/// @notice Interface for the XForkL2ContractsManager contract. -interface IXForkL2ContractsManager is ISemver { - /// @notice Executes the upgrade for all predeploys. - /// @dev This function MUST be called via DELEGATECALL from the L2ProxyAdmin. - function upgrade() external; - - /// @notice Constructor for the XForkL2ContractsManager contract. - /// @param _implementations The implementation struct containing the new implementation addresses for the L2 - /// predeploys. - function __constructor__(XForkL2CMTypes.Implementations memory _implementations) external; -} diff --git a/packages/contracts-bedrock/src/L2/XForkL2ContractsManager.sol b/packages/contracts-bedrock/src/L2/L2ContractsManager.sol similarity index 88% rename from packages/contracts-bedrock/src/L2/XForkL2ContractsManager.sol rename to packages/contracts-bedrock/src/L2/L2ContractsManager.sol index fc244725c1f..3be77f64be6 100644 --- a/packages/contracts-bedrock/src/L2/XForkL2ContractsManager.sol +++ b/packages/contracts-bedrock/src/L2/L2ContractsManager.sol @@ -18,14 +18,14 @@ import { IL1Block } from "interfaces/L2/IL1Block.sol"; // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; -import { XForkL2CMTypes } from "src/libraries/XForkL2CMTypes.sol"; +import { L2ContractsManagerTypes } from "src/libraries/L2ContractsManagerTypes.sol"; import { L2ContractsManagerUtils } from "src/libraries/L2ContractsManagerUtils.sol"; -/// @title XForkL2ContractsManager -/// @notice Manages the upgrade of the L2 predeploys for the XFork upgrade. -contract XForkL2ContractsManager is ISemver { +/// @title L2ContractsManager +/// @notice Manages the upgrade of the L2 predeploys. +contract L2ContractsManager is ISemver { /// @notice Thrown when the upgrade function is called outside of a DELEGATECALL context. - error XForkL2ContractsManager_OnlyDelegatecall(); + error L2ContractsManager_OnlyDelegatecall(); /// @notice The semantic version of the L2ContractsManager contract. /// @custom:semver 1.0.0 @@ -103,10 +103,10 @@ contract XForkL2ContractsManager is ISemver { /// @notice FeeSplitter implementation. address internal immutable FEE_SPLITTER_IMPL; - /// @notice Constructor for the XForkL2ContractsManager contract. + /// @notice Constructor for the L2ContractsManager contract. /// @param _implementations The implementation struct containing the new implementation addresses for the L2 /// predeploys. - constructor(XForkL2CMTypes.Implementations memory _implementations) { + constructor(L2ContractsManagerTypes.Implementations memory _implementations) { // Store the address of this contract for DELEGATECALL enforcement. THIS_L2CM = address(this); @@ -145,33 +145,38 @@ contract XForkL2ContractsManager is ISemver { /// @notice Executes the upgrade for all predeploys. /// @dev This function MUST be called via DELEGATECALL from the L2ProxyAdmin. function upgrade() external { - if (address(this) == THIS_L2CM) revert XForkL2ContractsManager_OnlyDelegatecall(); + if (address(this) == THIS_L2CM) revert L2ContractsManager_OnlyDelegatecall(); - XForkL2CMTypes.FullConfig memory fullConfig = _loadFullConfig(); + L2ContractsManagerTypes.FullConfig memory fullConfig = _loadFullConfig(); _apply(fullConfig); } /// @notice Loads the full configuration for the L2 Predeploys. /// @return fullConfig_ The full configuration. - function _loadFullConfig() internal view returns (XForkL2CMTypes.FullConfig memory fullConfig_) { + function _loadFullConfig() internal view returns (L2ContractsManagerTypes.FullConfig memory fullConfig_) { + // Note: Currently, this is the only way to determine if the network is a custom gas token network. + // We need our upgrades be able to determine if the network is a custom gas token network so that we can + // apply the appropriate configuration to the LiquidityController predeploy. In networks without custom gas + // tokens, the LiquidityController predeploy is not used and points to address(0). bool isCustomGasToken = IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken(); // L2CrossDomainMessenger - fullConfig_.crossDomainMessenger = XForkL2CMTypes.CrossDomainMessengerConfig({ + fullConfig_.crossDomainMessenger = L2ContractsManagerTypes.CrossDomainMessengerConfig({ otherMessenger: ICrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER).otherMessenger() }); // L2StandardBridge - fullConfig_.standardBridge = XForkL2CMTypes.StandardBridgeConfig({ + fullConfig_.standardBridge = L2ContractsManagerTypes.StandardBridgeConfig({ otherBridge: IStandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).otherBridge() }); // L2ERC721Bridge - fullConfig_.erc721Bridge = - XForkL2CMTypes.ERC721BridgeConfig({ otherBridge: IERC721Bridge(Predeploys.L2_ERC721_BRIDGE).otherBridge() }); + fullConfig_.erc721Bridge = L2ContractsManagerTypes.ERC721BridgeConfig({ + otherBridge: IERC721Bridge(Predeploys.L2_ERC721_BRIDGE).otherBridge() + }); // OptimismMintableERC20Factory - fullConfig_.mintableERC20Factory = XForkL2CMTypes.MintableERC20FactoryConfig({ + fullConfig_.mintableERC20Factory = L2ContractsManagerTypes.MintableERC20FactoryConfig({ bridge: IOptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY).bridge() }); @@ -190,7 +195,7 @@ contract XForkL2ContractsManager is ISemver { // LiquidityController if (isCustomGasToken) { ILiquidityController liquidityController = ILiquidityController(Predeploys.LIQUIDITY_CONTROLLER); - fullConfig_.liquidityController = XForkL2CMTypes.LiquidityControllerConfig({ + fullConfig_.liquidityController = L2ContractsManagerTypes.LiquidityControllerConfig({ owner: liquidityController.owner(), gasPayingTokenName: liquidityController.gasPayingTokenName(), gasPayingTokenSymbol: liquidityController.gasPayingTokenSymbol() @@ -198,17 +203,17 @@ contract XForkL2ContractsManager is ISemver { } // FeeSplitter - fullConfig_.feeSplitter = XForkL2CMTypes.FeeSplitterConfig({ + fullConfig_.feeSplitter = L2ContractsManagerTypes.FeeSplitterConfig({ sharesCalculator: IFeeSplitter(payable(Predeploys.FEE_SPLITTER)).sharesCalculator() }); + + fullConfig_.isCustomGasToken = isCustomGasToken; } /// @notice Upgrades each of the predeploys to its corresponding new implementation. Applies the appropriate /// configuration to each predeploy. /// @param _config The full configuration for the L2 Predeploys. - function _apply(XForkL2CMTypes.FullConfig memory _config) internal { - bool isCustomGasToken = IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken(); - + function _apply(L2ContractsManagerTypes.FullConfig memory _config) internal { // Initializable predeploys. // L2CrossDomainMessenger @@ -252,7 +257,7 @@ contract XForkL2ContractsManager is ISemver { ); // LiquidityController (only on custom gas token networks) - if (isCustomGasToken) { + if (_config.isCustomGasToken) { L2ContractsManagerUtils.upgradeToAndCall( Predeploys.LIQUIDITY_CONTROLLER, LIQUIDITY_CONTROLLER_IMPL, @@ -268,6 +273,9 @@ contract XForkL2ContractsManager is ISemver { INITIALIZABLE_SLOT_OZ_V4, 0 ); + + // NativeAssetLiquidity + L2ContractsManagerUtils.upgradeTo(Predeploys.NATIVE_ASSET_LIQUIDITY, NATIVE_ASSET_LIQUIDITY_IMPL); } // FeeSplitter @@ -352,11 +360,12 @@ contract XForkL2ContractsManager is ISemver { L2ContractsManagerUtils.upgradeTo(Predeploys.GAS_PRICE_ORACLE, GAS_PRICE_ORACLE_IMPL); // L1BlockAttributes and L2ToL1MessagePasser have different implementations for custom gas token networks. L2ContractsManagerUtils.upgradeTo( - Predeploys.L1_BLOCK_ATTRIBUTES, isCustomGasToken ? L1_BLOCK_ATTRIBUTES_CGT_IMPL : L1_BLOCK_ATTRIBUTES_IMPL + Predeploys.L1_BLOCK_ATTRIBUTES, + _config.isCustomGasToken ? L1_BLOCK_ATTRIBUTES_CGT_IMPL : L1_BLOCK_ATTRIBUTES_IMPL ); L2ContractsManagerUtils.upgradeTo( Predeploys.L2_TO_L1_MESSAGE_PASSER, - isCustomGasToken ? L2_TO_L1_MESSAGE_PASSER_CGT_IMPL : L2_TO_L1_MESSAGE_PASSER_IMPL + _config.isCustomGasToken ? L2_TO_L1_MESSAGE_PASSER_CGT_IMPL : L2_TO_L1_MESSAGE_PASSER_IMPL ); L2ContractsManagerUtils.upgradeTo( Predeploys.OPTIMISM_MINTABLE_ERC721_FACTORY, OPTIMISM_MINTABLE_ERC721_FACTORY_IMPL @@ -375,10 +384,6 @@ contract XForkL2ContractsManager is ISemver { Predeploys.OPTIMISM_SUPERCHAIN_ERC20_BEACON, OPTIMISM_SUPERCHAIN_ERC20_BEACON_IMPL ); L2ContractsManagerUtils.upgradeTo(Predeploys.SUPERCHAIN_TOKEN_BRIDGE, SUPERCHAIN_TOKEN_BRIDGE_IMPL); - // NativeAssetLiquidity - if (isCustomGasToken) { - L2ContractsManagerUtils.upgradeTo(Predeploys.NATIVE_ASSET_LIQUIDITY, NATIVE_ASSET_LIQUIDITY_IMPL); - } L2ContractsManagerUtils.upgradeTo(Predeploys.SCHEMA_REGISTRY, SCHEMA_REGISTRY_IMPL); L2ContractsManagerUtils.upgradeTo(Predeploys.EAS, EAS_IMPL); } diff --git a/packages/contracts-bedrock/src/libraries/XForkL2CMTypes.sol b/packages/contracts-bedrock/src/libraries/L2ContractsManagerTypes.sol similarity index 92% rename from packages/contracts-bedrock/src/libraries/XForkL2CMTypes.sol rename to packages/contracts-bedrock/src/libraries/L2ContractsManagerTypes.sol index 1d96c7660cd..008a8b77246 100644 --- a/packages/contracts-bedrock/src/libraries/XForkL2CMTypes.sol +++ b/packages/contracts-bedrock/src/libraries/L2ContractsManagerTypes.sol @@ -7,9 +7,9 @@ import { IStandardBridge } from "interfaces/universal/IStandardBridge.sol"; import { IERC721Bridge } from "interfaces/universal/IERC721Bridge.sol"; import { ISharesCalculator } from "interfaces/L2/ISharesCalculator.sol"; -/// @title XForkL2CMTypes -/// @notice Type definitions for XForkL2ContractsManager upgrade operations. -library XForkL2CMTypes { +/// @title L2ContractsManagerTypes +/// @notice Type definitions for L2ContractsManager upgrade operations. +library L2ContractsManagerTypes { /// @notice Configuration for L2CrossDomainMessenger. struct CrossDomainMessengerConfig { ICrossDomainMessenger otherMessenger; @@ -62,9 +62,10 @@ library XForkL2CMTypes { FeeVaultConfig operatorFeeVault; LiquidityControllerConfig liquidityController; FeeSplitterConfig feeSplitter; + bool isCustomGasToken; } - /// @notice The implementation addresses to manage the XFork upgrade. + /// @notice The current implementation addresses for the L2 predeploys. struct Implementations { address storageSetterImpl; address l2CrossDomainMessengerImpl; diff --git a/packages/contracts-bedrock/src/libraries/L2ContractsManagerUtils.sol b/packages/contracts-bedrock/src/libraries/L2ContractsManagerUtils.sol index e309a514674..72557fe25a4 100644 --- a/packages/contracts-bedrock/src/libraries/L2ContractsManagerUtils.sol +++ b/packages/contracts-bedrock/src/libraries/L2ContractsManagerUtils.sol @@ -2,18 +2,38 @@ pragma solidity ^0.8.0; // Libraries -import { XForkL2CMTypes } from "src/libraries/XForkL2CMTypes.sol"; -import { IProxy } from "interfaces/universal/IProxy.sol"; +import { L2ContractsManagerTypes } from "src/libraries/L2ContractsManagerTypes.sol"; +import { SemverComp } from "src/libraries/SemverComp.sol"; +import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Interfaces import { IStorageSetter } from "interfaces/universal/IStorageSetter.sol"; import { IFeeVault } from "interfaces/L2/IFeeVault.sol"; +import { ISemver } from "interfaces/universal/ISemver.sol"; +import { IProxy } from "interfaces/universal/IProxy.sol"; /// @title L2ContractsManagerUtils /// @notice L2ContractsManagerUtils is a library that provides utility functions for the L2ContractsManager system. library L2ContractsManagerUtils { + /// @notice Thrown when a user attempts to downgrade a contract. + /// @param _target The address of the contract that was attempted to be downgraded. + error L2ContractsManager_DowngradeNotAllowed(address _target); + /// @notice Upgrades a predeploy to a new implementation without calling an initializer. /// @param _proxy The proxy address of the predeploy. /// @param _implementation The new implementation address. function upgradeTo(address _proxy, address _implementation) internal { + // We avoid downgrading Predeploys + if ( + // Predploys.PROXY_ADMIN is not checked for downgrades because it has no version number. + _proxy != Predeploys.PROXY_ADMIN + && ProxyAdmin(Predeploys.PROXY_ADMIN).getProxyImplementation(_proxy) != address(0) + && SemverComp.gt(ISemver(_proxy).version(), ISemver(_implementation).version()) + ) { + revert L2ContractsManager_DowngradeNotAllowed(address(_proxy)); + } + IProxy(payable(_proxy)).upgradeTo(_implementation); } @@ -23,13 +43,16 @@ library L2ContractsManagerUtils { function readFeeVaultConfig(address _feeVault) internal view - returns (XForkL2CMTypes.FeeVaultConfig memory config_) + returns (L2ContractsManagerTypes.FeeVaultConfig memory config_) { + // Note: We are intentionally using legacy deprecated getters for this 1.0.0 version of the L2ContractsManager. + // Subsequent versions should use the new getters as L2ContractsManager should ensure that the new current + // version of the FeeVault is used. IFeeVault feeVault = IFeeVault(payable(_feeVault)); - config_ = XForkL2CMTypes.FeeVaultConfig({ - recipient: feeVault.recipient(), - minWithdrawalAmount: feeVault.minWithdrawalAmount(), - withdrawalNetwork: feeVault.withdrawalNetwork() + config_ = L2ContractsManagerTypes.FeeVaultConfig({ + recipient: feeVault.RECIPIENT(), + minWithdrawalAmount: feeVault.MIN_WITHDRAWAL_AMOUNT(), + withdrawalNetwork: feeVault.WITHDRAWAL_NETWORK() }); } @@ -51,6 +74,16 @@ library L2ContractsManagerUtils { ) internal { + if ( + // Predeploys.PROXY_ADMIN is not checked for downgrades because it has no version number. + // This should never be the case, if you're trying to initialize the ProxyAdmin, it's probably a mistake. + _proxy != Predeploys.PROXY_ADMIN + && ProxyAdmin(Predeploys.PROXY_ADMIN).getProxyImplementation(_proxy) != address(0) + && SemverComp.gt(ISemver(_proxy).version(), ISemver(_implementation).version()) + ) { + revert L2ContractsManager_DowngradeNotAllowed(address(_proxy)); + } + // Upgrade to StorageSetter. IProxy(payable(_proxy)).upgradeTo(_storageSetterImpl); diff --git a/packages/contracts-bedrock/test/L2/XForkL2ContractsManager.t.sol b/packages/contracts-bedrock/test/L2/L2ContractsManager.t.sol similarity index 94% rename from packages/contracts-bedrock/test/L2/XForkL2ContractsManager.t.sol rename to packages/contracts-bedrock/test/L2/L2ContractsManager.t.sol index 571ca3702be..58832699bac 100644 --- a/packages/contracts-bedrock/test/L2/XForkL2ContractsManager.t.sol +++ b/packages/contracts-bedrock/test/L2/L2ContractsManager.t.sol @@ -2,8 +2,8 @@ pragma solidity 0.8.15; import { Predeploys } from "src/libraries/Predeploys.sol"; -import { XForkL2ContractsManager } from "src/L2/XForkL2ContractsManager.sol"; -import { XForkL2CMTypes } from "src/libraries/XForkL2CMTypes.sol"; +import { L2ContractsManager } from "src/L2/L2ContractsManager.sol"; +import { L2ContractsManagerTypes } from "src/libraries/L2ContractsManagerTypes.sol"; import { CommonTest } from "test/setup/CommonTest.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { StorageSetter } from "src/universal/StorageSetter.sol"; @@ -36,19 +36,19 @@ import { LiquidityController } from "src/L2/LiquidityController.sol"; import { Types } from "src/libraries/Types.sol"; import { Features } from "src/libraries/Features.sol"; -/// @title XForkL2ContractsManager_Harness +/// @title L2ContractsManager_Harness /// @notice Harness contract that exposes internal functions for testing. -contract XForkL2ContractsManager_FullConfigExposer_Harness is XForkL2ContractsManager { - constructor(XForkL2CMTypes.Implementations memory _implementations) XForkL2ContractsManager(_implementations) { } +contract L2ContractsManager_FullConfigExposer_Harness is L2ContractsManager { + constructor(L2ContractsManagerTypes.Implementations memory _implementations) L2ContractsManager(_implementations) { } /// @notice Returns the full configuration for the L2 predeploys. - function loadFullConfig() external view returns (XForkL2CMTypes.FullConfig memory) { + function loadFullConfig() external view returns (L2ContractsManagerTypes.FullConfig memory) { return _loadFullConfig(); } /// @notice Returns the target implementations for the L2 predeploys. - function implementations() external view returns (XForkL2CMTypes.Implementations memory) { - return XForkL2CMTypes.Implementations({ + function implementations() external view returns (L2ContractsManagerTypes.Implementations memory) { + return L2ContractsManagerTypes.Implementations({ storageSetterImpl: STORAGE_SETTER_IMPL, l2CrossDomainMessengerImpl: L2_CROSS_DOMAIN_MESSENGER_IMPL, gasPriceOracleImpl: GAS_PRICE_ORACLE_IMPL, @@ -81,11 +81,11 @@ contract XForkL2ContractsManager_FullConfigExposer_Harness is XForkL2ContractsMa } } -/// @title XForkL2ContractsManager_Test -/// @notice Test contract for the XForkL2ContractsManager contract, testing the upgrade path for this fork. -contract XForkL2ContractsManager_Upgrade_Test is CommonTest { - XForkL2ContractsManager_FullConfigExposer_Harness internal l2cm; - XForkL2CMTypes.Implementations internal implementations; +/// @title L2ContractsManager_Test +/// @notice Test contract for the L2ContractsManager contract, testing the upgrade path. +contract L2ContractsManager_Upgrade_Test is CommonTest { + L2ContractsManager_FullConfigExposer_Harness internal l2cm; + L2ContractsManagerTypes.Implementations internal implementations; /// @notice Struct to capture the post-upgrade state for comparison. struct PostUpgradeState { @@ -117,7 +117,7 @@ contract XForkL2ContractsManager_Upgrade_Test is CommonTest { address liquidityControllerImpl; address feeSplitterImpl; // Config values, take advantage of the harness to capture the config values - XForkL2CMTypes.FullConfig config; + L2ContractsManagerTypes.FullConfig config; } function setUp() public override { @@ -166,10 +166,10 @@ contract XForkL2ContractsManager_Upgrade_Test is CommonTest { implementations.feeSplitterImpl = deployCode("src/L2/FeeSplitter.sol:FeeSplitter"); } - /// @notice Deploys the XForkL2ContractsManager with the loaded implementations. + /// @notice Deploys the L2ContractsManager with the loaded implementations. function _deployL2CM() internal { - l2cm = new XForkL2ContractsManager_FullConfigExposer_Harness(implementations); - vm.label(address(l2cm), "XForkL2ContractsManager"); + l2cm = new L2ContractsManager_FullConfigExposer_Harness(implementations); + vm.label(address(l2cm), "L2ContractsManager"); } /// @notice Executes the upgrade via DELEGATECALL from the L2ProxyAdmin context. @@ -178,7 +178,7 @@ contract XForkL2ContractsManager_Upgrade_Test is CommonTest { // We simulate this by pranking as the ProxyAdmin and using delegatecall. address proxyAdmin = Predeploys.PROXY_ADMIN; prankDelegateCall(proxyAdmin); - (bool success,) = address(l2cm).delegatecall(abi.encodeCall(XForkL2ContractsManager.upgrade, ())); + (bool success,) = address(l2cm).delegatecall(abi.encodeCall(L2ContractsManager.upgrade, ())); require(success, "L2ContractsManager: Upgrade failed"); } @@ -360,7 +360,7 @@ contract XForkL2ContractsManager_Upgrade_Test is CommonTest { /// @notice Tests that all network-specific configuration is preserved after upgrade. function test_upgradePreservesAllConfiguration_succeeds() public { // Get the pre-upgrade configuration - XForkL2CMTypes.FullConfig memory preUpgradeConfig = l2cm.loadFullConfig(); + L2ContractsManagerTypes.FullConfig memory preUpgradeConfig = l2cm.loadFullConfig(); // Execute the upgrade _executeUpgrade(); @@ -474,7 +474,7 @@ contract XForkL2ContractsManager_Upgrade_Test is CommonTest { /// @notice Tests that calling upgrade() directly (not via DELEGATECALL) reverts. function test_upgrade_whenCalledDirectly_reverts() public { // Calling upgrade() directly should revert with OnlyDelegatecall error - vm.expectRevert(XForkL2ContractsManager.XForkL2ContractsManager_OnlyDelegatecall.selector); + vm.expectRevert(L2ContractsManager.L2ContractsManager_OnlyDelegatecall.selector); l2cm.upgrade(); } @@ -567,9 +567,9 @@ contract XForkL2ContractsManager_Upgrade_Test is CommonTest { } } -/// @title XForkL2ContractsManager_CGT_Test -/// @notice Test contract for the XForkL2ContractsManager on Custom Gas Token networks. -contract XForkL2ContractsManager_Upgrade_CGT_Test is XForkL2ContractsManager_Upgrade_Test { +/// @title L2ContractsManager_CGT_Test +/// @notice Test contract for the L2ContractsManager on Custom Gas Token networks. +contract L2ContractsManager_Upgrade_CGT_Test is L2ContractsManager_Upgrade_Test { /// @notice Tests that CGT-specific contracts are upgraded when CGT is enabled. function test_upgradeUpgradesCGTContracts_whenCGTEnabled_succeeds() public { skipIfSysFeatureDisabled(Features.CUSTOM_GAS_TOKEN); @@ -629,7 +629,7 @@ contract XForkL2ContractsManager_Upgrade_CGT_Test is XForkL2ContractsManager_Upg skipIfSysFeatureDisabled(Features.CUSTOM_GAS_TOKEN); // Capture pre-upgrade config - XForkL2CMTypes.FullConfig memory preUpgradeConfig = l2cm.loadFullConfig(); + L2ContractsManagerTypes.FullConfig memory preUpgradeConfig = l2cm.loadFullConfig(); // Execute the upgrade _executeUpgrade();