Skip to content
Draft
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
16 changes: 12 additions & 4 deletions op-chain-ops/script/script.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,10 +354,18 @@ func (h *Host) Call(from common.Address, to common.Address, input []byte, gas ui

defer func() {
if r := recover(); r != nil {
// Cast to a string to check the error message. If it's not a string it's
// an unexpected panic and we should re-raise it.
rStr, ok := r.(string)
if !ok || !strings.Contains(strings.ToLower(rStr), "revision id 1") {
// Extract the panic message as a string. op-geth's journal.go panics with
// fmt.Errorf (an error type), so we must handle both string and error.
var rStr string
switch v := r.(type) {
case string:
rStr = v
case error:
rStr = v.Error()
default:
panic(r)
}
if !strings.Contains(strings.ToLower(rStr), "revision id") {
fmt.Println("panic", rStr)
panic(r)
}
Expand Down
50 changes: 40 additions & 10 deletions op-deployer/pkg/deployer/standard/standard.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,15 @@ func L1VersionsFor(chainID uint64) (validation.Versions, error) {
func GuardianAddressFor(chainID uint64) (common.Address, error) {
switch chainID {
case 1:
return common.Address(validation.StandardConfigRolesMainnet.Guardian), nil
// Celo Mainnet
return common.HexToAddress("0x6E226fa22e5F19363d231D3FA048aaBa73CC1f47"), nil
// Superchain
// return common.Address(validation.StandardConfigRolesMainnet.Guardian), nil
case 11155111:
return common.Address(validation.StandardConfigRolesSepolia.Guardian), nil
// Celo Mainnet
return common.HexToAddress("0x5e60d897Cd62588291656b54655e98ee73f0aabF"), nil
// Superchain
// return common.Address(validation.StandardConfigRolesSepolia.Guardian), nil
default:
return common.Address{}, fmt.Errorf("unsupported chain ID: %d", chainID)
}
Expand All @@ -76,9 +82,15 @@ func GuardianAddressFor(chainID uint64) (common.Address, error) {
func ChallengerAddressFor(chainID uint64) (common.Address, error) {
switch chainID {
case 1:
return common.Address(validation.StandardConfigRolesMainnet.Challenger), nil
// Celo Mainnet
return common.HexToAddress("0x6b145ebf66602ec524b196426b46631259689583"), nil
// Superchain
// return common.Address(validation.StandardConfigRolesMainnet.Challenger), nil
case 11155111:
return common.Address(validation.StandardConfigRolesSepolia.Challenger), nil
// Celo Mainnet
return common.HexToAddress("0xC813b28614BD4CFA3d5Fdf153df41B273AB9D497"), nil
// Superchain
// return common.Address(validation.StandardConfigRolesSepolia.Challenger), nil
default:
return common.Address{}, fmt.Errorf("unsupported chain ID: %d", chainID)
}
Expand Down Expand Up @@ -121,9 +133,15 @@ func OPCMImplAddressFor(chainID uint64, tag string) (common.Address, error) {
func SuperchainProxyAdminAddrFor(chainID uint64) (common.Address, error) {
switch chainID {
case 1:
return common.HexToAddress("0x543bA4AADBAb8f9025686Bd03993043599c6fB04"), nil
// Celo Mainnet
return common.HexToAddress("0x783A434532Ee94667979213af1711505E8bFE374"), nil
// Superchain
// return common.HexToAddress("0x543bA4AADBAb8f9025686Bd03993043599c6fB04"), nil
case 11155111:
return common.HexToAddress("0x189aBAAaa82DfC015A588A7dbaD6F13b1D3485Bc"), nil
// Celo Mainnet
return common.HexToAddress("0xf7d7a3d3bb8abb6829249b3d3ad3d525d052027e"), nil
// Superchain
// return common.HexToAddress("0x189aBAAaa82DfC015A588A7dbaD6F13b1D3485Bc"), nil
default:
return common.Address{}, fmt.Errorf("unsupported chain ID: %d", chainID)
}
Expand All @@ -132,9 +150,15 @@ func SuperchainProxyAdminAddrFor(chainID uint64) (common.Address, error) {
func L1ProxyAdminOwner(chainID uint64) (common.Address, error) {
switch chainID {
case 1:
return common.Address(validation.StandardConfigRolesMainnet.L1ProxyAdminOwner), nil
// Celo Mainnet
return common.HexToAddress("0x4092A77bAF58fef0309452cEaCb09221e556E112"), nil
// Superchain
// return common.Address(validation.StandardConfigRolesMainnet.L1ProxyAdminOwner), nil
case 11155111:
return common.Address(validation.StandardConfigRolesSepolia.L1ProxyAdminOwner), nil
// Celo Mainnet
return common.HexToAddress("0x5e60d897Cd62588291656b54655e98ee73f0aabF"), nil
// Superchain
// return common.Address(validation.StandardConfigRolesSepolia.L1ProxyAdminOwner), nil
default:
return common.Address{}, fmt.Errorf("unsupported chain ID: %d", chainID)
}
Expand All @@ -154,9 +178,15 @@ func L2ProxyAdminOwner(chainID uint64) (common.Address, error) {
func ProtocolVersionsOwner(chainID uint64) (common.Address, error) {
switch chainID {
case 1:
return common.Address(validation.StandardConfigRolesMainnet.ProtocolVersionsOwner), nil
// Celo Mainnet
return common.HexToAddress("0x4092A77bAF58fef0309452cEaCb09221e556E112"), nil
// Superchain
// return common.Address(validation.StandardConfigRolesMainnet.ProtocolVersionsOwner), nil
case 11155111:
return common.Address(validation.StandardConfigRolesSepolia.ProtocolVersionsOwner), nil
// Celo Mainnet
return common.HexToAddress("0x5e60d897Cd62588291656b54655e98ee73f0aabF"), nil
// Superchain
// return common.Address(validation.StandardConfigRolesSepolia.ProtocolVersionsOwner), nil
default:
return common.Address{}, fmt.Errorf("unsupported chain ID: %d", chainID)
}
Expand Down
1 change: 1 addition & 0 deletions op-deployer/pkg/deployer/upgrade/v2_0_0/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type UpgradeOPChainInput struct {
Prank common.Address `json:"prank"`
Opcm common.Address `json:"opcm"`
EncodedChainConfigs []OPChainConfig `evm:"-" json:"chainConfigs"`
UpgradeSuperchainConfig bool `json:"upgradeSuperchainConfig"`
}

type OPChainConfig struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ interface IOPContractsManagerUpgrader {

function __constructor__(IOPContractsManagerContractsContainer _contractsContainer) external;

function upgrade(IOPContractsManager.OpChainConfig[] memory _opChainConfigs) external;
function upgrade(IOPContractsManager.OpChainConfig[] memory _opChainConfigs, bool _upgradeSuperchainConfig) external;

function upgradeSuperchainConfig(ISuperchainConfig _superchainConfig, IProxyAdmin _superchainProxyAdmin) external;

Expand Down Expand Up @@ -339,7 +339,8 @@ interface IOPContractsManager {

/// @notice Upgrades the implementation of all proxies in the specified chains
/// @param _opChainConfigs The chains to upgrade
function upgrade(OpChainConfig[] memory _opChainConfigs) external;
/// @param _upgradeSuperchainConfig Flag to optionally upgrade superchain config
function upgrade(OpChainConfig[] memory _opChainConfigs, bool _upgradeSuperchainConfig) external;

/// @notice Upgrades the SuperchainConfig contract.
/// @param _superchainConfig The SuperchainConfig contract to upgrade.
Expand Down
17 changes: 14 additions & 3 deletions packages/contracts-bedrock/scripts/deploy/UpgradeOPChain.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ contract UpgradeOPChainInput is BaseDeployIO {
address internal _prank;
OPContractsManager internal _opcm;
bytes _opChainConfigs;
bool _upgradeSuperchainConfig;

// Setter for OPContractsManager type
function set(bytes4 _sel, address _value) public {
Expand All @@ -26,6 +27,11 @@ contract UpgradeOPChainInput is BaseDeployIO {
else revert("UpgradeOPCMInput: unknown selector");
}

function set(bytes4 _sel, bool _value) public {
if (_sel == this.upgradeSuperchainConfig.selector) _upgradeSuperchainConfig = _value;
else revert("UpgradeOPCMInput: unknown selector");
}

function prank() public view returns (address) {
require(address(_prank) != address(0), "UpgradeOPCMInput: prank not set");
return _prank;
Expand All @@ -40,13 +46,18 @@ contract UpgradeOPChainInput is BaseDeployIO {
require(_opChainConfigs.length > 0, "UpgradeOPCMInput: not set");
return _opChainConfigs;
}

function upgradeSuperchainConfig() public view returns (bool) {
return _upgradeSuperchainConfig;
}
}

contract UpgradeOPChain is Script {
function run(UpgradeOPChainInput _uoci) external {
OPContractsManager opcm = _uoci.opcm();
OPContractsManager.OpChainConfig[] memory opChainConfigs =
abi.decode(_uoci.opChainConfigs(), (OPContractsManager.OpChainConfig[]));
bool upgradeSuperchainConfig_ = _uoci.upgradeSuperchainConfig();

// Etch DummyCaller contract. This contract is used to mimic the contract that is used
// as the source of the delegatecall to the OPCM. In practice this will be the governance
Expand All @@ -60,16 +71,16 @@ contract UpgradeOPChain is Script {
// Call into the DummyCaller. This will perform the delegatecall under the hood and
// return the result.
vm.broadcast(msg.sender);
(bool success,) = DummyCaller(prank).upgrade(opChainConfigs);
(bool success,) = DummyCaller(prank).upgrade(opChainConfigs, upgradeSuperchainConfig_);
require(success, "UpgradeChain: upgrade failed");
}
}

contract DummyCaller {
address internal _opcmAddr;

function upgrade(OPContractsManager.OpChainConfig[] memory _opChainConfigs) external returns (bool, bytes memory) {
bytes memory data = abi.encodeCall(DummyCaller.upgrade, _opChainConfigs);
function upgrade(OPContractsManager.OpChainConfig[] memory _opChainConfigs, bool _upgradeSuperchainConfig) external returns (bool, bytes memory) {
bytes memory data = abi.encodeCall(DummyCaller.upgrade, (_opChainConfigs, _upgradeSuperchainConfig));
(bool success, bytes memory result) = _opcmAddr.delegatecall(data);
return (success, result);
}
Expand Down
27 changes: 20 additions & 7 deletions packages/contracts-bedrock/src/L1/OPContractsManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { IPermissionedDisputeGame } from "interfaces/dispute/IPermissionedDisput
import { ISuperFaultDisputeGame } from "interfaces/dispute/ISuperFaultDisputeGame.sol";
import { ISuperPermissionedDisputeGame } from "interfaces/dispute/ISuperPermissionedDisputeGame.sol";
import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol";
import { IHasSuperchainConfig } from "interfaces/L1/IHasSuperchainConfig.sol";
import { IProtocolVersions } from "interfaces/L1/IProtocolVersions.sol";
import { IOptimismPortal2 as IOptimismPortal } from "interfaces/L1/IOptimismPortal2.sol";
import { IOptimismPortalInterop } from "interfaces/L1/IOptimismPortalInterop.sol";
Expand Down Expand Up @@ -732,10 +733,11 @@ contract OPContractsManagerUpgrader is OPContractsManagerBase {

/// @notice Upgrades a set of chains to the latest implementation contracts
/// @param _opChainConfigs Array of OpChain structs, one per chain to upgrade
/// @param _upgradeSuperchainConfig Flag to indicate if superchainConfig should be upgraded
/// @dev This function is intended to be DELEGATECALLed by an address that is the common owner of every chain in
/// `_opChainConfigs`'s ProxyAdmin.
/// @dev This function requires that each chain's superchainConfig is already upgraded.
function upgrade(OPContractsManager.OpChainConfig[] memory _opChainConfigs) external virtual {
function upgrade(OPContractsManager.OpChainConfig[] memory _opChainConfigs, bool _upgradeSuperchainConfig) external virtual {
// Grab the implementations.
OPContractsManager.Implementations memory impls = getImplementations();

Expand All @@ -745,11 +747,17 @@ contract OPContractsManagerUpgrader is OPContractsManagerBase {
uint256 l2ChainId = _opChainConfigs[i].systemConfigProxy.l2ChainId();

// Grab the SuperchainConfig.
ISuperchainConfig superchainConfig = _opChainConfigs[i].systemConfigProxy.superchainConfig();
ISuperchainConfig celoSuperchainConfig = _opChainConfigs[i].systemConfigProxy.superchainConfig();
ISuperchainConfig superchainConfig = IHasSuperchainConfig(address(celoSuperchainConfig)).superchainConfig();

// SuperchainConfig should be in older version than impl on Celo L1.
if (!SemverComp.lt(superchainConfig.version(), ISuperchainConfig(impls.superchainConfigImpl).version())) {
revert OPContractsManagerUpgrader_SuperchainConfigMismatch();
{
if (!SemverComp.lt(superchainConfig.version(), ISuperchainConfig(impls.superchainConfigImpl).version())) {
revert OPContractsManagerUpgrader_SuperchainConfigMismatch();
} else if (_upgradeSuperchainConfig) {
// Celo: some chains (like Celo Mainnet) follow external superchain config that is not desired to be upgraded
__upgradeSuperchainConfig(superchainConfig, _opChainConfigs[i].proxyAdmin);
}
}

// Do the chain upgrade.
Expand Down Expand Up @@ -898,12 +906,16 @@ contract OPContractsManagerUpgrader is OPContractsManagerBase {
}
}

function upgradeSuperchainConfig(ISuperchainConfig _superchainConfig, IProxyAdmin _superchainProxyAdmin) external {
__upgradeSuperchainConfig(_superchainConfig, _superchainProxyAdmin);
}

/// @notice Upgrades the SuperchainConfig contract.
/// @param _superchainConfig The SuperchainConfig contract to upgrade.
/// @param _superchainProxyAdmin The ProxyAdmin contract to use for the upgrade.
/// @dev This function is intended to be DELEGATECALLed by the superchainConfig's ProxyAdminOwner.
/// @dev This function will revert if the SuperchainConfig is already at or above the target version.
function upgradeSuperchainConfig(ISuperchainConfig _superchainConfig, IProxyAdmin _superchainProxyAdmin) external {
function __upgradeSuperchainConfig(ISuperchainConfig _superchainConfig, IProxyAdmin _superchainProxyAdmin) internal {
// Only upgrade the superchainConfig if the current version is less than the target version.
if (
SemverComp.gte(
Expand Down Expand Up @@ -2031,13 +2043,14 @@ contract OPContractsManager is ISemver {

/// @notice Upgrades a set of chains to the latest implementation contracts
/// @param _opChainConfigs Array of OpChain structs, one per chain to upgrade
/// @param _upgradeSuperchainConfig Flag to indicate if superchainConfig should be upgraded
/// @dev This function is intended to be DELEGATECALLed by an address that is the common owner of every chain in
/// `_opChainConfigs`'s ProxyAdmin.
/// @dev This function requires that each chain's superchainConfig is already upgraded.
function upgrade(OpChainConfig[] memory _opChainConfigs) external virtual {
function upgrade(OpChainConfig[] memory _opChainConfigs, bool _upgradeSuperchainConfig) external virtual {
if (address(this) == address(thisOPCM)) revert OnlyDelegatecall();

bytes memory data = abi.encodeCall(OPContractsManagerUpgrader.upgrade, (_opChainConfigs));
bytes memory data = abi.encodeCall(OPContractsManagerUpgrader.upgrade, (_opChainConfigs, _upgradeSuperchainConfig));
_performDelegateCall(address(opcmUpgrader), data);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.so
import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol";
import { IL1CrossDomainMessenger } from "interfaces/L1/IL1CrossDomainMessenger.sol";
import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol";
import { IHasSuperchainConfig } from "interfaces/L1/IHasSuperchainConfig.sol";
import { IOptimismMintableERC20Factory } from "interfaces/universal/IOptimismMintableERC20Factory.sol";
import { IL1StandardBridge } from "interfaces/L1/IL1StandardBridge.sol";
import { IL1ERC721Bridge } from "interfaces/L1/IL1ERC721Bridge.sol";
Expand Down Expand Up @@ -232,6 +233,10 @@ contract OPContractsManagerStandardValidator is ISemver {
return _errors;
}

function celoSuperchainConfig(address _celoSuperchainConfig) internal view returns (ISuperchainConfig) {
return IHasSuperchainConfig(_celoSuperchainConfig).superchainConfig();
}

/// @notice Asserts that the SystemConfig contract is valid.
function assertValidSystemConfig(
string memory _errors,
Expand Down Expand Up @@ -261,13 +266,31 @@ contract OPContractsManagerStandardValidator is ISemver {
_errors = internalRequire(_sysCfg.operatorFeeScalar() == 0, "SYSCON-110", _errors);
_errors = internalRequire(_sysCfg.operatorFeeConstant() == 0, "SYSCON-120", _errors);
_errors = internalRequire(getProxyAdmin(address(_sysCfg)) == _admin, "SYSCON-130", _errors);
_errors = internalRequire(_sysCfg.superchainConfig() == superchainConfig, "SYSCON-140", _errors);
_errors = internalRequire(celoSuperchainConfig(address(_sysCfg.superchainConfig())) == superchainConfig, "SYSCON-140", _errors);

// CGT prevents Lockbox
if (_sysCfg.isCustomGasToken()) {
_errors = internalRequire(!_sysCfg.isFeatureEnabled(Features.ETH_LOCKBOX), "SYSCON-150", _errors);
}

// Celo extra validation: custom gas token
(address address_, uint8 decimals_) = _sysCfg.gasPayingToken();
address expected_;
string memory name_;
if (address(_sysCfg) == address(0x760a5F022C9940f4A074e0030be682F560d29818)) {
// sepolia
expected_ = address(0x3C7011fD5e6Aed460cAa4985cF8d8Caba435b092);
name_ = "Celo";
} else if (address(_sysCfg) == address(0x89E31965D844a309231B1f17759Ccaf1b7c09861)) {
// mainnet
expected_ = address(0x057898f3C43F129a17517B9056D23851F124b19f);
name_ = "Celo native asset";
}
_errors = internalRequire(address_ == expected_, "SYSCON-CEL-10", _errors);
_errors = internalRequire(decimals_ == 18, "SYSCON-CEL-20", _errors);
_errors = internalRequire(LibString.eq(_sysCfg.gasPayingTokenName(), name_) , "SYSCON-CEL-30", _errors);
_errors = internalRequire(LibString.eq(_sysCfg.gasPayingTokenSymbol(), "CELO") , "SYSCON-CEL-40", _errors);

return _errors;
}

Expand Down Expand Up @@ -421,6 +444,16 @@ contract OPContractsManagerStandardValidator is ISemver {
_errors = internalRequire(address(_portal.systemConfig()) == address(_sysCfg), "PORTAL-40", _errors);
_errors = internalRequire(_portal.l2Sender() == Constants.DEFAULT_L2_SENDER, "PORTAL-80", _errors);
_errors = internalRequire(getProxyAdmin(address(_portal)) == _admin, "PORTAL-90", _errors);

// Celo extra validation: celo superchain config vs external superchain config
address celoSuperchainConfig_ = address(_portal.superchainConfig());
_errors = internalRequire(
_portal.guardian() != superchainConfig.guardian(), "PORTAL-CEL-10", _errors
); // True only for Celo Mainnet
_errors = internalRequire(
_portal.guardian() == ISuperchainConfig(celoSuperchainConfig_).guardian(), "PORTAL-CEL-20", _errors
); // True for Celo Mainnet & Celo Testnets

return _errors;
}

Expand Down Expand Up @@ -451,7 +484,7 @@ contract OPContractsManagerStandardValidator is ISemver {
_errors = internalRequire(_lockbox.systemConfig() == _sysCfg, "LOCKBOX-40", _errors);
_errors = internalRequire(_lockbox.authorizedPortals(_portal), "LOCKBOX-50", _errors);
// Lockbox is not compatible with CGT
_errors = internalRequire(!_sysCfg.isCustomGasToken(), "LOCKBOX-60", _errors);
_errors = internalRequire(!_sysCfg.isCustomGasToken(), "LOCKBOX-CEL-10", _errors);
return _errors;
}

Expand Down
4 changes: 2 additions & 2 deletions packages/contracts-bedrock/test/L1/OPContractsManager.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ contract OPContractsManager_Upgrade_Harness is CommonTest {

// Execute the chain upgrade.
DelegateCaller(_delegateCaller).dcForward(
address(_opcm), abi.encodeCall(IOPContractsManager.upgrade, (opChainConfigs))
address(_opcm), abi.encodeCall(IOPContractsManager.upgrade, (opChainConfigs, false))
);

// Return early if a revert was expected. Otherwise we'll get errors below.
Expand Down Expand Up @@ -1343,7 +1343,7 @@ contract OPContractsManager_Upgrade_Test is OPContractsManager_Upgrade_Harness {
function test_upgrade_notDelegateCalled_reverts() public {
vm.prank(upgrader);
vm.expectRevert(IOPContractsManager.OnlyDelegatecall.selector);
opcm.upgrade(opChainConfigs);
opcm.upgrade(opChainConfigs, false);
}

function test_upgrade_notProxyAdminOwner_reverts() public {
Expand Down
Loading