Skip to content

Commit ef6ef6f

Browse files
authored
make interfaces for opcm contracts and use them in tests and scripts (#13922)
* make interfaces for opcm contracts and use them in tests and scripts * fix opcm interop deployment
1 parent 9580179 commit ef6ef6f

15 files changed

+424
-148
lines changed
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.0;
3+
4+
// Libraries
5+
import { Claim, Duration, GameType } from "src/dispute/lib/Types.sol";
6+
7+
// Interfaces
8+
import { IBigStepper } from "interfaces/dispute/IBigStepper.sol";
9+
import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol";
10+
import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol";
11+
import { IAddressManager } from "interfaces/legacy/IAddressManager.sol";
12+
import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol";
13+
import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol";
14+
import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol";
15+
import { IFaultDisputeGame } from "interfaces/dispute/IFaultDisputeGame.sol";
16+
import { IPermissionedDisputeGame } from "interfaces/dispute/IPermissionedDisputeGame.sol";
17+
import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol";
18+
import { IProtocolVersions } from "interfaces/L1/IProtocolVersions.sol";
19+
import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol";
20+
import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol";
21+
import { IL1CrossDomainMessenger } from "interfaces/L1/IL1CrossDomainMessenger.sol";
22+
import { IL1ERC721Bridge } from "interfaces/L1/IL1ERC721Bridge.sol";
23+
import { IL1StandardBridge } from "interfaces/L1/IL1StandardBridge.sol";
24+
import { IOptimismMintableERC20Factory } from "interfaces/universal/IOptimismMintableERC20Factory.sol";
25+
26+
interface IOPContractsManager {
27+
// -------- Structs --------
28+
29+
/// @notice Represents the roles that can be set when deploying a standard OP Stack chain.
30+
struct Roles {
31+
address opChainProxyAdminOwner;
32+
address systemConfigOwner;
33+
address batcher;
34+
address unsafeBlockSigner;
35+
address proposer;
36+
address challenger;
37+
}
38+
39+
/// @notice The full set of inputs to deploy a new OP Stack chain.
40+
struct DeployInput {
41+
Roles roles;
42+
uint32 basefeeScalar;
43+
uint32 blobBasefeeScalar;
44+
uint256 l2ChainId;
45+
// The correct type is OutputRoot memory but OP Deployer does not yet support structs.
46+
bytes startingAnchorRoot;
47+
// The salt mixer is used as part of making the resulting salt unique.
48+
string saltMixer;
49+
uint64 gasLimit;
50+
// Configurable dispute game parameters.
51+
GameType disputeGameType;
52+
Claim disputeAbsolutePrestate;
53+
uint256 disputeMaxGameDepth;
54+
uint256 disputeSplitDepth;
55+
Duration disputeClockExtension;
56+
Duration disputeMaxClockDuration;
57+
}
58+
59+
/// @notice The full set of outputs from deploying a new OP Stack chain.
60+
struct DeployOutput {
61+
IProxyAdmin opChainProxyAdmin;
62+
IAddressManager addressManager;
63+
IL1ERC721Bridge l1ERC721BridgeProxy;
64+
ISystemConfig systemConfigProxy;
65+
IOptimismMintableERC20Factory optimismMintableERC20FactoryProxy;
66+
IL1StandardBridge l1StandardBridgeProxy;
67+
IL1CrossDomainMessenger l1CrossDomainMessengerProxy;
68+
// Fault proof contracts below.
69+
IOptimismPortal2 optimismPortalProxy;
70+
IDisputeGameFactory disputeGameFactoryProxy;
71+
IAnchorStateRegistry anchorStateRegistryProxy;
72+
IFaultDisputeGame faultDisputeGame;
73+
IPermissionedDisputeGame permissionedDisputeGame;
74+
IDelayedWETH delayedWETHPermissionedGameProxy;
75+
IDelayedWETH delayedWETHPermissionlessGameProxy;
76+
}
77+
78+
/// @notice Addresses of ERC-5202 Blueprint contracts. There are used for deploying full size
79+
/// contracts, to reduce the code size of this factory contract. If it deployed full contracts
80+
/// using the `new Proxy()` syntax, the code size would get large fast, since this contract would
81+
/// contain the bytecode of every contract it deploys. Therefore we instead use Blueprints to
82+
/// reduce the code size of this contract.
83+
struct Blueprints {
84+
address addressManager;
85+
address proxy;
86+
address proxyAdmin;
87+
address l1ChugSplashProxy;
88+
address resolvedDelegateProxy;
89+
address permissionedDisputeGame1;
90+
address permissionedDisputeGame2;
91+
address permissionlessDisputeGame1;
92+
address permissionlessDisputeGame2;
93+
}
94+
95+
/// @notice The latest implementation contracts for the OP Stack.
96+
struct Implementations {
97+
address l1ERC721BridgeImpl;
98+
address optimismPortalImpl;
99+
address systemConfigImpl;
100+
address optimismMintableERC20FactoryImpl;
101+
address l1CrossDomainMessengerImpl;
102+
address l1StandardBridgeImpl;
103+
address disputeGameFactoryImpl;
104+
address anchorStateRegistryImpl;
105+
address delayedWETHImpl;
106+
address mipsImpl;
107+
}
108+
109+
/// @notice The input required to identify a chain for upgrading.
110+
struct OpChain {
111+
ISystemConfig systemConfigProxy;
112+
IProxyAdmin proxyAdmin;
113+
}
114+
115+
struct AddGameInput {
116+
string saltMixer;
117+
ISystemConfig systemConfig;
118+
IProxyAdmin proxyAdmin;
119+
IDelayedWETH delayedWETH;
120+
GameType disputeGameType;
121+
Claim disputeAbsolutePrestate;
122+
uint256 disputeMaxGameDepth;
123+
uint256 disputeSplitDepth;
124+
Duration disputeClockExtension;
125+
Duration disputeMaxClockDuration;
126+
uint256 initialBond;
127+
IBigStepper vm;
128+
bool permissioned;
129+
}
130+
131+
struct AddGameOutput {
132+
IDelayedWETH delayedWETH;
133+
IFaultDisputeGame faultDisputeGame;
134+
}
135+
136+
// -------- Constants and Variables --------
137+
138+
function version() external pure returns (string memory);
139+
140+
/// @notice Address of the SuperchainConfig contract shared by all chains.
141+
function superchainConfig() external view returns (ISuperchainConfig);
142+
143+
/// @notice Address of the ProtocolVersions contract shared by all chains.
144+
function protocolVersions() external view returns (IProtocolVersions);
145+
146+
/// @notice L1 smart contracts release deployed by this version of OPCM. This is used in opcm to signal which
147+
/// version of the L1 smart contracts is deployed. It takes the format of `op-contracts/vX.Y.Z`.
148+
function l1ContractsRelease() external view returns (string memory);
149+
150+
// -------- Events --------
151+
152+
/// @notice Emitted when a new OP Stack chain is deployed.
153+
/// @param l2ChainId Chain ID of the new chain.
154+
/// @param deployer Address that deployed the chain.
155+
/// @param deployOutput ABI-encoded output of the deployment.
156+
event Deployed(uint256 indexed l2ChainId, address indexed deployer, bytes deployOutput);
157+
158+
/// @notice Emitted when a chain is upgraded
159+
/// @param systemConfig Address of the chain's SystemConfig contract
160+
/// @param upgrader Address that initiated the upgrade
161+
event Upgraded(uint256 indexed l2ChainId, ISystemConfig indexed systemConfig, address indexed upgrader);
162+
163+
// -------- Errors --------
164+
165+
error BytesArrayTooLong();
166+
error DeploymentFailed();
167+
error EmptyInitcode();
168+
error IdentityPrecompileCallFailed();
169+
error NotABlueprint();
170+
error ReservedBitsSet();
171+
error UnexpectedPreambleData(bytes data);
172+
error UnsupportedERCVersion(uint8 version);
173+
174+
/// @notice Thrown when an address is the zero address.
175+
error AddressNotFound(address who);
176+
177+
/// @notice Throw when a contract address has no code.
178+
error AddressHasNoCode(address who);
179+
180+
/// @notice Thrown when a release version is already set.
181+
error AlreadyReleased();
182+
183+
/// @notice Thrown when an invalid `l2ChainId` is provided to `deploy`.
184+
error InvalidChainId();
185+
186+
/// @notice Thrown when a role's address is not valid.
187+
error InvalidRoleAddress(string role);
188+
189+
/// @notice Thrown when the latest release is not set upon initialization.
190+
error LatestReleaseNotSet();
191+
192+
/// @notice Thrown when the starting anchor root is not provided.
193+
error InvalidStartingAnchorRoot();
194+
195+
/// @notice Thrown when certain methods are called outside of a DELEGATECALL.
196+
error OnlyDelegatecall();
197+
198+
/// @notice Thrown when game configs passed to addGameType are invalid.
199+
error InvalidGameConfigs();
200+
201+
/// @notice Thrown when the SuperchainConfig of the chain does not match the SuperchainConfig of this OPCM.
202+
error SuperchainConfigMismatch(ISystemConfig systemConfig);
203+
204+
// -------- Methods --------
205+
206+
function __constructor__(
207+
ISuperchainConfig _superchainConfig,
208+
IProtocolVersions _protocolVersions,
209+
string memory _l1ContractsRelease,
210+
Blueprints memory _blueprints,
211+
Implementations memory _implementations
212+
)
213+
external;
214+
215+
function deploy(DeployInput calldata _input) external returns (DeployOutput memory);
216+
217+
/// @notice Upgrades a set of chains to the latest implementation contracts
218+
/// @param _opChains Array of OpChain structs, one per chain to upgrade
219+
/// @dev This function is intended to be called via DELEGATECALL from the Upgrade Controller Safe
220+
function upgrade(OpChain[] memory _opChains) external;
221+
222+
/// @notice addGameType deploys a new dispute game and links it to the DisputeGameFactory. The inputted _gameConfigs
223+
/// must be added in ascending GameType order.
224+
function addGameType(AddGameInput[] memory _gameConfigs) external returns (AddGameOutput[] memory);
225+
226+
/// @notice Maps an L2 chain ID to an L1 batch inbox address as defined by the standard
227+
/// configuration's convention. This convention is `versionByte || keccak256(bytes32(chainId))[:19]`,
228+
/// where || denotes concatenation`, versionByte is 0x00, and chainId is a uint256.
229+
/// https://specs.optimism.io/protocol/configurability.html#consensus-parameters
230+
function chainIdToBatchInboxAddress(uint256 _l2ChainId) external pure returns (address);
231+
232+
/// @notice Returns the blueprint contract addresses.
233+
function blueprints() external view returns (Blueprints memory);
234+
235+
/// @notice Returns the implementation contract addresses.
236+
function implementations() external view returns (Implementations memory);
237+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.0;
3+
4+
import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol";
5+
import { IProtocolVersions } from "interfaces/L1/IProtocolVersions.sol";
6+
import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol";
7+
8+
interface IOPContractsManagerInterop is IOPContractsManager {
9+
function __constructor__(
10+
ISuperchainConfig _superchainConfig,
11+
IProtocolVersions _protocolVersions,
12+
string memory _l1ContractsRelease,
13+
Blueprints memory _blueprints,
14+
Implementations memory _implementations
15+
)
16+
external;
17+
}

packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,8 @@ import { Predeploys } from "src/libraries/Predeploys.sol";
1717
import { Types } from "scripts/libraries/Types.sol";
1818
import { Blueprint } from "src/libraries/Blueprint.sol";
1919

20-
// Contracts
21-
import { OPContractsManager } from "src/L1/OPContractsManager.sol";
22-
2320
// Interfaces
21+
import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol";
2422
import { IResourceMetering } from "interfaces/L1/IResourceMetering.sol";
2523
import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol";
2624
import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol";
@@ -472,7 +470,7 @@ library ChainAssertions {
472470
/// @notice Asserts that the OPContractsManager is setup correctly
473471
function checkOPContractsManager(
474472
Types.ContractSet memory _contracts,
475-
OPContractsManager _opcm,
473+
IOPContractsManager _opcm,
476474
IMIPS _mips
477475
)
478476
internal
@@ -494,7 +492,7 @@ library ChainAssertions {
494492
require(bytes(_opcm.l1ContractsRelease()).length > 0, "CHECK-OPCM-40");
495493

496494
// Ensure that the OPCM impls are correctly saved
497-
OPContractsManager.Implementations memory impls = _opcm.implementations();
495+
IOPContractsManager.Implementations memory impls = _opcm.implementations();
498496
require(impls.l1ERC721BridgeImpl == _contracts.L1ERC721Bridge, "CHECK-OPCM-50");
499497
require(impls.optimismPortalImpl == _contracts.OptimismPortal, "CHECK-OPCM-60");
500498
require(impls.systemConfigImpl == _contracts.SystemConfig, "CHECK-OPCM-70");
@@ -506,7 +504,7 @@ library ChainAssertions {
506504
require(impls.mipsImpl == address(_mips), "CHECK-OPCM-130");
507505

508506
// Verify that initCode is correctly set into the blueprints
509-
OPContractsManager.Blueprints memory blueprints = _opcm.blueprints();
507+
IOPContractsManager.Blueprints memory blueprints = _opcm.blueprints();
510508
Blueprint.Preamble memory addressManagerPreamble =
511509
Blueprint.parseBlueprintPreamble(address(blueprints.addressManager).code);
512510
require(keccak256(addressManagerPreamble.initcode) == keccak256(vm.getCode("AddressManager")), "CHECK-OPCM-140");

packages/contracts-bedrock/scripts/deploy/Deploy.s.sol

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ import {
2424
DeployImplementationsOutput
2525
} from "scripts/deploy/DeployImplementations.s.sol";
2626

27-
// Contracts
28-
import { OPContractsManager } from "src/L1/OPContractsManager.sol";
29-
3027
// Libraries
3128
import { Constants } from "src/libraries/Constants.sol";
3229
import { Types } from "scripts/libraries/Types.sol";
@@ -35,6 +32,7 @@ import { StorageSlot, ForgeArtifacts } from "scripts/libraries/ForgeArtifacts.so
3532
import { GameType, Claim, GameTypes, OutputRoot, Hash } from "src/dispute/lib/Types.sol";
3633

3734
// Interfaces
35+
import { IOPContractsManager } from "interfaces/L1/IOPContractsManager.sol";
3836
import { IProxy } from "interfaces/universal/IProxy.sol";
3937
import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol";
4038
import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol";
@@ -346,7 +344,7 @@ contract Deploy is Deployer {
346344
});
347345
ChainAssertions.checkOPContractsManager({
348346
_contracts: contracts,
349-
_opcm: OPContractsManager(address(dio.opcm())),
347+
_opcm: IOPContractsManager(address(dio.opcm())),
350348
_mips: IMIPS(address(dio.mipsSingleton()))
351349
});
352350
if (_isInterop) {
@@ -362,10 +360,10 @@ contract Deploy is Deployer {
362360

363361
// Ensure that the requisite contracts are deployed
364362
address superchainConfigProxy = artifacts.mustGetAddress("SuperchainConfigProxy");
365-
OPContractsManager opcm = OPContractsManager(artifacts.mustGetAddress("OPContractsManager"));
363+
IOPContractsManager opcm = IOPContractsManager(artifacts.mustGetAddress("OPContractsManager"));
366364

367-
OPContractsManager.DeployInput memory deployInput = getDeployInput();
368-
OPContractsManager.DeployOutput memory deployOutput = opcm.deploy(deployInput);
365+
IOPContractsManager.DeployInput memory deployInput = getDeployInput();
366+
IOPContractsManager.DeployOutput memory deployOutput = opcm.deploy(deployInput);
369367

370368
// Save all deploy outputs from the OPCM, in the order they are declared in the DeployOutput struct
371369
artifacts.save("ProxyAdmin", address(deployOutput.opChainProxyAdmin));
@@ -854,10 +852,10 @@ contract Deploy is Deployer {
854852
}
855853

856854
/// @notice Get the DeployInput struct to use for testing
857-
function getDeployInput() public view returns (OPContractsManager.DeployInput memory) {
855+
function getDeployInput() public view returns (IOPContractsManager.DeployInput memory) {
858856
string memory saltMixer = "salt mixer";
859-
return OPContractsManager.DeployInput({
860-
roles: OPContractsManager.Roles({
857+
return IOPContractsManager.DeployInput({
858+
roles: IOPContractsManager.Roles({
861859
opChainProxyAdminOwner: msg.sender,
862860
systemConfigOwner: cfg.finalSystemOwner(),
863861
batcher: cfg.batchSenderAddress(),

0 commit comments

Comments
 (0)