Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Front OPSM with Proxy and Initialize #11875

Merged
merged 11 commits into from
Sep 14, 2024
1 change: 1 addition & 0 deletions op-chain-ops/interopgen/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ func deploySuperchainToL1(l1Host *script.Host, superCfg *SuperchainConfig) (*Sup
Release: superCfg.Implementations.Release,
SuperchainConfigProxy: superDeployment.SuperchainConfigProxy,
ProtocolVersionsProxy: superDeployment.ProtocolVersionsProxy,
SuperchainProxyAdmin: superDeployment.SuperchainProxyAdmin,
UseInterop: superCfg.Implementations.UseInterop,
})
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions op-chain-ops/interopgen/deployers/implementations.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type DeployImplementationsInput struct {
Release string
SuperchainConfigProxy common.Address
ProtocolVersionsProxy common.Address
SuperchainProxyAdmin common.Address
UseInterop bool // if true, deploy Interop implementations
}

Expand Down
75 changes: 51 additions & 24 deletions packages/contracts-bedrock/scripts/DeployImplementations.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity 0.8.15;

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

import { LibString } from "@solady/utils/LibString.sol";

Expand Down Expand Up @@ -37,7 +38,7 @@ import { DeployUtils } from "scripts/libraries/DeployUtils.sol";
import { Solarray } from "scripts/libraries/Solarray.sol";

