Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -59,7 +59,7 @@ interface IOPContractsManagerGameTypeAdder {
returns (IOPContractsManager.AddGameOutput[] memory);

function updatePrestate(
IOPContractsManager.OpChainConfig[] memory _prestateUpdateInputs,
IOPContractsManager.UpdatePrestateInput[] memory _prestateUpdateInputs,
address _superchainConfig
)
external;
Expand Down Expand Up @@ -225,6 +225,13 @@ interface IOPContractsManager {
Claim absolutePrestate;
}

/// @notice The input required to identify a chain for updating prestates
struct UpdatePrestateInput {
ISystemConfig systemConfigProxy;
Claim cannonPrestate;
Claim cannonKonaPrestate;
}

struct AddGameInput {
string saltMixer;
ISystemConfig systemConfig;
Expand Down Expand Up @@ -345,8 +352,8 @@ interface IOPContractsManager {
function addGameType(AddGameInput[] memory _gameConfigs) external returns (AddGameOutput[] memory);

/// @notice Updates the prestate hash for a new game type while keeping all other parameters the same
/// @param _prestateUpdateInputs The new prestate hash to use
function updatePrestate(OpChainConfig[] memory _prestateUpdateInputs) external;
/// @param _prestateUpdateInputs The new prestates to use
function updatePrestate(UpdatePrestateInput[] memory _prestateUpdateInputs) external;

/// @notice Migrates one or more OP Stack chains to use the Super Root dispute games and shared
/// dispute game contracts.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -774,17 +774,17 @@
"type": "address"
},
{
"internalType": "contract IProxyAdmin",
"name": "proxyAdmin",
"type": "address"
"internalType": "Claim",
"name": "cannonPrestate",
"type": "bytes32"
},
{
"internalType": "Claim",
"name": "absolutePrestate",
"name": "cannonKonaPrestate",
"type": "bytes32"
}
],
"internalType": "struct OPContractsManager.OpChainConfig[]",
"internalType": "struct OPContractsManager.UpdatePrestateInput[]",
"name": "_prestateUpdateInputs",
"type": "tuple[]"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,17 +360,17 @@
"type": "address"
},
{
"internalType": "contract IProxyAdmin",
"name": "proxyAdmin",
"type": "address"
"internalType": "Claim",
"name": "cannonPrestate",
"type": "bytes32"
},
{
"internalType": "Claim",
"name": "absolutePrestate",
"name": "cannonKonaPrestate",
"type": "bytes32"
}
],
"internalType": "struct OPContractsManager.OpChainConfig[]",
"internalType": "struct OPContractsManager.UpdatePrestateInput[]",
"name": "_prestateUpdateInputs",
"type": "tuple[]"
}
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": "0xb0db1b8b4e24626c018dd524608256e57fbb2b71fa164a32e0553280d6ff52d7",
"sourceCodeHash": "0x4c1a80a787d42e49c0dab8903259e1d32f5a21d2990148ab92a9ff4c80c68548"
"initCodeHash": "0xfc9b6327dc3fae8c26ce9d3ae8072b53845f2b8d992bc77a50f04134f0b0a7cc",
"sourceCodeHash": "0xa11523c7a9e71e2acee453e84cc981070881050ae6100aea7453188e0ca48796"
},
"src/L1/OPContractsManagerStandardValidator.sol:OPContractsManagerStandardValidator": {
"initCodeHash": "0x57d6a6729d887ead009d518e8f17fa0d26bfc97b8efe1494ab4ef8dbb000d109",
Expand Down
91 changes: 59 additions & 32 deletions packages/contracts-bedrock/src/L1/OPContractsManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,9 @@ abstract contract OPContractsManagerBase {
/// This method should be used as the salt mixer when deploying contracts when there is no user
/// provided salt mixer. This protects against a situation where multiple chains with the same
/// L2 chain ID exist, which would otherwise result in address collisions.
function reusableSaltMixer(OPContractsManager.OpChainConfig memory _opChainConfig)
internal
pure
returns (string memory)
{
return string(bytes.concat(bytes32(uint256(uint160(address(_opChainConfig.systemConfigProxy))))));
/// @param _systemConfigProxy The SystemConfig contract found in the OpChainConfig of the chain being deployed to.
function reusableSaltMixer(ISystemConfig _systemConfigProxy) internal pure returns (string memory) {
return string(bytes.concat(bytes32(uint256(uint160(address(_systemConfigProxy))))));
}

/// @notice Deterministically deploys a new proxy contract owned by the provided ProxyAdmin.
Expand Down Expand Up @@ -335,6 +332,7 @@ abstract contract OPContractsManagerBase {
if (
gameType.raw() == GameTypes.SUPER_CANNON.raw()
|| gameType.raw() == GameTypes.SUPER_PERMISSIONED_CANNON.raw()
|| gameType.raw() == GameTypes.SUPER_CANNON_KONA.raw()
) {
l2ChainId = 0;
} else {
Expand Down Expand Up @@ -565,28 +563,28 @@ contract OPContractsManagerGameTypeAdder is OPContractsManagerBase {
return outputs;
}

/// @notice Updates the prestate hash for a given game type while keeping all other game
/// @notice Updates the prestate hash for all deployed dispute games while keeping all other game
/// parameters exactly the same. Currently requires deploying a new implementation
/// as there is no way to update the prestate on an existing implementation.
/// @param _prestateUpdateInputs The new prestate hash to use.
function updatePrestate(OPContractsManager.OpChainConfig[] memory _prestateUpdateInputs) public {
function updatePrestate(OPContractsManager.UpdatePrestateInput[] memory _prestateUpdateInputs) public {
// Loop through each chain and prestate hash
for (uint256 i = 0; i < _prestateUpdateInputs.length; i++) {
// Ensure that the prestate is not the zero hash.
if (Claim.unwrap(_prestateUpdateInputs[i].absolutePrestate) == bytes32(0)) {
revert OPContractsManager.PrestateRequired();
}

// Grab the DisputeGameFactory.
IDisputeGameFactory dgf =
IDisputeGameFactory(_prestateUpdateInputs[i].systemConfigProxy.disputeGameFactory());

uint256 numGameTypes = isDevFeatureEnabled(DevFeatures.CANNON_KONA) ? 6 : 4;
// Create an array of all of the potential game types to update.
GameType[] memory gameTypes = new GameType[](4);
GameType[] memory gameTypes = new GameType[](numGameTypes);
gameTypes[0] = GameTypes.CANNON;
gameTypes[1] = GameTypes.PERMISSIONED_CANNON;
gameTypes[2] = GameTypes.SUPER_CANNON;
gameTypes[3] = GameTypes.SUPER_PERMISSIONED_CANNON;
if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) {
gameTypes[4] = GameTypes.CANNON_KONA;
gameTypes[5] = GameTypes.SUPER_CANNON_KONA;
}

// Track if we have a legacy game, super game, or both. We will revert if this function
// is ever called with a mix of legacy and super games. Should never happen in
Expand All @@ -610,6 +608,7 @@ contract OPContractsManagerGameTypeAdder is OPContractsManagerBase {
if (
gameType.raw() == GameTypes.SUPER_CANNON.raw()
|| gameType.raw() == GameTypes.SUPER_PERMISSIONED_CANNON.raw()
|| gameType.raw() == GameTypes.SUPER_CANNON_KONA.raw()
) {
hasSuperGame = true;
} else {
Expand All @@ -621,15 +620,26 @@ contract OPContractsManagerGameTypeAdder is OPContractsManagerBase {
revert OPContractsManagerGameTypeAdder_MixedGameTypes();
}

// Select the prestate to use
Claim prestate = gameType.raw() == GameTypes.CANNON_KONA.raw()
|| gameType.raw() == GameTypes.SUPER_CANNON_KONA.raw()
? _prestateUpdateInputs[i].cannonKonaPrestate
: _prestateUpdateInputs[i].cannonPrestate;

// Ensure that the prestate is not the zero hash.
if (Claim.unwrap(prestate) == bytes32(0)) {
revert OPContractsManager.PrestateRequired();
}

// Grab the existing game constructor params and init bond.
IFaultDisputeGame.GameConstructorParams memory gameParams = getGameConstructorParams(existingGame);

// Create a new game input with the updated prestate.
OPContractsManager.AddGameInput memory input = OPContractsManager.AddGameInput({
disputeAbsolutePrestate: _prestateUpdateInputs[i].absolutePrestate,
saltMixer: reusableSaltMixer(_prestateUpdateInputs[i]),
disputeAbsolutePrestate: prestate,
saltMixer: reusableSaltMixer(_prestateUpdateInputs[i].systemConfigProxy),
systemConfig: _prestateUpdateInputs[i].systemConfigProxy,
proxyAdmin: _prestateUpdateInputs[i].proxyAdmin,
proxyAdmin: _prestateUpdateInputs[i].systemConfigProxy.proxyAdmin(),
delayedWETH: IDelayedWETH(payable(address(gameParams.weth))),
disputeGameType: gameParams.gameType,
disputeMaxGameDepth: gameParams.maxGameDepth,
Expand Down Expand Up @@ -733,7 +743,7 @@ contract OPContractsManagerUpgrader is OPContractsManagerBase {
deployProxy({
_l2ChainId: _l2ChainId,
_proxyAdmin: _opChainConfig.proxyAdmin,
_saltMixer: reusableSaltMixer(_opChainConfig),
_saltMixer: reusableSaltMixer(_opChainConfig.systemConfigProxy),
_contractName: "ETHLockbox-U16a"
})
);
Expand Down Expand Up @@ -921,7 +931,9 @@ contract OPContractsManagerUpgrader is OPContractsManagerBase {
Blueprint.deployFrom(
bps.permissionedDisputeGame1,
bps.permissionedDisputeGame2,
computeSalt(_l2ChainId, reusableSaltMixer(_opChainConfig), "PermissionedDisputeGame"),
computeSalt(
_l2ChainId, reusableSaltMixer(_opChainConfig.systemConfigProxy), "PermissionedDisputeGame"
),
encodePermissionedFDGConstructor(params, proposer, challenger)
)
);
Expand All @@ -930,7 +942,9 @@ contract OPContractsManagerUpgrader is OPContractsManagerBase {
Blueprint.deployFrom(
bps.permissionlessDisputeGame1,
bps.permissionlessDisputeGame2,
computeSalt(_l2ChainId, reusableSaltMixer(_opChainConfig), "PermissionlessDisputeGame"),
computeSalt(
_l2ChainId, reusableSaltMixer(_opChainConfig.systemConfigProxy), "PermissionlessDisputeGame"
),
encodePermissionlessFDGConstructor(params)
)
);
Expand Down Expand Up @@ -1479,7 +1493,7 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase {
deployProxy({
_l2ChainId: block.timestamp,
_proxyAdmin: _input.opChainConfigs[0].proxyAdmin,
_saltMixer: reusableSaltMixer(_input.opChainConfigs[0]),
_saltMixer: reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy),
_contractName: "ETHLockbox-Interop"
})
);
Expand Down Expand Up @@ -1507,7 +1521,7 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase {
deployProxy({
_l2ChainId: block.timestamp,
_proxyAdmin: _input.opChainConfigs[0].proxyAdmin,
_saltMixer: reusableSaltMixer(_input.opChainConfigs[0]),
_saltMixer: reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy),
_contractName: "DisputeGameFactory-Interop"
})
);
Expand All @@ -1525,7 +1539,7 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase {
deployProxy({
_l2ChainId: block.timestamp,
_proxyAdmin: _input.opChainConfigs[0].proxyAdmin,
_saltMixer: reusableSaltMixer(_input.opChainConfigs[0]),
_saltMixer: reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy),
_contractName: "AnchorStateRegistry-Interop"
})
);
Expand Down Expand Up @@ -1584,7 +1598,7 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase {
deployProxy({
_l2ChainId: block.timestamp,
_proxyAdmin: _input.opChainConfigs[0].proxyAdmin,
_saltMixer: reusableSaltMixer(_input.opChainConfigs[0]),
_saltMixer: reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy),
_contractName: "DelayedWETH-Interop-Permissioned"
})
)
Expand All @@ -1608,7 +1622,9 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase {
blueprints().superPermissionedDisputeGame1,
blueprints().superPermissionedDisputeGame2,
computeSalt(
block.timestamp, reusableSaltMixer(_input.opChainConfigs[0]), "SuperPermissionedDisputeGame"
block.timestamp,
reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy),
"SuperPermissionedDisputeGame"
),
encodePermissionedSuperFDGConstructor(
ISuperFaultDisputeGame.GameConstructorParams({
Expand Down Expand Up @@ -1644,7 +1660,7 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase {
deployProxy({
_l2ChainId: block.timestamp,
_proxyAdmin: _input.opChainConfigs[0].proxyAdmin,
_saltMixer: reusableSaltMixer(_input.opChainConfigs[0]),
_saltMixer: reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy),
_contractName: "DelayedWETH-Interop-Permissionless"
})
)
Expand All @@ -1663,7 +1679,11 @@ contract OPContractsManagerInteropMigrator is OPContractsManagerBase {
Blueprint.deployFrom(
blueprints().superPermissionlessDisputeGame1,
blueprints().superPermissionlessDisputeGame2,
computeSalt(block.timestamp, reusableSaltMixer(_input.opChainConfigs[0]), "SuperFaultDisputeGame"),
computeSalt(
block.timestamp,
reusableSaltMixer(_input.opChainConfigs[0].systemConfigProxy),
"SuperFaultDisputeGame"
),
encodePermissionlessSuperFDGConstructor(
ISuperFaultDisputeGame.GameConstructorParams({
gameType: GameTypes.SUPER_CANNON,
Expand Down Expand Up @@ -1787,6 +1807,13 @@ contract OPContractsManager is ISemver {
Claim absolutePrestate;
}

/// @notice The input required to identify a chain for updating prestates
struct UpdatePrestateInput {
ISystemConfig systemConfigProxy;
Claim cannonPrestate;
Claim cannonKonaPrestate;
}

struct AddGameInput {
string saltMixer;
ISystemConfig systemConfig;
Expand All @@ -1810,9 +1837,9 @@ contract OPContractsManager is ISemver {

// -------- Constants and Variables --------

/// @custom:semver 3.7.0
/// @custom:semver 3.8.0
function version() public pure virtual returns (string memory) {
return "3.7.0";
return "3.8.0";
}

OPContractsManagerGameTypeAdder public immutable opcmGameTypeAdder;
Expand Down Expand Up @@ -1984,9 +2011,9 @@ contract OPContractsManager is ISemver {
return abi.decode(returnData, (AddGameOutput[]));
}

/// @notice Updates the prestate hash for a new game type while keeping all other parameters the same
/// @param _prestateUpdateInputs The new prestate hash to use
function updatePrestate(OpChainConfig[] memory _prestateUpdateInputs) public {
/// @notice Updates the prestate hash for dispute games while keeping all other parameters the same
/// @param _prestateUpdateInputs The new prestate hashes to use
function updatePrestate(UpdatePrestateInput[] memory _prestateUpdateInputs) public {
if (address(this) == address(thisOPCM)) revert OnlyDelegatecall();

bytes memory data = abi.encodeCall(OPContractsManagerGameTypeAdder.updatePrestate, (_prestateUpdateInputs));
Expand Down
Loading