Skip to content

feat: migration path C zkdg#21518

Draft
ashitakah wants to merge 44 commits into
ethereum-optimism:developfrom
defi-wonderland:feat/migration-path-szkdg
Draft

feat: migration path C zkdg#21518
ashitakah wants to merge 44 commits into
ethereum-optimism:developfrom
defi-wonderland:feat/migration-path-szkdg

Conversation

@ashitakah

Copy link
Copy Markdown
Contributor

Summary

Adds the interop migration path (Path C): OPContractsManagerV2.setInteropDisputeGames(...), which re-points the shared dispute games of an already-interop set to a new respected super game in a single transaction covering all chains. Current use case is the post-migration transition from shared fault proofs to a shared super ZKDisputeGame. Reuses the migrator machinery; the standard upgrade() path can't be used since it re-inits per chain and would clobber the shared AnchorStateRegistry / ETHLockbox. Paths A and B (isolated chains) need no contract changes and go through upgrade(), since ZK is already in isSuperGame.

Changes

Contracts — src/L1/opcm/OPContractsManagerMigrator.sol

Area Change
setInteropDisputeGames New function. Validates the chain set, re-initializes the shared AnchorStateRegistry with the new respected game type + anchor root, then sets the dispute game impls on the shared DisputeGameFactory via the existing _getGameImpl / _makeGameArgs. Enabled configs register, disabled configs clear. No new infra deployed, per-chain portals untouched.
Guards Gates on OPTIMISM_PORTAL_INTEROP + ZK_DISPUTE_GAME dev features (TODO to drop the ZK gate once finalized; the function is generic across super games). Requires startingRespectedGameType ∈ isSuperGame. Runtime check that all portals resolve to the same shared ASR.
Errors OPContractsManagerMigrator_ZKDisputeGameNotEnabled, OPContractsManagerMigrator_NotSharedInteropSet.

Contracts — src/L1/opcm/OPContractsManagerV2.sol

Area Change
setInteropDisputeGames Thin entry point, _onlyDelegateCall + delegatecall to the migrator (mirrors migrate()). Transitional, removed once interop is native in OPCM.
Version 7.1.227.1.23.

Interfaces

File Change
interfaces/L1/opcm/IOPContractsManagerMigrator.sol Added setInteropDisputeGames + the two errors.
interfaces/L1/opcm/IOPContractsManagerV2.sol Added setInteropDisputeGames.

Forge script — scripts/deploy/SetInteropDisputeGames.s.sol

Area Change
Script New Input / Output / run mirroring InteropMigration.s.sol. Etches DummyCaller to simulate the governance delegatecall. checkOutput asserts on chain: all portals share the DGF, respected game type updated, and each input config applied (enabled registered, disabled cleared).

Op-deployer (Go)

File Change
op-deployer/pkg/deployer/manage/set_interop_dispute_games.go SetInteropDisputeGames runner, encodeZKGameArgs (5-field ZK config), SetInteropDisputeGamesCLI. Validates all address flags with IsHexAddress. Default clears only SUPER_CANNON_KONA (9, the permissionless slot ZK replaces) and keeps SUPER_PERMISSIONED_CANNON (5) as the permissioned liveness backup.
op-deployer/pkg/deployer/manage/flags.go New flags (--system-config-proxy-addresses, --source-game-types, --zk-verifier-address, --zk-max-challenge-duration, --zk-max-prove-duration) + set-interop-dispute-games command.

Tests

File Change
test/L1/opcm/OPContractsManagerV2.t.sol test_setInteropDisputeGames_succeeds (migrate to interop with SPDG + kona, swap to ZK, asserts SPDG kept, ZK registered + respected, kona cleared), _notDelegateCalled_reverts, _notSharedInteropSet_reverts.
op-deployer/pkg/deployer/manage/set_interop_dispute_games_test.go TestEncodeZKGameArgs (encoder round-trip + validation), TestSetInteropDisputeGames (forked-Sepolia e2e: deploy with ZK impl, migrate to interop, swap, asserts the end shape on chain).