// See DeploySuperchain.s.sol for detailed comments on the script architecture used here.
contract DeployImplementationsInput {
contract DeployImplementationsInput is CommonBase {
uint256 internal _withdrawalDelaySeconds;
uint256 internal _minProposalSizeBytes;
uint256 internal _challengePeriodSeconds;
Expand Down Expand Up @@ -130,6 +131,15 @@ contract DeployImplementationsInput {
require(address(_protocolVersionsProxy) != address(0), "DeployImplementationsInput: not set");
return _protocolVersionsProxy;
}

function superchainProxyAdmin() public returns (ProxyAdmin) {
SuperchainConfig proxy = this.superchainConfigProxy();
// Can infer the superchainProxyAdmin from the superchainConfigProxy.
vm.prank(address(0));
ProxyAdmin proxyAdmin = ProxyAdmin(Proxy(payable(address(proxy))).admin());
require(address(proxyAdmin) != address(0), "DeployImplementationsInput: not set");
return proxyAdmin;
}
}

contract DeployImplementationsOutput {
Expand Down Expand Up @@ -169,7 +179,7 @@ contract DeployImplementationsOutput {
require(false, "DeployImplementationsOutput: not implemented");
}

function checkOutput() public view {
function checkOutput() public {
blmalone marked this conversation as resolved.
Show resolved Hide resolved
address[] memory addrs = Solarray.addresses(
address(this.opsm()),
address(this.optimismPortalImpl()),
Expand All @@ -186,8 +196,9 @@ contract DeployImplementationsOutput {
DeployUtils.assertValidContractAddresses(addrs);
}

function opsm() public view returns (OPStackManager) {
function opsm() public returns (OPStackManager) {
DeployUtils.assertValidContractAddress(address(_opsm));
DeployUtils.assertImplementationSet(address(_opsm));
return _opsm;
}

Expand Down Expand Up @@ -292,24 +303,34 @@ contract DeployImplementations is Script {
});
}

// Deploy and initialize a proxied OPStackManager.
function createOPSMContract(
DeployImplementationsInput _dii,
DeployImplementationsOutput,
OPStackManager.Blueprints memory blueprints
OPStackManager.Blueprints memory blueprints,
string memory release,
OPStackManager.ImplementationSetter[] memory setters
)
internal
virtual
returns (OPStackManager opsm_)
returns (OPStackManager opsmProxy_)
{
SuperchainConfig superchainConfigProxy = _dii.superchainConfigProxy();
ProtocolVersions protocolVersionsProxy = _dii.protocolVersionsProxy();
ProxyAdmin proxyAdmin = _dii.superchainProxyAdmin();

vm.broadcast(msg.sender);
opsm_ = new OPStackManager({
_superchainConfig: superchainConfigProxy,
_protocolVersions: protocolVersionsProxy,
_blueprints: blueprints
});
vm.startBroadcast(msg.sender);
Proxy proxy = new Proxy(address(msg.sender));
OPStackManager opsm = new OPStackManager(superchainConfigProxy, protocolVersionsProxy);

OPStackManager.InitializerInputs memory initializerInputs =
OPStackManager.InitializerInputs(blueprints, setters, release, true);
proxy.upgradeToAndCall(address(opsm), abi.encodeWithSelector(opsm.initialize.selector, initializerInputs));

proxy.changeAdmin(address(proxyAdmin)); // transfer ownership of Proxy contract to the ProxyAdmin contract
vm.stopBroadcast();

opsmProxy_ = OPStackManager(address(proxy));
}

function deployOPStackManager(DeployImplementationsInput _dii, DeployImplementationsOutput _dio) public virtual {
Expand All @@ -329,9 +350,6 @@ contract DeployImplementations is Script {
vm.stopBroadcast();
// forgefmt: disable-end

// This call contains a broadcast to deploy OPSM.
OPStackManager opsm = createOPSMContract(_dii, _dio, blueprints);

OPStackManager.ImplementationSetter[] memory setters = new OPStackManager.ImplementationSetter[](6);
setters[0] = OPStackManager.ImplementationSetter({
name: "L1ERC721Bridge",
Expand Down Expand Up @@ -359,8 +377,8 @@ contract DeployImplementations is Script {
info: OPStackManager.Implementation(address(_dio.l1StandardBridgeImpl()), L1StandardBridge.initialize.selector)
});

vm.broadcast(msg.sender);
opsm.setRelease({ _release: release, _isLatest: true, _setters: setters });
// This call contains a broadcast to deploy OPSM which is proxied.
OPStackManager opsm = createOPSMContract(_dii, _dio, blueprints, release, setters);

vm.label(address(opsm), "OPStackManager");
_dio.set(_dio.opsm.selector, address(opsm));
Expand Down Expand Up @@ -571,21 +589,30 @@ contract DeployImplementationsInterop is DeployImplementations {
function createOPSMContract(
DeployImplementationsInput _dii,
DeployImplementationsOutput,
OPStackManager.Blueprints memory blueprints
OPStackManager.Blueprints memory blueprints,
string memory release,
OPStackManager.ImplementationSetter[] memory setters
)
internal
override
returns (OPStackManager opsm_)
returns (OPStackManager opsmProxy_)
{
SuperchainConfig superchainConfigProxy = _dii.superchainConfigProxy();
ProtocolVersions protocolVersionsProxy = _dii.protocolVersionsProxy();
ProxyAdmin proxyAdmin = _dii.superchainProxyAdmin();

vm.broadcast(msg.sender);
opsm_ = new OPStackManagerInterop({
_superchainConfig: superchainConfigProxy,
_protocolVersions: protocolVersionsProxy,
_blueprints: blueprints
});
vm.startBroadcast(msg.sender);
Proxy proxy = new Proxy(address(msg.sender));
OPStackManager opsm = new OPStackManagerInterop(superchainConfigProxy, protocolVersionsProxy);

OPStackManager.InitializerInputs memory initializerInputs =
OPStackManager.InitializerInputs(blueprints, setters, release, true);
proxy.upgradeToAndCall(address(opsm), abi.encodeWithSelector(opsm.initialize.selector, initializerInputs));

proxy.changeAdmin(address(proxyAdmin)); // transfer ownership of Proxy contract to the ProxyAdmin contract
vm.stopBroadcast();

opsmProxy_ = OPStackManagerInterop(address(proxy));
}

function deployOptimismPortalImpl(
Expand Down
1 change: 1 addition & 0 deletions packages/contracts-bedrock/scripts/DeployOPChain.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ contract DeployOPChainInput {
return _l2ChainId;
}

// TODO: Check that opsm is proxied and it has an implementation.
function opsm() public view returns (OPStackManager) {
require(address(_opsm) != address(0), "DeployOPChainInput: not set");
return _opsm;
Expand Down
12 changes: 12 additions & 0 deletions packages/contracts-bedrock/scripts/libraries/DeployUtils.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import { Proxy } from "src/universal/Proxy.sol";
import { LibString } from "@solady/utils/LibString.sol";
import { Vm } from "forge-std/Vm.sol";

library DeployUtils {
Vm internal constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code")))));

// This takes a sender and an identifier and returns a deterministic address based on the two.
// The result is used to etch the input and output contracts to a deterministic address based on
// those two values, where the identifier represents the input or output contract, such as
Expand All @@ -18,6 +22,14 @@ library DeployUtils {
require(_who.code.length > 0, string.concat("DeployUtils: no code at ", LibString.toHexStringChecksummed(_who)));
}

function assertImplementationSet(address _proxy) internal {
// We prank as the zero address due to the Proxy's `proxyCallIfNotAdmin` modifier.
// Pranking inside this function also means it can no longer be considered `view`.
vm.prank(address(0));
address implementation = Proxy(payable(_proxy)).implementation();
assertValidContractAddress(implementation);
}

function assertValidContractAddresses(address[] memory _addrs) internal view {
// Assert that all addresses are non-zero and have code.
// We use LibString to avoid the need for adding cheatcodes to this contract.
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts-bedrock/semver-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
"sourceCodeHash": "0xde4df0f9633dc0cdb1c9f634003ea5b0f7c5c1aebc407bc1b2f44c0ecf938649"
},
"src/L1/OPStackManager.sol": {
"initCodeHash": "0xe1eab75651e3d81ad20ca01b1e7d373b25d716ee5f8841a56e56b4531a6e0e70",
"sourceCodeHash": "0x5182a2678dadb200dd255ecdfa395e5f7b1e1e27288e78ddf8802ab51ed2dd81"
"initCodeHash": "0x8081ca5dd48497b74758d1425ad6f025d6fd3cb144b4c5d4335b9a04e78b8474",
"sourceCodeHash": "0xb5fb50a9ddf8c0aee6d0e545f8ef4528f27698f3522cab744cd44ffaef6364d2"
},
"src/L1/OptimismPortal.sol": {
"initCodeHash": "0xb7a7a28d5b3b88334e7cb4bc1c5fbbf9f691d934e907a2fed6a30e461eb1c0f6",
Expand Down
Loading