Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
19f579b
Add SystemConfigV4 contract and upgrade script
doutv Oct 21, 2025
31f6c91
Upgrade okb adapter success
doutv Oct 21, 2025
78c3763
Merge remote-tracking branch 'origin/pre-release' into jason/upgrade-…
doutv Oct 22, 2025
f482c9e
Refactor UpgradeSystemConfigToV4 script to streamline deployment proc…
doutv Oct 23, 2025
28ba582
Merge remote-tracking branch 'origin/pre-release' into jason/upgrade-…
doutv Oct 23, 2025
c7369e1
Refactor UpgradeSystemConfigToV4 script by removing whitelist setup f…
doutv Oct 23, 2025
86f76e0
Update SystemConfigV4 constructor version and modify gas paying token…
doutv Oct 23, 2025
b5a416e
Merge remote-tracking branch 'origin/pre-release' into jason/upgrade-…
doutv Oct 24, 2025
9b62d34
Add SystemConfigV312 contract and upgrade script for OKB adapter inte…
doutv Oct 24, 2025
634c57b
fix script
doutv Oct 24, 2025
6b776e4
Update SystemConfigV312 contract to allow ProxyAdmin to set gas payin…
doutv Oct 24, 2025
716e456
Pre release (#105)
louisliu2048 Oct 26, 2025
30bd2d5
Jason/update cgt contract (#120)
albbm Oct 27, 2025
c3286a9
Drop overwrite fro Transactor.sol during build (#125)
Vui-Chee Oct 27, 2025
b201006
update go mod, using remote op-geth instand local one (#126)
louisliu2048 Oct 27, 2025
5e741d0
Refactor DepositedOKBAdapter and OptimismPortal2 to enhance token tra…
albbm Oct 27, 2025
c690812
Merge branch 'dev' into jason/upgrade-contract
albbm Oct 28, 2025
9b0e128
fix: remove script that cause failed (#131)
cuiweixie Oct 28, 2025
2d5b5ab
Improvement(devnet RPC): Reth as RPC (#88)
dloghin Oct 29, 2025
f0f1032
support reth as sequencer and cooperate with conductor (#132)
xzav3r Oct 29, 2025
ed48d79
chore(test): fix some issues (#134)
xzav3r Oct 29, 2025
6bac470
feature(devnet): Reth as sequencer (#133)
dloghin Oct 29, 2025
db1a962
fix docker compose by adding env to container (#135)
dloghin Oct 30, 2025
945912e
fix scripts (#136)
KyrinCode Nov 3, 2025
38e895d
update test readme to make it more easy to run reth (#137)
louisliu2048 Nov 4, 2025
bc1f74e
fix: add .env sync functionality to clean.sh (#139)
xrqin Nov 4, 2025
1b4c2db
feat: Add mempool rebroadcaster service (#138)
sieniven Nov 5, 2025
a30dc45
update geth version (#140)
louisliu2048 Nov 5, 2025
2d42536
update (#142)
zjg555543 Nov 5, 2025
e3bbac8
Merge remote-tracking branch 'origin/dev' into jason/upgrade-contract
doutv Nov 6, 2025
61f2ae8
remove unused
doutv Nov 6, 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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,11 @@ crytic-export
test/l1-geth/consensus/beacondata
test/l1-geth/consensus/validatordata
test/config-op/genesis.json
test/config-op/genesis-reth.json
test/config-op/genesis.json.gz
test/config-op/genesis-reth.json
test/config-op/gen.test.geth.rpc.config.toml
test/config-op/gen.test.reth.rpc.config.toml
test/config-op/implementations.json
test/config-op/intent.toml
test/config-op/rollup.json
Expand All @@ -66,6 +70,7 @@ test/l1-geth/consensus/genesis.ssz
test/l1-geth/execution/geth/genesis.json
test/l1-geth/execution/geth
test/data
test/saved-cannon-data

# ignore local asdf config
.tool-versions
Expand Down
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ require (
github.com/libp2p/go-netroute v0.2.1 // indirect
github.com/libp2p/go-reuseport v0.4.0 // indirect
github.com/libp2p/go-yamux/v4 v4.0.1 // indirect
github.com/linxGnu/grocksdb v1.10.2 // indirect
github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae // indirect
github.com/magiconair/properties v1.8.5 // indirect
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect
Expand Down Expand Up @@ -320,9 +321,9 @@ require (
lukechampine.com/blake3 v1.3.0 // indirect
)

//replace github.com/ethereum/go-ethereum => github.com/ethereum-optimism/op-geth v1.101603.1-rc.1
replace github.com/ethereum/go-ethereum => github.com/okx/op-geth v0.0.7

replace github.com/ethereum/go-ethereum => ./op-geth
//replace github.com/ethereum/go-ethereum => ./op-geth

// replace github.com/ethereum-optimism/superchain-registry/superchain => ../superchain-registry/superchain

Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,8 @@ github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQsc
github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU=
github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ=
github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4=
github.com/linxGnu/grocksdb v1.10.2 h1:y0dXsWYULY15/BZMcwAZzLd13ZuyA470vyoNzWwmqG0=
github.com/linxGnu/grocksdb v1.10.2/go.mod h1:C3CNe9UYc9hlEM2pC82AqiGS3LRW537u9LFV4wIZuHk=
github.com/lmittmann/w3 v0.19.5 h1:WwVRyIwhRLfIahmpB1EglsB3o1XWsgydgrxIUp5upFQ=
github.com/lmittmann/w3 v0.19.5/go.mod h1:pN97sGGYGvsbqOYj/ms3Pd+7k/aiK/9OpNcxMmmzSOI=
github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae h1:dIZY4ULFcto4tAFlj1FYZl8ztUZ13bdq+PLY+NOfbyI=
Expand Down Expand Up @@ -800,6 +802,8 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc=
github.com/okx/op-geth v0.0.7 h1:EOxCr2qmObfTQj7nmI1aO9QoWztsq1Mip/1YsuzLcGk=
github.com/okx/op-geth v0.0.7/go.mod h1:MD4m7TCs3bDlgtuio/99+iVscH4eEpkhvJuOojm7D/o=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
Expand Down
2 changes: 1 addition & 1 deletion op-geth
620 changes: 620 additions & 0 deletions packages/contracts-bedrock/scripts/SystemConfigV312.sol

Large diffs are not rendered by default.

299 changes: 299 additions & 0 deletions packages/contracts-bedrock/scripts/UpgradeSystemConfigToV312.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { Script } from "forge-std/Script.sol";
import { console } from "forge-std/console.sol";
import { SystemConfigV312 } from "scripts/SystemConfigV312.sol";
import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol";
import { IOKB } from "interfaces/L1/IOKB.sol";
import { DepositedOKBAdapter } from "src/L1/DepositedOKBAdapter.sol";
import { Transactor } from "src/periphery/Transactor.sol";
import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol";

/// @title UpgradeSystemConfig
/// @notice Custom script to upgrade SystemConfig to V3.12 and set OKB adapter as gas paying token via Transactor
/// @dev This script:
/// 1. Reads OKB token address and Transactor address from environment variables
/// 2. Validates ownership chain (Transactor owns ProxyAdmin, ProxyAdmin controls SystemConfig)
/// 3. Deploys DepositedOKBAdapter that handles OKB burning internally
/// 4. Atomically upgrades SystemConfig to V3.12 and sets OKB adapter via ProxyAdmin.upgradeAndCall()
/// 5. Verifies all configurations on L1
/// 6. Verifies reinitializer protection
contract UpgradeSystemConfig is Script {

// Environment variable names
string constant SYSTEM_CONFIG_PROXY = "SYSTEM_CONFIG_PROXY_ADDRESS";
string constant PROXY_ADMIN = "OP_PROXY_ADMIN";
string constant TRANSACTOR = "TRANSACTOR";
string constant OKB_TOKEN_ADDRESS = "OKB_TOKEN_ADDRESS";
string constant OPTIMISM_PORTAL_PROXY = "OPTIMISM_PORTAL_PROXY_ADDRESS";
string constant OKB_ADAPTER_OWNER_ADDRESS = "OKB_ADAPTER_OWNER_ADDRESS";

// State variables for configuration
address systemConfigProxy;
address proxyAdmin;
address transactorAddress;
address okbTokenAddress;
address optimismPortalProxy;
address deployerAddress;
address adatperOwnerAddress;

// Deployed contracts
IOKB okbToken;
DepositedOKBAdapter adapter;
Transactor transactor;

/// @notice Main upgrade function
function run() external {
_loadConfiguration();
_validateConfiguration();
_performUpgrade();
}

/// @notice Load configuration from environment variables
function _loadConfiguration() internal {
// Get deployer address from msg.sender (set by forge script --private-key)
deployerAddress = msg.sender;

// Load addresses from environment
systemConfigProxy = vm.envAddress(SYSTEM_CONFIG_PROXY);
proxyAdmin = vm.envAddress(PROXY_ADMIN);
transactorAddress = vm.envAddress(TRANSACTOR);
okbTokenAddress = vm.envAddress(OKB_TOKEN_ADDRESS);
optimismPortalProxy = vm.envAddress(OPTIMISM_PORTAL_PROXY);
adatperOwnerAddress = vm.envAddress(OKB_ADAPTER_OWNER_ADDRESS);

console.log("=== Upgrade Configuration ===");
console.log("Deployer address:", deployerAddress);
console.log("SystemConfig Proxy:", systemConfigProxy);
console.log("ProxyAdmin:", proxyAdmin);
console.log("Transactor:", transactorAddress);
console.log("OKB Token Address:", okbTokenAddress);
console.log("OptimismPortal Proxy:", optimismPortalProxy);
console.log("OKB Adapter Owner Address:", adatperOwnerAddress);

// Initialize contract interfaces
okbToken = IOKB(okbTokenAddress);
transactor = Transactor(transactorAddress);
}

/// @notice Validate the configuration before proceeding
function _validateConfiguration() internal view {
require(systemConfigProxy != address(0), "SystemConfig proxy address cannot be zero");
require(proxyAdmin != address(0), "ProxyAdmin address cannot be zero");
require(transactorAddress != address(0), "Transactor address cannot be zero");
require(okbTokenAddress != address(0), "OKB token address cannot be zero");
require(optimismPortalProxy != address(0), "OptimismPortal proxy address cannot be zero");
require(deployerAddress != address(0), "Deployer address cannot be zero");
require(adatperOwnerAddress != address(0), "OKB Adapter owner address cannot be zero");

// Verify contracts have code
require(
systemConfigProxy.code.length > 0,
"SystemConfig proxy must have code (not an EOA)"
);
require(
proxyAdmin.code.length > 0,
"ProxyAdmin must have code (not an EOA)"
);
require(
transactorAddress.code.length > 0,
"Transactor must have code (not an EOA)"
);
require(
okbTokenAddress.code.length > 0,
"OKB token must have code (not an EOA)"
);
require(
optimismPortalProxy.code.length > 0,
"OptimismPortal proxy must have code (not an EOA)"
);

// Verify ownership chain for upgrade permissions
_validateOwnershipChain();
}

/// @notice Validate the ownership chain for upgrade permissions
function _validateOwnershipChain() internal view {
console.log("\n--- Validating Ownership Chain ---");

// Check ProxyAdmin owner
IProxyAdmin admin = IProxyAdmin(proxyAdmin);
address proxyAdminOwner = admin.owner();
console.log("ProxyAdmin owner:", proxyAdminOwner);
console.log("Transactor address:", transactorAddress);

// Verify Transactor owns ProxyAdmin
require(
proxyAdminOwner == transactorAddress,
"Transactor must be the owner of ProxyAdmin"
);

// Check SystemConfig proxy admin
ISystemConfig systemConfigContract = ISystemConfig(systemConfigProxy);
address systemConfigAdmin = address(systemConfigContract.proxyAdmin());
console.log("SystemConfig proxy admin:", systemConfigAdmin);
console.log("Expected ProxyAdmin:", proxyAdmin);

// Verify ProxyAdmin controls SystemConfig proxy
require(
systemConfigAdmin == proxyAdmin,
"ProxyAdmin must be the admin of SystemConfig proxy"
);

console.log("Ownership chain validated successfully");
}

/// @notice Deploy DepositedOKBAdapter
function _deployAdapter() internal {
console.log("\n--- Deploying DepositedOKBAdapter ---");
adapter = new DepositedOKBAdapter(okbTokenAddress, payable(optimismPortalProxy), adatperOwnerAddress);
console.log("DepositedOKBAdapter deployed at:", address(adapter));
}

/// @notice Perform the complete upgrade process
function _performUpgrade() internal {
console.log("\n=== Starting SystemConfig V3.12 Upgrade ===");

// Step 1: Check current state
_logCurrentState();

// Step 2: Deploy new SystemConfigV312 implementation
vm.startBroadcast();

console.log("\n--- Deploying SystemConfigV312 Implementation ---");
SystemConfigV312 newImplementation = new SystemConfigV312();
console.log("SystemConfigV312 deployed at:", address(newImplementation));
console.log("New implementation version:", newImplementation.version());
console.log("New init version:", newImplementation.initVersion());

// Step 3: Deploy DepositedOKBAdapter
_deployAdapter();

// Step 4: Upgrade proxy and call upgradeAndSetGasPayingToken atomically
console.log("\n--- Upgrading and Initializing SystemConfig V3.12 via Transactor ---");

// Convert string to bytes32 for SystemConfig function
bytes32 nameBytes32 = bytes32(bytes(okbToken.name()));
bytes32 symbolBytes32 = bytes32(bytes(okbToken.symbol()));

// Encode the upgradeAndSetGasPayingToken() call data
bytes memory initCalldata = abi.encodeWithSelector(
SystemConfigV312.setGasPayingToken.selector,
address(adapter),
okbToken.decimals(),
nameBytes32,
symbolBytes32
);

// Encode the ProxyAdmin.upgradeAndCall() call
bytes memory upgradeAndCallData = abi.encodeWithSelector(
IProxyAdmin.upgradeAndCall.selector,
payable(systemConfigProxy),
address(newImplementation),
initCalldata
);

console.log("Calling ProxyAdmin.upgradeAndCall() via Transactor.CALL()");
console.log("This atomically upgrades and initializes the SystemConfig");

// Call ProxyAdmin.upgradeAndCall() through Transactor.CALL()
(bool success,) = transactor.CALL(
proxyAdmin,
upgradeAndCallData,
0 // no ETH value
);
require(success, "Transactor CALL to ProxyAdmin.upgradeAndCall failed");
console.log("Atomic upgrade and initialization completed successfully");

SystemConfigV312 upgradedSystemConfig = SystemConfigV312(systemConfigProxy);

// Step 5: Verify the upgrade
_verifyUpgrade(upgradedSystemConfig);

vm.stopBroadcast();

console.log("\n=== SystemConfig V3.12 Upgrade Completed Successfully ===");
}

/// @notice Log the current state before upgrade
function _logCurrentState() internal view {
ISystemConfig currentSystemConfig = ISystemConfig(systemConfigProxy);

console.log("\n--- Current SystemConfig State ---");
console.log("Current version:", currentSystemConfig.version());
console.log("Current init version:", currentSystemConfig.initVersion());

(address currentGasToken, uint8 currentDecimals) = currentSystemConfig.gasPayingToken();
console.log("Current gas token (DepositedOKBAdapter):", currentGasToken);
console.log("Current gas token decimals:", currentDecimals);

string memory tokenName = currentSystemConfig.gasPayingTokenName();
string memory tokenSymbol = currentSystemConfig.gasPayingTokenSymbol();
console.log("Current gas token name:", tokenName);
console.log("Current gas token symbol:", tokenSymbol);

bool isCustomGasToken = currentSystemConfig.isCustomGasToken();
console.log("Is custom gas token:", isCustomGasToken);
}

/// @notice Verify the upgrade was successful
function _verifyUpgrade(SystemConfigV312 upgradedSystemConfig) internal {
console.log("\n--- Verifying Upgrade Results ---");

// Check version updated
string memory newVersion = upgradedSystemConfig.version();
require(
keccak256(bytes(newVersion)) == keccak256(bytes("3.12.0")),
"Version not updated correctly"
);

// Check init version
uint8 newInitVersion = upgradedSystemConfig.initVersion();
require(newInitVersion == 3, "Init version not updated correctly");

// Check gas paying token is set to adapter
(address newGasToken, uint8 newDecimals) = upgradedSystemConfig.gasPayingToken();
console.log("New gas token:", newGasToken);
console.log("New gas token decimals:", newDecimals);
require(newGasToken == address(adapter), "FAILED: Token address should be adapter");
require(newDecimals == okbToken.decimals(), "FAILED: Token decimals mismatch");

// Check token metadata matches OKB
string memory newTokenName = upgradedSystemConfig.gasPayingTokenName();
string memory newTokenSymbol = upgradedSystemConfig.gasPayingTokenSymbol();
console.log("New gas token name:", newTokenName);
console.log("New gas token symbol:", newTokenSymbol);
require(
keccak256(abi.encodePacked(newTokenName)) == keccak256(abi.encodePacked(okbToken.name())),
"FAILED: Token name mismatch"
);
require(
keccak256(abi.encodePacked(newTokenSymbol)) == keccak256(abi.encodePacked(okbToken.symbol())),
"FAILED: Token symbol mismatch"
);

// Verify custom gas token flag is true
bool isCustomGasToken = upgradedSystemConfig.isCustomGasToken();
require(isCustomGasToken, "Custom gas token flag should be true");

// Check DepositedOKBAdapter configuration
require(address(adapter.OKB()) == okbTokenAddress, "FAILED: Adapter OKB mismatch");
require(address(adapter.PORTAL()) == optimismPortalProxy, "FAILED: Adapter portal mismatch");
require(adapter.owner() == deployerAddress, "FAILED: Adapter owner mismatch");

// Check adapter has preminted total supply
uint256 adapterBalance = adapter.balanceOf(address(adapter));
uint256 expectedBalance = okbToken.totalSupply();
console.log("Adapter balance:", adapterBalance);
console.log("Expected balance (OKB total supply):", expectedBalance);
require(adapterBalance == expectedBalance, "FAILED: Adapter balance should equal OKB total supply");

// Check Adapter approval to portal (should be zero initially)
uint256 allowance = adapter.allowance(address(adapter), optimismPortalProxy);
console.log("Adapter approval to Portal:", allowance);
require(allowance == 0, "FAILED: Adapter should not pre-approve portal");

console.log("All upgrade verifications passed!");
}
}
Loading