Snapshots

File Change
snapshots/semver-lock.json, snapshots/abi/* Regenerated for the OPCMv2 version bump and the new setInteropDisputeGames ABI.

Notes

  • Target post-swap shape is SUPER_PERMISSIONED_CANNON (permissioned backup) + ZK_DISPUTE_GAME (permissionless, respected), mirroring today's permissioned + permissionless super shape.
  • Paths A and B (single-chain SPDG/SFDG → ZK) and full game-lifecycle / finalization tests are handled in the integration tests PR.
  • No on-chain validator covers the post-swap state yet (StandardValidator super-mode is gated on SUPER_ROOT_GAMES_MIGRATION; MigrationValidator requires the cannon super types). Tracked with the ZKDG-NOSHAPE TODO.
  • op-challenger ZK actor needs interop super-root handling + the invalid-parent challenge fix (op-challenger: should challenge ZK child games built on locally-invalid parent games #21445) before the games can be defended in production.

Closes #20757

0xarktos and others added 30 commits May 21, 2026 13:38
ashitakah and others added 14 commits June 8, 2026 23:16
* feat: merge with dev

* feat: merge with dev

* fix: merge with dev

* fix: merge with dev

* feat: opcm super zkdg

* feat: opcm super zkdg

* fix: enforce l2ChainId=0 in StandardValidator ZK game args

ZK_DISPUTE_GAME is a super game; the chain ID is embedded in per-game
extraData via the super-root proof, not in the immutable factory args
(makeGameArgs sets chainId=0 for isSuperGame() types). The previous
check args.l2ChainId == _l2ChainID always failed; drop the unused
_l2ChainID parameter and assert args.l2ChainId == 0.

* refactor: rename ZK_DISPUTE_GAME → SUPER_ZK_DISPUTE_GAME

Aligns the game type naming with the existing super-game convention
(CANNON→SUPER_CANNON, ASTERISC_KONA→SUPER_ASTERISC_KONA) since game type
10 uses super-root semantics (l2ChainId=0 in factory args). Also fixes
the StandardValidator ZKDG-60 check that always failed for super games
(args.l2ChainId == _l2ChainID → args.l2ChainId == 0) and removes the
now-unused _l2ChainID parameter.

Solidity:
- GameTypes.ZK_DISPUTE_GAME → SUPER_ZK_DISPUTE_GAME
- IOPContractsManagerUtils.ZKDisputeGameConfig → SuperZKDisputeGameConfig
- DevFeatures.ZK_DISPUTE_GAME flag, zkDisputeGameImpl field, and
  LibGameArgs.ZKGameArgs struct are intentionally kept (internal names).

Go (op-deployer):
- embedded.GameTypeZKDisputeGame → GameTypeSuperZKDisputeGame
- embedded.ZKDisputeGameConfig → SuperZKDisputeGameConfig
- state.VMTypeZK ("ZK") → VMTypeSuperZK ("SUPER_ZK")
- state.ZKDisputeGameParams → SuperZKDisputeGameParams
- state.ErrZKDisputeGameMissingParams → ErrSuperZKDisputeGameMissingParams
- JSON fields zkDisputeGame/zkDisputeGameConfig → superZkDisputeGame/
  superZkDisputeGameConfig

Note: the SuperZKDisputeGame.sol contract rename itself lands in a
companion PR; this PR keeps zkDisputeGameImpl field and devfeatures.
ZKDisputeGameFlag untouched until that merges.

* feat: rename and validator

* fix: revert renaming

* fix: merge with develop

* fix: coments

* chore: bump superchain-registry to match develop

* feat: remove l2 chain

* fix: complete l2ChainId removal

* fix: complete l2ChainId removal

* fix: lint and build
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[SuperZKDG Milestone 4] Migration paths

3 participants