From 909bc9bae68524eacb8e01550cd39a5d096d9abb Mon Sep 17 00:00:00 2001 From: syntrust Date: Fri, 14 Nov 2025 18:39:17 +0800 Subject: [PATCH 01/14] fix lint --- .../scripts/deploy/ChainAssertions.sol | 10 +++++++- .../deploy/UpgradeAnchorStateRegistry.s.sol | 24 ++++++++++++------- .../src/L1/OptimismPortal2.sol | 2 -- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol b/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol index 380eeab52acd0..717059b660b80 100644 --- a/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol +++ b/packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol @@ -84,7 +84,15 @@ library ChainAssertions { require(config.scalar() >> 248 == 1, "CHECK-SCFG-70"); // Depends on start block being set to 0 in `initialize` require(config.startBlock() == block.number, "CHECK-SCFG-140"); - require(config.batchInbox() == (_doi.batchInbox() == address(0) ? _doi.opcm().chainIdToBatchInboxAddress(_doi.l2ChainId()) : _doi.batchInbox()), "CHECK-SCFG-150"); + require( + config.batchInbox() + == ( + _doi.batchInbox() == address(0) + ? _doi.opcm().chainIdToBatchInboxAddress(_doi.l2ChainId()) + : _doi.batchInbox() + ), + "CHECK-SCFG-150" + ); // Check _addresses require(config.l1CrossDomainMessenger() == _contracts.L1CrossDomainMessenger, "CHECK-SCFG-160"); require(config.l1ERC721Bridge() == _contracts.L1ERC721Bridge, "CHECK-SCFG-170"); diff --git a/packages/contracts-bedrock/scripts/deploy/UpgradeAnchorStateRegistry.s.sol b/packages/contracts-bedrock/scripts/deploy/UpgradeAnchorStateRegistry.s.sol index e7e2cefa06bca..3bfad8ac0af16 100644 --- a/packages/contracts-bedrock/scripts/deploy/UpgradeAnchorStateRegistry.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/UpgradeAnchorStateRegistry.s.sol @@ -52,11 +52,7 @@ contract UpgradeAnchorStateRegistry is Script { _startingAnchorRoot ); vm.stopBroadcast(); - checkOutput( - IAnchorStateRegistry(_anchorStateRegistryProxy), - GameType.wrap(_type), - _startingAnchorRoot - ); + checkOutput(IAnchorStateRegistry(_anchorStateRegistryProxy), GameType.wrap(_type), _startingAnchorRoot); } function upgradeAnchorStateRegistryImpl( @@ -73,7 +69,9 @@ contract UpgradeAnchorStateRegistry is Script { address anchorStateRegistryImpl = DeployUtils.create1({ _name: "AnchorStateRegistry", _args: DeployUtils.encodeConstructor( - abi.encodeCall(IAnchorStateRegistry.__constructor__, (_anchorStateRegistryProxy.disputeGameFinalityDelaySeconds())) + abi.encodeCall( + IAnchorStateRegistry.__constructor__, (_anchorStateRegistryProxy.disputeGameFinalityDelaySeconds()) + ) ) }); @@ -106,7 +104,9 @@ contract UpgradeAnchorStateRegistry is Script { virtual returns (bytes memory) { - return abi.encodeCall(IAnchorStateRegistry.initialize, (_systemConfig, _disputeGameFactory, _startingAnchorRoot, _type)); + return abi.encodeCall( + IAnchorStateRegistry.initialize, (_systemConfig, _disputeGameFactory, _startingAnchorRoot, _type) + ); } /// @notice Makes an external call to the target to initialize the proxy with the specified data. @@ -135,8 +135,14 @@ contract UpgradeAnchorStateRegistry is Script { view { (Hash root, uint256 l2BlockNumber) = IAnchorStateRegistry(_anchorStateRegistryProxy).anchors(_type); - require(Hash.unwrap(root) == Hash.unwrap(_startingAnchorRoot.root), "UpgradeAnchorStateRegistryOutput: root mismatch"); - require(l2BlockNumber == _startingAnchorRoot.l2SequenceNumber, "UpgradeAnchorStateRegistryOutput: l2BlockNumber mismatch"); + require( + Hash.unwrap(root) == Hash.unwrap(_startingAnchorRoot.root), + "UpgradeAnchorStateRegistryOutput: root mismatch" + ); + require( + l2BlockNumber == _startingAnchorRoot.l2SequenceNumber, + "UpgradeAnchorStateRegistryOutput: l2BlockNumber mismatch" + ); } function bytes32ToHex(bytes32 _data) internal pure returns (string memory) { diff --git a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol index 6961da98a3bf2..f6cb746b16ec0 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol @@ -179,7 +179,6 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase /// @param success Whether the withdrawal transaction was successful. event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success); - /// @notice added back by QKC error OptimismPortal_Unauthorized(); @@ -190,7 +189,6 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase /// @notice Emitted when native deposit is enabled. event NativeDepositEnabled(); - /// @notice Thrown when a withdrawal has already been finalized. error OptimismPortal_AlreadyFinalized(); From 8ce9360676aab7c290ec995bda591dd2b1d36a78 Mon Sep 17 00:00:00 2001 From: syntrust Date: Fri, 14 Nov 2025 19:12:33 +0800 Subject: [PATCH 02/14] fix unused-imports and interfaces check --- .../contracts-bedrock/interfaces/L1/IOptimismPortal2.sol | 5 +++++ .../contracts-bedrock/interfaces/L2/IL2ToL1MessagePasser.sol | 4 ++++ .../scripts/deploy/UpgradeSoulGasToken.s.sol | 3 --- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/contracts-bedrock/interfaces/L1/IOptimismPortal2.sol b/packages/contracts-bedrock/interfaces/L1/IOptimismPortal2.sol index 44c4e30e18c9e..14c267e349aa2 100644 --- a/packages/contracts-bedrock/interfaces/L1/IOptimismPortal2.sol +++ b/packages/contracts-bedrock/interfaces/L1/IOptimismPortal2.sol @@ -33,11 +33,16 @@ interface IOptimismPortal2 is IProxyAdminOwnedBase { error OptimismPortal_ProofNotOldEnough(); error OptimismPortal_Unproven(); error OptimismPortal_InvalidLockboxState(); + error OptimismPortal_Unauthorized(); + error OptimismPortal_NativeDepositForbidden(); error OutOfGas(); error UnexpectedList(); error UnexpectedString(); event Initialized(uint8 version); + event NativeDepositEnabled(); + event NativeDepositDisabled(); + event MinterSet(address indexed minter); event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData); event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success); event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to); diff --git a/packages/contracts-bedrock/interfaces/L2/IL2ToL1MessagePasser.sol b/packages/contracts-bedrock/interfaces/L2/IL2ToL1MessagePasser.sol index 6da156237feca..7526983ea28dc 100644 --- a/packages/contracts-bedrock/interfaces/L2/IL2ToL1MessagePasser.sol +++ b/packages/contracts-bedrock/interfaces/L2/IL2ToL1MessagePasser.sol @@ -2,6 +2,10 @@ pragma solidity ^0.8.0; interface IL2ToL1MessagePasser { + event NativeDepositEnabled(); + event NativeDepositDisabled(); + error L2ToL1MessagePasser_NativeDepositDisabled(); + event MessagePassed( uint256 indexed nonce, address indexed sender, diff --git a/packages/contracts-bedrock/scripts/deploy/UpgradeSoulGasToken.s.sol b/packages/contracts-bedrock/scripts/deploy/UpgradeSoulGasToken.s.sol index 3dbe9e9cda6a8..3850cfecb31d7 100644 --- a/packages/contracts-bedrock/scripts/deploy/UpgradeSoulGasToken.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/UpgradeSoulGasToken.s.sol @@ -7,9 +7,6 @@ import { Script } from "forge-std/Script.sol"; // Scripts import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; -// Contracts -import { StorageSetter } from "src/universal/StorageSetter.sol"; - // Interfaces import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; import { IStorageSetter } from "interfaces/universal/IStorageSetter.sol"; From d8dfcd7df9d03463c21ade0fc8ebbc0bd3830059 Mon Sep 17 00:00:00 2001 From: syntrust Date: Mon, 17 Nov 2025 19:45:18 +0800 Subject: [PATCH 03/14] fix not set --- packages/contracts-bedrock/test/L1/OPContractsManager.t.sol | 1 + packages/contracts-bedrock/test/opcm/DeployOPChain.t.sol | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol index 7a60dd9f3d54b..efd360de78aad 100644 --- a/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol +++ b/packages/contracts-bedrock/test/L1/OPContractsManager.t.sol @@ -1635,6 +1635,7 @@ contract OPContractsManager_Deploy_Test is DeployOPChain_TestBase { doi.set(doi.disputeSplitDepth.selector, disputeSplitDepth); doi.set(doi.disputeClockExtension.selector, disputeClockExtension); doi.set(doi.disputeMaxClockDuration.selector, disputeMaxClockDuration); + doi.set(doi.batchInbox.selector, opcm.chainIdToBatchInboxAddress(l2ChainId)); } // This helper function is used to convert the input struct type defined in DeployOPChain.s.sol diff --git a/packages/contracts-bedrock/test/opcm/DeployOPChain.t.sol b/packages/contracts-bedrock/test/opcm/DeployOPChain.t.sol index 6f735c9a61198..66dd3f5472ba1 100644 --- a/packages/contracts-bedrock/test/opcm/DeployOPChain.t.sol +++ b/packages/contracts-bedrock/test/opcm/DeployOPChain.t.sol @@ -506,5 +506,6 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { doi.set(doi.disputeSplitDepth.selector, disputeSplitDepth); doi.set(doi.disputeClockExtension.selector, disputeClockExtension); doi.set(doi.disputeMaxClockDuration.selector, disputeMaxClockDuration); + doi.set(doi.batchInbox.selector, opcm.chainIdToBatchInboxAddress(l2ChainId)); } } From 43893cb5361585ccf81ef94337ae63410d459b7e Mon Sep 17 00:00:00 2001 From: syntrust Date: Tue, 18 Nov 2025 10:29:42 +0800 Subject: [PATCH 04/14] fix snapshots --- .../snapshots/abi/L2ToL1MessagePasser.json | 30 +++++++ .../snapshots/abi/OPContractsManager.json | 5 ++ .../abi/OPContractsManagerDeployer.json | 5 ++ .../snapshots/abi/OptimismPortal2.json | 79 +++++++++++++++++++ .../snapshots/abi/SoulGasToken.json | 52 ++++++++++++ .../snapshots/semver-lock.json | 10 +-- 6 files changed, 176 insertions(+), 5 deletions(-) diff --git a/packages/contracts-bedrock/snapshots/abi/L2ToL1MessagePasser.json b/packages/contracts-bedrock/snapshots/abi/L2ToL1MessagePasser.json index 77e1cf7596b35..998a46e7aa5dc 100644 --- a/packages/contracts-bedrock/snapshots/abi/L2ToL1MessagePasser.json +++ b/packages/contracts-bedrock/snapshots/abi/L2ToL1MessagePasser.json @@ -78,6 +78,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_disable", + "type": "bool" + } + ], + "name": "setNativeDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "version", @@ -140,6 +153,18 @@ "name": "MessagePassed", "type": "event" }, + { + "anonymous": false, + "inputs": [], + "name": "NativeDepositDisabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "NativeDepositEnabled", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -152,5 +177,10 @@ ], "name": "WithdrawerBalanceBurnt", "type": "event" + }, + { + "inputs": [], + "name": "L2ToL1MessagePasser_NativeDepositDisabled", + "type": "error" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json index f4ef1718aa42b..ee55ba647db03 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json +++ b/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json @@ -347,6 +347,11 @@ "internalType": "Duration", "name": "disputeMaxClockDuration", "type": "uint64" + }, + { + "internalType": "address", + "name": "batchInbox", + "type": "address" } ], "internalType": "struct OPContractsManager.DeployInput", diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerDeployer.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerDeployer.json index 7cd7a44502c06..61b26d88006ae 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerDeployer.json +++ b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerDeployer.json @@ -235,6 +235,11 @@ "internalType": "Duration", "name": "disputeMaxClockDuration", "type": "uint64" + }, + { + "internalType": "address", + "name": "batchInbox", + "type": "address" } ], "internalType": "struct OPContractsManager.DeployInput", diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json b/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json index 6b3a36bf234ae..e122f209f0edb 100644 --- a/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json +++ b/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json @@ -333,6 +333,24 @@ "stateMutability": "pure", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "mintTransaction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -588,6 +606,32 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "_minter", + "type": "address" + } + ], + "name": "setMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_disable", + "type": "bool" + } + ], + "name": "setNativeDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "superchainConfig", @@ -653,6 +697,31 @@ "name": "Initialized", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "MinterSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "NativeDepositDisabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "NativeDepositEnabled", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -832,6 +901,11 @@ "name": "OptimismPortal_InvalidRootClaim", "type": "error" }, + { + "inputs": [], + "name": "OptimismPortal_NativeDepositForbidden", + "type": "error" + }, { "inputs": [], "name": "OptimismPortal_NoReentrancy", @@ -842,6 +916,11 @@ "name": "OptimismPortal_ProofNotOldEnough", "type": "error" }, + { + "inputs": [], + "name": "OptimismPortal_Unauthorized", + "type": "error" + }, { "inputs": [], "name": "OptimismPortal_Unproven", diff --git a/packages/contracts-bedrock/snapshots/abi/SoulGasToken.json b/packages/contracts-bedrock/snapshots/abi/SoulGasToken.json index be5f31855e48a..2b1da1119daa2 100644 --- a/packages/contracts-bedrock/snapshots/abi/SoulGasToken.json +++ b/packages/contracts-bedrock/snapshots/abi/SoulGasToken.json @@ -567,6 +567,32 @@ "name": "Approval", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "burner", + "type": "address" + } + ], + "name": "BurnerAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "burner", + "type": "address" + } + ], + "name": "BurnerDeleted", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -593,6 +619,32 @@ "name": "Initialized", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "MinterAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "MinterDeleted", + "type": "event" + }, { "anonymous": false, "inputs": [ diff --git a/packages/contracts-bedrock/snapshots/semver-lock.json b/packages/contracts-bedrock/snapshots/semver-lock.json index ab5894d1bdb41..cec205a7bb911 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -20,8 +20,8 @@ "sourceCodeHash": "0x8eae1c2bbc501b231f75e75cbdbc99d2bbb0cc909ab39e9c473ac90daf1a7add" }, "src/L1/OPContractsManager.sol:OPContractsManager": { - "initCodeHash": "0x8755e500e7905a9bf26939555366639b5e39fa39645665e93d86b47e59867213", - "sourceCodeHash": "0x60cd2ab14324b550b96c90e1af2879198ea00942d70cfa5a915679cc85c47f9c" + "initCodeHash": "0x369f9ef6ecdc6126d8ab4bf37bbf929c4ac86215a19934eba510e922bc4091f0", + "sourceCodeHash": "0xa6f158bce9944c885f3d0d7e30f4f44e088fac75af498fffcebc7b3f301a19e2" }, "src/L1/OPContractsManagerStandardValidator.sol:OPContractsManagerStandardValidator": { "initCodeHash": "0x00544069c2122703f3234e5f315f5849c139d34d0e2f864c28d15ac210fe132b", @@ -29,7 +29,7 @@ }, "src/L1/OptimismPortal2.sol:OptimismPortal2": { "initCodeHash": "0x5d2ce1fffce653e225e611516405600e212f1d533a3e9c061d5644c509ff6170", - "sourceCodeHash": "0x920e96784b34d34da0135716c64064f01859b777c024c3a1416d6e85afaa303a" + "sourceCodeHash": "0xd5e08606935cc338679ed39789f292896c8d921e5582b8025462c37f683925e3" }, "src/L1/OptimismPortalInterop.sol:OptimismPortalInterop": { "initCodeHash": "0x7911f37dc9614291a3dfd76c5434d70ae573bb84f213f1c28baec078a2f4b559", @@ -148,8 +148,8 @@ "sourceCodeHash": "0x03c160168986ffc8d26a90c37366e7ad6da03f49d83449e1f8b3de0f4b590f6f" }, "src/dispute/AnchorStateRegistry.sol:AnchorStateRegistry": { - "initCodeHash": "0x9bb9cd78ac1d15844fbff2e7c759f2c949f3aa1a8d950d54ddb4b1ed88863239", - "sourceCodeHash": "0xf2715ff5393244742428454e1661aae7a56433867ee7bc563f44ad572c492d82" + "initCodeHash": "0xc9d6c547bf949e5e6d4b3d24dc12b8a5194efa6ffa9e1de00c748a94db517a67", + "sourceCodeHash": "0x16e5996752efad8e1c5e3811fb8febf44c3c5aecd9eddcc60e7093b8f3ec562b" }, "src/dispute/DelayedWETH.sol:DelayedWETH": { "initCodeHash": "0xa8f60e142108b33675a8f6b6979c73b96eea247884842d796f9f878904c0a906", From dd225de9da10e4720a68e9f35ab2cc1932d263b9 Mon Sep 17 00:00:00 2001 From: syntrust Date: Thu, 27 Nov 2025 14:17:09 +0800 Subject: [PATCH 05/14] test script --- .mise-tasks/dev-test.sh | 184 ++++++++++++++++++++++++---------------- 1 file changed, 112 insertions(+), 72 deletions(-) diff --git a/.mise-tasks/dev-test.sh b/.mise-tasks/dev-test.sh index 0445739d61852..3f1607c004fd9 100755 --- a/.mise-tasks/dev-test.sh +++ b/.mise-tasks/dev-test.sh @@ -4,97 +4,137 @@ #MISE alias="dt" set -e +# Inherit ERR trap in functions/subshells and catch pipeline failures +set -E -o pipefail SECONDS=0 error_handler() { - echo "Execution time: ${SECONDS} seconds" - exit 1 + local rc=$? + local cmd=${BASH_COMMAND:-unknown} + local where + where=$(caller 0 2>/dev/null || true) + halt "Command failed (exit $rc): ${cmd} | at: ${where}" } trap 'error_handler' ERR -# Environment tests +# Graceful halt helper: print error, show total time, stop script without closing terminal +halt() { + echo "Error: $*" >&2 + echo "Execution time: ${SECONDS} seconds" + # remove ERR trap to avoid double messaging + trap - ERR + # If sourced use return, else exit with success code (0) to not signal failure + return 0 2>/dev/null || exit 0 +} -forge --version +# Environment verify +echo "==========Checking environment..." +# mise install + +if [ -z "${MISE_SHELL:-}" ]; then + if [ -n "${ZSH_VERSION:-}" ]; then + eval "$(mise activate zsh)" + elif [ -n "${BASH_VERSION:-}" ]; then + eval "$(mise activate bash)" + fi +fi + +echo "Current branch: $(git rev-parse --abbrev-ref HEAD)" >&2 +if [ -n "$(git status --porcelain)" ]; then + echo "WARN: Working tree not clean. Commit/stash changes first." >&2 + git status --porcelain + exit 1 +fi for var in SEPOLIA_RPC_URL MAINNET_RPC_URL; do if [ -z "${!var}" ]; then echo "Error: $var is not set." - exit 1 + return 0 2>/dev/null || exit 0 fi done +echo "==========Checking environment done" -STATUS=$(kurtosis engine status) -if echo "$STATUS" | grep -q "1.4.3"; then - echo "Kurtosis engine is running." -else - echo "The Kurtosis engine is not running, or there is a version mismatch." - exit 1 -fi - -# Runs semgrep tests on the entire monorepo - -just semgrep -just semgrep-test - -# Solidity +echo "==========Cleaning workspace..." +git clean -df +echo "==========Workspace cleaned." +# Updating dependencies in contracts lib cd packages/contracts-bedrock -just lint-check -just pre-pr -just test - -# Go - +forge install + +# contracts-bedrock-tests & contracts-bedrock-tests-preimage-oracle +echo "==========Starting contracts-bedrock tests..." +just build-go-ffi +for _spec in \ + "-name '*.t.sol' -not -name 'PreimageOracle.t.sol'" \ + "-name 'PreimageOracle.t.sol'"; do + TEST_FILES=$(eval find test ${_spec}) + if [ -z "$TEST_FILES" ]; then + echo "No tests matched spec: ${_spec}; skipping" + continue + fi + TEST_FILES=$(echo "$TEST_FILES" | sed 's|^test/||') + MATCH_PATH="./test/{$(echo "$TEST_FILES" | paste -sd "," -)}" + echo "Running forge test --match-path $MATCH_PATH" + forge test --match-path "$MATCH_PATH" +done +echo "==========Contracts-bedrock tests done." + +# contracts-bedrock-build +just clean +just forge-build --deny-warnings --skip test +forge script "scripts/deploy/DeployImplementations.s.sol" \ + --skip "/**/test/**" \ + --sig "idonotexist()" \ + --skip-simulation \ + 2>/dev/null || true +ls forge-artifacts/DeployImplementations.s.sol/DeployImplementations.json cd ../.. -make lint-go -make build-go - -cd op-program && make op-program-client && cd .. -cd cannon && make elf && cd .. -cd op-e2e && make pre-test && cd .. - -make devnet-allocs - -export ENABLE_KURTOSIS=true -export OP_E2E_CANNON_ENABLED="false" -export OP_E2E_SKIP_SLOW_TEST=true -export OP_E2E_USE_HTTP=true -export ENABLE_ANVIL=true - -# Note: not all packages are tested. -# For example the test `TestFinalization` in `op-alt-da` package fails even in upstream. -packages=( - op-batcher - op-chain-ops - op-node - op-proposer - op-challenger - op-dispute-mon - op-conductor - op-program - op-service - op-supervisor - op-deployer - op-e2e/system - op-e2e/e2eutils - op-e2e/opgeth - op-e2e/interop - op-e2e/actions - op-e2e/faultproofs - op-e2e/l2blob - op-e2e/inbox - op-e2e/sgt - packages/contracts-bedrock/scripts/checks -) -formatted_packages="" -for package in "${packages[@]}"; do - formatted_packages="$formatted_packages ./$package/..." + +# op-deployer embedded artifacts (required by op-deployer Go tests) +echo "==========Packing op-deployer artifacts..." +just -f op-deployer/justfile copy-contract-artifacts +echo "==========Artifacts packed." + +# cannon-prestate-quick +echo "==========Starting cannon-prestates-quick..." +make cannon-prestates +echo "==========Cannon-prestates-quick done." + +# op-e2e-fuzz +echo "==========Starting op-e2e-fuzz..." +cd op-e2e && make fuzz && cd .. +echo "==========Op-e2e-fuzz done." + +# cannon-fuzz +echo "==========Starting cannon-fuzz..." +cd cannon && make fuzz && cd .. +echo "==========Cannon-fuzz done." + +# op-program-compat +echo "==========Starting op-program-compat..." +cd op-program && make verify-compat && cd .. +echo "==========Op-program-compat done." + +# fuzz-golang +echo "==========Starting fuzz-golang..." +if ! command -v parallel >/dev/null 2>&1; then + echo "Notice: GNU parallel not found; stopping before fuzz and later steps." >&2 + echo "Install it to enable fuzzing. Examples:" >&2 + echo " macOS: brew install parallel" >&2 + echo " Ubuntu: apt-get update && apt-get install -y parallel" >&2 + return 0 2>/dev/null || exit 0 +fi +for dir in op-challenger op-node op-service op-chain-ops; do + (cd "$dir" && just fuzz && cd ..) done +echo "==========Fuzz-golang done." -gotestsum --no-summary=skipped,output \ - --packages="$formatted_packages" \ - --format=short-verbose \ - --rerun-fails=2 +# go-tests-full +echo "==========Starting go-tests-full..." +export TEST_TIMEOUT=90m +make go-tests-ci +echo "==========Go-tests-full done." echo "Execution time: $((SECONDS / 60)) minute(s) and $((SECONDS % 60)) second(s)" \ No newline at end of file From b73c483dac364f9d98893c2e08bfd1c700126418 Mon Sep 17 00:00:00 2001 From: syntrust Date: Fri, 28 Nov 2025 10:42:14 +0800 Subject: [PATCH 06/14] fix src/dispute/AnchorStateRegistry.sol has changes in semver-lock.json but no version change --- .../contracts-bedrock/src/dispute/AnchorStateRegistry.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol b/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol index b70734d9028bc..e7ec69e70a1e3 100644 --- a/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol +++ b/packages/contracts-bedrock/src/dispute/AnchorStateRegistry.sol @@ -25,8 +25,8 @@ import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; /// be initialized with a more recent starting state which reduces the amount of required offchain computation. contract AnchorStateRegistry is ProxyAdminOwnedBase, Initializable, ReinitializableBase, ISemver { /// @notice Semantic version. - /// @custom:semver 3.5.0 - string public constant version = "3.5.0"; + /// @custom:semver 3.5.1 + string public constant version = "3.5.1"; /// @notice The dispute game finality delay in seconds. uint256 internal immutable DISPUTE_GAME_FINALITY_DELAY_SECONDS; From 4b273dcf8f5c332327ebc34ca088c64260c8db2d Mon Sep 17 00:00:00 2001 From: syntrust Date: Fri, 28 Nov 2025 14:27:29 +0800 Subject: [PATCH 07/14] fix semgrep --- packages/contracts-bedrock/snapshots/semver-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/snapshots/semver-lock.json b/packages/contracts-bedrock/snapshots/semver-lock.json index cec205a7bb911..f5d05386f5f2c 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -148,8 +148,8 @@ "sourceCodeHash": "0x03c160168986ffc8d26a90c37366e7ad6da03f49d83449e1f8b3de0f4b590f6f" }, "src/dispute/AnchorStateRegistry.sol:AnchorStateRegistry": { - "initCodeHash": "0xc9d6c547bf949e5e6d4b3d24dc12b8a5194efa6ffa9e1de00c748a94db517a67", - "sourceCodeHash": "0x16e5996752efad8e1c5e3811fb8febf44c3c5aecd9eddcc60e7093b8f3ec562b" + "initCodeHash": "0xcc402498941f71d8b99ed35389161d4f6577bb707b92beb94c2761a6bdf0619a", + "sourceCodeHash": "0xc08a269802974c2a38c8374435166fe9d83395737653489c3265ce95c58d09a6" }, "src/dispute/DelayedWETH.sol:DelayedWETH": { "initCodeHash": "0xa8f60e142108b33675a8f6b6979c73b96eea247884842d796f9f878904c0a906", From 4f5582f019993509a551cd27466b7290fbb3991b Mon Sep 17 00:00:00 2001 From: syntrust Date: Fri, 28 Nov 2025 16:53:50 +0800 Subject: [PATCH 08/14] fix go-lint: opcm.L2GenesisInput is missing fields DeploySoulGasToken, IsSoulBackedByNative --- op-chain-ops/interopgen/deploy.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/op-chain-ops/interopgen/deploy.go b/op-chain-ops/interopgen/deploy.go index f20db887567f0..8bb65c521bdc4 100644 --- a/op-chain-ops/interopgen/deploy.go +++ b/op-chain-ops/interopgen/deploy.go @@ -329,6 +329,8 @@ func GenesisL2(l2Host *script.Host, cfg *L2Config, deployment *L2Deployment, mul DeployCrossL2Inbox: multichainDepSet, EnableGovernance: cfg.EnableGovernance, FundDevAccounts: cfg.FundDevAccounts, + DeploySoulGasToken: false, + IsSoulBackedByNative: false, }); err != nil { return fmt.Errorf("failed L2 genesis: %w", err) } From 41464d1740a94be6a66c163b6403e1acac7bea4e Mon Sep 17 00:00:00 2001 From: syntrust Date: Fri, 28 Nov 2025 19:09:00 +0800 Subject: [PATCH 09/14] merge --- .mise-tasks/dev-test.sh | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/.mise-tasks/dev-test.sh b/.mise-tasks/dev-test.sh index 3f1607c004fd9..482f8d2af1d5a 100755 --- a/.mise-tasks/dev-test.sh +++ b/.mise-tasks/dev-test.sh @@ -55,12 +55,8 @@ for var in SEPOLIA_RPC_URL MAINNET_RPC_URL; do done echo "==========Checking environment done" -echo "==========Cleaning workspace..." -git clean -df -echo "==========Workspace cleaned." - # Updating dependencies in contracts lib -cd packages/contracts-bedrock +pushd packages/contracts-bedrock > /dev/null forge install # contracts-bedrock-tests & contracts-bedrock-tests-preimage-oracle @@ -82,15 +78,8 @@ done echo "==========Contracts-bedrock tests done." # contracts-bedrock-build -just clean -just forge-build --deny-warnings --skip test -forge script "scripts/deploy/DeployImplementations.s.sol" \ - --skip "/**/test/**" \ - --sig "idonotexist()" \ - --skip-simulation \ - 2>/dev/null || true -ls forge-artifacts/DeployImplementations.s.sol/DeployImplementations.json -cd ../.. +just clean && just forge-build --deny-warnings --skip test +popd > /dev/null # op-deployer embedded artifacts (required by op-deployer Go tests) echo "==========Packing op-deployer artifacts..." From 60a94bab2db45af3bc84cf3df3f101dcedb90c23 Mon Sep 17 00:00:00 2001 From: syntrust Date: Fri, 28 Nov 2025 19:10:50 +0800 Subject: [PATCH 10/14] update --- .mise-tasks/dev-check.sh | 164 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100755 .mise-tasks/dev-check.sh diff --git a/.mise-tasks/dev-check.sh b/.mise-tasks/dev-check.sh new file mode 100755 index 0000000000000..24dacac288f33 --- /dev/null +++ b/.mise-tasks/dev-check.sh @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +#MISE description="Developers' local tests" +#MISE alias="dc" + +set -e +# Inherit ERR trap in functions/subshells and catch pipeline failures +set -E -o pipefail +SECONDS=0 + +error_handler() { + local rc=$? + local cmd=${BASH_COMMAND:-unknown} + local where + where=$(caller 0 2>/dev/null || true) + halt "Command failed (exit $rc): ${cmd} | at: ${where}" +} + +trap 'error_handler' ERR + +# Graceful halt helper: print error, show total time, stop script without closing terminal +halt() { + echo "Error: $*" >&2 + echo "Execution time: ${SECONDS} seconds" + # remove ERR trap to avoid double messaging + trap - ERR + # If sourced use return, else exit with success code (0) to not signal failure + return 0 2>/dev/null || exit 0 +} + +# Environment verify +echo "==========Checking environment..." +# mise install + +if [ -z "${MISE_SHELL:-}" ]; then + if [ -n "${ZSH_VERSION:-}" ]; then + eval "$(mise activate zsh)" + elif [ -n "${BASH_VERSION:-}" ]; then + eval "$(mise activate bash)" + fi +fi + +echo "Current branch: $(git rev-parse --abbrev-ref HEAD)" >&2 +if [ -n "$(git status --porcelain)" ]; then + echo "WARN: Working tree not clean. Commit/stash changes first." >&2 + git status --porcelain + exit 1 +fi + +echo "==========Checking environment done" + +# Updating dependencies in contracts lib +pushd packages/contracts-bedrock > /dev/null +forge install + +# contracts-bedrock-build +just clean && just forge-build --deny-warnings --skip test + +# contracts-bedrock-checks +for cmd in \ + check-kontrol-summaries-unchanged \ + semgrep-test-validity-check \ + semgrep \ + semver-lock-no-build \ + semver-diff-check-no-build \ + validate-deploy-configs \ + lint \ + snapshots-check-no-build \ + interfaces-check-no-build \ + reinitializer-check-no-build \ + size-check \ + unused-imports-check-no-build \ + validate-spacers-no-build \ + opcm-upgrade-checks-no-build; do + git reset --hard + git clean -df + echo "==========Running just $cmd..." + just $cmd + echo "==========just $cmd done" + git status --porcelain + [ -z "$(git status --porcelain)" ] || exit 1 +done + +popd > /dev/null + +# diff-fetcher-forge-artifacts +echo "==========Running diff-fetcher-forge-artifacts..." +git reset --hard +git clean -df +pushd op-fetcher > /dev/null +just build-contracts +popd > /dev/null +diff -qr "packages/contracts-bedrock/forge-artifacts/FetchChainInfo.s.sol" \ + "op-fetcher/pkg/fetcher/fetch/forge-artifacts/FetchChainInfo.s.sol" + +if [ $? -ne 0 ]; then + echo "ERROR: The checked-in forge artifacts for FetchChainInfo.s.sol do not match the ci build." + echo "Please run 'cd op-fetcher && just build-contracts' and commit the changes." + exit 1 +fi + +echo "==========diff-fetcher-forge-artifacts check done" + +# diff-asterisc-bytecode +echo "==========Running diff-asterisc-bytecode..." +git reset --hard +git clean -df + +pushd packages/contracts-bedrock > /dev/null + +# Clone asterisc @ the pinned version to fetch remote `RISCV.sol` +ASTERISC_REV="v$(yq '.tools.asterisc' ../../mise.toml)" +REMOTE_ASTERISC_PATH="./src/vendor/asterisc/RISCV_Remote.sol" + +git -c advice.detachedHead=false clone https://github.com/ethereum-optimism/asterisc \ + -b "$ASTERISC_REV" \ + ./asterisc + +cp ./asterisc/rvsol/src/RISCV.sol "$REMOTE_ASTERISC_PATH" + +# Replace import paths +sed -i -e 's/@optimism\///' "$REMOTE_ASTERISC_PATH" +# Replace legacy interface paths +sed -i -e 's/src\/cannon\/interfaces\//interfaces\/cannon\//g' "$REMOTE_ASTERISC_PATH" +sed -i -e 's/src\/dispute\/interfaces\//interfaces\/dispute\//g' "$REMOTE_ASTERISC_PATH" +# Replace contract name +sed -i -e 's/contract RISCV/contract RISCV_Remote/' "$REMOTE_ASTERISC_PATH" + +# Install deps +forge install + +# Diff bytecode, with both contracts compiled in the local environment. +REMOTE_ASTERISC_CODE="$(forge inspect RISCV_Remote bytecode | tr -d '\n')" +LOCAL_ASTERISC_CODE="$(forge inspect RISCV bytecode | tr -d '\n')" + +if [ "$REMOTE_ASTERISC_CODE" != "$LOCAL_ASTERISC_CODE" ]; then + echo "Asterisc bytecode mismatch. Local version does not match remote. Diff:" + diff <(echo "$REMOTE_ASTERISC_CODE") <(echo "$LOCAL_ASTERISC_CODE") + popd > /dev/null + exit 1 +fi +rm -rf ./asterisc +popd > /dev/null +echo "==========diff-asterisc-bytecode check done" + +git reset --hard +git clean -df + +# semgrep-scan-local +echo "==========Running semgrep-scan-local..." +semgrep scan --timeout=100 --config .semgrep/rules/ --error . +echo "==========semgrep-scan-local done" + +# semgrep-test +echo "==========Running semgrep-test..." +semgrep scan --test --config .semgrep/rules/ .semgrep/tests/ +echo "==========semgrep-test done" + +# go-lint +echo "==========Running go-lint (make lint-go)..." +make lint-go +echo "==========go-lint done" + +echo "Execution time: $((SECONDS / 60)) minute(s) and $((SECONDS % 60)) second(s)" \ No newline at end of file From c08f4994c49560effa7a3b889b0153f969406a0a Mon Sep 17 00:00:00 2001 From: syntrust Date: Mon, 1 Dec 2025 10:34:02 +0800 Subject: [PATCH 11/14] for merge --- .mise-tasks/dev-test.sh | 179 +++++++++++++++++----------------------- 1 file changed, 75 insertions(+), 104 deletions(-) diff --git a/.mise-tasks/dev-test.sh b/.mise-tasks/dev-test.sh index 482f8d2af1d5a..0445739d61852 100755 --- a/.mise-tasks/dev-test.sh +++ b/.mise-tasks/dev-test.sh @@ -4,126 +4,97 @@ #MISE alias="dt" set -e -# Inherit ERR trap in functions/subshells and catch pipeline failures -set -E -o pipefail SECONDS=0 error_handler() { - local rc=$? - local cmd=${BASH_COMMAND:-unknown} - local where - where=$(caller 0 2>/dev/null || true) - halt "Command failed (exit $rc): ${cmd} | at: ${where}" -} - -trap 'error_handler' ERR - -# Graceful halt helper: print error, show total time, stop script without closing terminal -halt() { - echo "Error: $*" >&2 echo "Execution time: ${SECONDS} seconds" - # remove ERR trap to avoid double messaging - trap - ERR - # If sourced use return, else exit with success code (0) to not signal failure - return 0 2>/dev/null || exit 0 + exit 1 } -# Environment verify -echo "==========Checking environment..." -# mise install +trap 'error_handler' ERR -if [ -z "${MISE_SHELL:-}" ]; then - if [ -n "${ZSH_VERSION:-}" ]; then - eval "$(mise activate zsh)" - elif [ -n "${BASH_VERSION:-}" ]; then - eval "$(mise activate bash)" - fi -fi +# Environment tests -echo "Current branch: $(git rev-parse --abbrev-ref HEAD)" >&2 -if [ -n "$(git status --porcelain)" ]; then - echo "WARN: Working tree not clean. Commit/stash changes first." >&2 - git status --porcelain - exit 1 -fi +forge --version for var in SEPOLIA_RPC_URL MAINNET_RPC_URL; do if [ -z "${!var}" ]; then echo "Error: $var is not set." - return 0 2>/dev/null || exit 0 - fi -done -echo "==========Checking environment done" - -# Updating dependencies in contracts lib -pushd packages/contracts-bedrock > /dev/null -forge install - -# contracts-bedrock-tests & contracts-bedrock-tests-preimage-oracle -echo "==========Starting contracts-bedrock tests..." -just build-go-ffi -for _spec in \ - "-name '*.t.sol' -not -name 'PreimageOracle.t.sol'" \ - "-name 'PreimageOracle.t.sol'"; do - TEST_FILES=$(eval find test ${_spec}) - if [ -z "$TEST_FILES" ]; then - echo "No tests matched spec: ${_spec}; skipping" - continue + exit 1 fi - TEST_FILES=$(echo "$TEST_FILES" | sed 's|^test/||') - MATCH_PATH="./test/{$(echo "$TEST_FILES" | paste -sd "," -)}" - echo "Running forge test --match-path $MATCH_PATH" - forge test --match-path "$MATCH_PATH" done -echo "==========Contracts-bedrock tests done." - -# contracts-bedrock-build -just clean && just forge-build --deny-warnings --skip test -popd > /dev/null - -# op-deployer embedded artifacts (required by op-deployer Go tests) -echo "==========Packing op-deployer artifacts..." -just -f op-deployer/justfile copy-contract-artifacts -echo "==========Artifacts packed." - -# cannon-prestate-quick -echo "==========Starting cannon-prestates-quick..." -make cannon-prestates -echo "==========Cannon-prestates-quick done." - -# op-e2e-fuzz -echo "==========Starting op-e2e-fuzz..." -cd op-e2e && make fuzz && cd .. -echo "==========Op-e2e-fuzz done." - -# cannon-fuzz -echo "==========Starting cannon-fuzz..." -cd cannon && make fuzz && cd .. -echo "==========Cannon-fuzz done." - -# op-program-compat -echo "==========Starting op-program-compat..." -cd op-program && make verify-compat && cd .. -echo "==========Op-program-compat done." - -# fuzz-golang -echo "==========Starting fuzz-golang..." -if ! command -v parallel >/dev/null 2>&1; then - echo "Notice: GNU parallel not found; stopping before fuzz and later steps." >&2 - echo "Install it to enable fuzzing. Examples:" >&2 - echo " macOS: brew install parallel" >&2 - echo " Ubuntu: apt-get update && apt-get install -y parallel" >&2 - return 0 2>/dev/null || exit 0 + +STATUS=$(kurtosis engine status) +if echo "$STATUS" | grep -q "1.4.3"; then + echo "Kurtosis engine is running." +else + echo "The Kurtosis engine is not running, or there is a version mismatch." + exit 1 fi -for dir in op-challenger op-node op-service op-chain-ops; do - (cd "$dir" && just fuzz && cd ..) + +# Runs semgrep tests on the entire monorepo + +just semgrep +just semgrep-test + +# Solidity + +cd packages/contracts-bedrock +just lint-check +just pre-pr +just test + +# Go + +cd ../.. +make lint-go +make build-go + +cd op-program && make op-program-client && cd .. +cd cannon && make elf && cd .. +cd op-e2e && make pre-test && cd .. + +make devnet-allocs + +export ENABLE_KURTOSIS=true +export OP_E2E_CANNON_ENABLED="false" +export OP_E2E_SKIP_SLOW_TEST=true +export OP_E2E_USE_HTTP=true +export ENABLE_ANVIL=true + +# Note: not all packages are tested. +# For example the test `TestFinalization` in `op-alt-da` package fails even in upstream. +packages=( + op-batcher + op-chain-ops + op-node + op-proposer + op-challenger + op-dispute-mon + op-conductor + op-program + op-service + op-supervisor + op-deployer + op-e2e/system + op-e2e/e2eutils + op-e2e/opgeth + op-e2e/interop + op-e2e/actions + op-e2e/faultproofs + op-e2e/l2blob + op-e2e/inbox + op-e2e/sgt + packages/contracts-bedrock/scripts/checks +) +formatted_packages="" +for package in "${packages[@]}"; do + formatted_packages="$formatted_packages ./$package/..." done -echo "==========Fuzz-golang done." -# go-tests-full -echo "==========Starting go-tests-full..." -export TEST_TIMEOUT=90m -make go-tests-ci -echo "==========Go-tests-full done." +gotestsum --no-summary=skipped,output \ + --packages="$formatted_packages" \ + --format=short-verbose \ + --rerun-fails=2 echo "Execution time: $((SECONDS / 60)) minute(s) and $((SECONDS % 60)) second(s)" \ No newline at end of file From fa5d1ff9efb5a6e9badeadee9a0a0a205217cc43 Mon Sep 17 00:00:00 2001 From: syntrust Date: Mon, 1 Dec 2025 10:53:52 +0800 Subject: [PATCH 12/14] for merge --- op-chain-ops/interopgen/deploy.go | 35 ++++++++++++++++++------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/op-chain-ops/interopgen/deploy.go b/op-chain-ops/interopgen/deploy.go index 8bb65c521bdc4..e681ce3438359 100644 --- a/op-chain-ops/interopgen/deploy.go +++ b/op-chain-ops/interopgen/deploy.go @@ -18,6 +18,7 @@ import ( "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis/beacondeposit" "github.com/ethereum-optimism/optimism/op-chain-ops/script" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/manage" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm" "github.com/ethereum-optimism/optimism/op-service/eth" @@ -27,10 +28,6 @@ var ( // sysGenesisDeployer is used as tx.origin/msg.sender on system genesis script calls. // At the end we verify none of the deployed contracts persist (there may be temporary ones, to insert bytecode). sysGenesisDeployer = common.Address(crypto.Keccak256([]byte("System genesis deployer"))[12:]) - - // OptimismPortalInteropDevFlag is the feature bitmap that enables the OptimismPortalInterop contract. - OptimismPortalInteropDevFlag = common.Hash{31: 0x01} // 0x0000000000000000000000000000000000000000000000000000000000000001 - ) func Deploy(logger log.Logger, fa *foundry.ArtifactsFS, srcFS *foundry.SourceMapFS, cfg *WorldConfig) (*WorldDeployment, *WorldOutput, error) { @@ -157,7 +154,7 @@ func CreateL2(logger log.Logger, fa *foundry.ArtifactsFS, srcFS *foundry.SourceM } l2Host := script.NewHost(logger.New("role", "l2", "chain", l2Cfg.L2ChainID), fa, srcFS, l2Context) l2Host.SetEnvVar("OUTPUT_MODE", "none") // we don't use the cheatcode, but capture the state outside of EVM execution - l2Host.SetEnvVar("FORK", "holocene") // latest fork + l2Host.SetEnvVar("FORK", "jovian") // latest fork return l2Host } @@ -195,11 +192,15 @@ func DeploySuperchainToL1(l1Host *script.Host, opcmScripts *opcm.Scripts, superC ProofMaturityDelaySeconds: superCfg.Implementations.FaultProof.ProofMaturityDelaySeconds, DisputeGameFinalityDelaySeconds: superCfg.Implementations.FaultProof.DisputeGameFinalityDelaySeconds, MipsVersion: superCfg.Implementations.FaultProof.MipsVersion, - DevFeatureBitmap: OptimismPortalInteropDevFlag, + DevFeatureBitmap: deployer.OptimismPortalInteropDevFlag, + FaultGameV2MaxGameDepth: big.NewInt(73), + FaultGameV2SplitDepth: big.NewInt(30), + FaultGameV2ClockExtension: big.NewInt(10800), + FaultGameV2MaxClockDuration: big.NewInt(302400), SuperchainProxyAdmin: superDeployment.SuperchainProxyAdmin, SuperchainConfigProxy: superDeployment.SuperchainConfigProxy, ProtocolVersionsProxy: superDeployment.ProtocolVersionsProxy, - UpgradeController: superCfg.ProxyAdminOwner, + L1ProxyAdminOwner: superCfg.ProxyAdminOwner, Challenger: superCfg.Challenger, }) if err != nil { @@ -225,7 +226,12 @@ func DeployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme l1Host.SetTxOrigin(cfg.Deployer) - output, err := opcm.DeployOPChain(l1Host, opcm.DeployOPChainInput{ + deployOPChainScript, err := opcm.NewDeployOPChainScript(l1Host) + if err != nil { + return nil, fmt.Errorf("failed to load DeployOPChain script: %w", err) + } + + output, err := deployOPChainScript.Run(opcm.DeployOPChainInput{ OpChainProxyAdminOwner: superCfg.ProxyAdminOwner, SystemConfigOwner: cfg.SystemConfigOwner, Batcher: cfg.BatchSenderAddress, @@ -240,8 +246,8 @@ func DeployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme GasLimit: cfg.GasLimit, DisputeGameType: cfg.DisputeGameType, DisputeAbsolutePrestate: cfg.DisputeAbsolutePrestate, - DisputeMaxGameDepth: cfg.DisputeMaxGameDepth, - DisputeSplitDepth: cfg.DisputeSplitDepth, + DisputeMaxGameDepth: new(big.Int).SetUint64(cfg.DisputeMaxGameDepth), + DisputeSplitDepth: new(big.Int).SetUint64(cfg.DisputeSplitDepth), DisputeClockExtension: cfg.DisputeClockExtension, DisputeMaxClockDuration: cfg.DisputeMaxClockDuration, AllowCustomDisputeParameters: true, @@ -254,7 +260,7 @@ func DeployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme // Collect deployment addresses return &L2Deployment{ - L2OpchainDeployment: L2OpchainDeployment(output), + L2OpchainDeployment: NewL2OPChainDeploymentFromDeployOPChainOutput(output), }, nil } @@ -268,8 +274,7 @@ func MigrateInterop( l2Deployment := l2Deployments[l2ChainID] chainConfigs[i] = manage.OPChainConfig{ SystemConfigProxy: l2Deployment.SystemConfigProxy, - ProxyAdmin: superDeployment.ProxyAdmin, - AbsolutePrestate: l2Cfgs[l2ChainID].DisputeAbsolutePrestate, + CannonPrestate: l2Cfgs[l2ChainID].DisputeAbsolutePrestate, } } @@ -329,8 +334,8 @@ func GenesisL2(l2Host *script.Host, cfg *L2Config, deployment *L2Deployment, mul DeployCrossL2Inbox: multichainDepSet, EnableGovernance: cfg.EnableGovernance, FundDevAccounts: cfg.FundDevAccounts, - DeploySoulGasToken: false, - IsSoulBackedByNative: false, + DeploySoulGasToken: cfg.DeploySoulGasToken, + IsSoulBackedByNative: cfg.IsSoulBackedByNative, }); err != nil { return fmt.Errorf("failed L2 genesis: %w", err) } From 35d1405e567a9ca6112164b7823e38e8616d94de Mon Sep 17 00:00:00 2001 From: syntrust Date: Mon, 1 Dec 2025 11:09:18 +0800 Subject: [PATCH 13/14] for merge --- op-chain-ops/interopgen/deploy.go | 33 ++++++++++++------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/op-chain-ops/interopgen/deploy.go b/op-chain-ops/interopgen/deploy.go index e681ce3438359..f20db887567f0 100644 --- a/op-chain-ops/interopgen/deploy.go +++ b/op-chain-ops/interopgen/deploy.go @@ -18,7 +18,6 @@ import ( "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis/beacondeposit" "github.com/ethereum-optimism/optimism/op-chain-ops/script" - "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/manage" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm" "github.com/ethereum-optimism/optimism/op-service/eth" @@ -28,6 +27,10 @@ var ( // sysGenesisDeployer is used as tx.origin/msg.sender on system genesis script calls. // At the end we verify none of the deployed contracts persist (there may be temporary ones, to insert bytecode). sysGenesisDeployer = common.Address(crypto.Keccak256([]byte("System genesis deployer"))[12:]) + + // OptimismPortalInteropDevFlag is the feature bitmap that enables the OptimismPortalInterop contract. + OptimismPortalInteropDevFlag = common.Hash{31: 0x01} // 0x0000000000000000000000000000000000000000000000000000000000000001 + ) func Deploy(logger log.Logger, fa *foundry.ArtifactsFS, srcFS *foundry.SourceMapFS, cfg *WorldConfig) (*WorldDeployment, *WorldOutput, error) { @@ -154,7 +157,7 @@ func CreateL2(logger log.Logger, fa *foundry.ArtifactsFS, srcFS *foundry.SourceM } l2Host := script.NewHost(logger.New("role", "l2", "chain", l2Cfg.L2ChainID), fa, srcFS, l2Context) l2Host.SetEnvVar("OUTPUT_MODE", "none") // we don't use the cheatcode, but capture the state outside of EVM execution - l2Host.SetEnvVar("FORK", "jovian") // latest fork + l2Host.SetEnvVar("FORK", "holocene") // latest fork return l2Host } @@ -192,15 +195,11 @@ func DeploySuperchainToL1(l1Host *script.Host, opcmScripts *opcm.Scripts, superC ProofMaturityDelaySeconds: superCfg.Implementations.FaultProof.ProofMaturityDelaySeconds, DisputeGameFinalityDelaySeconds: superCfg.Implementations.FaultProof.DisputeGameFinalityDelaySeconds, MipsVersion: superCfg.Implementations.FaultProof.MipsVersion, - DevFeatureBitmap: deployer.OptimismPortalInteropDevFlag, - FaultGameV2MaxGameDepth: big.NewInt(73), - FaultGameV2SplitDepth: big.NewInt(30), - FaultGameV2ClockExtension: big.NewInt(10800), - FaultGameV2MaxClockDuration: big.NewInt(302400), + DevFeatureBitmap: OptimismPortalInteropDevFlag, SuperchainProxyAdmin: superDeployment.SuperchainProxyAdmin, SuperchainConfigProxy: superDeployment.SuperchainConfigProxy, ProtocolVersionsProxy: superDeployment.ProtocolVersionsProxy, - L1ProxyAdminOwner: superCfg.ProxyAdminOwner, + UpgradeController: superCfg.ProxyAdminOwner, Challenger: superCfg.Challenger, }) if err != nil { @@ -226,12 +225,7 @@ func DeployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme l1Host.SetTxOrigin(cfg.Deployer) - deployOPChainScript, err := opcm.NewDeployOPChainScript(l1Host) - if err != nil { - return nil, fmt.Errorf("failed to load DeployOPChain script: %w", err) - } - - output, err := deployOPChainScript.Run(opcm.DeployOPChainInput{ + output, err := opcm.DeployOPChain(l1Host, opcm.DeployOPChainInput{ OpChainProxyAdminOwner: superCfg.ProxyAdminOwner, SystemConfigOwner: cfg.SystemConfigOwner, Batcher: cfg.BatchSenderAddress, @@ -246,8 +240,8 @@ func DeployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme GasLimit: cfg.GasLimit, DisputeGameType: cfg.DisputeGameType, DisputeAbsolutePrestate: cfg.DisputeAbsolutePrestate, - DisputeMaxGameDepth: new(big.Int).SetUint64(cfg.DisputeMaxGameDepth), - DisputeSplitDepth: new(big.Int).SetUint64(cfg.DisputeSplitDepth), + DisputeMaxGameDepth: cfg.DisputeMaxGameDepth, + DisputeSplitDepth: cfg.DisputeSplitDepth, DisputeClockExtension: cfg.DisputeClockExtension, DisputeMaxClockDuration: cfg.DisputeMaxClockDuration, AllowCustomDisputeParameters: true, @@ -260,7 +254,7 @@ func DeployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme // Collect deployment addresses return &L2Deployment{ - L2OpchainDeployment: NewL2OPChainDeploymentFromDeployOPChainOutput(output), + L2OpchainDeployment: L2OpchainDeployment(output), }, nil } @@ -274,7 +268,8 @@ func MigrateInterop( l2Deployment := l2Deployments[l2ChainID] chainConfigs[i] = manage.OPChainConfig{ SystemConfigProxy: l2Deployment.SystemConfigProxy, - CannonPrestate: l2Cfgs[l2ChainID].DisputeAbsolutePrestate, + ProxyAdmin: superDeployment.ProxyAdmin, + AbsolutePrestate: l2Cfgs[l2ChainID].DisputeAbsolutePrestate, } } @@ -334,8 +329,6 @@ func GenesisL2(l2Host *script.Host, cfg *L2Config, deployment *L2Deployment, mul DeployCrossL2Inbox: multichainDepSet, EnableGovernance: cfg.EnableGovernance, FundDevAccounts: cfg.FundDevAccounts, - DeploySoulGasToken: cfg.DeploySoulGasToken, - IsSoulBackedByNative: cfg.IsSoulBackedByNative, }); err != nil { return fmt.Errorf("failed L2 genesis: %w", err) } From 86feb4c09212294656c74c12303e8c1b6f6d10bb Mon Sep 17 00:00:00 2001 From: syntrust Date: Mon, 1 Dec 2025 11:24:26 +0800 Subject: [PATCH 14/14] fix golint: opcm.L2GenesisInput is missing fields DeploySoulGasToken, IsSoulBackedByNative (exhaustruct) --- op-chain-ops/interopgen/deploy.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/op-chain-ops/interopgen/deploy.go b/op-chain-ops/interopgen/deploy.go index f20db887567f0..8bb65c521bdc4 100644 --- a/op-chain-ops/interopgen/deploy.go +++ b/op-chain-ops/interopgen/deploy.go @@ -329,6 +329,8 @@ func GenesisL2(l2Host *script.Host, cfg *L2Config, deployment *L2Deployment, mul DeployCrossL2Inbox: multichainDepSet, EnableGovernance: cfg.EnableGovernance, FundDevAccounts: cfg.FundDevAccounts, + DeploySoulGasToken: false, + IsSoulBackedByNative: false, }); err != nil { return fmt.Errorf("failed L2 genesis: %w", err) }