Commit 28c4ad2a authored by blaine's avatar blaine Committed by GitHub

OPCMs state should be checked after a deploy (#13510)

* fix: more robust opcm checking upon deploy.

* Update packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol
Co-authored-by: default avatarMaurelian <john@oplabs.co>

* Update packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol
Co-authored-by: default avatarMaurelian <john@oplabs.co>

* fix: pr comments.

---------
Co-authored-by: default avatarMaurelian <john@oplabs.co>
parent 80ca71a6
...@@ -4,6 +4,7 @@ pragma solidity ^0.8.0; ...@@ -4,6 +4,7 @@ pragma solidity ^0.8.0;
// Testing // Testing
import { Vm } from "forge-std/Vm.sol"; import { Vm } from "forge-std/Vm.sol";
import { console2 as console } from "forge-std/console2.sol"; import { console2 as console } from "forge-std/console2.sol";
import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
// Scripts // Scripts
import { DeployConfig } from "scripts/deploy/DeployConfig.s.sol"; import { DeployConfig } from "scripts/deploy/DeployConfig.s.sol";
...@@ -14,6 +15,7 @@ import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; ...@@ -14,6 +15,7 @@ import { DeployUtils } from "scripts/libraries/DeployUtils.sol";
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { Types } from "scripts/libraries/Types.sol"; import { Types } from "scripts/libraries/Types.sol";
import { Blueprint } from "src/libraries/Blueprint.sol";
// Contracts // Contracts
import { OPContractsManager } from "src/L1/OPContractsManager.sol"; import { OPContractsManager } from "src/L1/OPContractsManager.sol";
...@@ -567,23 +569,80 @@ library ChainAssertions { ...@@ -567,23 +569,80 @@ library ChainAssertions {
} }
} }
/// @notice Asserts that the SuperchainConfig is setup correctly /// @notice Asserts that the OPContractsManager is setup correctly
function checkOPContractsManager(Types.ContractSet memory _contracts, bool _isProxy) internal view { function checkOPContractsManager(
OPContractsManager opcm = OPContractsManager(_contracts.OPContractsManager); Types.ContractSet memory _contracts,
console.log( OPContractsManager _opcm,
"Running chain assertions on the OPContractsManager %s at %s", IMIPS _mips
_isProxy ? "proxy" : "implementation", )
address(opcm) internal
); view
require(address(opcm) != address(0), "CHECK-OPCM-10"); {
console.log("Running chain assertions on the OPContractsManager at %s", address(_opcm));
require(address(_opcm) != address(0), "CHECK-OPCM-10");
// Check that the contract is initialized require(
DeployUtils.assertInitialized({ _contractAddress: address(opcm), _isProxy: _isProxy, _slot: 0, _offset: 0 }); address(EIP1967Helper.getImplementation(address(_opcm.superchainConfig())))
== address(_contracts.SuperchainConfig),
"CHECK-OPCM-20"
);
require(
EIP1967Helper.getImplementation(address(_opcm.protocolVersions())) == address(_contracts.ProtocolVersions),
"CHECK-OPCM-30"
);
// These values are immutable so are shared by the proxy and implementation require(bytes(_opcm.l1ContractsRelease()).length > 0, "CHECK-OPCM-40");
require(address(opcm.superchainConfig()) == address(_contracts.SuperchainConfig), "CHECK-OPCM-30");
require(address(opcm.protocolVersions()) == address(_contracts.ProtocolVersions), "CHECK-OPCM-40"); // Ensure that the OPCM impls are correctly saved
OPContractsManager.Implementations memory impls = _opcm.implementations();
require(impls.l1ERC721BridgeImpl == _contracts.L1ERC721Bridge, "CHECK-OPCM-50");
require(impls.optimismPortalImpl == _contracts.OptimismPortal2, "CHECK-OPCM-60");
require(impls.systemConfigImpl == _contracts.SystemConfig, "CHECK-OPCM-70");
require(impls.optimismMintableERC20FactoryImpl == _contracts.OptimismMintableERC20Factory, "CHECK-OPCM-80");
require(impls.l1CrossDomainMessengerImpl == _contracts.L1CrossDomainMessenger, "CHECK-OPCM-90");
require(impls.l1StandardBridgeImpl == _contracts.L1StandardBridge, "CHECK-OPCM-100");
require(impls.disputeGameFactoryImpl == _contracts.DisputeGameFactory, "CHECK-OPCM-110");
require(impls.delayedWETHImpl == _contracts.DelayedWETH, "CHECK-OPCM-120");
require(impls.mipsImpl == address(_mips), "CHECK-OPCM-130");
// Verify that initCode is correctly set into the blueprints
OPContractsManager.Blueprints memory blueprints = _opcm.blueprints();
Blueprint.Preamble memory addressManagerPreamble =
Blueprint.parseBlueprintPreamble(address(blueprints.addressManager).code);
require(keccak256(addressManagerPreamble.initcode) == keccak256(vm.getCode("AddressManager")), "CHECK-OPCM-140");
Blueprint.Preamble memory proxyPreamble = Blueprint.parseBlueprintPreamble(address(blueprints.proxy).code);
require(keccak256(proxyPreamble.initcode) == keccak256(vm.getCode("Proxy")), "CHECK-OPCM-150");
Blueprint.Preamble memory proxyAdminPreamble =
Blueprint.parseBlueprintPreamble(address(blueprints.proxyAdmin).code);
require(keccak256(proxyAdminPreamble.initcode) == keccak256(vm.getCode("ProxyAdmin")), "CHECK-OPCM-160");
Blueprint.Preamble memory l1ChugSplashProxyPreamble =
Blueprint.parseBlueprintPreamble(address(blueprints.l1ChugSplashProxy).code);
require(
keccak256(l1ChugSplashProxyPreamble.initcode) == keccak256(vm.getCode("L1ChugSplashProxy")),
"CHECK-OPCM-170"
);
// TODO: Add assertions for blueprints and setters? Blueprint.Preamble memory rdProxyPreamble =
Blueprint.parseBlueprintPreamble(address(blueprints.resolvedDelegateProxy).code);
require(keccak256(rdProxyPreamble.initcode) == keccak256(vm.getCode("ResolvedDelegateProxy")), "CHECK-OPCM-180");
Blueprint.Preamble memory asrPreamble =
Blueprint.parseBlueprintPreamble(address(blueprints.anchorStateRegistry).code);
require(keccak256(asrPreamble.initcode) == keccak256(vm.getCode("AnchorStateRegistry")), "CHECK-OPCM-190");
Blueprint.Preamble memory pdg1Preamble =
Blueprint.parseBlueprintPreamble(address(blueprints.permissionedDisputeGame1).code);
Blueprint.Preamble memory pdg2Preamble =
Blueprint.parseBlueprintPreamble(address(blueprints.permissionedDisputeGame2).code);
// combine pdg1 and pdg2 initcodes
bytes memory fullPermissionedDisputeGameInitcode =
abi.encodePacked(pdg1Preamble.initcode, pdg2Preamble.initcode);
require(
keccak256(fullPermissionedDisputeGameInitcode) == keccak256(vm.getCode("PermissionedDisputeGame")),
"CHECK-OPCM-200"
);
} }
} }
...@@ -128,8 +128,7 @@ contract Deploy is Deployer { ...@@ -128,8 +128,7 @@ contract Deploy is Deployer {
SystemConfig: getAddress("SystemConfigProxy"), SystemConfig: getAddress("SystemConfigProxy"),
L1ERC721Bridge: getAddress("L1ERC721BridgeProxy"), L1ERC721Bridge: getAddress("L1ERC721BridgeProxy"),
ProtocolVersions: getAddress("ProtocolVersionsProxy"), ProtocolVersions: getAddress("ProtocolVersionsProxy"),
SuperchainConfig: getAddress("SuperchainConfigProxy"), SuperchainConfig: getAddress("SuperchainConfigProxy")
OPContractsManager: getAddress("OPContractsManager")
}); });
} }
...@@ -149,8 +148,7 @@ contract Deploy is Deployer { ...@@ -149,8 +148,7 @@ contract Deploy is Deployer {
SystemConfig: getAddress("SystemConfig"), SystemConfig: getAddress("SystemConfig"),
L1ERC721Bridge: getAddress("L1ERC721Bridge"), L1ERC721Bridge: getAddress("L1ERC721Bridge"),
ProtocolVersions: getAddress("ProtocolVersions"), ProtocolVersions: getAddress("ProtocolVersions"),
SuperchainConfig: getAddress("SuperchainConfig"), SuperchainConfig: getAddress("SuperchainConfig")
OPContractsManager: getAddress("OPContractsManager")
}); });
} }
...@@ -363,6 +361,11 @@ contract Deploy is Deployer { ...@@ -363,6 +361,11 @@ contract Deploy is Deployer {
_mips: IMIPS(address(dio.mipsSingleton())), _mips: IMIPS(address(dio.mipsSingleton())),
_oracle: IPreimageOracle(address(dio.preimageOracleSingleton())) _oracle: IPreimageOracle(address(dio.preimageOracleSingleton()))
}); });
ChainAssertions.checkOPContractsManager({
_contracts: contracts,
_opcm: OPContractsManager(mustGetAddress("OPContractsManager")),
_mips: IMIPS(mustGetAddress("Mips"))
});
if (_isInterop) { if (_isInterop) {
ChainAssertions.checkSystemConfigInterop({ _contracts: contracts, _cfg: cfg, _isProxy: false }); ChainAssertions.checkSystemConfigInterop({ _contracts: contracts, _cfg: cfg, _isProxy: false });
} else { } else {
......
...@@ -3,6 +3,7 @@ pragma solidity ^0.8.0; ...@@ -3,6 +3,7 @@ pragma solidity ^0.8.0;
library Types { library Types {
/// @notice Represents a set of L1 contracts. Used to represent a set of proxies. /// @notice Represents a set of L1 contracts. Used to represent a set of proxies.
/// This is not an exhaustive list of all contracts on L1, but rather a subset.
struct ContractSet { struct ContractSet {
address L1CrossDomainMessenger; address L1CrossDomainMessenger;
address L1StandardBridge; address L1StandardBridge;
...@@ -18,6 +19,5 @@ library Types { ...@@ -18,6 +19,5 @@ library Types {
address L1ERC721Bridge; address L1ERC721Bridge;
address ProtocolVersions; address ProtocolVersions;
address SuperchainConfig; address SuperchainConfig;
address OPContractsManager;
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment