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
16 changes: 16 additions & 0 deletions packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol";
import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol";
import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol";
import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol";
import { ISharedLockbox } from "src/L1/interfaces/ISharedLockbox.sol";
import { IL1CrossDomainMessenger } from "src/L1/interfaces/IL1CrossDomainMessenger.sol";
import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol";
import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol";
Expand Down Expand Up @@ -577,6 +578,21 @@ library ChainAssertions {
// TODO: Add assertions for blueprints and setters?
}

/// @notice Asserts that the SharedLockbox is setup correctly
function checkSharedLockbox(Types.ContractSet memory _contracts, bool _isProxy) internal view {
ISharedLockbox sharedLockbox = ISharedLockbox(_contracts.SharedLockbox);
ISuperchainConfig superchainConfig = ISuperchainConfig(_contracts.SuperchainConfig);

console.log(
"Running chain assertions on the SharedLockbox %s at %s",
_isProxy ? "proxy" : "implementation",
address(sharedLockbox)
);

require(address(sharedLockbox) != address(0), "CHECK-SLB-10");
require(sharedLockbox.SUPERCHAIN_CONFIG() == address(superchainConfig), "CHECK-SLB-20");
}

/// @dev Asserts that for a given contract the value of a storage slot at an offset is 1 or 0xff.
/// A call to `initialize` will set it to 1 and a call to _disableInitializers will set it to 0xff.
function assertInitializedSlotIsSet(address _contractAddress, uint256 _slot, uint256 _offset) internal view {
Expand Down
26 changes: 22 additions & 4 deletions packages/contracts-bedrock/scripts/deploy/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ contract Deploy is Deployer {
L1ERC721Bridge: getAddress("L1ERC721BridgeProxy"),
ProtocolVersions: getAddress("ProtocolVersionsProxy"),
SuperchainConfig: getAddress("SuperchainConfigProxy"),
OPContractsManager: getAddress("OPContractsManager")
OPContractsManager: getAddress("OPContractsManager"),
SharedLockbox: getAddress("SharedLockboxProxy")
});
}

Expand All @@ -183,7 +184,8 @@ contract Deploy is Deployer {
L1ERC721Bridge: getAddress("L1ERC721Bridge"),
ProtocolVersions: getAddress("ProtocolVersions"),
SuperchainConfig: getAddress("SuperchainConfig"),
OPContractsManager: getAddress("OPContractsManager")
OPContractsManager: getAddress("OPContractsManager"),
SharedLockbox: getAddress("SharedLockbox")
});
}

