Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sep/027: upgrade and re-initialize SystemConfig across sepolia superchain #418

Open
wants to merge 68 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 52 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
e5623ea
first pass at task sep 025
geoknee Dec 17, 2024
14500b8
bump task index
geoknee Dec 17, 2024
9c83d58
undo change to submodule
geoknee Dec 17, 2024
cc782b3
add exceptions for EOAs in SystemConfig storage
geoknee Dec 17, 2024
dcd607c
bump task sequence number
geoknee Dec 18, 2024
c04293c
change validation script to use Seb's new framework
geoknee Dec 18, 2024
eb21f18
addAllowedStorageAccess for each system config
geoknee Dec 18, 2024
4014438
SystemConfigUpgrade exposes code exceptions thru getter
geoknee Dec 18, 2024
fcda94c
introduce SystemConfigUpgradeEcotoneScalars
geoknee Dec 18, 2024
d130513
add deprecation notice to task 020
geoknee Dec 18, 2024
ef18399
remove unecessary forge build commands
geoknee Dec 18, 2024
35b4718
add some logging
geoknee Dec 18, 2024
1355535
reactivate all chains
geoknee Dec 19, 2024
bb163d9
update to superbundle
geoknee Dec 20, 2024
0b39283
TEMP: do not try to load all contract addresses (some chains do not …
geoknee Dec 20, 2024
85aac3a
improve err msg
geoknee Dec 20, 2024
ca3699e
fix superbundle
geoknee Dec 20, 2024
7b7f0d1
use dynamic storage array
geoknee Dec 20, 2024
80aa1cc
validate in a smarter way for chains migrating from pre ecotone scalars
geoknee Dec 20, 2024
7e0c7fe
SuperchainRegistry: instead of skipping missing addresses globally, s…
geoknee Jan 3, 2025
127d370
update overview and readme
geoknee Jan 3, 2025
6786304
add some more logging
geoknee Jan 3, 2025
1ccf1b6
fill out validation.md
geoknee Jan 3, 2025
e0364ba
don't alias SystemConfigUpgradeEcotoneScalars
geoknee Jan 3, 2025
b1ef291
fix validation document
geoknee Jan 3, 2025
6c2961f
add sep/027 to CI
geoknee Jan 4, 2025
e568b3a
undo changes to submodule
geoknee Jan 6, 2025
35c68f8
undo change to submodule
geoknee Jan 6, 2025
94a0e19
Revert "remove unecessary forge build commands"
geoknee Jan 6, 2025
5098753
avoid shadowing variables
geoknee Jan 7, 2025
ab72af4
add explanatory comment and removed unused imports
geoknee Jan 7, 2025
ddad3df
avoid shadowing variabls
geoknee Jan 7, 2025
3d0999f
previous.owner codeException added conditionally
geoknee Jan 7, 2025
0b4dbee
update forge-std to v1.9.5
geoknee Jan 7, 2025
8a770be
prefer stdToml.readAddressOr to rolling my own tryReadAddress
geoknee Jan 7, 2025
1ce96af
spellcheck
geoknee Jan 7, 2025
7d05ab9
move overview contents into readme
geoknee Jan 7, 2025
7f5ac68
set status as READY TO SIGN
geoknee Jan 7, 2025
2cd5a75
Update tasks/sep/027-holocene-system-config-upgrade-and-init-multi-ch…
geoknee Jan 7, 2025
58bc135
pull scalar checks out of base contract into SystemConfigUpgradeEcoto…
geoknee Jan 7, 2025
5253651
make validation of migration of scalar from version 0 to 1 very explicit
geoknee Jan 7, 2025
0f0c539
add link to ecotone scalars specs
geoknee Jan 7, 2025
ece1fe9
Update script/verification/SystemConfigUpgrade.s.sol
geoknee Jan 7, 2025
dd88bab
add step to validate target semver of SystemConfig
geoknee Jan 8, 2025
deac638
Merge remote-tracking branch 'origin/main' into gk/025-holocene-sys-cfg
geoknee Jan 8, 2025
ce792fc
SystemConfigUpgrade.getSysCfgVars() copes with explicit contract vers…
geoknee Jan 8, 2025
9ffc1a6
comments
geoknee Jan 8, 2025
d2162ee
SystemConfigUpgrade: pull gasPayingToken and disputeGameFactory check…
geoknee Jan 8, 2025
4892a5c
combine SystemConfigUpgrade with SystemConfigUpgradeEcotoneScalars an…
geoknee Jan 9, 2025
06f91d1
tidy
geoknee Jan 9, 2025
566477e
some more improvements
geoknee Jan 9, 2025
497007f
more code comments
geoknee Jan 9, 2025
e843ff4
Update script/verification/HoloceneSystemConfigUpgrade.s.sol
geoknee Jan 10, 2025
7c2a9c8
Update script/verification/HoloceneSystemConfigUpgrade.s.sol
geoknee Jan 10, 2025
a44a491
typos
geoknee Jan 10, 2025
556d1d5
refactor for readability
geoknee Jan 10, 2025
cd7ec86
consolidate interfaces into one file
geoknee Jan 10, 2025
a14b6a3
Update tasks/sep/027-holocene-system-config-upgrade-and-init-multi-ch…
geoknee Jan 10, 2025
1389e43
typos
geoknee Jan 10, 2025
1a12121
Update tasks/sep/027-holocene-system-config-upgrade-and-init-multi-ch…
geoknee Jan 10, 2025
ce9614d
improve formatting and links
geoknee Jan 10, 2025
89e4726
Merge remote-tracking branch 'origin/main' into gk/025-holocene-sys-cfg
geoknee Jan 10, 2025
ef7ccef
tidy
geoknee Jan 10, 2025
c5da1ab
respond to review comments
geoknee Jan 10, 2025
c904f92
tidy up logging
geoknee Jan 10, 2025
1e1fc2b
add links to storage layouts
geoknee Jan 10, 2025
3eec9d8
put `cast td` hints into validation doc
geoknee Jan 10, 2025
31ab749
combine cases in if/else statement
geoknee Jan 10, 2025
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
8 changes: 8 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,13 @@ jobs:
just prepare-json
just simulate-council # simulate again to make sure the json is still valid

simulate_sep_027:
docker:
- image: << pipeline.parameters.ci_builder_image >>
steps:
- simulate_nested:
task: "sep/027-holocene-system-config-upgrade-and-init-multi-chain"

just_simulate_permissionless_fp_upgrade:
docker:
- image: << pipeline.parameters.ci_builder_image >>
Expand Down Expand Up @@ -295,3 +302,4 @@ workflows:
- just_simulate_sc_rehearsal_2
- just_simulate_sc_rehearsal_4
- just_simulate_permissionless_fp_upgrade
- simulate_sep_027
2 changes: 1 addition & 1 deletion lib/forge-std
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the forge-std upgrade intended?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. It pulls in stdToml.readAddressOr() which lets us handle chains which have missing data in the superchain registry.

187 changes: 187 additions & 0 deletions script/verification/HoloceneSystemConfigUpgrade.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import {console2 as console} from "forge-std/console2.sol";
import {LibString} from "solady/utils/LibString.sol";
import {ISystemConfig} from "./ISystemConfig.sol";
import {IResourceMetering} from "./IResourceMetering.sol";
import {SuperchainRegistry} from "script/verification/Verification.s.sol";

// HoloceneSystemConfigUpgrade is a contract that can be used to verify the Holocene upgrade of the SystemConfig contract.
// The upgrade paths supported are:
// 1.12.0 -> 2.3.0
// 2.2.0 -> 2.3.0
// 2.3.0 -> 2.3.0 (this case covers where the SystemConfig contract is already at the target version but was upgraded incorrectly)
// The verification checks that the following storage values are properly modified if appropriate:
// - scalar (may be migrated to a different encoding version)
// - basefeeScalar (new storage variable, needs to be set in a way which is consistent with the previous scalar)
// - blobbasefeeScalar (new storage variable, needs to be set in a way which is consistent with the previous scalar)
// - gasPayingToken (new storage variable, needs to be set to a magic value representing ETH)
// - disputeGameFactory (does not exist @ 1.12.0, needs to be set to zero address for changes on this upgrade path)
// It also verified that remaining storage variables are unchanged.
contract HoloceneSystemConfigUpgrade is SuperchainRegistry {
using LibString for string;

address public systemConfigAddress;
ISystemConfig sysCfg;

// Storage variables which exist in the existing and target
// SystemConfig contract versions irrespective of upgrade path,
// and which should be preserved:
struct BaseSysCfgVars {
address owner;
bytes32 batcherHash;
uint256 gasLimit;
address unsafeBlockSigner;
IResourceMetering.ResourceConfig resourceConfig;
address batchInbox;
address l1CrossDomainMessenger;
address l1StandardBridge;
address l1ERC721Bridge;
address optimismPortal;
address optimismMintableERC20Factory;
}

BaseSysCfgVars previous;

// Values which may change during the upgrade, depending on the chain::
uint256 previousScalar;

// The target value for the DisputeGameFactory address,
// this getter does not exist in the SystemConfig contract @ 1.12.0:
address targetDGF;

// Target values for gasPayingToken and its decimals. This should represent ETH
// on all upgrade paths:
address constant targetGasPayingToken = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
uint8 constant targetDecimals = 18;

// The target version of the SystemConfig contract, read from the SCR @ specified release:
string targetVersion;

// The constructor caches some information from the SCR and from the existing SystemConfig contract
geoknee marked this conversation as resolved.
Show resolved Hide resolved
// before the upgrade is executed.
constructor(string memory _l1ChainName, string memory _l2ChainName, string memory _release)
SuperchainRegistry(_l1ChainName, _l2ChainName, _release)
sebastianst marked this conversation as resolved.
Show resolved Hide resolved
{
systemConfigAddress = proxies.SystemConfig;
sysCfg = ISystemConfig(proxies.SystemConfig);

// cache the values of the SystemConfig contract before the upgrade
previous = getBaseSysCfgVars();
previousScalar = sysCfg.scalar();

// Read target version from SCR @ specified release
targetVersion = standardVersions.SystemConfig.version;

if (sysCfg.version().eq("2.3.0")) {
// Supported initial version
targetDGF = sysCfg.disputeGameFactory();
} else if (sysCfg.version().eq("2.2.0")) {
// Supported initial version
targetDGF = sysCfg.disputeGameFactory();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could merge them

Suggested change
if (sysCfg.version().eq("2.3.0")) {
// Supported initial version
targetDGF = sysCfg.disputeGameFactory();
} else if (sysCfg.version().eq("2.2.0")) {
// Supported initial version
targetDGF = sysCfg.disputeGameFactory();
if (sysCfg.version().eq("2.3.0") || sysCfg.version().eq("2.2.0")) {
// Supported initial version
targetDGF = sysCfg.disputeGameFactory();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

} else if (sysCfg.version().eq("1.12.0")) {
// Supported initial version
targetDGF = address(0);
} else {
revert("unsupported SystemConfig version");
}
}

/// @notice Public function that must be called by the verification script.
function checkSystemConfigUpgrade() public view {
sebastianst marked this conversation as resolved.
Show resolved Hide resolved
checkTargetVersion();
checkScalar();
checkDGF();
checkGasPayingToken();
checkBaseSysCfgVars();
}

function getCodeExceptions() public view returns (address[] memory exceptions) {
uint256 len = block.chainid == 1 ? 3 : 4; // Mainnet doesn't need owner exception.
exceptions = new address[](len);
uint256 i = 0;
if (block.chainid != 1) exceptions[i++] = previous.owner;
exceptions[i++] = address(uint160(uint256((previous.batcherHash))));
exceptions[i++] = previous.unsafeBlockSigner;
exceptions[i++] = previous.batchInbox;
}
Comment on lines +95 to +103
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better pattern with the verification framework is to make the contract also a VerificationBase and then here do

Suggested change
function getCodeExceptions() public view returns (address[] memory exceptions) {
uint256 len = block.chainid == 1 ? 3 : 4; // Mainnet doesn't need owner exception.
exceptions = new address[](len);
uint256 i = 0;
if (block.chainid != 1) exceptions[i++] = previous.owner;
exceptions[i++] = address(uint160(uint256((previous.batcherHash))));
exceptions[i++] = previous.unsafeBlockSigner;
exceptions[i++] = previous.batchInbox;
}
function _getCodeExceptions() internal {
if (block.chainid != 1) addCodeException(previous.owner);
addCodeException(address(uint160(uint256(previous.batcherHash))));
addCodeException(previous.unsafeBlockSigner);
addCodeException(previous.batchInbox);
}

then call _getCodeExceptions() inside the constructor, and in the actual check script instance, you do

    function getAllowedStorageAccess() internal view override returns (address[] memory) {
        return allowedStorageAccess;
    }

    function getCodeExceptions() internal view override returns (address[] memory) {
        return codeExceptions;
    }

see for example the check script for task eth/022.

Copy link
Member

@sebastianst sebastianst Jan 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I realize you need to collect all those code exceptions from multiple instances. Still you could inherit the VerificationBase contract and then do something like

Suggested change
function getCodeExceptions() public view returns (address[] memory exceptions) {
uint256 len = block.chainid == 1 ? 3 : 4; // Mainnet doesn't need owner exception.
exceptions = new address[](len);
uint256 i = 0;
if (block.chainid != 1) exceptions[i++] = previous.owner;
exceptions[i++] = address(uint160(uint256((previous.batcherHash))));
exceptions[i++] = previous.unsafeBlockSigner;
exceptions[i++] = previous.batchInbox;
}
// call this from main script
function getCodeExceptions() public view returns (address[] memory exceptions) {
return codeExceptions
}
// call this from the constructor
function _addCodeExceptions() internal {
if (block.chainid != 1) addCodeException(previous.owner);
addCodeException(address(uint160(uint256(previous.batcherHash))));
addCodeException(previous.unsafeBlockSigner);
addCodeException(previous.batchInbox);
}

this way, if this check contract is directly used in a task that only updates a single SystemConfig via inheriting this contract, it automatically has all the right code exceptions set.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this will work for my multi chain task though?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried it, and it doesn't work -- because my top level script doesn't inherit the base validation script (it deploys multiple copies of it). That's why I thought I need to actually pass the values back from the children to the parent explicitly.

Copy link
Member

@sebastianst sebastianst Jan 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My proposal still gives you that. It just has two advantages

  1. you use the VerificationBase to give you addCodeException to manage the array
  2. if you use this contract in a single-verification (not multi-instance like this one), it's automatically compatible with that pattern.

Note that my proposal gives you the exact same function getCodeExceptions() public view returns (address[] memory exceptions) so same api.

To clarify further, of course you still need to explicitly call getCodeExceptions() in a loop on each contract, like you do now, and add it to the main code exceptions.


// Checks semver of SystemConfig is correct after the upgrade
function checkTargetVersion() internal view {
require(
keccak256(abi.encode(getSysCfgVersion())) == keccak256(abi.encode(targetVersion)),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
keccak256(abi.encode(getSysCfgVersion())) == keccak256(abi.encode(targetVersion)),
getSysCfgVersion().eq(targetVersion),

"system-config-050: targetVersion"
);
console.log("confirmed SystemConfig upgraded to version", targetVersion);
}

// Checks scalar, basefeeScalar, blobbasefeeScalar are set consistently:
function checkScalar() internal view {
geoknee marked this conversation as resolved.
Show resolved Hide resolved
uint256 reencodedScalar =
(uint256(0x01) << 248) | (uint256(sysCfg.blobbasefeeScalar()) << 32) | sysCfg.basefeeScalar();
console.log(
"checking baseFeeScalar and blobbaseFeeScalar ",
LibString.toString(sysCfg.basefeeScalar()),
LibString.toString(sysCfg.blobbasefeeScalar())
);
if (
// If the scalar version (i.e. the most significant bit of the scalar)
// is 1, we expect it to be unchanged during the upgrade.
uint8(previousScalar >> 248) == 1
geoknee marked this conversation as resolved.
Show resolved Hide resolved
) {
require(reencodedScalar == previousScalar, "scalar-100 scalar mismatch");
} else {
// Otherwise, if the scalar version is 0,
// and the blobbasefeeScalar is 0,
// the upgrade will migrate the scalar version to 1 and preserve
// everything else.
// See https://specs.optimism.io/protocol/system-config.html?highlight=ecotone%20scalar#ecotone-scalar-overhead-uint256uint256-change
require(previousScalar >> 248 == 0, "scalar-101 previous scalar version != 0 or 1");
require(reencodedScalar >> 248 == 1, "scalar-102 reenconded scalar version != 1");
require(sysCfg.blobbasefeeScalar() == uint32(0), "scalar-103 blobbasefeeScalar !=0");
require(reencodedScalar << 8 == previousScalar << 8, "scalar-104 scalar mismatch");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two comments on this:

  1. It's not very clear, if we define a variable or at least put in the revert reason "baseFeeScalar" that would help a lot
  2. The bit shift looks wrong, we probably want << 32 instead of << 8

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this is not working indeed, i tried with the mask 0xfffff and this seems to have a more reasonable value @geoknee:
14aa2bca398d7e38779daed1c1b54d44fb9d852fb8378e0b4641ebcf9c47b124

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed this here. In fact what I was trying to do was compare the scalars without the scalar version (first byte). 556d1d5

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm,
Just to make sure, you want to compare the if the first byte (0x0) are correctly incremented to (0x1) when the value scalarVersion is 0 right (if yes for me it works as expected).
CleanShot 2025-01-10 at 13 05 23@2x

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that's right.

}
// Check that basefeeScalar and blobbasefeeScalar are correct by re-encoding them and comparing to the new scalar value.
require(sysCfg.scalar() == reencodedScalar, "scalar-105");
}

// Checks the disputeGameFactory address is set correctly after the upgrade
function checkDGF() internal view {
require(sysCfg.disputeGameFactory() == targetDGF, "scalar-106");
}

// Checks gasPayingToken and its decimals are set correctly after the upgrade
function checkGasPayingToken() internal view {
(address t, uint8 d) = sysCfg.gasPayingToken();
require(t == targetGasPayingToken, "scalar-107");
require(d == targetDecimals, "scalar-108");
}

// CHecsk the remaining storage variables are unchanged after the upgrade
function checkBaseSysCfgVars() internal view {
// Check remaining storage variables didn't change
require(keccak256(abi.encode(getBaseSysCfgVars())) == keccak256(abi.encode(previous)), "system-config-100");
sebastianst marked this conversation as resolved.
Show resolved Hide resolved
}

// Reads
function getSysCfgVersion() internal view returns (string memory) {
return sysCfg.version();
sebastianst marked this conversation as resolved.
Show resolved Hide resolved
}

function getBaseSysCfgVars() internal view returns (BaseSysCfgVars memory) {
return BaseSysCfgVars({
owner: sysCfg.owner(),
batcherHash: sysCfg.batcherHash(),
gasLimit: sysCfg.gasLimit(),
unsafeBlockSigner: sysCfg.unsafeBlockSigner(),
resourceConfig: sysCfg.resourceConfig(),
batchInbox: sysCfg.batchInbox(),
l1CrossDomainMessenger: sysCfg.l1CrossDomainMessenger(),
l1StandardBridge: sysCfg.l1StandardBridge(),
l1ERC721Bridge: sysCfg.l1ERC721Bridge(),
optimismPortal: sysCfg.optimismPortal(),
optimismMintableERC20Factory: sysCfg.optimismMintableERC20Factory()
});
}
}
27 changes: 27 additions & 0 deletions script/verification/IResourceMetering.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IResourceMetering {
struct ResourceParams {
uint128 prevBaseFee;
uint64 prevBoughtGas;
uint64 prevBlockNum;
}

struct ResourceConfig {
uint32 maxResourceLimit;
uint8 elasticityMultiplier;
uint8 baseFeeMaxChangeDenominator;
uint32 minimumBaseFee;
uint32 systemTxMaxGas;
uint128 maximumBaseFee;
}

error OutOfGas();

event Initialized(uint8 version);

function params() external view returns (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum); // nosemgrep

function __constructor__() external;
Copy link
Contributor

@Ethnical Ethnical Jan 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

function __constructor__() external;

NIT: curious to know if this is required?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
87 changes: 87 additions & 0 deletions script/verification/ISystemConfig.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IResourceMetering} from "./IResourceMetering.sol";

/// @notice This interface corresponds to the Custom Gas Token version of the SystemConfig contract.
interface ISystemConfig {
enum UpdateType {
BATCHER,
FEE_SCALARS,
GAS_LIMIT,
UNSAFE_BLOCK_SIGNER,
EIP_1559_PARAMS
}

struct Addresses {
address l1CrossDomainMessenger;
address l1ERC721Bridge;
address l1StandardBridge;
address disputeGameFactory;
address optimismPortal;
address optimismMintableERC20Factory;
address gasPayingToken;
}

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 eip1559Denominator() external view returns (uint32);
function eip1559Elasticity() external view returns (uint32);
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 setEIP1559Params(uint32 _denominator, uint32 _elasticity) 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;
}
14 changes: 9 additions & 5 deletions script/verification/Verification.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ pragma solidity ^0.8.15;

import {LibString} from "solady/utils/LibString.sol";
import {Types} from "@eth-optimism-bedrock/scripts/Types.sol";
import {CommonBase} from "forge-std/Base.sol";
import {ScriptBase} from "forge-std/Base.sol";
import {stdToml} from "forge-std/StdToml.sol";
import {console2 as console} from "forge-std/console2.sol";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is already happening on line 4?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, removed.


// TODO(#427): Proposing to just merge this contract into JsonTxBuilderBase.
contract VerificationBase {
Expand All @@ -20,7 +21,7 @@ contract VerificationBase {
}
}

contract SuperchainRegistry is CommonBase {
contract SuperchainRegistry is ScriptBase {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the difference? why don't we want or need this for all other script contacts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I may be able to revert this. I had it previously because it exposed external TOML utilities which I could wrap with a try/catch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reverted this change in the end.

using LibString for string;

struct StandardVersion {
Expand Down Expand Up @@ -100,12 +101,15 @@ contract SuperchainRegistry is CommonBase {
proxies.L1CrossDomainMessenger = stdToml.readAddress(toml, "$.addresses.L1CrossDomainMessengerProxy");
proxies.L1StandardBridge = stdToml.readAddress(toml, "$.addresses.L1StandardBridgeProxy");
proxies.SystemConfig = stdToml.readAddress(toml, "$.addresses.SystemConfigProxy");
proxies.AnchorStateRegistry = stdToml.readAddress(toml, "$.addresses.AnchorStateRegistryProxy");
proxies.DisputeGameFactory = stdToml.readAddress(toml, "$.addresses.DisputeGameFactoryProxy");

// Not all chains have the following values specified in the registry, so we will
// set them to the zero address if they are not found.
proxies.AnchorStateRegistry = stdToml.readAddressOr(toml, "$.addresses.AnchorStateRegistryProxy", address(0));
proxies.DisputeGameFactory = stdToml.readAddressOr(toml, "$.addresses.DisputeGameFactoryProxy", address(0));
chainConfig.unsafeBlockSigner = stdToml.readAddressOr(toml, "$.addresses.UnsafeBlockSigner", address(0));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd still put this line back to where it was, so it's grouped with the other chainConfig setters as before.


chainConfig.chainId = stdToml.readUint(toml, "$.chain_id");
chainConfig.systemConfigOwner = stdToml.readAddress(toml, "$.addresses.SystemConfigOwner");
chainConfig.unsafeBlockSigner = stdToml.readAddress(toml, "$.addresses.UnsafeBlockSigner");
chainConfig.batchSubmitter = stdToml.readAddress(toml, "$.addresses.BatchSubmitter");
chainConfig.batchInbox = stdToml.readAddress(toml, "$.batch_inbox_addr");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

Status: [EXECUTED](https://sepolia.etherscan.io/tx/0x88bd1d85740af3741e2ed96d6fd07f2abb4541afc667625480bf6a28451c4d6d)

> ⚠️ **Warning:** This task is incorrect and is superseded by [Task 027](../027-holocene-system-config-upgrade-and-init-multi-chain/)
## Objective

Upgrades the `SystemConfig` for the Holocene hardfork for Sepolia/{OP,Mode,Metal,Zora,Base}.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ETH_RPC_URL="https://ethereum-sepolia.publicnode.com"
COUNCIL_SAFE=0xf64bc17485f0B4Ea5F06A96514182FC4cB561977
FOUNDATION_SAFE=0xDEe57160aAfCF04c34C887B5962D0a69676d3C8B
OWNER_SAFE=0x1Eb2fFc903729a0F03966B917003800b145F56E2
Loading