Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
396ee89
feat: integrate v2 implementations into opcm
stevennevins Sep 10, 2025
5ba2178
fix: skip v2 implementations if not deployed
stevennevins Sep 10, 2025
97b34ab
chore: bump semver version
stevennevins Sep 11, 2025
961e8cd
feat: conditionally set the v2 games based on feature flag
stevennevins Sep 15, 2025
9287013
feat: add override for setup to re-deploy opcm with feature flag
stevennevins Sep 15, 2025
ef29b42
test: improve test by deploying with the feature flag and asserting o…
stevennevins Sep 15, 2025
249ba99
test: add assertion that the deployment configuration on the dgf is c…
stevennevins Sep 15, 2025
e3584b7
chore: improve test name
stevennevins Sep 15, 2025
3022729
refactor: add helper function for feature toggled deployment of opcm
stevennevins Sep 15, 2025
78656fd
fix: bytecode size check failing
stevennevins Sep 16, 2025
3749303
chore: run forge fmt
stevennevins Sep 16, 2025
ddd42de
fix: address CI naming and semver bump
stevennevins Sep 16, 2025
015c220
fix: rename setup contract name to align with ci checks
stevennevins Sep 16, 2025
71374af
chore: comment out added fix
stevennevins Sep 17, 2025
d491a4b
fix: verify opcm
stevennevins Sep 17, 2025
2ebc280
fix: naming convention for test contracts
stevennevins Sep 17, 2025
67194d8
fix: move the updates for addGameType to the addGameType pr
stevennevins Sep 17, 2025
3b769e0
fix: proposer removed
stevennevins Sep 24, 2025
8734e9d
fix: rename function for clarity in VerifyOPCM script
stevennevins Sep 24, 2025
1fb7ca5
fix: add proper gameArgs for V2 dispute game registration and fix set…
stevennevins Sep 24, 2025
cef1fc3
test: add helper functin for creating game proxies
stevennevins Sep 25, 2025
503835f
test: refactor helper functions for test and remove impl from output …
stevennevins Sep 25, 2025
30ef2f3
test: test args correct on created proxy games
stevennevins Sep 25, 2025
bcbe98f
chore: remove unused helper for now
stevennevins Sep 25, 2025
78f65b6
fix: remove guard clause from local issue
stevennevins Sep 25, 2025
0a464cd
chore: bump semver
stevennevins Sep 25, 2025
ac768a5
chore: revert changes to ignore v2 implementations
stevennevins Sep 25, 2025
5fda712
fix: check bitmap and contract name for ref
stevennevins Sep 26, 2025
d688186
test: with feature toggle on
stevennevins Sep 26, 2025
5a585a3
chore: forge fmt
stevennevins Sep 26, 2025
3c4c529
Revert "chore: forge fmt"
stevennevins Sep 26, 2025
e6e7888
Revert "test: with feature toggle on"
stevennevins Sep 26, 2025
3bd2507
chore: forge fmt
stevennevins Sep 26, 2025
a253141
fix: test compiler restriction fix
stevennevins Sep 29, 2025
df9a767
Revert "fix: test compiler restriction fix"
stevennevins Sep 29, 2025
7adc269
fix: compiler bump
stevennevins Sep 29, 2025
05f8750
fix: typo
stevennevins Sep 29, 2025
113651b
test: add test for verify opcm with v2 dispute games deployed
stevennevins Sep 29, 2025
8e8d8a5
test: add skips for v1 tests if v2 deployed
stevennevins Sep 29, 2025
c2a4b66
fix: skip standard validator until its implemented
stevennevins Sep 30, 2025
35ffb7a
fix: skip addGameType until its implemented
stevennevins Sep 30, 2025
c9aebae
fix: skip updatePrestate until its implemented
stevennevins Sep 30, 2025
d2d8781
fix: remove diff in natspec
stevennevins Sep 30, 2025
ebb8185
chore: add TODO comments with issue tracking to skips
stevennevins Sep 30, 2025
8bf14ec
fix: bump semver
stevennevins Sep 30, 2025
997d107
chore: bump semver
stevennevins Sep 30, 2025
9f2d031
Merge branch 'develop' into snevin/issue-17257/creator-pattern-opcm-d…
mbaxter Oct 2, 2025
d8d2426
Fix silent merge conflicts with develop
mbaxter Oct 2, 2025
3301eea
Bump semver version
mbaxter Oct 6, 2025
5eb5f3b
Run semver-lock
mbaxter Oct 6, 2025
06a236d
Reintroduce OPContractsManager_Version_Test
mbaxter Oct 6, 2025
40f9160
Cleanup - revert comment change
mbaxter Oct 6, 2025
9df861a
Remove v2 contracts from DeployOutput
mbaxter Oct 6, 2025
61e4338
Remove unused imports
mbaxter Oct 6, 2025
7f7c1c7
Update DeployOPChain tests to run across feature flags (in progress)
mbaxter Oct 7, 2025
f355827
Update OPCM tests to work with FeatureFlags options
mbaxter Oct 7, 2025
3394856
Merge PermissionedDisputeGame tests, use feature flags
mbaxter Oct 7, 2025
f6cd910
Merge FaultDisputeGame tests, use feature flag in setup
mbaxter Oct 7, 2025
6032f6d
Remove redundant test
mbaxter Oct 7, 2025
4fe9e44
Fix test name
mbaxter Oct 7, 2025
c7ab682
Fix anchorRootNotFound test - pass in extra data
mbaxter Oct 7, 2025
d5385ce
Extend deployment test to check more fields
mbaxter Oct 7, 2025
7184c8b
Add guards around new setImplementation call
mbaxter Oct 7, 2025
f1f963f
Add new error to OPCM interface
mbaxter Oct 7, 2025
8168bd6
Merge branch 'develop' into snevin/issue-17257/creator-pattern-opcm-d…
mbaxter Oct 7, 2025
756ce03
Run semver-lock
mbaxter Oct 7, 2025
9be001b
Prefix var with underscore
mbaxter Oct 9, 2025
9d1323f
Remove unused imports
mbaxter Oct 9, 2025
0409e70
Regenerate snapshots
mbaxter Oct 9, 2025
97e6775
Pass opcm as an argument to _verifyOpcmContractRef
mbaxter Oct 9, 2025
94ef1c6
Reorganize verifyOPCM v2 skip logic
mbaxter Oct 9, 2025
cdb9d1f
Merge branch 'develop' into snevin/issue-17257/creator-pattern-opcm-d…
mbaxter Oct 9, 2025
ad552a0
Add TODO to fix acceptance test
mbaxter Oct 9, 2025
26ce735
Add function documentation for the new opcm param
mbaxter Oct 10, 2025
d68a798
Cleanup: add test assertion messages
mbaxter Oct 10, 2025
63409d3
Remove opcm param from runSingle script
mbaxter Oct 10, 2025
463a7d1
Tweak method documentation
mbaxter Oct 10, 2025
81cbdd2
Cleanup dead code
mbaxter Oct 10, 2025
a2e4cc6
Merge branch 'develop' into snevin/issue-17257/creator-pattern-opcm-d…
mbaxter Oct 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
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ import (
)