Expand Down Expand Up @@ -222,16 +224,19 @@ contract Deploy is Deployer {
/// @notice Deploy a new OP Chain using an existing SuperchainConfig and ProtocolVersions
/// @param _superchainConfigProxy Address of the existing SuperchainConfig proxy
/// @param _protocolVersionsProxy Address of the existing ProtocolVersions proxy
/// @param _sharedLockboxProxy Address of the existing SharedLockbox proxy
/// @param _includeDump Whether to include a state dump after deployment
function runWithSuperchain(
address payable _superchainConfigProxy,
address payable _protocolVersionsProxy,
address payable _sharedLockboxProxy,
bool _includeDump
)
public
{
require(_superchainConfigProxy != address(0), "Deploy: must specify address for superchain config proxy");
require(_protocolVersionsProxy != address(0), "Deploy: must specify address for protocol versions proxy");
require(_sharedLockboxProxy != address(0), "Deploy: must specify address for shared lockbox proxy");

vm.chainId(cfg.l1ChainID());

Expand All @@ -245,6 +250,10 @@ contract Deploy is Deployer {
save("ProtocolVersions", pvProxy.implementation());
save("ProtocolVersionsProxy", _protocolVersionsProxy);

IProxy slProxy = IProxy(_sharedLockboxProxy);
save("SharedLockbox", slProxy.implementation());
save("SharedLockboxProxy", _sharedLockboxProxy);

_run(false);

if (_includeDump) {
Expand Down Expand Up @@ -324,9 +333,10 @@ contract Deploy is Deployer {
////////////////////////////////////////////////////////////////

/// @notice Deploy a full system with a new SuperchainConfig
/// The Superchain system has 2 singleton contracts which lie outside of an OP Chain:
/// The Superchain system has 3 singleton contracts which lie outside of an OP Chain:
/// 1. The SuperchainConfig contract
/// 2. The ProtocolVersions contract
/// 3. The SharedLockbox contract
function deploySuperchain() public {
console.log("Setting up Superchain");
DeploySuperchain ds = new DeploySuperchain();
Expand All @@ -348,11 +358,18 @@ contract Deploy is Deployer {
save("SuperchainConfig", address(dso.superchainConfigImpl()));
save("ProtocolVersionsProxy", address(dso.protocolVersionsProxy()));
save("ProtocolVersions", address(dso.protocolVersionsImpl()));
save("SharedLockboxProxy", address(dso.sharedLockboxProxy()));
save("SharedLockbox", address(dso.sharedLockboxImpl()));

// First run assertions for the ProtocolVersions and SuperchainConfig proxy contracts.
// First run assertions for the ProtocolVersions, SuperchainConfig and SharedLockbox proxy contracts.
Types.ContractSet memory contracts = _proxies();
ChainAssertions.checkProtocolVersions({ _contracts: contracts, _cfg: cfg, _isProxy: true });
ChainAssertions.checkSuperchainConfig({ _contracts: contracts, _cfg: cfg, _isProxy: true, _isPaused: false });
ChainAssertions.checkSharedLockbox({ _contracts: contracts, _isProxy: true });

// Then replace the SharedLockbox proxy with the implementation address and run assertions on it.
contracts.SharedLockbox = mustGetAddress("SharedLockbox");
ChainAssertions.checkSharedLockbox({ _contracts: contracts, _isProxy: false });

// Then replace the ProtocolVersions proxy with the implementation address and run assertions on it.
contracts.ProtocolVersions = mustGetAddress("ProtocolVersions");
Expand Down Expand Up @@ -384,6 +401,7 @@ contract Deploy is Deployer {
);
dii.set(dii.superchainConfigProxy.selector, mustGetAddress("SuperchainConfigProxy"));
dii.set(dii.protocolVersionsProxy.selector, mustGetAddress("ProtocolVersionsProxy"));
dii.set(dii.sharedLockboxProxy.selector, mustGetAddress("SharedLockboxProxy"));
dii.set(dii.salt.selector, _implSalt());

if (_isInterop) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { LibString } from "@solady/utils/LibString.sol";
import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol";
import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol";
import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol";
import { ISharedLockbox } from "src/L1/interfaces/ISharedLockbox.sol";

import { Constants } from "src/libraries/Constants.sol";
import { Predeploys } from "src/libraries/Predeploys.sol";
Expand Down Expand Up @@ -53,6 +54,7 @@ contract DeployImplementationsInput is BaseDeployIO {
// Outputs from DeploySuperchain.s.sol.
ISuperchainConfig internal _superchainConfigProxy;
IProtocolVersions internal _protocolVersionsProxy;
ISharedLockbox internal _sharedLockboxProxy;

string internal _standardVersionsToml;

Expand Down Expand Up @@ -88,6 +90,7 @@ contract DeployImplementationsInput is BaseDeployIO {
require(_addr != address(0), "DeployImplementationsInput: cannot set zero address");
if (_sel == this.superchainConfigProxy.selector) _superchainConfigProxy = ISuperchainConfig(_addr);
else if (_sel == this.protocolVersionsProxy.selector) _protocolVersionsProxy = IProtocolVersions(_addr);
else if (_sel == this.sharedLockboxProxy.selector) _sharedLockboxProxy = ISharedLockbox(_addr);
else revert("DeployImplementationsInput: unknown selector");
}

Expand Down Expand Up @@ -153,6 +156,11 @@ contract DeployImplementationsInput is BaseDeployIO {
require(address(_protocolVersionsProxy) != address(0), "DeployImplementationsInput: not set");
return _protocolVersionsProxy;
}

function sharedLockboxProxy() public view returns (ISharedLockbox) {
require(address(_sharedLockboxProxy) != address(0), "DeployImplementationsInput: not set");
return _sharedLockboxProxy;
}
}

contract DeployImplementationsOutput is BaseDeployIO {
Expand Down Expand Up @@ -711,13 +719,15 @@ contract DeployImplementations is Script {
} else {
uint256 proofMaturityDelaySeconds = _dii.proofMaturityDelaySeconds();
uint256 disputeGameFinalityDelaySeconds = _dii.disputeGameFinalityDelaySeconds();
address sharedLockbox = address(_dii.sharedLockboxProxy());
vm.broadcast(msg.sender);
impl = IOptimismPortal2(
DeployUtils.create1({
_name: "OptimismPortal2",
_args: DeployUtils.encodeConstructor(
abi.encodeCall(
IOptimismPortal2.__constructor__, (proofMaturityDelaySeconds, disputeGameFinalityDelaySeconds)
IOptimismPortal2.__constructor__,
(proofMaturityDelaySeconds, disputeGameFinalityDelaySeconds, sharedLockbox)
)
)
})
Expand Down Expand Up @@ -992,14 +1002,15 @@ contract DeployImplementationsInterop is DeployImplementations {
} else {
uint256 proofMaturityDelaySeconds = _dii.proofMaturityDelaySeconds();
uint256 disputeGameFinalityDelaySeconds = _dii.disputeGameFinalityDelaySeconds();
address sharedLockbox = address(_dii.sharedLockboxProxy());
vm.broadcast(msg.sender);
impl = IOptimismPortalInterop(
DeployUtils.create1({
_name: "OptimismPortalInterop",
_args: DeployUtils.encodeConstructor(
abi.encodeCall(
IOptimismPortalInterop.__constructor__,
(proofMaturityDelaySeconds, disputeGameFinalityDelaySeconds)
(proofMaturityDelaySeconds, disputeGameFinalityDelaySeconds, sharedLockbox)
)
)
})
Expand Down
70 changes: 69 additions & 1 deletion packages/contracts-bedrock/scripts/deploy/DeploySuperchain.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol";
import { IProtocolVersions, ProtocolVersion } from "src/L1/interfaces/IProtocolVersions.sol";
import { IProxyAdmin } from "src/universal/interfaces/IProxyAdmin.sol";
import { IProxy } from "src/universal/interfaces/IProxy.sol";
import { ISharedLockbox } from "src/L1/interfaces/ISharedLockbox.sol";

import { DeployUtils } from "scripts/libraries/DeployUtils.sol";
import { Solarray } from "scripts/libraries/Solarray.sol";
Expand Down Expand Up @@ -161,6 +162,8 @@ contract DeploySuperchainOutput is BaseDeployIO {
ISuperchainConfig internal _superchainConfigImpl;
ISuperchainConfig internal _superchainConfigProxy;
IProxyAdmin internal _superchainProxyAdmin;
ISharedLockbox internal _sharedLockboxImpl;
ISharedLockbox internal _sharedLockboxProxy;

// This method lets each field be set individually. The selector of an output's getter method
// is used to determine which field to set.
Expand All @@ -171,6 +174,8 @@ contract DeploySuperchainOutput is BaseDeployIO {
else if (_sel == this.superchainConfigProxy.selector) _superchainConfigProxy = ISuperchainConfig(_address);
else if (_sel == this.protocolVersionsImpl.selector) _protocolVersionsImpl = IProtocolVersions(_address);
else if (_sel == this.protocolVersionsProxy.selector) _protocolVersionsProxy = IProtocolVersions(_address);
else if (_sel == this.sharedLockboxImpl.selector) _sharedLockboxImpl = ISharedLockbox(_address);
else if (_sel == this.sharedLockboxProxy.selector) _sharedLockboxProxy = ISharedLockbox(_address);
else revert("DeploySuperchainOutput: unknown selector");
}

Expand All @@ -182,20 +187,25 @@ contract DeploySuperchainOutput is BaseDeployIO {
address(this.superchainConfigImpl()),
address(this.superchainConfigProxy()),
address(this.protocolVersionsImpl()),
address(this.protocolVersionsProxy())
address(this.protocolVersionsProxy()),
address(this.sharedLockboxImpl()),
address(this.sharedLockboxProxy())
);
DeployUtils.assertValidContractAddresses(addrs);

// To read the implementations we prank as the zero address due to the proxyCallIfNotAdmin modifier.
vm.startPrank(address(0));
address actualSuperchainConfigImpl = IProxy(payable(address(_superchainConfigProxy))).implementation();
address actualProtocolVersionsImpl = IProxy(payable(address(_protocolVersionsProxy))).implementation();
address actualSharedLockboxImpl = IProxy(payable(address(_sharedLockboxProxy))).implementation();
vm.stopPrank();

require(actualSuperchainConfigImpl == address(_superchainConfigImpl), "100"); // nosemgrep:
// sol-style-malformed-require
require(actualProtocolVersionsImpl == address(_protocolVersionsImpl), "200"); // nosemgrep:
// sol-style-malformed-require
require(actualSharedLockboxImpl == address(_sharedLockboxImpl), "300"); // nosemgrep:
// sol-style-malformed-require

assertValidDeploy(_dsi);
}
Expand Down Expand Up @@ -225,11 +235,22 @@ contract DeploySuperchainOutput is BaseDeployIO {
return _protocolVersionsProxy;
}

function sharedLockboxImpl() public view returns (ISharedLockbox) {
DeployUtils.assertValidContractAddress(address(_sharedLockboxImpl));
return _sharedLockboxImpl;
}

function sharedLockboxProxy() public view returns (ISharedLockbox) {
DeployUtils.assertValidContractAddress(address(_sharedLockboxProxy));
return _sharedLockboxProxy;
}

// -------- Deployment Assertions --------
function assertValidDeploy(DeploySuperchainInput _dsi) public {
assertValidSuperchainProxyAdmin(_dsi);
assertValidSuperchainConfig(_dsi);
assertValidProtocolVersions(_dsi);
assertValidSharedLockbox();
}

function assertValidSuperchainProxyAdmin(DeploySuperchainInput _dsi) internal view {
Expand Down Expand Up @@ -280,6 +301,21 @@ contract DeploySuperchainOutput is BaseDeployIO {
require(ProtocolVersion.unwrap(pv.required()) == 0, "PV-70");
require(ProtocolVersion.unwrap(pv.recommended()) == 0, "PV-80");
}

function assertValidSharedLockbox() internal {
// Proxy checks.
ISharedLockbox sl = sharedLockboxProxy();

vm.startPrank(address(0));
require(IProxy(payable(address(sl))).implementation() == address(sharedLockboxImpl()), "SLB-10");
require(IProxy(payable(address(sl))).admin() == address(superchainProxyAdmin()), "SLB-20");
require(sl.SUPERCHAIN_CONFIG() == address(superchainConfigProxy()), "SLB-30");
vm.stopPrank();

// Implementation checks.
sl = sharedLockboxImpl();
require(sl.SUPERCHAIN_CONFIG() == address(superchainConfigProxy()), "SLB-40");
}
}

// For all broadcasts in this script we explicitly specify the deployer as `msg.sender` because for
Expand All @@ -306,6 +342,7 @@ contract DeploySuperchain is Script {
deploySuperchainImplementationContracts(_dsi, _dso);
deployAndInitializeSuperchainConfig(_dsi, _dso);
deployAndInitializeProtocolVersions(_dsi, _dso);
deploySharedLockbox(_dsi, _dso);

// Transfer ownership of the ProxyAdmin from the deployer to the specified owner.
transferProxyAdminOwnership(_dsi, _dso);
Expand Down Expand Up @@ -415,6 +452,37 @@ contract DeploySuperchain is Script {
_dso.set(_dso.protocolVersionsProxy.selector, address(protocolVersionsProxy));
}

function deploySharedLockbox(DeploySuperchainInput, DeploySuperchainOutput _dso) public {
IProxyAdmin superchainProxyAdmin = _dso.superchainProxyAdmin();
ISuperchainConfig superchainConfigProxy = _dso.superchainConfigProxy();

vm.startBroadcast(msg.sender);
ISharedLockbox sharedLockboxImpl = ISharedLockbox(
DeployUtils.create1({
_name: "SharedLockbox",
_args: DeployUtils.encodeConstructor(
abi.encodeCall(ISharedLockbox.__constructor__, (address(superchainConfigProxy)))
)
})
);
ISharedLockbox sharedLockboxProxy = ISharedLockbox(
DeployUtils.create1({
_name: "Proxy",
_args: DeployUtils.encodeConstructor(
abi.encodeCall(IProxy.__constructor__, (address(superchainProxyAdmin)))
)
})
);
superchainProxyAdmin.upgrade(payable(address(sharedLockboxProxy)), address(sharedLockboxImpl));
vm.stopBroadcast();

vm.label(address(sharedLockboxImpl), "SharedLockboxImpl");
vm.label(address(sharedLockboxProxy), "SharedLockboxProxy");

_dso.set(_dso.sharedLockboxImpl.selector, address(sharedLockboxImpl));
_dso.set(_dso.sharedLockboxProxy.selector, address(sharedLockboxProxy));
}

function transferProxyAdminOwnership(DeploySuperchainInput _dsi, DeploySuperchainOutput _dso) public {
address superchainProxyAdminOwner = _dsi.superchainProxyAdminOwner();

Expand Down
1 change: 1 addition & 0 deletions packages/contracts-bedrock/scripts/libraries/Types.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ library Types {
address ProtocolVersions;
address SuperchainConfig;
address OPContractsManager;
address SharedLockbox;
}
}
14 changes: 7 additions & 7 deletions packages/contracts-bedrock/snapshots/.gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ GasBenchMark_L1BlockInterop_SetValuesInterop:test_setL1BlockValuesInterop_benchm
GasBenchMark_L1BlockInterop_SetValuesInterop_Warm:test_setL1BlockValuesInterop_benchmark() (gas: 5099)
GasBenchMark_L1Block_SetValuesEcotone:test_setL1BlockValuesEcotone_benchmark() (gas: 158531)
GasBenchMark_L1Block_SetValuesEcotone_Warm:test_setL1BlockValuesEcotone_benchmark() (gas: 7597)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 369280)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2967465)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 564398)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4076613)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 467098)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3512802)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 72664)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 369342)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2967527)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 564475)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4076690)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 467025)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3512729)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 72661)
GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 92973)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68422)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68986)
Expand Down
Loading