diff --git a/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol b/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol index eb043e832f203..697f1a30b55d3 100644 --- a/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol +++ b/packages/contracts-bedrock/interfaces/L1/IOPContractsManager.sol @@ -333,6 +333,23 @@ interface IOPContractsManager { view returns (string memory); + function validateWithOverrides( + IOPContractsManagerStandardValidator.ValidationInputDev calldata _input, + bool _allowFailure, + IOPContractsManagerStandardValidator.ValidationOverrides calldata _overrides + ) + external + view + returns (string memory); + + function validate( + IOPContractsManagerStandardValidator.ValidationInputDev calldata _input, + bool _allowFailure + ) + external + view + returns (string memory); + function deploy(DeployInput calldata _input) external returns (DeployOutput memory); /// @notice Upgrades the implementation of all proxies in the specified chains diff --git a/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol b/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol index 6585609f63883..6820c1b3acdd7 100644 --- a/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol +++ b/packages/contracts-bedrock/interfaces/L1/IOPContractsManagerStandardValidator.sol @@ -30,6 +30,15 @@ interface IOPContractsManagerStandardValidator { address proposer; } + struct ValidationInputDev { + IProxyAdmin proxyAdmin; + ISystemConfig sysCfg; + bytes32 cannonPrestate; + bytes32 cannonKonaPrestate; + uint256 l2ChainID; + address proposer; + } + struct ValidationOverrides { address l1PAOMultisig; address challenger; @@ -66,8 +75,20 @@ interface IOPContractsManagerStandardValidator { external view returns (string memory); + function validate(ValidationInput memory _input, bool _allowFailure) external view returns (string memory); + function validateWithOverrides( + ValidationInputDev memory _input, + bool _allowFailure, + ValidationOverrides memory _overrides + ) + external + view + returns (string memory); + + function validate(ValidationInputDev memory _input, bool _allowFailure) external view returns (string memory); + function __constructor__( Implementations memory _implementations, ISuperchainConfig _superchainConfig, diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json index 07595f49b8731..cd167bfb29e42 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json +++ b/packages/contracts-bedrock/snapshots/abi/OPContractsManager.json @@ -865,6 +865,62 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IProxyAdmin", + "name": "proxyAdmin", + "type": "address" + }, + { + "internalType": "contract ISystemConfig", + "name": "sysCfg", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "cannonPrestate", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "cannonKonaPrestate", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "l2ChainID", + "type": "uint256" + }, + { + "internalType": "address", + "name": "proposer", + "type": "address" + } + ], + "internalType": "struct OPContractsManagerStandardValidator.ValidationInputDev", + "name": "_input", + "type": "tuple" + }, + { + "internalType": "bool", + "name": "_allowFailure", + "type": "bool" + } + ], + "name": "validate", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -933,6 +989,79 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IProxyAdmin", + "name": "proxyAdmin", + "type": "address" + }, + { + "internalType": "contract ISystemConfig", + "name": "sysCfg", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "cannonPrestate", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "cannonKonaPrestate", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "l2ChainID", + "type": "uint256" + }, + { + "internalType": "address", + "name": "proposer", + "type": "address" + } + ], + "internalType": "struct OPContractsManagerStandardValidator.ValidationInputDev", + "name": "_input", + "type": "tuple" + }, + { + "internalType": "bool", + "name": "_allowFailure", + "type": "bool" + }, + { + "components": [ + { + "internalType": "address", + "name": "l1PAOMultisig", + "type": "address" + }, + { + "internalType": "address", + "name": "challenger", + "type": "address" + } + ], + "internalType": "struct OPContractsManagerStandardValidator.ValidationOverrides", + "name": "_overrides", + "type": "tuple" + } + ], + "name": "validateWithOverrides", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "version", diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerStandardValidator.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerStandardValidator.json index 3c21aacf89f8e..45c3b77e14589 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerStandardValidator.json +++ b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerStandardValidator.json @@ -382,6 +382,62 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IProxyAdmin", + "name": "proxyAdmin", + "type": "address" + }, + { + "internalType": "contract ISystemConfig", + "name": "sysCfg", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "cannonPrestate", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "cannonKonaPrestate", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "l2ChainID", + "type": "uint256" + }, + { + "internalType": "address", + "name": "proposer", + "type": "address" + } + ], + "internalType": "struct OPContractsManagerStandardValidator.ValidationInputDev", + "name": "_input", + "type": "tuple" + }, + { + "internalType": "bool", + "name": "_allowFailure", + "type": "bool" + } + ], + "name": "validate", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -450,6 +506,79 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IProxyAdmin", + "name": "proxyAdmin", + "type": "address" + }, + { + "internalType": "contract ISystemConfig", + "name": "sysCfg", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "cannonPrestate", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "cannonKonaPrestate", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "l2ChainID", + "type": "uint256" + }, + { + "internalType": "address", + "name": "proposer", + "type": "address" + } + ], + "internalType": "struct OPContractsManagerStandardValidator.ValidationInputDev", + "name": "_input", + "type": "tuple" + }, + { + "internalType": "bool", + "name": "_allowFailure", + "type": "bool" + }, + { + "components": [ + { + "internalType": "address", + "name": "l1PAOMultisig", + "type": "address" + }, + { + "internalType": "address", + "name": "challenger", + "type": "address" + } + ], + "internalType": "struct OPContractsManagerStandardValidator.ValidationOverrides", + "name": "_overrides", + "type": "tuple" + } + ], + "name": "validateWithOverrides", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "version", diff --git a/packages/contracts-bedrock/snapshots/semver-lock.json b/packages/contracts-bedrock/snapshots/semver-lock.json index a140631af7aab..b29bd4dd5fb5c 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -20,12 +20,12 @@ "sourceCodeHash": "0xfca613b5d055ffc4c3cbccb0773ddb9030abedc1aa6508c9e2e7727cc0cd617b" }, "src/L1/OPContractsManager.sol:OPContractsManager": { - "initCodeHash": "0x3c4a51c5845588b4d19570cc1bae0099c15f43051d66b41c28d27d3c918a2e72", - "sourceCodeHash": "0x4a011105a9c1019cef7f35aa8f6eef131c29c54078e1df57d2089a43f7d81f3a" + "initCodeHash": "0x103775faed94486265eb7f68a9ae83b3055aa34f635c3a03938f1e57917eebca", + "sourceCodeHash": "0x7b627075f2ee890e526e038e47b9cc8f70f93e971f2cbebaed6ef93631bc4b00" }, "src/L1/OPContractsManagerStandardValidator.sol:OPContractsManagerStandardValidator": { - "initCodeHash": "0xe0e6d892d38211dc0165ca00dc1e8aa558eb7a1240560260e23262f066f6be72", - "sourceCodeHash": "0xe40f42a857c9b0905db4c91d61073d9dd572a6bc49921c5ee6e875cf54dc9407" + "initCodeHash": "0xa5113ddf9f502b9ebf1b2d487f24caed21a5946c271ba69cb381f1a8cad27fcb", + "sourceCodeHash": "0x5a28bd2252503efdd3622aca1a3bbf253e6e757b4008520950c3a2177acb6fa0" }, "src/L1/OptimismPortal2.sol:OptimismPortal2": { "initCodeHash": "0x5bf576ea7f566e402a997204988471fc9b971410aa9dff8fe810b10baf6b7456", diff --git a/packages/contracts-bedrock/src/L1/OPContractsManager.sol b/packages/contracts-bedrock/src/L1/OPContractsManager.sol index a32e877334450..3247cb9c3ebb3 100644 --- a/packages/contracts-bedrock/src/L1/OPContractsManager.sol +++ b/packages/contracts-bedrock/src/L1/OPContractsManager.sol @@ -2118,9 +2118,9 @@ contract OPContractsManager is ISemver { // -------- Constants and Variables -------- - /// @custom:semver 5.1.0 + /// @custom:semver 5.2.0 function version() public pure virtual returns (string memory) { - return "5.1.0"; + return "5.2.0"; } OPContractsManagerGameTypeAdder public immutable opcmGameTypeAdder; @@ -2241,6 +2241,32 @@ contract OPContractsManager is ISemver { return opcmStandardValidator.validateWithOverrides(_input, _allowFailure, _overrides); } + /// @notice Validates the configuration of the L1 contracts. + function validate( + OPContractsManagerStandardValidator.ValidationInputDev memory _input, + bool _allowFailure + ) + public + view + returns (string memory) + { + return opcmStandardValidator.validate(_input, _allowFailure); + } + + /// @notice Validates the configuration of the L1 contracts. + /// @notice Supports overrides of certain storage values denoted in the ValidationOverrides struct. + function validateWithOverrides( + OPContractsManagerStandardValidator.ValidationInputDev memory _input, + bool _allowFailure, + OPContractsManagerStandardValidator.ValidationOverrides memory _overrides + ) + public + view + returns (string memory) + { + return opcmStandardValidator.validateWithOverrides(_input, _allowFailure, _overrides); + } + /// @notice Deploys a new OP Stack chain. /// @param _input The deploy input parameters for the deployment. /// @return The deploy output values of the deployment. diff --git a/packages/contracts-bedrock/src/L1/OPContractsManagerStandardValidator.sol b/packages/contracts-bedrock/src/L1/OPContractsManagerStandardValidator.sol index 12ab3a53d3704..63c762308ec77 100644 --- a/packages/contracts-bedrock/src/L1/OPContractsManagerStandardValidator.sol +++ b/packages/contracts-bedrock/src/L1/OPContractsManagerStandardValidator.sol @@ -40,8 +40,8 @@ import { IBigStepper } from "interfaces/dispute/IBigStepper.sol"; /// before and after an upgrade. contract OPContractsManagerStandardValidator is ISemver { /// @notice The semantic version of the OPContractsManagerStandardValidator contract. - /// @custom:semver 2.0.0 - string public constant version = "2.0.0"; + /// @custom:semver 2.1.0 + string public constant version = "2.1.0"; /// @notice The SuperchainConfig contract. ISuperchainConfig public superchainConfig; @@ -121,6 +121,16 @@ contract OPContractsManagerStandardValidator is ISemver { address proposer; } + /// @notice Struct containing the input parameters for the validation process when dev features are enabled. + struct ValidationInputDev { + IProxyAdmin proxyAdmin; + ISystemConfig sysCfg; + bytes32 cannonPrestate; + bytes32 cannonKonaPrestate; + uint256 l2ChainID; + address proposer; + } + /// @notice Struct containing override parameters for the validation process. struct ValidationOverrides { address l1PAOMultisig; @@ -550,22 +560,21 @@ contract OPContractsManagerStandardValidator is ISemver { function assertValidPermissionlessDisputeGame( string memory _errors, ISystemConfig _sysCfg, + GameType _gameType, bytes32 _absolutePrestate, uint256 _l2ChainID, IProxyAdmin _admin, - ValidationOverrides memory _overrides + ValidationOverrides memory _overrides, + string memory _errorPrefix ) internal view returns (string memory) { - GameType gameType = GameTypes.CANNON; - string memory errorPrefix = "PLDG"; - // Collect game implementation parameters DisputeGameImplementation memory gameImpl; bool failedToGetImpl = false; - (gameImpl, _errors, failedToGetImpl) = getGameImplementation(_errors, gameType, _sysCfg, errorPrefix); + (gameImpl, _errors, failedToGetImpl) = getGameImplementation(_errors, _gameType, _sysCfg, _errorPrefix); if (failedToGetImpl) { // Return early on failure to avoid trying to validate an invalid dispute game return _errors; @@ -579,9 +588,9 @@ contract OPContractsManagerStandardValidator is ISemver { absolutePrestate: _absolutePrestate, l2ChainID: _l2ChainID, admin: _admin, - gameType: gameType, + gameType: _gameType, overrides: _overrides, - errorPrefix: errorPrefix + errorPrefix: _errorPrefix }) ); @@ -818,6 +827,12 @@ contract OPContractsManagerStandardValidator is ISemver { /// @notice Validates the configuration of the L1 contracts. function validate(ValidationInput memory _input, bool _allowFailure) external view returns (string memory) { + ValidationInputDev memory devInput = _toValidationInputDev(_input); + return validate(devInput, _allowFailure); + } + + /// @notice Validates the configuration of the L1 contracts when dev features are enabled. + function validate(ValidationInputDev memory _input, bool _allowFailure) public view returns (string memory) { return validateWithOverrides( _input, _allowFailure, ValidationOverrides({ l1PAOMultisig: address(0), challenger: address(0) }) ); @@ -833,6 +848,21 @@ contract OPContractsManagerStandardValidator is ISemver { public view returns (string memory) + { + ValidationInputDev memory devInput = _toValidationInputDev(_input); + return validateWithOverrides(devInput, _allowFailure, _overrides); + } + + /// @notice Validates the configuration of the L1 contracts. Supports overrides of certain storage values denoted in + /// the ValidationOverrides struct. Includes validation fields relevant for dev features. + function validateWithOverrides( + ValidationInputDev memory _input, + bool _allowFailure, + ValidationOverrides memory _overrides + ) + public + view + returns (string memory) { string memory _errors = ""; @@ -848,15 +878,35 @@ contract OPContractsManagerStandardValidator is ISemver { _errors = assertValidPermissionedDisputeGame( _errors, _input.sysCfg, - _input.absolutePrestate, + _input.cannonPrestate, _input.l2ChainID, _input.proxyAdmin, _input.proposer, _overrides ); _errors = assertValidPermissionlessDisputeGame( - _errors, _input.sysCfg, _input.absolutePrestate, _input.l2ChainID, _input.proxyAdmin, _overrides + _errors, + _input.sysCfg, + GameTypes.CANNON, + _input.cannonPrestate, + _input.l2ChainID, + _input.proxyAdmin, + _overrides, + "PLDG" ); + if (DevFeatures.isDevFeatureEnabled(devFeatureBitmap, DevFeatures.CANNON_KONA)) { + _errors = assertValidPermissionlessDisputeGame( + _errors, + _input.sysCfg, + GameTypes.CANNON_KONA, + _input.cannonKonaPrestate, + _input.l2ChainID, + _input.proxyAdmin, + _overrides, + "CKDG" + ); + } + _errors = assertValidETHLockbox(_errors, _input.sysCfg, _input.proxyAdmin); string memory overridesString = getOverridesString(_overrides); @@ -881,6 +931,18 @@ contract OPContractsManagerStandardValidator is ISemver { return finalErrors; } + /// @notice Transforms current ValidationInput structs into the dev feature format. + function _toValidationInputDev(ValidationInput memory _input) internal pure returns (ValidationInputDev memory) { + return ValidationInputDev({ + proxyAdmin: _input.proxyAdmin, + sysCfg: _input.sysCfg, + cannonPrestate: _input.absolutePrestate, + cannonKonaPrestate: bytes32(0), + l2ChainID: _input.l2ChainID, + proposer: _input.proposer + }); + } + function assertGameArgsLength( string memory _errors, bytes memory _gameArgsBytes, diff --git a/packages/contracts-bedrock/test/L1/OPContractsManagerStandardValidator.t.sol b/packages/contracts-bedrock/test/L1/OPContractsManagerStandardValidator.t.sol index a4ba64b52cee2..94e943ac52e8f 100644 --- a/packages/contracts-bedrock/test/L1/OPContractsManagerStandardValidator.t.sol +++ b/packages/contracts-bedrock/test/L1/OPContractsManagerStandardValidator.t.sol @@ -92,7 +92,10 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest, Di uint256 l2ChainId; /// @notice The absolute prestate, either from config or dummy value if fork test. - Claim absolutePrestate; + Claim cannonPrestate; + + /// @notice The CannonKona absolute prestate. + Claim cannonKonaPrestate = Claim.wrap(bytes32(keccak256("cannonKona"))); /// @notice The proposer role set on the PermissionedDisputeGame instance. address proposer; @@ -100,11 +103,11 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest, Di /// @notice The DisputeGameFactory instance. IDisputeGameFactory dgf; - /// @notice The PermissionedDisputeGame instance. - IPermissionedDisputeGame pdg; + /// @notice The PermissionedDisputeGame implementation. + IPermissionedDisputeGame pdgImpl; - /// @notice The FaultDisputeGame instance. - IFaultDisputeGame fdg; + /// @notice The FaultDisputeGame implementation. + IFaultDisputeGame fdgImpl; /// @notice The PreimageOracle instance. IPreimageOracle preimageOracle; @@ -123,7 +126,7 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest, Di dgf = IDisputeGameFactory(artifacts.mustGetAddress("DisputeGameFactoryProxy")); // Load the PermissionedDisputeGame once, we'll need it later. - pdg = IPermissionedDisputeGame(artifacts.mustGetAddress("PermissionedDisputeGame")); + pdgImpl = IPermissionedDisputeGame(artifacts.mustGetAddress("PermissionedDisputeGame")); // Load the PreimageOracle once, we'll need it later. preimageOracle = IPreimageOracle(artifacts.mustGetAddress("PreimageOracle")); @@ -134,7 +137,7 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest, Di // address in fork tests but it's fine. if (isForkTest()) { l2ChainId = uint256(uint160(address(artifacts.mustGetAddress("L2ChainId")))); - absolutePrestate = Claim.wrap(bytes32(keccak256("absolutePrestate"))); + cannonPrestate = Claim.wrap(bytes32(keccak256("absolutePrestate"))); proposer = address(123); vm.mockCall( @@ -142,12 +145,18 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest, Di abi.encodeCall(IProxyAdmin.getProxyImplementation, (address(l1OptimismMintableERC20Factory))), abi.encode(opcm.opcmStandardValidator().optimismMintableERC20FactoryImpl()) ); - vm.mockCall( - address(pdg), - abi.encodeCall(IPermissionedDisputeGame.challenger, ()), - abi.encode(opcm.opcmStandardValidator().challenger()) - ); - vm.mockCall(address(pdg), abi.encodeCall(IPermissionedDisputeGame.proposer, ()), abi.encode(proposer)); + + if (!isDevFeatureEnabled(DevFeatures.DEPLOY_V2_DISPUTE_GAMES)) { + vm.mockCall( + address(pdgImpl), + abi.encodeCall(IPermissionedDisputeGame.challenger, ()), + abi.encode(opcm.opcmStandardValidator().challenger()) + ); + vm.mockCall( + address(pdgImpl), abi.encodeCall(IPermissionedDisputeGame.proposer, ()), abi.encode(proposer) + ); + } + vm.mockCall( address(proxyAdmin), abi.encodeCall(IProxyAdmin.owner, ()), @@ -167,7 +176,7 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest, Di ); } else { l2ChainId = deployInput.l2ChainId; - absolutePrestate = deployInput.disputeAbsolutePrestate; + cannonPrestate = deployInput.disputeAbsolutePrestate; proposer = deployInput.roles.proposer; } @@ -178,32 +187,51 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest, Di if (isForkTest()) { // Load the FaultDisputeGame once, we'll need it later. - fdg = IFaultDisputeGame(artifacts.mustGetAddress("FaultDisputeGame")); + fdgImpl = IFaultDisputeGame(artifacts.mustGetAddress("FaultDisputeGame")); + + // Add the FaultDisputeGame to the DisputeGameFactory. + vm.prank(disputeGameFactory.owner()); + disputeGameFactory.setImplementation(GameTypes.CANNON, IDisputeGame(address(fdgImpl))); } else { // Deploy a permissionless FaultDisputeGame. - IOPContractsManager.AddGameOutput memory output = addGameType(GameTypes.CANNON); - fdg = output.faultDisputeGame; - } + IOPContractsManager.AddGameOutput memory output = addGameType(GameTypes.CANNON, cannonPrestate); + fdgImpl = output.faultDisputeGame; - // Add the FaultDisputeGame to the DisputeGameFactory. - vm.prank(disputeGameFactory.owner()); - disputeGameFactory.setImplementation(GameTypes.CANNON, IDisputeGame(address(fdg))); + // Deploy cannon-kona + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + addGameType(GameTypes.CANNON_KONA, cannonKonaPrestate); + } + } } /// @notice Runs the OPContractsManagerStandardValidator.validate function. /// @param _allowFailure Whether to allow failure. /// @return The error message(s) from the validate function. function _validate(bool _allowFailure) internal view returns (string memory) { - return opcm.validate( - IOPContractsManagerStandardValidator.ValidationInput({ - proxyAdmin: proxyAdmin, - sysCfg: systemConfig, - absolutePrestate: absolutePrestate.raw(), - l2ChainID: l2ChainId, - proposer: proposer - }), - _allowFailure - ); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + return opcm.validate( + IOPContractsManagerStandardValidator.ValidationInputDev({ + proxyAdmin: proxyAdmin, + sysCfg: systemConfig, + cannonPrestate: cannonPrestate.raw(), + cannonKonaPrestate: cannonKonaPrestate.raw(), + l2ChainID: l2ChainId, + proposer: proposer + }), + _allowFailure + ); + } else { + return opcm.validate( + IOPContractsManagerStandardValidator.ValidationInput({ + proxyAdmin: proxyAdmin, + sysCfg: systemConfig, + absolutePrestate: cannonPrestate.raw(), + l2ChainID: l2ChainId, + proposer: proposer + }), + _allowFailure + ); + } } /// @notice Runs the OPContractsManagerStandardValidator.validateWithOverrides function. @@ -217,17 +245,32 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest, Di view returns (string memory) { - return opcm.validateWithOverrides( - IOPContractsManagerStandardValidator.ValidationInput({ - proxyAdmin: proxyAdmin, - sysCfg: systemConfig, - absolutePrestate: absolutePrestate.raw(), - l2ChainID: l2ChainId, - proposer: proposer - }), - _allowFailure, - _overrides - ); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + return opcm.validateWithOverrides( + IOPContractsManagerStandardValidator.ValidationInputDev({ + proxyAdmin: proxyAdmin, + sysCfg: systemConfig, + cannonPrestate: cannonPrestate.raw(), + cannonKonaPrestate: cannonKonaPrestate.raw(), + l2ChainID: l2ChainId, + proposer: proposer + }), + _allowFailure, + _overrides + ); + } else { + return opcm.validateWithOverrides( + IOPContractsManagerStandardValidator.ValidationInput({ + proxyAdmin: proxyAdmin, + sysCfg: systemConfig, + absolutePrestate: cannonPrestate.raw(), + l2ChainID: l2ChainId, + proposer: proposer + }), + _allowFailure, + _overrides + ); + } } function _defaultValidationOverrides() @@ -241,8 +284,14 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest, Di }); } - function addGameType(GameType _gameType) internal returns (IOPContractsManager.AddGameOutput memory) { - IOPContractsManager.AddGameInput memory input = newGameInputFactory(_gameType); + function addGameType( + GameType _gameType, + Claim _prestate + ) + internal + returns (IOPContractsManager.AddGameOutput memory) + { + IOPContractsManager.AddGameInput memory input = newGameInputFactory(_gameType, _prestate); return addGameType(input); } @@ -265,14 +314,21 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest, Di return addGameOutAll[0]; } - function newGameInputFactory(GameType _gameType) internal view returns (IOPContractsManager.AddGameInput memory) { + function newGameInputFactory( + GameType _gameType, + Claim _prestate + ) + internal + view + returns (IOPContractsManager.AddGameInput memory) + { return IOPContractsManager.AddGameInput({ saltMixer: "hello", systemConfig: systemConfig, proxyAdmin: proxyAdmin, delayedWETH: delayedWeth, disputeGameType: _gameType, - disputeAbsolutePrestate: absolutePrestate, + disputeAbsolutePrestate: _prestate, disputeMaxGameDepth: 73, disputeSplitDepth: 30, disputeClockExtension: Duration.wrap(10800), @@ -312,10 +368,17 @@ contract OPContractsManagerStandardValidator_GeneralOverride_Test is OPContracts IOPContractsManagerStandardValidator.ValidationOverrides memory overrides = _defaultValidationOverrides(); overrides.l1PAOMultisig = address(0xace); overrides.challenger = address(0xbad); - assertEq( - "OVERRIDES-L1PAOMULTISIG,OVERRIDES-CHALLENGER,PROXYA-10,DF-30,PDDG-DWETH-30,PDDG-130,PLDG-DWETH-30", - _validateWithOverrides(true, overrides) - ); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq( + "OVERRIDES-L1PAOMULTISIG,OVERRIDES-CHALLENGER,PROXYA-10,DF-30,PDDG-DWETH-30,PDDG-130,PLDG-DWETH-30,CKDG-DWETH-30", + _validateWithOverrides(true, overrides) + ); + } else { + assertEq( + "OVERRIDES-L1PAOMULTISIG,OVERRIDES-CHALLENGER,PROXYA-10,DF-30,PDDG-DWETH-30,PDDG-130,PLDG-DWETH-30", + _validateWithOverrides(true, overrides) + ); + } } /// @notice Tests that the validate function (with the L1PAOMultisig and Challenger overridden) @@ -346,11 +409,20 @@ contract OPContractsManagerStandardValidator_GeneralOverride_Test is OPContracts IOPContractsManagerStandardValidator.ValidationOverrides memory overrides = IOPContractsManagerStandardValidator .ValidationOverrides({ l1PAOMultisig: address(0xbad), challenger: address(0xc0ffee) }); - vm.expectRevert( - bytes( - "OPContractsManagerStandardValidator: OVERRIDES-L1PAOMULTISIG,OVERRIDES-CHALLENGER,PROXYA-10,DF-30,PDDG-DWETH-30,PDDG-130,PLDG-DWETH-30" - ) - ); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + vm.expectRevert( + bytes( + "OPContractsManagerStandardValidator: OVERRIDES-L1PAOMULTISIG,OVERRIDES-CHALLENGER,PROXYA-10,DF-30,PDDG-DWETH-30,PDDG-130,PLDG-DWETH-30,CKDG-DWETH-30" + ) + ); + } else { + vm.expectRevert( + bytes( + "OPContractsManagerStandardValidator: OVERRIDES-L1PAOMULTISIG,OVERRIDES-CHALLENGER,PROXYA-10,DF-30,PDDG-DWETH-30,PDDG-130,PLDG-DWETH-30" + ) + ); + } + _validateWithOverrides(false, overrides); } } @@ -380,7 +452,11 @@ contract OPContractsManagerStandardValidator_ProxyAdmin_Test is OPContractsManag vm.mockCall( address(delayedWeth), abi.encodeCall(IProxyAdminOwnedBase.proxyAdminOwner, ()), abi.encode(address(0xbad)) ); - assertEq("PROXYA-10,PDDG-DWETH-30,PLDG-DWETH-30", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PROXYA-10,PDDG-DWETH-30,PLDG-DWETH-30,CKDG-DWETH-30", _validate(true)); + } else { + assertEq("PROXYA-10,PDDG-DWETH-30,PLDG-DWETH-30", _validate(true)); + } } /// @notice Tests that the validate function successfully returns the right overrides error @@ -403,10 +479,17 @@ contract OPContractsManagerStandardValidator_ProxyAdmin_Test is OPContractsManag function test_validateOverrideL1PAOMultisig_invalidProxyAdminOwner_succeeds() public view { IOPContractsManagerStandardValidator.ValidationOverrides memory overrides = _defaultValidationOverrides(); overrides.l1PAOMultisig = address(0xbad); - assertEq( - "OVERRIDES-L1PAOMULTISIG,PROXYA-10,DF-30,PDDG-DWETH-30,PLDG-DWETH-30", - _validateWithOverrides(true, overrides) - ); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq( + "OVERRIDES-L1PAOMULTISIG,PROXYA-10,DF-30,PDDG-DWETH-30,PLDG-DWETH-30,CKDG-DWETH-30", + _validateWithOverrides(true, overrides) + ); + } else { + assertEq( + "OVERRIDES-L1PAOMULTISIG,PROXYA-10,DF-30,PDDG-DWETH-30,PLDG-DWETH-30", + _validateWithOverrides(true, overrides) + ); + } } } @@ -916,7 +999,7 @@ contract OPContractsManagerStandardValidator_PermissionedDisputeGame_Test is /// @notice Tests that the validate function successfully returns the right error when the /// PermissionedDisputeGame version is invalid. function test_validate_permissionedDisputeGameInvalidVersion_succeeds() public { - vm.mockCall(address(pdg), abi.encodeCall(ISemver.version, ()), abi.encode("0.0.0")); + vm.mockCall(address(pdgImpl), abi.encodeCall(ISemver.version, ()), abi.encode("0.0.0")); assertEq("PDDG-20", _validate(true)); } @@ -926,7 +1009,7 @@ contract OPContractsManagerStandardValidator_PermissionedDisputeGame_Test is // For v2 game contracts, we don't store the game type anywhere other than the DGF gameImpls and gameArgs maps // So, there's not really an obvious way to return an invalid gameType skipIfDevFeatureEnabled(DevFeatures.DEPLOY_V2_DISPUTE_GAMES); - vm.mockCall(address(pdg), abi.encodeCall(IDisputeGame.gameType, ()), abi.encode(GameTypes.CANNON)); + vm.mockCall(address(pdgImpl), abi.encodeCall(IDisputeGame.gameType, ()), abi.encode(GameTypes.CANNON)); assertEq("PDDG-30", _validate(true)); } @@ -1015,7 +1098,11 @@ contract OPContractsManagerStandardValidator_PermissionedDisputeGame_Test is /// PermissionedDisputeGame VM's state version is invalid. function test_validate_permissionedDisputeGameInvalidVMStateVersion_succeeds() public { vm.mockCall(address(mips), abi.encodeCall(IMIPS64.stateVersion, ()), abi.encode(6)); - assertEq("PDDG-VM-30,PLDG-VM-30", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PDDG-VM-30,PLDG-VM-30,CKDG-VM-30", _validate(true)); + } else { + assertEq("PDDG-VM-30,PLDG-VM-30", _validate(true)); + } } /// @notice Tests that the validate function successfully returns the right error when the @@ -1029,7 +1116,7 @@ contract OPContractsManagerStandardValidator_PermissionedDisputeGame_Test is /// @notice Tests that the validate function successfully returns the right error when the /// PermissionedDisputeGame L2 Sequence Number is invalid. function test_validate_permissionedDisputeGameInvalidL2SequenceNumber_succeeds() public { - vm.mockCall(address(pdg), abi.encodeCall(IDisputeGame.l2SequenceNumber, ()), abi.encode(123)); + vm.mockCall(address(pdgImpl), abi.encodeCall(IDisputeGame.l2SequenceNumber, ()), abi.encode(123)); assertEq("PDDG-70", _validate(true)); } @@ -1037,7 +1124,9 @@ contract OPContractsManagerStandardValidator_PermissionedDisputeGame_Test is /// PermissionedDisputeGame clockExtension is invalid. function test_validate_permissionedDisputeGameInvalidClockExtension_succeeds() public { vm.mockCall( - address(pdg), abi.encodeCall(IPermissionedDisputeGame.clockExtension, ()), abi.encode(Duration.wrap(1000)) + address(pdgImpl), + abi.encodeCall(IPermissionedDisputeGame.clockExtension, ()), + abi.encode(Duration.wrap(1000)) ); assertEq("PDDG-80", _validate(true)); } @@ -1045,14 +1134,14 @@ contract OPContractsManagerStandardValidator_PermissionedDisputeGame_Test is /// @notice Tests that the validate function successfully returns the right error when the /// PermissionedDisputeGame splitDepth is invalid. function test_validate_permissionedDisputeGameInvalidSplitDepth_succeeds() public { - vm.mockCall(address(pdg), abi.encodeCall(IPermissionedDisputeGame.splitDepth, ()), abi.encode(20)); + vm.mockCall(address(pdgImpl), abi.encodeCall(IPermissionedDisputeGame.splitDepth, ()), abi.encode(20)); assertEq("PDDG-90", _validate(true)); } /// @notice Tests that the validate function successfully returns the right error when the /// PermissionedDisputeGame maxGameDepth is invalid. function test_validate_permissionedDisputeGameInvalidMaxGameDepth_succeeds() public { - vm.mockCall(address(pdg), abi.encodeCall(IPermissionedDisputeGame.maxGameDepth, ()), abi.encode(50)); + vm.mockCall(address(pdgImpl), abi.encodeCall(IPermissionedDisputeGame.maxGameDepth, ()), abi.encode(50)); assertEq("PDDG-100", _validate(true)); } @@ -1060,7 +1149,9 @@ contract OPContractsManagerStandardValidator_PermissionedDisputeGame_Test is /// PermissionedDisputeGame maxClockDuration is invalid. function test_validate_permissionedDisputeGameInvalidMaxClockDuration_succeeds() public { vm.mockCall( - address(pdg), abi.encodeCall(IPermissionedDisputeGame.maxClockDuration, ()), abi.encode(Duration.wrap(1000)) + address(pdgImpl), + abi.encodeCall(IPermissionedDisputeGame.maxClockDuration, ()), + abi.encode(Duration.wrap(1000)) ); assertEq("PDDG-110", _validate(true)); } @@ -1073,7 +1164,11 @@ contract OPContractsManagerStandardValidator_PermissionedDisputeGame_Test is abi.encodeCall(IAnchorStateRegistry.getAnchorRoot, ()), abi.encode(bytes32(0), 1) ); - assertEq("PDDG-120,PLDG-120", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PDDG-120,PLDG-120,CKDG-120", _validate(true)); + } else { + assertEq("PDDG-120,PLDG-120", _validate(true)); + } } /// @notice Tests that the validate function successfully returns the right error when the @@ -1122,7 +1217,11 @@ contract OPContractsManagerStandardValidator_AnchorStateRegistry_Test is /// AnchorStateRegistry version is invalid. function test_validate_anchorStateRegistryInvalidVersion_succeeds() public { vm.mockCall(address(anchorStateRegistry), abi.encodeCall(ISemver.version, ()), abi.encode("0.0.1")); - assertEq("PDDG-ANCHORP-10,PLDG-ANCHORP-10", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PDDG-ANCHORP-10,PLDG-ANCHORP-10,CKDG-ANCHORP-10", _validate(true)); + } else { + assertEq("PDDG-ANCHORP-10,PLDG-ANCHORP-10", _validate(true)); + } } /// @notice Tests that the validate function successfully returns the right error when the @@ -1133,7 +1232,11 @@ contract OPContractsManagerStandardValidator_AnchorStateRegistry_Test is abi.encodeCall(IProxyAdmin.getProxyImplementation, (address(anchorStateRegistry))), abi.encode(address(0xbad)) ); - assertEq("PDDG-ANCHORP-20,PLDG-ANCHORP-20", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PDDG-ANCHORP-20,PLDG-ANCHORP-20,CKDG-ANCHORP-20", _validate(true)); + } else { + assertEq("PDDG-ANCHORP-20,PLDG-ANCHORP-20", _validate(true)); + } } /// @notice Tests that the validate function successfully returns the right error when the @@ -1144,7 +1247,11 @@ contract OPContractsManagerStandardValidator_AnchorStateRegistry_Test is address(badDisputeGameFactoryReturner), abi.encodeCall(IAnchorStateRegistry.disputeGameFactory, ()) ); - assertEq("PDDG-ANCHORP-30,PLDG-ANCHORP-30", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PDDG-ANCHORP-30,PLDG-ANCHORP-30,CKDG-ANCHORP-30", _validate(true)); + } else { + assertEq("PDDG-ANCHORP-30,PLDG-ANCHORP-30", _validate(true)); + } } /// @notice Tests that the validate function successfully returns the right error when the @@ -1155,7 +1262,11 @@ contract OPContractsManagerStandardValidator_AnchorStateRegistry_Test is abi.encodeCall(IAnchorStateRegistry.systemConfig, ()), abi.encode(address(0xbad)) ); - assertEq("PDDG-ANCHORP-40,PLDG-ANCHORP-40", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PDDG-ANCHORP-40,PLDG-ANCHORP-40,CKDG-ANCHORP-40", _validate(true)); + } else { + assertEq("PDDG-ANCHORP-40,PLDG-ANCHORP-40", _validate(true)); + } } /// @notice Tests that the validate function successfully returns the right error when the @@ -1166,7 +1277,11 @@ contract OPContractsManagerStandardValidator_AnchorStateRegistry_Test is abi.encodeCall(IProxyAdminOwnedBase.proxyAdmin, ()), abi.encode(address(0xbad)) ); - assertEq("PDDG-ANCHORP-50,PLDG-ANCHORP-50", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PDDG-ANCHORP-50,PLDG-ANCHORP-50,CKDG-ANCHORP-50", _validate(true)); + } else { + assertEq("PDDG-ANCHORP-50,PLDG-ANCHORP-50", _validate(true)); + } } /// @notice Tests that the validate function successfully returns the right error when the @@ -1175,7 +1290,11 @@ contract OPContractsManagerStandardValidator_AnchorStateRegistry_Test is vm.mockCall( address(anchorStateRegistry), abi.encodeCall(IAnchorStateRegistry.retirementTimestamp, ()), abi.encode(0) ); - assertEq("PDDG-ANCHORP-60,PLDG-ANCHORP-60", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PDDG-ANCHORP-60,PLDG-ANCHORP-60,CKDG-ANCHORP-60", _validate(true)); + } else { + assertEq("PDDG-ANCHORP-60,PLDG-ANCHORP-60", _validate(true)); + } } } @@ -1193,7 +1312,11 @@ contract OPContractsManagerStandardValidator_DelayedWETH_Test is OPContractsMana if (isForkTest()) { assertEq("PDDG-DWETH-10", _validate(true)); } else { - assertEq("PLDG-DWETH-10", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PLDG-DWETH-10,CKDG-DWETH-10", _validate(true)); + } else { + assertEq("PLDG-DWETH-10", _validate(true)); + } } } @@ -1209,7 +1332,11 @@ contract OPContractsManagerStandardValidator_DelayedWETH_Test is OPContractsMana if (isForkTest()) { assertEq("PDDG-DWETH-20", _validate(true)); } else { - assertEq("PLDG-DWETH-20", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PLDG-DWETH-20,CKDG-DWETH-20", _validate(true)); + } else { + assertEq("PLDG-DWETH-20", _validate(true)); + } } } @@ -1223,7 +1350,11 @@ contract OPContractsManagerStandardValidator_DelayedWETH_Test is OPContractsMana if (isForkTest()) { assertEq("PDDG-DWETH-30", _validate(true)); } else { - assertEq("PLDG-DWETH-30", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PLDG-DWETH-30,CKDG-DWETH-30", _validate(true)); + } else { + assertEq("PLDG-DWETH-30", _validate(true)); + } } } @@ -1235,7 +1366,11 @@ contract OPContractsManagerStandardValidator_DelayedWETH_Test is OPContractsMana if (isForkTest()) { assertEq("PDDG-DWETH-40", _validate(true)); } else { - assertEq("PLDG-DWETH-40", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PLDG-DWETH-40,CKDG-DWETH-40", _validate(true)); + } else { + assertEq("PLDG-DWETH-40", _validate(true)); + } } } @@ -1247,7 +1382,11 @@ contract OPContractsManagerStandardValidator_DelayedWETH_Test is OPContractsMana if (isForkTest()) { assertEq("PDDG-DWETH-50", _validate(true)); } else { - assertEq("PLDG-DWETH-50", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PLDG-DWETH-50,CKDG-DWETH-50", _validate(true)); + } else { + assertEq("PLDG-DWETH-50", _validate(true)); + } } } @@ -1261,7 +1400,11 @@ contract OPContractsManagerStandardValidator_DelayedWETH_Test is OPContractsMana if (isForkTest()) { assertEq("PDDG-DWETH-60", _validate(true)); } else { - assertEq("PLDG-DWETH-60", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PLDG-DWETH-60,CKDG-DWETH-60", _validate(true)); + } else { + assertEq("PLDG-DWETH-60", _validate(true)); + } } } } @@ -1273,21 +1416,33 @@ contract OPContractsManagerStandardValidator_PreimageOracle_Test is OPContractsM /// PreimageOracle version is invalid. function test_validate_preimageOracleInvalidVersion_succeeds() public { vm.mockCall(address(preimageOracle), abi.encodeCall(ISemver.version, ()), abi.encode("0.0.1")); - assertEq("PDDG-PIMGO-10,PLDG-PIMGO-10", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PDDG-PIMGO-10,PLDG-PIMGO-10,CKDG-PIMGO-10", _validate(true)); + } else { + assertEq("PDDG-PIMGO-10,PLDG-PIMGO-10", _validate(true)); + } } /// @notice Tests that the validate function successfully returns the right error when the /// PreimageOracle challengePeriod is invalid. function test_validate_preimageOracleInvalidChallengePeriod_succeeds() public { vm.mockCall(address(preimageOracle), abi.encodeCall(IPreimageOracle.challengePeriod, ()), abi.encode(1000)); - assertEq("PDDG-PIMGO-20,PLDG-PIMGO-20", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PDDG-PIMGO-20,PLDG-PIMGO-20,CKDG-PIMGO-20", _validate(true)); + } else { + assertEq("PDDG-PIMGO-20,PLDG-PIMGO-20", _validate(true)); + } } /// @notice Tests that the validate function successfully returns the right error when the /// PreimageOracle minProposalSize is invalid. function test_validate_preimageOracleInvalidMinProposalSize_succeeds() public { vm.mockCall(address(preimageOracle), abi.encodeCall(IPreimageOracle.minProposalSize, ()), abi.encode(1000)); - assertEq("PDDG-PIMGO-30,PLDG-PIMGO-30", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PDDG-PIMGO-30,PLDG-PIMGO-30,CKDG-PIMGO-30", _validate(true)); + } else { + assertEq("PDDG-PIMGO-30,PLDG-PIMGO-30", _validate(true)); + } } } @@ -1295,8 +1450,8 @@ contract OPContractsManagerStandardValidator_PreimageOracle_Test is OPContractsM /// @notice Tests validation of `FaultDisputeGame` configuration contract OPContractsManagerStandardValidator_FaultDisputeGame_Test is OPContractsManagerStandardValidator_TestInit { /// @notice Tests that the validate function successfully returns the right error when the - /// FaultDisputeGame (permissionless) implementation is null. - function test_validate_faultDisputeGameNullImplementation_succeeds() public { + /// FaultDisputeGame (permissionless) Cannon implementation is null. + function test_validate_faultDisputeGameNullCannonImplementation_succeeds() public { vm.mockCall( address(disputeGameFactory), abi.encodeCall(IDisputeGameFactory.gameImpls, (GameTypes.CANNON)), @@ -1305,11 +1460,27 @@ contract OPContractsManagerStandardValidator_FaultDisputeGame_Test is OPContract assertEq("PLDG-10", _validate(true)); } + /// @notice Tests that the validate function successfully returns the right error when the + /// FaultDisputeGame (permissionless) CannonKona implementation is null. + function test_validate_faultDisputeGameNullCannonKonaImplementation_succeeds() public { + skipIfDevFeatureDisabled(DevFeatures.CANNON_KONA); + vm.mockCall( + address(disputeGameFactory), + abi.encodeCall(IDisputeGameFactory.gameImpls, (GameTypes.CANNON_KONA)), + abi.encode(address(0)) + ); + assertEq("CKDG-10", _validate(true)); + } + /// @notice Tests that the validate function successfully returns the right error when the /// FaultDisputeGame (permissionless) version is invalid. function test_validate_faultDisputeGameInvalidVersion_succeeds() public { - vm.mockCall(address(fdg), abi.encodeCall(ISemver.version, ()), abi.encode("0.0.0")); - assertEq("PLDG-20", _validate(true)); + vm.mockCall(address(fdgImpl), abi.encodeCall(ISemver.version, ()), abi.encode("0.0.0")); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PLDG-20,CKDG-20", _validate(true)); + } else { + assertEq("PLDG-20", _validate(true)); + } } /// @notice Tests that the validate function successfully returns the right error when the @@ -1318,13 +1489,15 @@ contract OPContractsManagerStandardValidator_FaultDisputeGame_Test is OPContract // For v2 game contracts, we don't store the game type anywhere other than the DGF gameImpls and gameArgs maps // So, there's not really an obvious way to return an invalid gameType skipIfDevFeatureEnabled(DevFeatures.DEPLOY_V2_DISPUTE_GAMES); - vm.mockCall(address(fdg), abi.encodeCall(IDisputeGame.gameType, ()), abi.encode(GameTypes.PERMISSIONED_CANNON)); + vm.mockCall( + address(fdgImpl), abi.encodeCall(IDisputeGame.gameType, ()), abi.encode(GameTypes.PERMISSIONED_CANNON) + ); assertEq("PLDG-30", _validate(true)); } /// @notice Tests that the validate function successfully returns the right error when the - /// FaultDisputeGame (permissionless) game args are invalid. - function test_validate_faultDisputeGameInvalidGameArgs_succeeds() public { + /// FaultDisputeGame (permissionless) Cannon game args are invalid. + function test_validate_faultDisputeGameInvalidCannonGameArgs_succeeds() public { bytes memory invalidGameArgs = hex"123456"; GameType gameType = GameTypes.CANNON; vm.mockCall(address(dgf), abi.encodeCall(IDisputeGameFactory.gameArgs, (gameType)), abi.encode(invalidGameArgs)); @@ -1333,8 +1506,19 @@ contract OPContractsManagerStandardValidator_FaultDisputeGame_Test is OPContract } /// @notice Tests that the validate function successfully returns the right error when the - /// FaultDisputeGame (permissionless) absolute prestate is invalid. - function test_validate_faultDisputeGameInvalidAbsolutePrestate_succeeds() public { + /// FaultDisputeGame (permissionless) CannonKona game args are invalid. + function test_validate_faultDisputeGameInvalidCannonKonaGameArgs_succeeds() public { + skipIfDevFeatureDisabled(DevFeatures.CANNON_KONA); + bytes memory invalidGameArgs = hex"123456"; + GameType gameType = GameTypes.CANNON_KONA; + vm.mockCall(address(dgf), abi.encodeCall(IDisputeGameFactory.gameArgs, (gameType)), abi.encode(invalidGameArgs)); + + assertEq("CKDG-GARGS-10", _validate(true)); + } + + /// @notice Tests that the validate function successfully returns the right error when the + /// FaultDisputeGame (permissionless) Cannon absolute prestate is invalid. + function test_validate_faultDisputeGameInvalidCannonAbsolutePrestate_succeeds() public { bytes32 badPrestate = bytes32(uint256(0xbadbad)); mockGameImplPrestate(dgf, GameTypes.CANNON, badPrestate); @@ -1342,8 +1526,18 @@ contract OPContractsManagerStandardValidator_FaultDisputeGame_Test is OPContract } /// @notice Tests that the validate function successfully returns the right error when the - /// FaultDisputeGame (permissionless) VM address is invalid. - function test_validate_faultDisputeGameInvalidVM_succeeds() public { + /// FaultDisputeGame (permissionless) CannonKona absolute prestate is invalid. + function test_validate_faultDisputeGameInvalidCannonKonaAbsolutePrestate_succeeds() public { + skipIfDevFeatureDisabled(DevFeatures.CANNON_KONA); + bytes32 badPrestate = cannonPrestate.raw(); // Use the wrong prestate + mockGameImplPrestate(dgf, GameTypes.CANNON_KONA, badPrestate); + + assertEq("CKDG-40", _validate(true)); + } + + /// @notice Tests that the validate function successfully returns the right error when the + /// FaultDisputeGame (permissionless) Cannon VM address is invalid. + function test_validate_faultDisputeGameInvalidCannonVM_succeeds() public { address badVM = address(0xbad); mockGameImplVM(dgf, GameTypes.CANNON, badVM); vm.mockCall(badVM, abi.encodeCall(ISemver.version, ()), abi.encode("0.0.0")); @@ -1353,10 +1547,35 @@ contract OPContractsManagerStandardValidator_FaultDisputeGame_Test is OPContract } /// @notice Tests that the validate function successfully returns the right error when the - /// FaultDisputeGame (permissionless) ASR address is invalid. - function test_validate_faultDisputeGameInvalidASR_succeeds() public { + /// FaultDisputeGame (permissionless) CannonKona VM address is invalid. + function test_validate_faultDisputeGameInvalidCannonKonaVM_succeeds() public { + skipIfDevFeatureDisabled(DevFeatures.CANNON_KONA); + address badVM = address(0xbad); + mockGameImplVM(dgf, GameTypes.CANNON_KONA, badVM); + vm.mockCall(badVM, abi.encodeCall(ISemver.version, ()), abi.encode("0.0.0")); + vm.mockCall(badVM, abi.encodeCall(IMIPS64.stateVersion, ()), abi.encode(StandardConstants.MIPS_VERSION)); + + assertEq("CKDG-VM-10,CKDG-VM-20", _validate(true)); + } + + /// @notice Tests that the validate function successfully returns the right error when the + /// FaultDisputeGame (permissionless) Cannon ASR address is invalid. + function test_validate_faultDisputeGameInvalidCannonASR_succeeds() public { + _mockInvalidASR(GameTypes.CANNON); + assertEq("PLDG-ANCHORP-10,PLDG-ANCHORP-20", _validate(true)); + } + + /// @notice Tests that the validate function successfully returns the right error when the + /// FaultDisputeGame (permissionless) CannonKona ASR address is invalid. + function test_validate_faultDisputeGameInvalidCannonKonaASR_succeeds() public { + skipIfDevFeatureDisabled(DevFeatures.CANNON_KONA); + _mockInvalidASR(GameTypes.CANNON_KONA); + assertEq("CKDG-ANCHORP-10,CKDG-ANCHORP-20", _validate(true)); + } + + function _mockInvalidASR(GameType _gameType) internal { address badASR = address(0xbad); - mockGameImplASR(dgf, GameTypes.CANNON, badASR); + mockGameImplASR(dgf, _gameType, badASR); // Mock invalid values vm.mockCall(badASR, abi.encodeCall(IStaticERC1967Proxy.implementation, ()), abi.encode(address(0xdeadbeef))); @@ -1372,15 +1591,26 @@ contract OPContractsManagerStandardValidator_FaultDisputeGame_Test is OPContract vm.mockCall(badASR, abi.encodeCall(IAnchorStateRegistry.systemConfig, ()), abi.encode(sysCfg)); vm.mockCall(badASR, abi.encodeCall(IProxyAdminOwnedBase.proxyAdmin, ()), abi.encode(proxyAdmin)); vm.mockCall(badASR, abi.encodeCall(IAnchorStateRegistry.retirementTimestamp, ()), abi.encode(uint64(100))); + } - assertEq("PLDG-ANCHORP-10,PLDG-ANCHORP-20", _validate(true)); + /// @notice Tests that the validate function successfully returns the right error when the + /// FaultDisputeGame (permissionless) Cannon Weth address is invalid. + function test_validate_faultDisputeGameInvalidCannonWeth_succeeds() public { + _mockInvalidWeth(GameTypes.CANNON); + assertEq("PLDG-DWETH-10,PLDG-DWETH-20", _validate(true)); } /// @notice Tests that the validate function successfully returns the right error when the - /// FaultDisputeGame (permissionless) Weth address is invalid. - function test_validate_faultDisputeGameInvalidWeth_succeeds() public { + /// FaultDisputeGame (permissionless) CannonKona Weth address is invalid. + function test_validate_faultDisputeGameInvalidCannonKonaWeth_succeeds() public { + skipIfDevFeatureDisabled(DevFeatures.CANNON_KONA); + _mockInvalidWeth(GameTypes.CANNON_KONA); + assertEq("CKDG-DWETH-10,CKDG-DWETH-20", _validate(true)); + } + + function _mockInvalidWeth(GameType _gameType) internal { address badWeth = address(0xbad); - mockGameImplWeth(dgf, GameTypes.CANNON, badWeth); + mockGameImplWeth(dgf, _gameType, badWeth); // Mock invalid values vm.mockCall(badWeth, abi.encodeCall(IStaticERC1967Proxy.implementation, ()), abi.encode(address(0xdeadbeef))); @@ -1399,61 +1629,95 @@ contract OPContractsManagerStandardValidator_FaultDisputeGame_Test is OPContract ); vm.mockCall(badWeth, abi.encodeCall(IDelayedWETH.systemConfig, ()), abi.encode(sysCfg)); vm.mockCall(badWeth, abi.encodeCall(IProxyAdminOwnedBase.proxyAdmin, ()), abi.encode(proxyAdmin)); - - assertEq("PLDG-DWETH-10,PLDG-DWETH-20", _validate(true)); } /// @notice Tests that the validate function successfully returns the right error when the /// FaultDisputeGame (permissionless) VM's state version is invalid. function test_validate_faultDisputeGameInvalidVMStateVersion_succeeds() public { vm.mockCall(address(mips), abi.encodeCall(IMIPS64.stateVersion, ()), abi.encode(6)); - assertEq("PDDG-VM-30,PLDG-VM-30", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PDDG-VM-30,PLDG-VM-30,CKDG-VM-30", _validate(true)); + } else { + assertEq("PDDG-VM-30,PLDG-VM-30", _validate(true)); + } } /// @notice Tests that the validate function successfully returns the right error when the - /// FaultDisputeGame (permissionless) L2 Chain ID is invalid. - function test_validate_faultDisputeGameInvalidL2ChainId_succeeds() public { + /// FaultDisputeGame (permissionless) Cannon L2 Chain ID is invalid. + function test_validate_faultDisputeGameInvalidCannonL2ChainId_succeeds() public { uint256 badChainId = l2ChainId + 1; mockGameImplL2ChainId(dgf, GameTypes.CANNON, badChainId); assertEq("PLDG-60", _validate(true)); } + /// @notice Tests that the validate function successfully returns the right error when the + /// FaultDisputeGame (permissionless) CannonKona L2 Chain ID is invalid. + function test_validate_faultDisputeGameInvalidCannonKonaL2ChainId_succeeds() public { + skipIfDevFeatureDisabled(DevFeatures.CANNON_KONA); + uint256 badChainId = l2ChainId + 1; + mockGameImplL2ChainId(dgf, GameTypes.CANNON_KONA, badChainId); + + assertEq("CKDG-60", _validate(true)); + } + /// @notice Tests that the validate function successfully returns the right error when the /// FaultDisputeGame (permissionless) L2 Sequence Number is invalid. function test_validate_faultDisputeGameInvalidL2SequenceNumber_succeeds() public { - vm.mockCall(address(fdg), abi.encodeCall(IDisputeGame.l2SequenceNumber, ()), abi.encode(123)); - assertEq("PLDG-70", _validate(true)); + vm.mockCall(address(fdgImpl), abi.encodeCall(IDisputeGame.l2SequenceNumber, ()), abi.encode(123)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PLDG-70,CKDG-70", _validate(true)); + } else { + assertEq("PLDG-70", _validate(true)); + } } /// @notice Tests that the validate function successfully returns the right error when the /// FaultDisputeGame (permissionless) clockExtension is invalid. function test_validate_faultDisputeGameInvalidClockExtension_succeeds() public { - vm.mockCall(address(fdg), abi.encodeCall(IFaultDisputeGame.clockExtension, ()), abi.encode(Duration.wrap(1000))); - assertEq("PLDG-80", _validate(true)); + vm.mockCall( + address(fdgImpl), abi.encodeCall(IFaultDisputeGame.clockExtension, ()), abi.encode(Duration.wrap(1000)) + ); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PLDG-80,CKDG-80", _validate(true)); + } else { + assertEq("PLDG-80", _validate(true)); + } } /// @notice Tests that the validate function successfully returns the right error when the /// FaultDisputeGame (permissionless) splitDepth is invalid. function test_validate_faultDisputeGameInvalidSplitDepth_succeeds() public { - vm.mockCall(address(fdg), abi.encodeCall(IFaultDisputeGame.splitDepth, ()), abi.encode(20)); - assertEq("PLDG-90", _validate(true)); + vm.mockCall(address(fdgImpl), abi.encodeCall(IFaultDisputeGame.splitDepth, ()), abi.encode(20)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PLDG-90,CKDG-90", _validate(true)); + } else { + assertEq("PLDG-90", _validate(true)); + } } /// @notice Tests that the validate function successfully returns the right error when the /// FaultDisputeGame (permissionless) maxGameDepth is invalid. function test_validate_faultDisputeGameInvalidMaxGameDepth_succeeds() public { - vm.mockCall(address(fdg), abi.encodeCall(IFaultDisputeGame.maxGameDepth, ()), abi.encode(50)); - assertEq("PLDG-100", _validate(true)); + vm.mockCall(address(fdgImpl), abi.encodeCall(IFaultDisputeGame.maxGameDepth, ()), abi.encode(50)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PLDG-100,CKDG-100", _validate(true)); + } else { + assertEq("PLDG-100", _validate(true)); + } } /// @notice Tests that the validate function successfully returns the right error when the /// FaultDisputeGame (permissionless) maxClockDuration is invalid. function test_validate_faultDisputeGameInvalidMaxClockDuration_succeeds() public { vm.mockCall( - address(fdg), abi.encodeCall(IFaultDisputeGame.maxClockDuration, ()), abi.encode(Duration.wrap(1000)) + address(fdgImpl), abi.encodeCall(IFaultDisputeGame.maxClockDuration, ()), abi.encode(Duration.wrap(1000)) ); - assertEq("PLDG-110", _validate(true)); + if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { + assertEq("PLDG-110,CKDG-110", _validate(true)); + } else { + assertEq("PLDG-110", _validate(true)); + } } }