func TestMain(m *testing.M) {
presets.DoMain(m, presets.WithMinimal(), presets.WithDisputeGameV2())
// TODO(#17810): Use the new v2 dispute game flag via presets.WithDisputeGameV2()
//presets.DoMain(m, presets.WithMinimal(), presets.WithDisputeGameV2())
presets.DoMain(m, presets.WithMinimal())
}
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ interface IOPContractsManager {
address anchorStateRegistryImpl;
address delayedWETHImpl;
address mipsImpl;
address faultDisputeGameV2Impl;
address permissionedDisputeGameV2Impl;
}

/// @notice The input required to identify a chain for upgrading.
Expand Down Expand Up @@ -304,6 +306,8 @@ interface IOPContractsManager {

error PrestateRequired();

error InvalidDevFeatureAccess(bytes32 devFeature);

// -------- Methods --------

function __constructor__(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ contract DeployImplementations is Script {
disputeGameFactoryImpl: address(_output.disputeGameFactoryImpl),
anchorStateRegistryImpl: address(_output.anchorStateRegistryImpl),
delayedWETHImpl: address(_output.delayedWETHImpl),
mipsImpl: address(_output.mipsSingleton)
mipsImpl: address(_output.mipsSingleton),
faultDisputeGameV2Impl: address(_output.faultDisputeGameV2Impl),
permissionedDisputeGameV2Impl: address(_output.permissionedDisputeGameV2Impl)
});

deployOPCMBPImplsContainer(_input, _output, _blueprints, implementations);
Expand Down
34 changes: 28 additions & 6 deletions packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity 0.8.15;

import { Script } from "forge-std/Script.sol";

import { DevFeatures } from "src/libraries/DevFeatures.sol";
import { DeployUtils } from "scripts/libraries/DeployUtils.sol";
import { Solarray } from "scripts/libraries/Solarray.sol";
import { ChainAssertions } from "scripts/deploy/ChainAssertions.sol";
Expand All @@ -24,6 +25,7 @@ import { IL1ERC721Bridge } from "interfaces/L1/IL1ERC721Bridge.sol";
import { IL1StandardBridge } from "interfaces/L1/IL1StandardBridge.sol";
import { IOptimismMintableERC20Factory } from "interfaces/universal/IOptimismMintableERC20Factory.sol";
import { IETHLockbox } from "interfaces/L1/IETHLockbox.sol";
import { IOPContractsManager } from "../../interfaces/L1/IOPContractsManager.sol";

contract DeployOPChain is Script {
struct Output {
Expand Down Expand Up @@ -120,6 +122,13 @@ contract DeployOPChain is Script {
checkOutput(_input, output_);
}

// -------- Features --------

function isDevFeatureV2DisputeGamesEnabled(address _opcmAddr) internal view returns (bool) {
IOPContractsManager opcm = IOPContractsManager(_opcmAddr);
return DevFeatures.isDevFeatureEnabled(opcm.devFeatureBitmap(), DevFeatures.DEPLOY_V2_DISPUTE_GAMES);
}

// -------- Validations --------

function checkInput(Types.DeployOPChainInput memory _i) public view {
Expand Down Expand Up @@ -162,13 +171,19 @@ contract DeployOPChain is Script {
address(_o.optimismPortalProxy),
address(_o.disputeGameFactoryProxy),
address(_o.anchorStateRegistryProxy),
address(_o.permissionedDisputeGame),
address(_o.delayedWETHPermissionedGameProxy),
address(_o.ethLockboxProxy)
);
// TODO: Eventually switch from Permissioned to Permissionless. Add this address back in.
// address(_o.delayedWETHPermissionlessGameProxy)
// address(_o.faultDisputeGame()),

if (!isDevFeatureV2DisputeGamesEnabled(_i.opcm)) {
// Only check dispute game contracts if v2 dispute games are not enabled.
// When v2 contracts are enabled, we no longer deploy dispute games per chain
addrs2 = Solarray.extend(addrs2, Solarray.addresses(address(_o.permissionedDisputeGame)));

// TODO: Eventually switch from Permissioned to Permissionless. Add these addresses back in.
// address(_o.delayedWETHPermissionlessGameProxy)
// address(_o.faultDisputeGame()),
}

DeployUtils.assertValidContractAddresses(Solarray.extend(addrs1, addrs2));
_assertValidDeploy(_i, _o);
Expand All @@ -192,10 +207,17 @@ contract DeployOPChain is Script {
SuperchainConfig: address(0)
});

ChainAssertions.checkAnchorStateRegistryProxy(_o.anchorStateRegistryProxy, true);
// Check dispute games
address expectedPDGImpl = address(_o.permissionedDisputeGame);
if (isDevFeatureV2DisputeGamesEnabled(_i.opcm)) {
// With v2 game contracts enabled, we use the predeployed pdg implementation
expectedPDGImpl = IOPContractsManager(_i.opcm).implementations().permissionedDisputeGameV2Impl;
}
ChainAssertions.checkDisputeGameFactory(
_o.disputeGameFactoryProxy, _i.opChainProxyAdminOwner, address(_o.permissionedDisputeGame), true
_o.disputeGameFactoryProxy, _i.opChainProxyAdminOwner, expectedPDGImpl, true
);

ChainAssertions.checkAnchorStateRegistryProxy(_o.anchorStateRegistryProxy, true);
ChainAssertions.checkL1CrossDomainMessenger(_o.l1CrossDomainMessengerProxy, vm, true);
ChainAssertions.checkOptimismPortal2({
_contracts: proxies,
Expand Down
49 changes: 46 additions & 3 deletions packages/contracts-bedrock/scripts/deploy/VerifyOPCM.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { LibString } from "@solady/utils/LibString.sol";
import { Process } from "scripts/libraries/Process.sol";
import { Config } from "scripts/libraries/Config.sol";
import { Bytes } from "src/libraries/Bytes.sol";
import { DevFeatures } from "src/libraries/DevFeatures.sol";

// Interfaces
import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol";
Expand Down Expand Up @@ -113,6 +114,8 @@ contract VerifyOPCM is Script {
fieldNameOverrides["optimismPortalInteropImpl"] = "OptimismPortalInterop";
fieldNameOverrides["mipsImpl"] = "MIPS64";
fieldNameOverrides["ethLockboxImpl"] = "ETHLockbox";
fieldNameOverrides["faultDisputeGameV2Impl"] = "FaultDisputeGameV2";
fieldNameOverrides["permissionedDisputeGameV2Impl"] = "PermissionedDisputeGameV2";
fieldNameOverrides["permissionlessDisputeGame1"] = "FaultDisputeGame";
fieldNameOverrides["permissionlessDisputeGame2"] = "FaultDisputeGame";
fieldNameOverrides["permissionedDisputeGame1"] = "PermissionedDisputeGame";
Expand Down Expand Up @@ -177,8 +180,14 @@ contract VerifyOPCM is Script {
/// @param _addr Address of the contract to verify.
/// @param _skipConstructorVerification Whether to skip constructor verification.
function runSingle(string memory _name, address _addr, bool _skipConstructorVerification) public {
// This function is used as part of the release checklist to verify new contracts.
// Rather than requiring an opcm input parameter, just pass in an empty reference
// as we really only need this for features that are in development.
IOPContractsManager emptyOpcm = IOPContractsManager(address(0));
_verifyOpcmContractRef(
OpcmContractRef({ field: _name, name: _name, addr: _addr, blueprint: false }), _skipConstructorVerification
emptyOpcm,
OpcmContractRef({ field: _name, name: _name, addr: _addr, blueprint: false }),
_skipConstructorVerification
);
}

Expand Down Expand Up @@ -213,7 +222,7 @@ contract VerifyOPCM is Script {
// Verify each reference.
bool success = true;
for (uint256 i = 0; i < refs.length; i++) {
success = _verifyOpcmContractRef(refs[i], _skipConstructorVerification) && success;
success = _verifyOpcmContractRef(opcm, refs[i], _skipConstructorVerification) && success;
}

// Final Result
Expand Down Expand Up @@ -381,16 +390,20 @@ contract VerifyOPCM is Script {
}

/// @notice Verifies a single OPCM contract reference (implementation or bytecode).
/// @param _opcm The OPCM contract that contains the target contract reference.
/// @param _target The target contract reference to verify.
/// @param _skipConstructorVerification Whether to skip constructor verification.
/// @return True if the contract reference is verified, false otherwise.
function _verifyOpcmContractRef(
IOPContractsManager _opcm,
OpcmContractRef memory _target,
bool _skipConstructorVerification
)
internal
returns (bool)
{
bool success = true;

console.log();
console.log(string.concat("Checking Contract: ", _target.field));
console.log(string.concat(" Type: ", _target.blueprint ? "Blueprint" : "Implementation"));
Expand All @@ -401,6 +414,20 @@ contract VerifyOPCM is Script {
string memory artifactPath = _buildArtifactPath(_target.name);
console.log(string.concat(" Expected Runtime Artifact: ", artifactPath));

// Check if this is a V2 dispute game that should be skipped
if (_isV2DisputeGameImplementation(_target.name)) {
if (!_isV2DisputeGamesEnabled(_opcm)) {
if (_target.addr == address(0)) {
console.log("[SKIP] V2 dispute game not deployed (feature disabled)");
return true; // Consider this "verified" when feature is off
} else {
console.log("[FAIL] ERROR: V2 dispute game deployed but feature disabled");
success = false;
}
}
// If feature is enabled, continue with normal verification
}

// Load artifact information (bytecode, immutable refs) for detailed comparison
ArtifactInfo memory artifact = _loadArtifactInfo(artifactPath);

Expand Down Expand Up @@ -442,7 +469,7 @@ contract VerifyOPCM is Script {
}

// Perform detailed bytecode comparison.
bool success = _compareBytecode(actualCode, expectedCode, _target.name, artifact, !_target.blueprint);
success = _compareBytecode(actualCode, expectedCode, _target.name, artifact, !_target.blueprint) && success;

// If requested and this is not a blueprint, we also need to check the creation code.
if (!_target.blueprint && !_skipConstructorVerification) {
Expand Down Expand Up @@ -497,6 +524,22 @@ contract VerifyOPCM is Script {
return success;
}

/// @notice Checks if V2 dispute games feature is enabled in the dev feature bitmap.
/// @param _opcm The OPContractsManager to check.
/// @return True if V2 dispute games are enabled.
function _isV2DisputeGamesEnabled(IOPContractsManager _opcm) internal view returns (bool) {
bytes32 bitmap = _opcm.devFeatureBitmap();
return DevFeatures.isDevFeatureEnabled(bitmap, DevFeatures.DEPLOY_V2_DISPUTE_GAMES);
}

/// @notice Checks if a contract is a V2 dispute game implementation.
/// @param _contractName The name to check.
/// @return True if this is a V2 dispute game.
function _isV2DisputeGameImplementation(string memory _contractName) internal pure returns (bool) {
return LibString.eq(_contractName, "FaultDisputeGameV2")
|| LibString.eq(_contractName, "PermissionedDisputeGameV2");
}

/// @notice Verifies that the immutable variables in the OPCM contract match expected values.
/// @param _opcm The OPCM contract to verify immutable variables for.
/// @return True if all immutable variables are verified, false otherwise.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,16 @@
"internalType": "address",
"name": "mipsImpl",
"type": "address"
},
{
"internalType": "address",
"name": "faultDisputeGameV2Impl",
"type": "address"
},
{
"internalType": "address",
"name": "permissionedDisputeGameV2Impl",
"type": "address"
}
],
"internalType": "struct OPContractsManager.Implementations",
Expand Down Expand Up @@ -991,6 +1001,17 @@
"name": "InvalidChainId",
"type": "error"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "devFeature",
"type": "bytes32"
}
],
"name": "InvalidDevFeatureAccess",
"type": "error"
},
{
"inputs": [],
"name": "InvalidGameConfigs",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,16 @@
"internalType": "address",
"name": "mipsImpl",
"type": "address"
},
{
"internalType": "address",
"name": "faultDisputeGameV2Impl",
"type": "address"
},
{
"internalType": "address",
"name": "permissionedDisputeGameV2Impl",
"type": "address"
}
],
"internalType": "struct OPContractsManager.Implementations",
Expand Down Expand Up @@ -340,6 +350,16 @@
"internalType": "address",
"name": "mipsImpl",
"type": "address"
},
{
"internalType": "address",
"name": "faultDisputeGameV2Impl",
"type": "address"
},
{
"internalType": "address",
"name": "permissionedDisputeGameV2Impl",
"type": "address"
}
],
"internalType": "struct OPContractsManager.Implementations",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,16 @@
"internalType": "address",
"name": "mipsImpl",
"type": "address"
},
{
"internalType": "address",
"name": "faultDisputeGameV2Impl",
"type": "address"
},
{
"internalType": "address",
"name": "permissionedDisputeGameV2Impl",
"type": "address"
}
],
"internalType": "struct OPContractsManager.Implementations",
Expand Down Expand Up @@ -518,6 +528,17 @@
"name": "InvalidChainId",
"type": "error"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "devFeature",
"type": "bytes32"
}
],
"name": "InvalidDevFeatureAccess",
"type": "error"
},
{
"inputs": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,16 @@
"internalType": "address",
"name": "mipsImpl",
"type": "address"
},
{
"internalType": "address",
"name": "faultDisputeGameV2Impl",
"type": "address"
},
{
"internalType": "address",
"name": "permissionedDisputeGameV2Impl",
"type": "address"
}
],
"internalType": "struct OPContractsManager.Implementations",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,16 @@
"internalType": "address",
"name": "mipsImpl",
"type": "address"
},
{
"internalType": "address",
"name": "faultDisputeGameV2Impl",
"type": "address"
},
{
"internalType": "address",
"name": "permissionedDisputeGameV2Impl",
"type": "address"
}
],
"internalType": "struct OPContractsManager.Implementations",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,16 @@
"internalType": "address",
"name": "mipsImpl",
"type": "address"
},
{
"internalType": "address",
"name": "faultDisputeGameV2Impl",
"type": "address"
},
{
"internalType": "address",
"name": "permissionedDisputeGameV2Impl",
"type": "address"
}
],
"internalType": "struct OPContractsManager.Implementations",
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts-bedrock/snapshots/semver-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
"sourceCodeHash": "0xfca613b5d055ffc4c3cbccb0773ddb9030abedc1aa6508c9e2e7727cc0cd617b"
},
"src/L1/OPContractsManager.sol:OPContractsManager": {
"initCodeHash": "0x9f9a3738b05cae6597ea9a5c5747f7dbd3a5328b05a319955054fbd8b1aaa791",
"sourceCodeHash": "0x154c764083f353e2a56337c0dd5cbcd6f2e12c21966cd0580c7a0f96c4e147dd"
"initCodeHash": "0x42721744f90fa46ee680fecc69da2e5caf7fdd8093c2a7f3b33958e574a15579",
"sourceCodeHash": "0x3eab23f3f034eec77afb620a122e51fded9214b5ed6a4c5663e0174714ae0f5e"
},
"src/L1/OPContractsManagerStandardValidator.sol:OPContractsManagerStandardValidator": {
"initCodeHash": "0x57d6a6729d887ead009d518e8f17fa0d26bfc97b8efe1494ab4ef8dbb000d109",
Expand Down
Loading