Commit ef1bf0ac authored by Matt Solomon's avatar Matt Solomon Committed by GitHub

opsm: remove remaining structs (#11854)

* refactor: remove structs from DeployImplementations

* refactor: remove structs from DeployOPChain

* test: fix tests

* Update packages/contracts-bedrock/test/DeployOPChain.t.sol
Co-authored-by: default avatarBlaine Malone <blainemalone01@gmail.com>

* Update packages/contracts-bedrock/test/DeployOPChain.t.sol
Co-authored-by: default avatarBlaine Malone <blainemalone01@gmail.com>

* test: add missing assertions

* fix: update fuzz test timeout

---------
Co-authored-by: default avatarBlaine Malone <blainemalone01@gmail.com>
Co-authored-by: default avatarKelvin Fichter <kelvinfichter@gmail.com>
parent 935de9cb
......@@ -3,6 +3,8 @@ pragma solidity 0.8.15;
import { Script } from "forge-std/Script.sol";
import { LibString } from "@solady/utils/LibString.sol";
import { ProxyAdmin } from "src/universal/ProxyAdmin.sol";
import { Proxy } from "src/universal/Proxy.sol";
import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol";
......@@ -36,119 +38,128 @@ import { Solarray } from "scripts/libraries/Solarray.sol";
// See DeploySuperchain.s.sol for detailed comments on the script architecture used here.
contract DeployImplementationsInput {
struct Input {
uint256 withdrawalDelaySeconds;
uint256 minProposalSizeBytes;
uint256 challengePeriodSeconds;
uint256 proofMaturityDelaySeconds;
uint256 disputeGameFinalityDelaySeconds;
// We also deploy OP Stack Manager here, which has a dependency on the prior step of deploying
// the superchain contracts.
string release; // The release version to set OPSM implementations for, of the format `op-contracts/vX.Y.Z`.
SuperchainConfig superchainConfigProxy;
ProtocolVersions protocolVersionsProxy;
}
bool public inputSet = false;
Input internal inputs;
function loadInputFile(string memory _infile) public {
_infile;
Input memory parsedInput;
loadInput(parsedInput);
require(false, "DeployImplementationsInput: not implemented");
}
uint256 internal _withdrawalDelaySeconds;
uint256 internal _minProposalSizeBytes;
uint256 internal _challengePeriodSeconds;
uint256 internal _proofMaturityDelaySeconds;
uint256 internal _disputeGameFinalityDelaySeconds;
function loadInput(Input memory _input) public {
require(!inputSet, "DeployImplementationsInput: input already set");
require(
_input.challengePeriodSeconds <= type(uint64).max, "DeployImplementationsInput: challenge period too large"
);
// The release version to set OPSM implementations for, of the format `op-contracts/vX.Y.Z`.
string internal _release;
// Outputs from DeploySuperchain.s.sol.
SuperchainConfig internal _superchainConfigProxy;
ProtocolVersions internal _protocolVersionsProxy;
inputSet = true;
inputs = _input;
function set(bytes4 sel, uint256 _value) public {
require(_value != 0, "DeployImplementationsInput: cannot set zero value");
if (sel == this.withdrawalDelaySeconds.selector) {
_withdrawalDelaySeconds = _value;
} else if (sel == this.minProposalSizeBytes.selector) {
_minProposalSizeBytes = _value;
} else if (sel == this.challengePeriodSeconds.selector) {
require(_value <= type(uint64).max, "DeployImplementationsInput: challengePeriodSeconds too large");
_challengePeriodSeconds = _value;
} else if (sel == this.proofMaturityDelaySeconds.selector) {
_proofMaturityDelaySeconds = _value;
} else if (sel == this.disputeGameFinalityDelaySeconds.selector) {
_disputeGameFinalityDelaySeconds = _value;
} else {
revert("DeployImplementationsInput: unknown selector");
}
}
function set(bytes4 sel, string memory _value) public {
require(!LibString.eq(_value, ""), "DeployImplementationsInput: cannot set empty string");
if (sel == this.release.selector) _release = _value;
else revert("DeployImplementationsInput: unknown selector");
}
function assertInputSet() internal view {
require(inputSet, "DeployImplementationsInput: input not set");
function set(bytes4 sel, address _addr) public {
require(_addr != address(0), "DeployImplementationsInput: cannot set zero address");
if (sel == this.superchainConfigProxy.selector) _superchainConfigProxy = SuperchainConfig(_addr);
else if (sel == this.protocolVersionsProxy.selector) _protocolVersionsProxy = ProtocolVersions(_addr);
else revert("DeployImplementationsInput: unknown selector");
}
function input() public view returns (Input memory) {
assertInputSet();
return inputs;
function loadInputFile(string memory _infile) public pure {
_infile;
require(false, "DeployImplementationsInput: not implemented");
}
function withdrawalDelaySeconds() public view returns (uint256) {
assertInputSet();
return inputs.withdrawalDelaySeconds;
require(_withdrawalDelaySeconds != 0, "DeployImplementationsInput: not set");
return _withdrawalDelaySeconds;
}
function minProposalSizeBytes() public view returns (uint256) {
assertInputSet();
return inputs.minProposalSizeBytes;
require(_minProposalSizeBytes != 0, "DeployImplementationsInput: not set");
return _minProposalSizeBytes;
}
function challengePeriodSeconds() public view returns (uint256) {
assertInputSet();
return inputs.challengePeriodSeconds;
require(_challengePeriodSeconds != 0, "DeployImplementationsInput: not set");
require(
_challengePeriodSeconds <= type(uint64).max, "DeployImplementationsInput: challengePeriodSeconds too large"
);
return _challengePeriodSeconds;
}
function proofMaturityDelaySeconds() public view returns (uint256) {
assertInputSet();
return inputs.proofMaturityDelaySeconds;
require(_proofMaturityDelaySeconds != 0, "DeployImplementationsInput: not set");
return _proofMaturityDelaySeconds;
}
function disputeGameFinalityDelaySeconds() public view returns (uint256) {
assertInputSet();
return inputs.disputeGameFinalityDelaySeconds;
require(_disputeGameFinalityDelaySeconds != 0, "DeployImplementationsInput: not set");
return _disputeGameFinalityDelaySeconds;
}
function release() public view returns (string memory) {
assertInputSet();
return inputs.release;
require(!LibString.eq(_release, ""), "DeployImplementationsInput: not set");
return _release;
}
function superchainConfigProxy() public view returns (SuperchainConfig) {
assertInputSet();
return inputs.superchainConfigProxy;
require(address(_superchainConfigProxy) != address(0), "DeployImplementationsInput: not set");
return _superchainConfigProxy;
}
function protocolVersionsProxy() public view returns (ProtocolVersions) {
assertInputSet();
return inputs.protocolVersionsProxy;
require(address(_protocolVersionsProxy) != address(0), "DeployImplementationsInput: not set");
return _protocolVersionsProxy;
}
}
contract DeployImplementationsOutput {
struct Output {
OPStackManager opsm;
DelayedWETH delayedWETHImpl;
OptimismPortal2 optimismPortalImpl;
PreimageOracle preimageOracleSingleton;
MIPS mipsSingleton;
SystemConfig systemConfigImpl;
L1CrossDomainMessenger l1CrossDomainMessengerImpl;
L1ERC721Bridge l1ERC721BridgeImpl;
L1StandardBridge l1StandardBridgeImpl;
OptimismMintableERC20Factory optimismMintableERC20FactoryImpl;
DisputeGameFactory disputeGameFactoryImpl;
}
Output internal outputs;
OPStackManager internal _opsm;
DelayedWETH internal _delayedWETHImpl;
OptimismPortal2 internal _optimismPortalImpl;
PreimageOracle internal _preimageOracleSingleton;
MIPS internal _mipsSingleton;
SystemConfig internal _systemConfigImpl;
L1CrossDomainMessenger internal _l1CrossDomainMessengerImpl;
L1ERC721Bridge internal _l1ERC721BridgeImpl;
L1StandardBridge internal _l1StandardBridgeImpl;
OptimismMintableERC20Factory internal _optimismMintableERC20FactoryImpl;
DisputeGameFactory internal _disputeGameFactoryImpl;
function set(bytes4 sel, address _addr) public {
require(_addr != address(0), "DeployImplementationsOutput: cannot set zero address");
// forgefmt: disable-start
if (sel == this.opsm.selector) outputs.opsm = OPStackManager(payable(_addr));
else if (sel == this.optimismPortalImpl.selector) outputs.optimismPortalImpl = OptimismPortal2(payable(_addr));
else if (sel == this.delayedWETHImpl.selector) outputs.delayedWETHImpl = DelayedWETH(payable(_addr));
else if (sel == this.preimageOracleSingleton.selector) outputs.preimageOracleSingleton = PreimageOracle(_addr);
else if (sel == this.mipsSingleton.selector) outputs.mipsSingleton = MIPS(_addr);
else if (sel == this.systemConfigImpl.selector) outputs.systemConfigImpl = SystemConfig(_addr);
else if (sel == this.l1CrossDomainMessengerImpl.selector) outputs.l1CrossDomainMessengerImpl = L1CrossDomainMessenger(_addr);
else if (sel == this.l1ERC721BridgeImpl.selector) outputs.l1ERC721BridgeImpl = L1ERC721Bridge(_addr);
else if (sel == this.l1StandardBridgeImpl.selector) outputs.l1StandardBridgeImpl = L1StandardBridge(payable(_addr));
else if (sel == this.optimismMintableERC20FactoryImpl.selector) outputs.optimismMintableERC20FactoryImpl = OptimismMintableERC20Factory(_addr);
else if (sel == this.disputeGameFactoryImpl.selector) outputs.disputeGameFactoryImpl = DisputeGameFactory(_addr);
if (sel == this.opsm.selector) _opsm = OPStackManager(payable(_addr));
else if (sel == this.optimismPortalImpl.selector) _optimismPortalImpl = OptimismPortal2(payable(_addr));
else if (sel == this.delayedWETHImpl.selector) _delayedWETHImpl = DelayedWETH(payable(_addr));
else if (sel == this.preimageOracleSingleton.selector) _preimageOracleSingleton = PreimageOracle(_addr);
else if (sel == this.mipsSingleton.selector) _mipsSingleton = MIPS(_addr);
else if (sel == this.systemConfigImpl.selector) _systemConfigImpl = SystemConfig(_addr);
else if (sel == this.l1CrossDomainMessengerImpl.selector) _l1CrossDomainMessengerImpl = L1CrossDomainMessenger(_addr);
else if (sel == this.l1ERC721BridgeImpl.selector) _l1ERC721BridgeImpl = L1ERC721Bridge(_addr);
else if (sel == this.l1StandardBridgeImpl.selector) _l1StandardBridgeImpl = L1StandardBridge(payable(_addr));
else if (sel == this.optimismMintableERC20FactoryImpl.selector) _optimismMintableERC20FactoryImpl = OptimismMintableERC20Factory(_addr);
else if (sel == this.disputeGameFactoryImpl.selector) _disputeGameFactoryImpl = DisputeGameFactory(_addr);
else revert("DeployImplementationsOutput: unknown selector");
// forgefmt: disable-end
}
......@@ -158,80 +169,76 @@ contract DeployImplementationsOutput {
require(false, "DeployImplementationsOutput: not implemented");
}
function output() public view returns (Output memory) {
return outputs;
}
function checkOutput() public view {
address[] memory addrs = Solarray.addresses(
address(outputs.opsm),
address(outputs.optimismPortalImpl),
address(outputs.delayedWETHImpl),
address(outputs.preimageOracleSingleton),
address(outputs.mipsSingleton),
address(outputs.systemConfigImpl),
address(outputs.l1CrossDomainMessengerImpl),
address(outputs.l1ERC721BridgeImpl),
address(outputs.l1StandardBridgeImpl),
address(outputs.optimismMintableERC20FactoryImpl),
address(outputs.disputeGameFactoryImpl)
address(this.opsm()),
address(this.optimismPortalImpl()),
address(this.delayedWETHImpl()),
address(this.preimageOracleSingleton()),
address(this.mipsSingleton()),
address(this.systemConfigImpl()),
address(this.l1CrossDomainMessengerImpl()),
address(this.l1ERC721BridgeImpl()),
address(this.l1StandardBridgeImpl()),
address(this.optimismMintableERC20FactoryImpl()),
address(this.disputeGameFactoryImpl())
);
DeployUtils.assertValidContractAddresses(addrs);
}
function opsm() public view returns (OPStackManager) {
DeployUtils.assertValidContractAddress(address(outputs.opsm));
return outputs.opsm;
DeployUtils.assertValidContractAddress(address(_opsm));
return _opsm;
}
function optimismPortalImpl() public view returns (OptimismPortal2) {
DeployUtils.assertValidContractAddress(address(outputs.optimismPortalImpl));
return outputs.optimismPortalImpl;
DeployUtils.assertValidContractAddress(address(_optimismPortalImpl));
return _optimismPortalImpl;
}
function delayedWETHImpl() public view returns (DelayedWETH) {
DeployUtils.assertValidContractAddress(address(outputs.delayedWETHImpl));
return outputs.delayedWETHImpl;
DeployUtils.assertValidContractAddress(address(_delayedWETHImpl));
return _delayedWETHImpl;
}
function preimageOracleSingleton() public view returns (PreimageOracle) {
DeployUtils.assertValidContractAddress(address(outputs.preimageOracleSingleton));
return outputs.preimageOracleSingleton;
DeployUtils.assertValidContractAddress(address(_preimageOracleSingleton));
return _preimageOracleSingleton;
}
function mipsSingleton() public view returns (MIPS) {
DeployUtils.assertValidContractAddress(address(outputs.mipsSingleton));
return outputs.mipsSingleton;
DeployUtils.assertValidContractAddress(address(_mipsSingleton));
return _mipsSingleton;
}
function systemConfigImpl() public view returns (SystemConfig) {
DeployUtils.assertValidContractAddress(address(outputs.systemConfigImpl));
return outputs.systemConfigImpl;
DeployUtils.assertValidContractAddress(address(_systemConfigImpl));
return _systemConfigImpl;
}
function l1CrossDomainMessengerImpl() public view returns (L1CrossDomainMessenger) {
DeployUtils.assertValidContractAddress(address(outputs.l1CrossDomainMessengerImpl));
return outputs.l1CrossDomainMessengerImpl;
DeployUtils.assertValidContractAddress(address(_l1CrossDomainMessengerImpl));
return _l1CrossDomainMessengerImpl;
}
function l1ERC721BridgeImpl() public view returns (L1ERC721Bridge) {
DeployUtils.assertValidContractAddress(address(outputs.l1ERC721BridgeImpl));
return outputs.l1ERC721BridgeImpl;
DeployUtils.assertValidContractAddress(address(_l1ERC721BridgeImpl));
return _l1ERC721BridgeImpl;
}
function l1StandardBridgeImpl() public view returns (L1StandardBridge) {
DeployUtils.assertValidContractAddress(address(outputs.l1StandardBridgeImpl));
return outputs.l1StandardBridgeImpl;
DeployUtils.assertValidContractAddress(address(_l1StandardBridgeImpl));
return _l1StandardBridgeImpl;
}
function optimismMintableERC20FactoryImpl() public view returns (OptimismMintableERC20Factory) {
DeployUtils.assertValidContractAddress(address(outputs.optimismMintableERC20FactoryImpl));
return outputs.optimismMintableERC20FactoryImpl;
DeployUtils.assertValidContractAddress(address(_optimismMintableERC20FactoryImpl));
return _optimismMintableERC20FactoryImpl;
}
function disputeGameFactoryImpl() public view returns (DisputeGameFactory) {
DeployUtils.assertValidContractAddress(address(outputs.disputeGameFactoryImpl));
return outputs.disputeGameFactoryImpl;
DeployUtils.assertValidContractAddress(address(_disputeGameFactoryImpl));
return _disputeGameFactoryImpl;
}
}
......@@ -247,19 +254,7 @@ contract DeployImplementations is Script {
require(false, "DeployImplementations: run is not implemented");
}
function run(DeployImplementationsInput.Input memory _input)
public
returns (DeployImplementationsOutput.Output memory)
{
(DeployImplementationsInput dii, DeployImplementationsOutput dio) = etchIOContracts();
dii.loadInput(_input);
run(dii, dio);
return dio.output();
}
function run(DeployImplementationsInput _dii, DeployImplementationsOutput _dio) public {
require(_dii.inputSet(), "DeployImplementations: input not set");
// Deploy the implementations.
deploySystemConfigImpl(_dii, _dio);
deployL1CrossDomainMessengerImpl(_dii, _dio);
......@@ -521,7 +516,7 @@ contract DeployImplementations is Script {
// -------- Utilities --------
function etchIOContracts() internal returns (DeployImplementationsInput dii_, DeployImplementationsOutput dio_) {
function etchIOContracts() public returns (DeployImplementationsInput dii_, DeployImplementationsOutput dio_) {
(dii_, dio_) = getIOContracts();
vm.etch(address(dii_), type(DeployImplementationsInput).runtimeCode);
vm.etch(address(dio_), type(DeployImplementationsOutput).runtimeCode);
......
......@@ -3,6 +3,8 @@ pragma solidity 0.8.15;
import { Script } from "forge-std/Script.sol";
import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import { DeployUtils } from "scripts/libraries/DeployUtils.sol";
import { Solarray } from "scripts/libraries/Solarray.sol";
......@@ -24,151 +26,138 @@ import { L1StandardBridge } from "src/L1/L1StandardBridge.sol";
import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol";
contract DeployOPChainInput {
struct Roles {
address opChainProxyAdminOwner;
address systemConfigOwner;
address batcher;
address unsafeBlockSigner;
address proposer;
address challenger;
}
address internal _opChainProxyAdminOwner;
address internal _systemConfigOwner;
address internal _batcher;
address internal _unsafeBlockSigner;
address internal _proposer;
address internal _challenger;
// TODO Add fault proofs inputs in a future PR.
struct Input {
Roles roles;
uint32 basefeeScalar;
uint32 blobBaseFeeScalar;
uint256 l2ChainId;
OPStackManager opsm;
}
bool public inputSet = false;
Input internal inputs;
function loadInputFile(string memory _infile) public {
uint32 internal _basefeeScalar;
uint32 internal _blobBaseFeeScalar;
uint256 internal _l2ChainId;
OPStackManager internal _opsm;
function set(bytes4 _sel, address _addr) public {
require(_addr != address(0), "DeployOPChainInput: cannot set zero address");
if (_sel == this.opChainProxyAdminOwner.selector) _opChainProxyAdminOwner = _addr;
else if (_sel == this.systemConfigOwner.selector) _systemConfigOwner = _addr;
else if (_sel == this.batcher.selector) _batcher = _addr;
else if (_sel == this.unsafeBlockSigner.selector) _unsafeBlockSigner = _addr;
else if (_sel == this.proposer.selector) _proposer = _addr;
else if (_sel == this.challenger.selector) _challenger = _addr;
else if (_sel == this.opsm.selector) _opsm = OPStackManager(_addr);
else revert("DeployOPChainInput: unknown selector");
}
function set(bytes4 _sel, uint256 _value) public {
if (_sel == this.basefeeScalar.selector) {
_basefeeScalar = SafeCast.toUint32(_value);
} else if (_sel == this.blobBaseFeeScalar.selector) {
_blobBaseFeeScalar = SafeCast.toUint32(_value);
} else if (_sel == this.l2ChainId.selector) {
require(_value != 0 && _value != block.chainid, "DeployOPChainInput: invalid l2ChainId");
_l2ChainId = _value;
} else {
revert("DeployOPChainInput: unknown selector");
}
}
function loadInputFile(string memory _infile) public pure {
_infile;
Input memory parsedInput;
loadInput(parsedInput);
require(false, "DeployOPChainInput: not implemented");
}
function loadInput(Input memory _input) public {
require(!inputSet, "DeployOPChainInput: input already set");
require(_input.roles.opChainProxyAdminOwner != address(0), "DeployOPChainInput: null opChainProxyAdminOwner");
require(_input.roles.systemConfigOwner != address(0), "DeployOPChainInput: null systemConfigOwner");
require(_input.roles.batcher != address(0), "DeployOPChainInput: null batcher");
require(_input.roles.unsafeBlockSigner != address(0), "DeployOPChainInput: null unsafeBlockSigner");
require(_input.roles.proposer != address(0), "DeployOPChainInput: null proposer");
require(_input.roles.challenger != address(0), "DeployOPChainInput: null challenger");
require(_input.l2ChainId != 0 && _input.l2ChainId != block.chainid, "DeployOPChainInput: invalid l2ChainId");
require(address(_input.opsm) != address(0), "DeployOPChainInput: null opsm");
inputSet = true;
inputs = _input;
}
function assertInputSet() internal view {
require(inputSet, "DeployOPChainInput: input not set");
}
function input() public view returns (Input memory) {
assertInputSet();
return inputs;
}
function opChainProxyAdminOwner() public view returns (address) {
assertInputSet();
return inputs.roles.opChainProxyAdminOwner;
require(_opChainProxyAdminOwner != address(0), "DeployOPChainInput: not set");
return _opChainProxyAdminOwner;
}
function systemConfigOwner() public view returns (address) {
assertInputSet();
return inputs.roles.systemConfigOwner;
require(_systemConfigOwner != address(0), "DeployOPChainInput: not set");
return _systemConfigOwner;
}
function batcher() public view returns (address) {
assertInputSet();
return inputs.roles.batcher;
require(_batcher != address(0), "DeployOPChainInput: not set");
return _batcher;
}
function unsafeBlockSigner() public view returns (address) {
assertInputSet();
return inputs.roles.unsafeBlockSigner;
require(_unsafeBlockSigner != address(0), "DeployOPChainInput: not set");
return _unsafeBlockSigner;
}
function proposer() public view returns (address) {
assertInputSet();
return inputs.roles.proposer;
require(_proposer != address(0), "DeployOPChainInput: not set");
return _proposer;
}
function challenger() public view returns (address) {
assertInputSet();
return inputs.roles.challenger;
require(_challenger != address(0), "DeployOPChainInput: not set");
return _challenger;
}
function basefeeScalar() public view returns (uint32) {
assertInputSet();
return inputs.basefeeScalar;
require(_basefeeScalar != 0, "DeployOPChainInput: not set");
return _basefeeScalar;
}
function blobBaseFeeScalar() public view returns (uint32) {
assertInputSet();
return inputs.blobBaseFeeScalar;
require(_blobBaseFeeScalar != 0, "DeployOPChainInput: not set");
return _blobBaseFeeScalar;
}
function l2ChainId() public view returns (uint256) {
assertInputSet();
return inputs.l2ChainId;
require(_l2ChainId != 0, "DeployOPChainInput: not set");
require(_l2ChainId != block.chainid, "DeployOPChainInput: invalid l2ChainId");
return _l2ChainId;
}
function opsm() public view returns (OPStackManager) {
assertInputSet();
return inputs.opsm;
require(address(_opsm) != address(0), "DeployOPChainInput: not set");
return _opsm;
}
}
contract DeployOPChainOutput {
struct Output {
ProxyAdmin opChainProxyAdmin;
AddressManager addressManager;
L1ERC721Bridge l1ERC721BridgeProxy;
SystemConfig systemConfigProxy;
OptimismMintableERC20Factory optimismMintableERC20FactoryProxy;
L1StandardBridge l1StandardBridgeProxy;
L1CrossDomainMessenger l1CrossDomainMessengerProxy;
// Fault proof contracts below.
OptimismPortal2 optimismPortalProxy;
DisputeGameFactory disputeGameFactoryProxy;
DisputeGameFactory disputeGameFactoryImpl;
AnchorStateRegistry anchorStateRegistryProxy;
AnchorStateRegistry anchorStateRegistryImpl;
FaultDisputeGame faultDisputeGame;
PermissionedDisputeGame permissionedDisputeGame;
DelayedWETH delayedWETHPermissionedGameProxy;
DelayedWETH delayedWETHPermissionlessGameProxy;
}
Output internal outputs;
ProxyAdmin internal _opChainProxyAdmin;
AddressManager internal _addressManager;
L1ERC721Bridge internal _l1ERC721BridgeProxy;
SystemConfig internal _systemConfigProxy;
OptimismMintableERC20Factory internal _optimismMintableERC20FactoryProxy;
L1StandardBridge internal _l1StandardBridgeProxy;
L1CrossDomainMessenger internal _l1CrossDomainMessengerProxy;
OptimismPortal2 internal _optimismPortalProxy;
DisputeGameFactory internal _disputeGameFactoryProxy;
DisputeGameFactory internal _disputeGameFactoryImpl;
AnchorStateRegistry internal _anchorStateRegistryProxy;
AnchorStateRegistry internal _anchorStateRegistryImpl;
FaultDisputeGame internal _faultDisputeGame;
PermissionedDisputeGame internal _permissionedDisputeGame;
DelayedWETH internal _delayedWETHPermissionedGameProxy;
DelayedWETH internal _delayedWETHPermissionlessGameProxy;
function set(bytes4 sel, address _addr) public {
require(_addr != address(0), "DeployOPChainOutput: cannot set zero address");
// forgefmt: disable-start
if (sel == this.opChainProxyAdmin.selector) outputs.opChainProxyAdmin = ProxyAdmin(_addr) ;
else if (sel == this.addressManager.selector) outputs.addressManager = AddressManager(_addr) ;
else if (sel == this.l1ERC721BridgeProxy.selector) outputs.l1ERC721BridgeProxy = L1ERC721Bridge(_addr) ;
else if (sel == this.systemConfigProxy.selector) outputs.systemConfigProxy = SystemConfig(_addr) ;
else if (sel == this.optimismMintableERC20FactoryProxy.selector) outputs.optimismMintableERC20FactoryProxy = OptimismMintableERC20Factory(_addr) ;
else if (sel == this.l1StandardBridgeProxy.selector) outputs.l1StandardBridgeProxy = L1StandardBridge(payable(_addr)) ;
else if (sel == this.l1CrossDomainMessengerProxy.selector) outputs.l1CrossDomainMessengerProxy = L1CrossDomainMessenger(_addr) ;
else if (sel == this.optimismPortalProxy.selector) outputs.optimismPortalProxy = OptimismPortal2(payable(_addr)) ;
else if (sel == this.disputeGameFactoryProxy.selector) outputs.disputeGameFactoryProxy = DisputeGameFactory(_addr) ;
else if (sel == this.disputeGameFactoryImpl.selector) outputs.disputeGameFactoryImpl = DisputeGameFactory(_addr) ;
else if (sel == this.anchorStateRegistryProxy.selector) outputs.anchorStateRegistryProxy = AnchorStateRegistry(_addr) ;
else if (sel == this.anchorStateRegistryImpl.selector) outputs.anchorStateRegistryImpl = AnchorStateRegistry(_addr) ;
else if (sel == this.faultDisputeGame.selector) outputs.faultDisputeGame = FaultDisputeGame(_addr) ;
else if (sel == this.permissionedDisputeGame.selector) outputs.permissionedDisputeGame = PermissionedDisputeGame(_addr) ;
else if (sel == this.delayedWETHPermissionedGameProxy.selector) outputs.delayedWETHPermissionedGameProxy = DelayedWETH(payable(_addr)) ;
else if (sel == this.delayedWETHPermissionlessGameProxy.selector) outputs.delayedWETHPermissionlessGameProxy = DelayedWETH(payable(_addr)) ;
if (sel == this.opChainProxyAdmin.selector) _opChainProxyAdmin = ProxyAdmin(_addr) ;
else if (sel == this.addressManager.selector) _addressManager = AddressManager(_addr) ;
else if (sel == this.l1ERC721BridgeProxy.selector) _l1ERC721BridgeProxy = L1ERC721Bridge(_addr) ;
else if (sel == this.systemConfigProxy.selector) _systemConfigProxy = SystemConfig(_addr) ;
else if (sel == this.optimismMintableERC20FactoryProxy.selector) _optimismMintableERC20FactoryProxy = OptimismMintableERC20Factory(_addr) ;
else if (sel == this.l1StandardBridgeProxy.selector) _l1StandardBridgeProxy = L1StandardBridge(payable(_addr)) ;
else if (sel == this.l1CrossDomainMessengerProxy.selector) _l1CrossDomainMessengerProxy = L1CrossDomainMessenger(_addr) ;
else if (sel == this.optimismPortalProxy.selector) _optimismPortalProxy = OptimismPortal2(payable(_addr)) ;
else if (sel == this.disputeGameFactoryProxy.selector) _disputeGameFactoryProxy = DisputeGameFactory(_addr) ;
else if (sel == this.disputeGameFactoryImpl.selector) _disputeGameFactoryImpl = DisputeGameFactory(_addr) ;
else if (sel == this.anchorStateRegistryProxy.selector) _anchorStateRegistryProxy = AnchorStateRegistry(_addr) ;
else if (sel == this.anchorStateRegistryImpl.selector) _anchorStateRegistryImpl = AnchorStateRegistry(_addr) ;
else if (sel == this.faultDisputeGame.selector) _faultDisputeGame = FaultDisputeGame(_addr) ;
else if (sel == this.permissionedDisputeGame.selector) _permissionedDisputeGame = PermissionedDisputeGame(_addr) ;
else if (sel == this.delayedWETHPermissionedGameProxy.selector) _delayedWETHPermissionedGameProxy = DelayedWETH(payable(_addr)) ;
else if (sel == this.delayedWETHPermissionlessGameProxy.selector) _delayedWETHPermissionlessGameProxy = DelayedWETH(payable(_addr)) ;
else revert("DeployOPChainOutput: unknown selector");
// forgefmt: disable-end
}
......@@ -178,114 +167,110 @@ contract DeployOPChainOutput {
require(false, "DeployOPChainOutput: not implemented");
}
function output() public view returns (Output memory) {
return outputs;
}
function checkOutput() public view {
// With 16 addresses, we'd get a stack too deep error if we tried to do this inline as a
// single call to `Solarray.addresses`. So we split it into two calls.
address[] memory addrs1 = Solarray.addresses(
address(outputs.opChainProxyAdmin),
address(outputs.addressManager),
address(outputs.l1ERC721BridgeProxy),
address(outputs.systemConfigProxy),
address(outputs.optimismMintableERC20FactoryProxy),
address(outputs.l1StandardBridgeProxy),
address(outputs.l1CrossDomainMessengerProxy)
address(_opChainProxyAdmin),
address(_addressManager),
address(_l1ERC721BridgeProxy),
address(_systemConfigProxy),
address(_optimismMintableERC20FactoryProxy),
address(_l1StandardBridgeProxy),
address(_l1CrossDomainMessengerProxy)
);
address[] memory addrs2 = Solarray.addresses(
address(outputs.optimismPortalProxy),
address(outputs.disputeGameFactoryProxy),
address(outputs.disputeGameFactoryImpl),
address(outputs.anchorStateRegistryProxy),
address(outputs.anchorStateRegistryImpl),
address(outputs.faultDisputeGame),
address(outputs.permissionedDisputeGame),
address(outputs.delayedWETHPermissionedGameProxy),
address(outputs.delayedWETHPermissionlessGameProxy)
address(_optimismPortalProxy),
address(_disputeGameFactoryProxy),
address(_disputeGameFactoryImpl),
address(_anchorStateRegistryProxy),
address(_anchorStateRegistryImpl),
address(_faultDisputeGame),
address(_permissionedDisputeGame),
address(_delayedWETHPermissionedGameProxy),
address(_delayedWETHPermissionlessGameProxy)
);
DeployUtils.assertValidContractAddresses(Solarray.extend(addrs1, addrs2));
}
function opChainProxyAdmin() public view returns (ProxyAdmin) {
DeployUtils.assertValidContractAddress(address(outputs.opChainProxyAdmin));
return outputs.opChainProxyAdmin;
DeployUtils.assertValidContractAddress(address(_opChainProxyAdmin));
return _opChainProxyAdmin;
}
function addressManager() public view returns (AddressManager) {
DeployUtils.assertValidContractAddress(address(outputs.addressManager));
return outputs.addressManager;
DeployUtils.assertValidContractAddress(address(_addressManager));
return _addressManager;
}
function l1ERC721BridgeProxy() public view returns (L1ERC721Bridge) {
DeployUtils.assertValidContractAddress(address(outputs.l1ERC721BridgeProxy));
return outputs.l1ERC721BridgeProxy;
DeployUtils.assertValidContractAddress(address(_l1ERC721BridgeProxy));
return _l1ERC721BridgeProxy;
}
function systemConfigProxy() public view returns (SystemConfig) {
DeployUtils.assertValidContractAddress(address(outputs.systemConfigProxy));
return outputs.systemConfigProxy;
DeployUtils.assertValidContractAddress(address(_systemConfigProxy));
return _systemConfigProxy;
}
function optimismMintableERC20FactoryProxy() public view returns (OptimismMintableERC20Factory) {
DeployUtils.assertValidContractAddress(address(outputs.optimismMintableERC20FactoryProxy));
return outputs.optimismMintableERC20FactoryProxy;
DeployUtils.assertValidContractAddress(address(_optimismMintableERC20FactoryProxy));
return _optimismMintableERC20FactoryProxy;
}
function l1StandardBridgeProxy() public view returns (L1StandardBridge) {
DeployUtils.assertValidContractAddress(address(outputs.l1StandardBridgeProxy));
return outputs.l1StandardBridgeProxy;
DeployUtils.assertValidContractAddress(address(_l1StandardBridgeProxy));
return _l1StandardBridgeProxy;
}
function l1CrossDomainMessengerProxy() public view returns (L1CrossDomainMessenger) {
DeployUtils.assertValidContractAddress(address(outputs.l1CrossDomainMessengerProxy));
return outputs.l1CrossDomainMessengerProxy;
DeployUtils.assertValidContractAddress(address(_l1CrossDomainMessengerProxy));
return _l1CrossDomainMessengerProxy;
}
function optimismPortalProxy() public view returns (OptimismPortal2) {
DeployUtils.assertValidContractAddress(address(outputs.optimismPortalProxy));
return outputs.optimismPortalProxy;
DeployUtils.assertValidContractAddress(address(_optimismPortalProxy));
return _optimismPortalProxy;
}
function disputeGameFactoryProxy() public view returns (DisputeGameFactory) {
DeployUtils.assertValidContractAddress(address(outputs.disputeGameFactoryProxy));
return outputs.disputeGameFactoryProxy;
DeployUtils.assertValidContractAddress(address(_disputeGameFactoryProxy));
return _disputeGameFactoryProxy;
}
function disputeGameFactoryImpl() public view returns (DisputeGameFactory) {
DeployUtils.assertValidContractAddress(address(outputs.disputeGameFactoryImpl));
return outputs.disputeGameFactoryImpl;
DeployUtils.assertValidContractAddress(address(_disputeGameFactoryImpl));
return _disputeGameFactoryImpl;
}
function anchorStateRegistryProxy() public view returns (AnchorStateRegistry) {
DeployUtils.assertValidContractAddress(address(outputs.anchorStateRegistryProxy));
return outputs.anchorStateRegistryProxy;
DeployUtils.assertValidContractAddress(address(_anchorStateRegistryProxy));
return _anchorStateRegistryProxy;
}
function anchorStateRegistryImpl() public view returns (AnchorStateRegistry) {
DeployUtils.assertValidContractAddress(address(outputs.anchorStateRegistryImpl));
return outputs.anchorStateRegistryImpl;
DeployUtils.assertValidContractAddress(address(_anchorStateRegistryImpl));
return _anchorStateRegistryImpl;
}
function faultDisputeGame() public view returns (FaultDisputeGame) {
DeployUtils.assertValidContractAddress(address(outputs.faultDisputeGame));
return outputs.faultDisputeGame;
DeployUtils.assertValidContractAddress(address(_faultDisputeGame));
return _faultDisputeGame;
}
function permissionedDisputeGame() public view returns (PermissionedDisputeGame) {
DeployUtils.assertValidContractAddress(address(outputs.permissionedDisputeGame));
return outputs.permissionedDisputeGame;
DeployUtils.assertValidContractAddress(address(_permissionedDisputeGame));
return _permissionedDisputeGame;
}
function delayedWETHPermissionedGameProxy() public view returns (DelayedWETH) {
DeployUtils.assertValidContractAddress(address(outputs.delayedWETHPermissionedGameProxy));
return outputs.delayedWETHPermissionedGameProxy;
DeployUtils.assertValidContractAddress(address(_delayedWETHPermissionedGameProxy));
return _delayedWETHPermissionedGameProxy;
}
function delayedWETHPermissionlessGameProxy() public view returns (DelayedWETH) {
DeployUtils.assertValidContractAddress(address(outputs.delayedWETHPermissionlessGameProxy));
return outputs.delayedWETHPermissionlessGameProxy;
DeployUtils.assertValidContractAddress(address(_delayedWETHPermissionlessGameProxy));
return _delayedWETHPermissionlessGameProxy;
}
}
......@@ -300,16 +285,7 @@ contract DeployOPChain is Script {
require(false, "DeployOPChain: run is not implemented");
}
function run(DeployOPChainInput.Input memory _input) public returns (DeployOPChainOutput.Output memory) {
(DeployOPChainInput doi, DeployOPChainOutput doo) = etchIOContracts();
doi.loadInput(_input);
run(doi, doo);
return doo.output();
}
function run(DeployOPChainInput _doi, DeployOPChainOutput _doo) public {
require(_doi.inputSet(), "DeployOPChain: input not set");
OPStackManager opsm = _doi.opsm();
OPStackManager.Roles memory roles = OPStackManager.Roles({
......@@ -373,7 +349,7 @@ contract DeployOPChain is Script {
// -------- Utilities --------
function etchIOContracts() internal returns (DeployOPChainInput doi_, DeployOPChainOutput doo_) {
function etchIOContracts() public returns (DeployOPChainInput doi_, DeployOPChainOutput doo_) {
(doi_, doo_) = getIOContracts();
vm.etch(address(doi_), type(DeployOPChainInput).runtimeCode);
vm.etch(address(doo_), type(DeployOPChainOutput).runtimeCode);
......
......@@ -88,7 +88,7 @@ contract DeploySuperchainInput is CommonBase {
// These `set` methods let each input be set individually. The selector of an input's getter method
// is used to determine which field to set.
function set(bytes4 _sel, address _address) public {
require(_address != address(0), "DeploySuperchainInput: cannot set null address");
require(_address != address(0), "DeploySuperchainInput: cannot set zero address");
if (_sel == this.guardian.selector) _guardian = _address;
else if (_sel == this.protocolVersionsOwner.selector) _protocolVersionsOwner = _address;
else if (_sel == this.proxyAdminOwner.selector) _proxyAdminOwner = _address;
......@@ -181,6 +181,7 @@ contract DeploySuperchainOutput is CommonBase {
// This method lets each field be set individually. The selector of an output's getter method
// is used to determine which field to set.
function set(bytes4 sel, address _address) public {
require(_address != address(0), "DeploySuperchainOutput: cannot set zero address");
if (sel == this.superchainProxyAdmin.selector) _superchainProxyAdmin = ProxyAdmin(_address);
else if (sel == this.superchainConfigImpl.selector) _superchainConfigImpl = SuperchainConfig(_address);
else if (sel == this.superchainConfigProxy.selector) _superchainConfigProxy = SuperchainConfig(_address);
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol";
import { Test, stdStorage, StdStorage } from "forge-std/Test.sol";
import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol";
import { PreimageOracle } from "src/cannon/PreimageOracle.sol";
......@@ -28,54 +28,56 @@ import {
contract DeployImplementationsInput_Test is Test {
DeployImplementationsInput dii;
DeployImplementationsInput.Input input = DeployImplementationsInput.Input({
withdrawalDelaySeconds: 100,
minProposalSizeBytes: 200,
challengePeriodSeconds: 300,
proofMaturityDelaySeconds: 400,
disputeGameFinalityDelaySeconds: 500,
release: "op-contracts/latest",
superchainConfigProxy: SuperchainConfig(makeAddr("superchainConfigProxy")),
protocolVersionsProxy: ProtocolVersions(makeAddr("protocolVersionsProxy"))
});
uint256 withdrawalDelaySeconds = 100;
uint256 minProposalSizeBytes = 200;
uint256 challengePeriodSeconds = 300;
uint256 proofMaturityDelaySeconds = 400;
uint256 disputeGameFinalityDelaySeconds = 500;
string release = "op-contracts/latest";
SuperchainConfig superchainConfigProxy = SuperchainConfig(makeAddr("superchainConfigProxy"));
ProtocolVersions protocolVersionsProxy = ProtocolVersions(makeAddr("protocolVersionsProxy"));
function setUp() public {
dii = new DeployImplementationsInput();
}
function test_loadInput_succeeds() public {
dii.loadInput(input);
assertTrue(dii.inputSet(), "100");
// Compare the test input struct to the getter methods.
assertEq(input.withdrawalDelaySeconds, dii.withdrawalDelaySeconds(), "200");
assertEq(input.minProposalSizeBytes, dii.minProposalSizeBytes(), "300");
assertEq(input.challengePeriodSeconds, dii.challengePeriodSeconds(), "400");
assertEq(input.proofMaturityDelaySeconds, dii.proofMaturityDelaySeconds(), "500");
assertEq(input.disputeGameFinalityDelaySeconds, dii.disputeGameFinalityDelaySeconds(), "600");
// Compare the test input struct to the `input` getter method.
assertEq(keccak256(abi.encode(input)), keccak256(abi.encode(dii.input())), "800");
function test_loadInputFile_succeeds() public {
// See `test_loadInputFile_succeeds` in `DeploySuperchain.t.sol` for a reference implementation.
// This test is currently skipped because loadInputFile is not implemented.
vm.skip(true);
// Compare the test inputs to the getter methods.
// assertEq(withdrawalDelaySeconds, dii.withdrawalDelaySeconds(), "100");
// assertEq(minProposalSizeBytes, dii.minProposalSizeBytes(), "200");
// assertEq(challengePeriodSeconds, dii.challengePeriodSeconds(), "300");
// assertEq(proofMaturityDelaySeconds, dii.proofMaturityDelaySeconds(), "400");
// assertEq(disputeGameFinalityDelaySeconds, dii.disputeGameFinalityDelaySeconds(), "500");
}
function test_getters_whenNotSet_revert() public {
bytes memory expectedErr = "DeployImplementationsInput: input not set";
vm.expectRevert(expectedErr);
vm.expectRevert("DeployImplementationsInput: not set");
dii.withdrawalDelaySeconds();
vm.expectRevert(expectedErr);
vm.expectRevert("DeployImplementationsInput: not set");
dii.minProposalSizeBytes();
vm.expectRevert(expectedErr);
vm.expectRevert("DeployImplementationsInput: not set");
dii.challengePeriodSeconds();
vm.expectRevert(expectedErr);
vm.expectRevert("DeployImplementationsInput: not set");
dii.proofMaturityDelaySeconds();
vm.expectRevert(expectedErr);
vm.expectRevert("DeployImplementationsInput: not set");
dii.disputeGameFinalityDelaySeconds();
vm.expectRevert("DeployImplementationsInput: not set");
dii.release();
vm.expectRevert("DeployImplementationsInput: not set");
dii.superchainConfigProxy();
vm.expectRevert("DeployImplementationsInput: not set");
dii.protocolVersionsProxy();
}
}
......@@ -87,58 +89,54 @@ contract DeployImplementationsOutput_Test is Test {
}
function test_set_succeeds() public {
DeployImplementationsOutput.Output memory output = DeployImplementationsOutput.Output({
opsm: OPStackManager(makeAddr("opsm")),
optimismPortalImpl: OptimismPortal2(payable(makeAddr("optimismPortalImpl"))),
delayedWETHImpl: DelayedWETH(payable(makeAddr("delayedWETHImpl"))),
preimageOracleSingleton: PreimageOracle(makeAddr("preimageOracleSingleton")),
mipsSingleton: MIPS(makeAddr("mipsSingleton")),
systemConfigImpl: SystemConfig(makeAddr("systemConfigImpl")),
l1CrossDomainMessengerImpl: L1CrossDomainMessenger(makeAddr("l1CrossDomainMessengerImpl")),
l1ERC721BridgeImpl: L1ERC721Bridge(makeAddr("l1ERC721BridgeImpl")),
l1StandardBridgeImpl: L1StandardBridge(payable(makeAddr("l1StandardBridgeImpl"))),
optimismMintableERC20FactoryImpl: OptimismMintableERC20Factory(makeAddr("optimismMintableERC20FactoryImpl")),
disputeGameFactoryImpl: DisputeGameFactory(makeAddr("disputeGameFactoryImpl"))
});
vm.etch(address(output.opsm), hex"01");
vm.etch(address(output.optimismPortalImpl), hex"01");
vm.etch(address(output.delayedWETHImpl), hex"01");
vm.etch(address(output.preimageOracleSingleton), hex"01");
vm.etch(address(output.mipsSingleton), hex"01");
vm.etch(address(output.systemConfigImpl), hex"01");
vm.etch(address(output.l1CrossDomainMessengerImpl), hex"01");
vm.etch(address(output.l1ERC721BridgeImpl), hex"01");
vm.etch(address(output.l1StandardBridgeImpl), hex"01");
vm.etch(address(output.optimismMintableERC20FactoryImpl), hex"01");
vm.etch(address(output.disputeGameFactoryImpl), hex"01");
dio.set(dio.opsm.selector, address(output.opsm));
dio.set(dio.optimismPortalImpl.selector, address(output.optimismPortalImpl));
dio.set(dio.delayedWETHImpl.selector, address(output.delayedWETHImpl));
dio.set(dio.preimageOracleSingleton.selector, address(output.preimageOracleSingleton));
dio.set(dio.mipsSingleton.selector, address(output.mipsSingleton));
dio.set(dio.systemConfigImpl.selector, address(output.systemConfigImpl));
dio.set(dio.l1CrossDomainMessengerImpl.selector, address(output.l1CrossDomainMessengerImpl));
dio.set(dio.l1ERC721BridgeImpl.selector, address(output.l1ERC721BridgeImpl));
dio.set(dio.l1StandardBridgeImpl.selector, address(output.l1StandardBridgeImpl));
dio.set(dio.optimismMintableERC20FactoryImpl.selector, address(output.optimismMintableERC20FactoryImpl));
dio.set(dio.disputeGameFactoryImpl.selector, address(output.disputeGameFactoryImpl));
assertEq(address(output.opsm), address(dio.opsm()), "50");
assertEq(address(output.optimismPortalImpl), address(dio.optimismPortalImpl()), "100");
assertEq(address(output.delayedWETHImpl), address(dio.delayedWETHImpl()), "200");
assertEq(address(output.preimageOracleSingleton), address(dio.preimageOracleSingleton()), "300");
assertEq(address(output.mipsSingleton), address(dio.mipsSingleton()), "400");
assertEq(address(output.systemConfigImpl), address(dio.systemConfigImpl()), "500");
assertEq(address(output.l1CrossDomainMessengerImpl), address(dio.l1CrossDomainMessengerImpl()), "600");
assertEq(address(output.l1ERC721BridgeImpl), address(dio.l1ERC721BridgeImpl()), "700");
assertEq(address(output.l1StandardBridgeImpl), address(dio.l1StandardBridgeImpl()), "800");
assertEq(
address(output.optimismMintableERC20FactoryImpl), address(dio.optimismMintableERC20FactoryImpl()), "900"
);
assertEq(address(output.disputeGameFactoryImpl), address(dio.disputeGameFactoryImpl()), "950");
assertEq(keccak256(abi.encode(output)), keccak256(abi.encode(dio.output())), "1000");
OPStackManager opsm = OPStackManager(makeAddr("opsm"));
OptimismPortal2 optimismPortalImpl = OptimismPortal2(payable(makeAddr("optimismPortalImpl")));
DelayedWETH delayedWETHImpl = DelayedWETH(payable(makeAddr("delayedWETHImpl")));
PreimageOracle preimageOracleSingleton = PreimageOracle(makeAddr("preimageOracleSingleton"));
MIPS mipsSingleton = MIPS(makeAddr("mipsSingleton"));
SystemConfig systemConfigImpl = SystemConfig(makeAddr("systemConfigImpl"));
L1CrossDomainMessenger l1CrossDomainMessengerImpl =
L1CrossDomainMessenger(makeAddr("l1CrossDomainMessengerImpl"));
L1ERC721Bridge l1ERC721BridgeImpl = L1ERC721Bridge(makeAddr("l1ERC721BridgeImpl"));
L1StandardBridge l1StandardBridgeImpl = L1StandardBridge(payable(makeAddr("l1StandardBridgeImpl")));
OptimismMintableERC20Factory optimismMintableERC20FactoryImpl =
OptimismMintableERC20Factory(makeAddr("optimismMintableERC20FactoryImpl"));
DisputeGameFactory disputeGameFactoryImpl = DisputeGameFactory(makeAddr("disputeGameFactoryImpl"));
vm.etch(address(opsm), hex"01");
vm.etch(address(optimismPortalImpl), hex"01");
vm.etch(address(delayedWETHImpl), hex"01");
vm.etch(address(preimageOracleSingleton), hex"01");
vm.etch(address(mipsSingleton), hex"01");
vm.etch(address(systemConfigImpl), hex"01");
vm.etch(address(l1CrossDomainMessengerImpl), hex"01");
vm.etch(address(l1ERC721BridgeImpl), hex"01");
vm.etch(address(l1StandardBridgeImpl), hex"01");
vm.etch(address(optimismMintableERC20FactoryImpl), hex"01");
vm.etch(address(disputeGameFactoryImpl), hex"01");
dio.set(dio.opsm.selector, address(opsm));
dio.set(dio.optimismPortalImpl.selector, address(optimismPortalImpl));
dio.set(dio.delayedWETHImpl.selector, address(delayedWETHImpl));
dio.set(dio.preimageOracleSingleton.selector, address(preimageOracleSingleton));
dio.set(dio.mipsSingleton.selector, address(mipsSingleton));
dio.set(dio.systemConfigImpl.selector, address(systemConfigImpl));
dio.set(dio.l1CrossDomainMessengerImpl.selector, address(l1CrossDomainMessengerImpl));
dio.set(dio.l1ERC721BridgeImpl.selector, address(l1ERC721BridgeImpl));
dio.set(dio.l1StandardBridgeImpl.selector, address(l1StandardBridgeImpl));
dio.set(dio.optimismMintableERC20FactoryImpl.selector, address(optimismMintableERC20FactoryImpl));
dio.set(dio.disputeGameFactoryImpl.selector, address(disputeGameFactoryImpl));
assertEq(address(opsm), address(dio.opsm()), "50");
assertEq(address(optimismPortalImpl), address(dio.optimismPortalImpl()), "100");
assertEq(address(delayedWETHImpl), address(dio.delayedWETHImpl()), "200");
assertEq(address(preimageOracleSingleton), address(dio.preimageOracleSingleton()), "300");
assertEq(address(mipsSingleton), address(dio.mipsSingleton()), "400");
assertEq(address(systemConfigImpl), address(dio.systemConfigImpl()), "500");
assertEq(address(l1CrossDomainMessengerImpl), address(dio.l1CrossDomainMessengerImpl()), "600");
assertEq(address(l1ERC721BridgeImpl), address(dio.l1ERC721BridgeImpl()), "700");
assertEq(address(l1StandardBridgeImpl), address(dio.l1StandardBridgeImpl()), "800");
assertEq(address(optimismMintableERC20FactoryImpl), address(dio.optimismMintableERC20FactoryImpl()), "900");
assertEq(address(disputeGameFactoryImpl), address(dio.disputeGameFactoryImpl()), "950");
}
function test_getters_whenNotSet_revert() public {
......@@ -218,25 +216,25 @@ contract DeployImplementationsOutput_Test is Test {
}
contract DeployImplementations_Test is Test {
using stdStorage for StdStorage;
DeployImplementations deployImplementations;
DeployImplementationsInput dii;
DeployImplementationsOutput dio;
// Define a default input struct for testing.
DeployImplementationsInput.Input input = DeployImplementationsInput.Input({
withdrawalDelaySeconds: 100,
minProposalSizeBytes: 200,
challengePeriodSeconds: 300,
proofMaturityDelaySeconds: 400,
disputeGameFinalityDelaySeconds: 500,
release: "op-contracts/latest",
superchainConfigProxy: SuperchainConfig(makeAddr("superchainConfigProxy")),
protocolVersionsProxy: ProtocolVersions(makeAddr("protocolVersionsProxy"))
});
// Define default inputs for testing.
uint256 withdrawalDelaySeconds = 100;
uint256 minProposalSizeBytes = 200;
uint256 challengePeriodSeconds = 300;
uint256 proofMaturityDelaySeconds = 400;
uint256 disputeGameFinalityDelaySeconds = 500;
string release = "op-contracts/latest";
SuperchainConfig superchainConfigProxy = SuperchainConfig(makeAddr("superchainConfigProxy"));
ProtocolVersions protocolVersionsProxy = ProtocolVersions(makeAddr("protocolVersionsProxy"));
function setUp() public virtual {
deployImplementations = new DeployImplementations();
(dii, dio) = deployImplementations.getIOContracts();
(dii, dio) = deployImplementations.etchIOContracts();
}
// By deploying the `DeployImplementations` contract with this virtual function, we provide a
......@@ -246,50 +244,43 @@ contract DeployImplementations_Test is Test {
return new DeployImplementations();
}
function testFuzz_run_succeeds(DeployImplementationsInput.Input memory _input) public {
// This is a requirement in the PreimageOracle contract.
_input.challengePeriodSeconds = bound(_input.challengePeriodSeconds, 0, type(uint64).max);
DeployImplementationsOutput.Output memory output = deployImplementations.run(_input);
// Assert that individual input fields were properly set based on the input struct.
assertEq(_input.withdrawalDelaySeconds, dii.withdrawalDelaySeconds(), "100");
assertEq(_input.minProposalSizeBytes, dii.minProposalSizeBytes(), "200");
assertEq(_input.challengePeriodSeconds, dii.challengePeriodSeconds(), "300");
assertEq(_input.proofMaturityDelaySeconds, dii.proofMaturityDelaySeconds(), "400");
assertEq(_input.disputeGameFinalityDelaySeconds, dii.disputeGameFinalityDelaySeconds(), "500");
// Assert that individual output fields were properly set based on the output struct.
assertEq(address(output.optimismPortalImpl), address(dio.optimismPortalImpl()), "600");
assertEq(address(output.delayedWETHImpl), address(dio.delayedWETHImpl()), "700");
assertEq(address(output.preimageOracleSingleton), address(dio.preimageOracleSingleton()), "800");
assertEq(address(output.mipsSingleton), address(dio.mipsSingleton()), "900");
assertEq(address(output.systemConfigImpl), address(dio.systemConfigImpl()), "1000");
assertEq(address(output.l1CrossDomainMessengerImpl), address(dio.l1CrossDomainMessengerImpl()), "1100");
assertEq(address(output.l1ERC721BridgeImpl), address(dio.l1ERC721BridgeImpl()), "1200");
assertEq(address(output.l1StandardBridgeImpl), address(dio.l1StandardBridgeImpl()), "1300");
assertEq(
address(output.optimismMintableERC20FactoryImpl), address(dio.optimismMintableERC20FactoryImpl()), "1400"
);
assertEq(address(output.disputeGameFactoryImpl), address(dio.disputeGameFactoryImpl()), "1450");
// Assert that the full input and output structs were properly set.
assertEq(keccak256(abi.encode(_input)), keccak256(abi.encode(DeployImplementationsInput(dii).input())), "1500");
assertEq(
keccak256(abi.encode(output)), keccak256(abi.encode(DeployImplementationsOutput(dio).output())), "1600"
);
// Assert inputs were properly passed through to the contract initializers.
assertEq(output.delayedWETHImpl.delay(), _input.withdrawalDelaySeconds, "1700");
assertEq(output.preimageOracleSingleton.challengePeriod(), _input.challengePeriodSeconds, "1800");
assertEq(output.preimageOracleSingleton.minProposalSize(), _input.minProposalSizeBytes, "1900");
assertEq(output.optimismPortalImpl.proofMaturityDelaySeconds(), _input.proofMaturityDelaySeconds, "2000");
assertEq(
output.optimismPortalImpl.disputeGameFinalityDelaySeconds(), _input.disputeGameFinalityDelaySeconds, "2100"
);
function hash(bytes32 _seed, uint256 _i) internal pure returns (bytes32) {
return keccak256(abi.encode(_seed, _i));
}
function testFuzz_run_memory_succeeds(bytes32 _seed) public {
withdrawalDelaySeconds = uint256(hash(_seed, 0));
minProposalSizeBytes = uint256(hash(_seed, 1));
challengePeriodSeconds = bound(uint256(hash(_seed, 2)), 0, type(uint64).max);
proofMaturityDelaySeconds = uint256(hash(_seed, 3));
disputeGameFinalityDelaySeconds = uint256(hash(_seed, 4));
release = string(bytes.concat(hash(_seed, 5)));
superchainConfigProxy = SuperchainConfig(address(uint160(uint256(hash(_seed, 6)))));
protocolVersionsProxy = ProtocolVersions(address(uint160(uint256(hash(_seed, 7)))));
dii.set(dii.withdrawalDelaySeconds.selector, withdrawalDelaySeconds);
dii.set(dii.minProposalSizeBytes.selector, minProposalSizeBytes);
dii.set(dii.challengePeriodSeconds.selector, challengePeriodSeconds);
dii.set(dii.proofMaturityDelaySeconds.selector, proofMaturityDelaySeconds);
dii.set(dii.disputeGameFinalityDelaySeconds.selector, disputeGameFinalityDelaySeconds);
dii.set(dii.release.selector, release);
dii.set(dii.superchainConfigProxy.selector, address(superchainConfigProxy));
dii.set(dii.protocolVersionsProxy.selector, address(protocolVersionsProxy));
deployImplementations.run(dii, dio);
// Assert that individual input fields were properly set based on the inputs.
assertEq(withdrawalDelaySeconds, dii.withdrawalDelaySeconds(), "100");
assertEq(minProposalSizeBytes, dii.minProposalSizeBytes(), "200");
assertEq(challengePeriodSeconds, dii.challengePeriodSeconds(), "300");
assertEq(proofMaturityDelaySeconds, dii.proofMaturityDelaySeconds(), "400");
assertEq(disputeGameFinalityDelaySeconds, dii.disputeGameFinalityDelaySeconds(), "500");
assertEq(release, dii.release(), "525");
assertEq(address(superchainConfigProxy), address(dii.superchainConfigProxy()), "550");
assertEq(address(protocolVersionsProxy), address(dii.protocolVersionsProxy()), "575");
// Architecture assertions.
assertEq(address(output.mipsSingleton.oracle()), address(output.preimageOracleSingleton), "2200");
assertEq(address(dio.mipsSingleton().oracle()), address(dio.preimageOracleSingleton()), "600");
// Ensure that `checkOutput` passes. This is called by the `run` function during execution,
// so this just acts as a sanity check. It reverts on failure.
......@@ -297,9 +288,25 @@ contract DeployImplementations_Test is Test {
}
function testFuzz_run_largeChallengePeriodSeconds_reverts(uint256 _challengePeriodSeconds) public {
input.challengePeriodSeconds = bound(_challengePeriodSeconds, uint256(type(uint64).max) + 1, type(uint256).max);
vm.expectRevert("DeployImplementationsInput: challenge period too large");
deployImplementations.run(input);
// Set the defaults.
dii.set(dii.withdrawalDelaySeconds.selector, withdrawalDelaySeconds);
dii.set(dii.minProposalSizeBytes.selector, minProposalSizeBytes);
dii.set(dii.challengePeriodSeconds.selector, challengePeriodSeconds);
dii.set(dii.proofMaturityDelaySeconds.selector, proofMaturityDelaySeconds);
dii.set(dii.disputeGameFinalityDelaySeconds.selector, disputeGameFinalityDelaySeconds);
dii.set(dii.release.selector, release);
dii.set(dii.superchainConfigProxy.selector, address(superchainConfigProxy));
dii.set(dii.protocolVersionsProxy.selector, address(protocolVersionsProxy));
// Set the challenge period to a value that is too large, using vm.store because the setter
// method won't allow it.
challengePeriodSeconds = bound(_challengePeriodSeconds, uint256(type(uint64).max) + 1, type(uint256).max);
uint256 slot =
stdstore.enable_packed_slots().target(address(dii)).sig(dii.challengePeriodSeconds.selector).find();
vm.store(address(dii), bytes32(slot), bytes32(challengePeriodSeconds));
vm.expectRevert("DeployImplementationsInput: challengePeriodSeconds too large");
deployImplementations.run(dii, dio);
}
}
......
......@@ -34,48 +34,48 @@ import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC2
contract DeployOPChainInput_Test is Test {
DeployOPChainInput doi;
DeployOPChainInput.Input input = DeployOPChainInput.Input({
roles: DeployOPChainInput.Roles({
opChainProxyAdminOwner: makeAddr("opChainProxyAdminOwner"),
systemConfigOwner: makeAddr("systemConfigOwner"),
batcher: makeAddr("batcher"),
unsafeBlockSigner: makeAddr("unsafeBlockSigner"),
proposer: makeAddr("proposer"),
challenger: makeAddr("challenger")
}),
basefeeScalar: 100,
blobBaseFeeScalar: 200,
l2ChainId: 300,
opsm: OPStackManager(makeAddr("opsm"))
});
// Define defaults.
address opChainProxyAdminOwner = makeAddr("opChainProxyAdminOwner");
address systemConfigOwner = makeAddr("systemConfigOwner");
address batcher = makeAddr("batcher");
address unsafeBlockSigner = makeAddr("unsafeBlockSigner");
address proposer = makeAddr("proposer");
address challenger = makeAddr("challenger");
uint32 basefeeScalar = 100;
uint32 blobBaseFeeScalar = 200;
uint256 l2ChainId = 300;
OPStackManager opsm = OPStackManager(makeAddr("opsm"));
function setUp() public {
doi = new DeployOPChainInput();
}
function test_loadInput_succeeds() public {
doi.loadInput(input);
assertTrue(doi.inputSet(), "100");
// Compare the test input struct to the getter methods.
assertEq(input.roles.opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "200");
assertEq(input.roles.systemConfigOwner, doi.systemConfigOwner(), "300");
assertEq(input.roles.batcher, doi.batcher(), "400");
assertEq(input.roles.unsafeBlockSigner, doi.unsafeBlockSigner(), "500");
assertEq(input.roles.proposer, doi.proposer(), "600");
assertEq(input.roles.challenger, doi.challenger(), "700");
assertEq(input.basefeeScalar, doi.basefeeScalar(), "800");
assertEq(input.blobBaseFeeScalar, doi.blobBaseFeeScalar(), "900");
assertEq(input.l2ChainId, doi.l2ChainId(), "1000");
assertEq(address(input.opsm), address(doi.opsm()), "1100");
// Compare the test input struct to the `input` getter method.
assertEq(keccak256(abi.encode(input)), keccak256(abi.encode(doi.input())), "1200");
function test_set_succeeds() public {
doi.set(doi.opChainProxyAdminOwner.selector, opChainProxyAdminOwner);
doi.set(doi.systemConfigOwner.selector, systemConfigOwner);
doi.set(doi.batcher.selector, batcher);
doi.set(doi.unsafeBlockSigner.selector, unsafeBlockSigner);
doi.set(doi.proposer.selector, proposer);
doi.set(doi.challenger.selector, challenger);
doi.set(doi.basefeeScalar.selector, basefeeScalar);
doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar);
doi.set(doi.l2ChainId.selector, l2ChainId);
doi.set(doi.opsm.selector, address(opsm));
// Compare the default inputs to the getter methods.
assertEq(opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "200");
assertEq(systemConfigOwner, doi.systemConfigOwner(), "300");
assertEq(batcher, doi.batcher(), "400");
assertEq(unsafeBlockSigner, doi.unsafeBlockSigner(), "500");
assertEq(proposer, doi.proposer(), "600");
assertEq(challenger, doi.challenger(), "700");
assertEq(basefeeScalar, doi.basefeeScalar(), "800");
assertEq(blobBaseFeeScalar, doi.blobBaseFeeScalar(), "900");
assertEq(l2ChainId, doi.l2ChainId(), "1000");
assertEq(address(opsm), address(doi.opsm()), "1100");
}
function test_getters_whenNotSet_revert() public {
bytes memory expectedErr = "DeployOPChainInput: input not set";
bytes memory expectedErr = "DeployOPChainInput: not set";
vm.expectRevert(expectedErr);
doi.opChainProxyAdminOwner();
......@@ -109,90 +109,82 @@ contract DeployOPChainInput_Test is Test {
contract DeployOPChainOutput_Test is Test {
DeployOPChainOutput doo;
// Define default outputs to set.
// We set these in storage because doing it locally in test_set_succeeds results in stack too deep.
ProxyAdmin opChainProxyAdmin = ProxyAdmin(makeAddr("optimismPortal2Impl"));
AddressManager addressManager = AddressManager(makeAddr("delayedWETHImpl"));
L1ERC721Bridge l1ERC721BridgeProxy = L1ERC721Bridge(makeAddr("l1ERC721BridgeProxy"));
SystemConfig systemConfigProxy = SystemConfig(makeAddr("systemConfigProxy"));
OptimismMintableERC20Factory optimismMintableERC20FactoryProxy =
OptimismMintableERC20Factory(makeAddr("optimismMintableERC20FactoryProxy"));
L1StandardBridge l1StandardBridgeProxy = L1StandardBridge(payable(makeAddr("l1StandardBridgeProxy")));
L1CrossDomainMessenger l1CrossDomainMessengerProxy = L1CrossDomainMessenger(makeAddr("l1CrossDomainMessengerProxy"));
OptimismPortal2 optimismPortalProxy = OptimismPortal2(payable(makeAddr("optimismPortalProxy")));
DisputeGameFactory disputeGameFactoryProxy = DisputeGameFactory(makeAddr("disputeGameFactoryProxy"));
DisputeGameFactory disputeGameFactoryImpl = DisputeGameFactory(makeAddr("disputeGameFactoryImpl"));
AnchorStateRegistry anchorStateRegistryProxy = AnchorStateRegistry(makeAddr("anchorStateRegistryProxy"));
AnchorStateRegistry anchorStateRegistryImpl = AnchorStateRegistry(makeAddr("anchorStateRegistryImpl"));
FaultDisputeGame faultDisputeGame = FaultDisputeGame(makeAddr("faultDisputeGame"));
PermissionedDisputeGame permissionedDisputeGame = PermissionedDisputeGame(makeAddr("permissionedDisputeGame"));
DelayedWETH delayedWETHPermissionedGameProxy = DelayedWETH(payable(makeAddr("delayedWETHPermissionedGameProxy")));
DelayedWETH delayedWETHPermissionlessGameProxy =
DelayedWETH(payable(makeAddr("delayedWETHPermissionlessGameProxy")));
function setUp() public {
doo = new DeployOPChainOutput();
}
function test_set_succeeds() public {
DeployOPChainOutput.Output memory output = DeployOPChainOutput.Output({
opChainProxyAdmin: ProxyAdmin(makeAddr("optimismPortal2Impl")),
addressManager: AddressManager(makeAddr("delayedWETHImpl")),
l1ERC721BridgeProxy: L1ERC721Bridge(makeAddr("l1ERC721BridgeProxy")),
systemConfigProxy: SystemConfig(makeAddr("systemConfigProxy")),
optimismMintableERC20FactoryProxy: OptimismMintableERC20Factory(makeAddr("optimismMintableERC20FactoryProxy")),
l1StandardBridgeProxy: L1StandardBridge(payable(makeAddr("l1StandardBridgeProxy"))),
l1CrossDomainMessengerProxy: L1CrossDomainMessenger(makeAddr("l1CrossDomainMessengerProxy")),
optimismPortalProxy: OptimismPortal2(payable(makeAddr("optimismPortalProxy"))),
disputeGameFactoryProxy: DisputeGameFactory(makeAddr("disputeGameFactoryProxy")),
disputeGameFactoryImpl: DisputeGameFactory(makeAddr("disputeGameFactoryImpl")),
anchorStateRegistryProxy: AnchorStateRegistry(makeAddr("anchorStateRegistryProxy")),
anchorStateRegistryImpl: AnchorStateRegistry(makeAddr("anchorStateRegistryImpl")),
faultDisputeGame: FaultDisputeGame(makeAddr("faultDisputeGame")),
permissionedDisputeGame: PermissionedDisputeGame(makeAddr("permissionedDisputeGame")),
delayedWETHPermissionedGameProxy: DelayedWETH(payable(makeAddr("delayedWETHPermissionedGameProxy"))),
delayedWETHPermissionlessGameProxy: DelayedWETH(payable(makeAddr("delayedWETHPermissionlessGameProxy")))
});
vm.etch(address(output.opChainProxyAdmin), hex"01");
vm.etch(address(output.addressManager), hex"01");
vm.etch(address(output.l1ERC721BridgeProxy), hex"01");
vm.etch(address(output.systemConfigProxy), hex"01");
vm.etch(address(output.optimismMintableERC20FactoryProxy), hex"01");
vm.etch(address(output.l1StandardBridgeProxy), hex"01");
vm.etch(address(output.l1CrossDomainMessengerProxy), hex"01");
vm.etch(address(output.optimismPortalProxy), hex"01");
vm.etch(address(output.disputeGameFactoryProxy), hex"01");
vm.etch(address(output.disputeGameFactoryImpl), hex"01");
vm.etch(address(output.anchorStateRegistryProxy), hex"01");
vm.etch(address(output.anchorStateRegistryImpl), hex"01");
vm.etch(address(output.faultDisputeGame), hex"01");
vm.etch(address(output.permissionedDisputeGame), hex"01");
vm.etch(address(output.delayedWETHPermissionedGameProxy), hex"01");
vm.etch(address(output.delayedWETHPermissionlessGameProxy), hex"01");
doo.set(doo.opChainProxyAdmin.selector, address(output.opChainProxyAdmin));
doo.set(doo.addressManager.selector, address(output.addressManager));
doo.set(doo.l1ERC721BridgeProxy.selector, address(output.l1ERC721BridgeProxy));
doo.set(doo.systemConfigProxy.selector, address(output.systemConfigProxy));
doo.set(doo.optimismMintableERC20FactoryProxy.selector, address(output.optimismMintableERC20FactoryProxy));
doo.set(doo.l1StandardBridgeProxy.selector, address(output.l1StandardBridgeProxy));
doo.set(doo.l1CrossDomainMessengerProxy.selector, address(output.l1CrossDomainMessengerProxy));
doo.set(doo.optimismPortalProxy.selector, address(output.optimismPortalProxy));
doo.set(doo.disputeGameFactoryProxy.selector, address(output.disputeGameFactoryProxy));
doo.set(doo.disputeGameFactoryImpl.selector, address(output.disputeGameFactoryImpl));
doo.set(doo.anchorStateRegistryProxy.selector, address(output.anchorStateRegistryProxy));
doo.set(doo.anchorStateRegistryImpl.selector, address(output.anchorStateRegistryImpl));
doo.set(doo.faultDisputeGame.selector, address(output.faultDisputeGame));
doo.set(doo.permissionedDisputeGame.selector, address(output.permissionedDisputeGame));
doo.set(doo.delayedWETHPermissionedGameProxy.selector, address(output.delayedWETHPermissionedGameProxy));
doo.set(doo.delayedWETHPermissionlessGameProxy.selector, address(output.delayedWETHPermissionlessGameProxy));
assertEq(address(output.opChainProxyAdmin), address(doo.opChainProxyAdmin()), "100");
assertEq(address(output.addressManager), address(doo.addressManager()), "200");
assertEq(address(output.l1ERC721BridgeProxy), address(doo.l1ERC721BridgeProxy()), "300");
assertEq(address(output.systemConfigProxy), address(doo.systemConfigProxy()), "400");
assertEq(
address(output.optimismMintableERC20FactoryProxy), address(doo.optimismMintableERC20FactoryProxy()), "500"
);
assertEq(address(output.l1StandardBridgeProxy), address(doo.l1StandardBridgeProxy()), "600");
assertEq(address(output.l1CrossDomainMessengerProxy), address(doo.l1CrossDomainMessengerProxy()), "700");
assertEq(address(output.optimismPortalProxy), address(doo.optimismPortalProxy()), "800");
assertEq(address(output.disputeGameFactoryProxy), address(doo.disputeGameFactoryProxy()), "900");
assertEq(address(output.disputeGameFactoryImpl), address(doo.disputeGameFactoryImpl()), "1000");
assertEq(address(output.anchorStateRegistryProxy), address(doo.anchorStateRegistryProxy()), "1100");
assertEq(address(output.anchorStateRegistryImpl), address(doo.anchorStateRegistryImpl()), "1200");
assertEq(address(output.faultDisputeGame), address(doo.faultDisputeGame()), "1300");
assertEq(address(output.permissionedDisputeGame), address(doo.permissionedDisputeGame()), "1400");
assertEq(
address(output.delayedWETHPermissionedGameProxy), address(doo.delayedWETHPermissionedGameProxy()), "1500"
);
assertEq(
address(output.delayedWETHPermissionlessGameProxy),
address(doo.delayedWETHPermissionlessGameProxy()),
"1600"
);
assertEq(keccak256(abi.encode(output)), keccak256(abi.encode(doo.output())), "1700");
vm.etch(address(opChainProxyAdmin), hex"01");
vm.etch(address(addressManager), hex"01");
vm.etch(address(l1ERC721BridgeProxy), hex"01");
vm.etch(address(systemConfigProxy), hex"01");
vm.etch(address(optimismMintableERC20FactoryProxy), hex"01");
vm.etch(address(l1StandardBridgeProxy), hex"01");
vm.etch(address(l1CrossDomainMessengerProxy), hex"01");
vm.etch(address(optimismPortalProxy), hex"01");
vm.etch(address(disputeGameFactoryProxy), hex"01");
vm.etch(address(disputeGameFactoryImpl), hex"01");
vm.etch(address(anchorStateRegistryProxy), hex"01");
vm.etch(address(anchorStateRegistryImpl), hex"01");
vm.etch(address(faultDisputeGame), hex"01");
vm.etch(address(permissionedDisputeGame), hex"01");
vm.etch(address(delayedWETHPermissionedGameProxy), hex"01");
vm.etch(address(delayedWETHPermissionlessGameProxy), hex"01");
doo.set(doo.opChainProxyAdmin.selector, address(opChainProxyAdmin));
doo.set(doo.addressManager.selector, address(addressManager));
doo.set(doo.l1ERC721BridgeProxy.selector, address(l1ERC721BridgeProxy));
doo.set(doo.systemConfigProxy.selector, address(systemConfigProxy));
doo.set(doo.optimismMintableERC20FactoryProxy.selector, address(optimismMintableERC20FactoryProxy));
doo.set(doo.l1StandardBridgeProxy.selector, address(l1StandardBridgeProxy));
doo.set(doo.l1CrossDomainMessengerProxy.selector, address(l1CrossDomainMessengerProxy));
doo.set(doo.optimismPortalProxy.selector, address(optimismPortalProxy));
doo.set(doo.disputeGameFactoryProxy.selector, address(disputeGameFactoryProxy));
doo.set(doo.disputeGameFactoryImpl.selector, address(disputeGameFactoryImpl));
doo.set(doo.anchorStateRegistryProxy.selector, address(anchorStateRegistryProxy));
doo.set(doo.anchorStateRegistryImpl.selector, address(anchorStateRegistryImpl));
doo.set(doo.faultDisputeGame.selector, address(faultDisputeGame));
doo.set(doo.permissionedDisputeGame.selector, address(permissionedDisputeGame));
doo.set(doo.delayedWETHPermissionedGameProxy.selector, address(delayedWETHPermissionedGameProxy));
doo.set(doo.delayedWETHPermissionlessGameProxy.selector, address(delayedWETHPermissionlessGameProxy));
assertEq(address(opChainProxyAdmin), address(doo.opChainProxyAdmin()), "100");
assertEq(address(addressManager), address(doo.addressManager()), "200");
assertEq(address(l1ERC721BridgeProxy), address(doo.l1ERC721BridgeProxy()), "300");
assertEq(address(systemConfigProxy), address(doo.systemConfigProxy()), "400");
assertEq(address(optimismMintableERC20FactoryProxy), address(doo.optimismMintableERC20FactoryProxy()), "500");
assertEq(address(l1StandardBridgeProxy), address(doo.l1StandardBridgeProxy()), "600");
assertEq(address(l1CrossDomainMessengerProxy), address(doo.l1CrossDomainMessengerProxy()), "700");
assertEq(address(optimismPortalProxy), address(doo.optimismPortalProxy()), "800");
assertEq(address(disputeGameFactoryProxy), address(doo.disputeGameFactoryProxy()), "900");
assertEq(address(disputeGameFactoryImpl), address(doo.disputeGameFactoryImpl()), "1000");
assertEq(address(anchorStateRegistryProxy), address(doo.anchorStateRegistryProxy()), "1100");
assertEq(address(anchorStateRegistryImpl), address(doo.anchorStateRegistryImpl()), "1200");
assertEq(address(faultDisputeGame), address(doo.faultDisputeGame()), "1300");
assertEq(address(permissionedDisputeGame), address(doo.permissionedDisputeGame()), "1400");
assertEq(address(delayedWETHPermissionedGameProxy), address(doo.delayedWETHPermissionedGameProxy()), "1500");
assertEq(address(delayedWETHPermissionlessGameProxy), address(doo.delayedWETHPermissionlessGameProxy()), "1600");
}
function test_getters_whenNotSet_revert() public {
......@@ -324,8 +316,7 @@ contract DeployOPChain_TestBase is Test {
DeployOPChainInput doi;
DeployOPChainOutput doo;
// We define a default initial input set for DeploySuperchain. The other inputs are dependent
// on the outputs of the previous scripts, so we initialize them in the `setUp` method.
// Define default inputs for DeploySuperchain.
address proxyAdminOwner = makeAddr("defaultProxyAdminOwner");
address protocolVersionsOwner = makeAddr("defaultProtocolVersionsOwner");
address guardian = makeAddr("defaultGuardian");
......@@ -333,38 +324,32 @@ contract DeployOPChain_TestBase is Test {
ProtocolVersion requiredProtocolVersion = ProtocolVersion.wrap(1);
ProtocolVersion recommendedProtocolVersion = ProtocolVersion.wrap(2);
DeployImplementationsInput.Input deployImplementationsInput = DeployImplementationsInput.Input({
withdrawalDelaySeconds: 100,
minProposalSizeBytes: 200,
challengePeriodSeconds: 300,
proofMaturityDelaySeconds: 400,
disputeGameFinalityDelaySeconds: 500,
release: "op-contracts/latest",
// These are set during `setUp` since they are outputs of the previous step.
superchainConfigProxy: SuperchainConfig(address(0)),
protocolVersionsProxy: ProtocolVersions(address(0))
});
DeployOPChainInput.Input deployOPChainInput = DeployOPChainInput.Input({
roles: DeployOPChainInput.Roles({
opChainProxyAdminOwner: makeAddr("defaultOPChainProxyAdminOwner"),
systemConfigOwner: makeAddr("defaultSystemConfigOwner"),
batcher: makeAddr("defaultBatcher"),
unsafeBlockSigner: makeAddr("defaultUnsafeBlockSigner"),
proposer: makeAddr("defaultProposer"),
challenger: makeAddr("defaultChallenger")
}),
basefeeScalar: 100,
blobBaseFeeScalar: 200,
l2ChainId: 300,
// This is set during `setUp` since it is an output of the previous step.
opsm: OPStackManager(address(0))
});
// Set during `setUp`.
DeployImplementationsOutput.Output deployImplementationsOutput;
function setUp() public {
// Define default inputs for DeployImplementations.
// `superchainConfigProxy` and `protocolVersionsProxy` are set during `setUp` since they are
// outputs of the previous step.
uint256 withdrawalDelaySeconds = 100;
uint256 minProposalSizeBytes = 200;
uint256 challengePeriodSeconds = 300;
uint256 proofMaturityDelaySeconds = 400;
uint256 disputeGameFinalityDelaySeconds = 500;
string release = "op-contracts/latest";
SuperchainConfig superchainConfigProxy;
ProtocolVersions protocolVersionsProxy;
// Define default inputs for DeployOPChain.
// `opsm` is set during `setUp` since it is an output of the previous step.
address opChainProxyAdminOwner = makeAddr("defaultOPChainProxyAdminOwner");
address systemConfigOwner = makeAddr("defaultSystemConfigOwner");
address batcher = makeAddr("defaultBatcher");
address unsafeBlockSigner = makeAddr("defaultUnsafeBlockSigner");
address proposer = makeAddr("defaultProposer");
address challenger = makeAddr("defaultChallenger");
uint32 basefeeScalar = 100;
uint32 blobBaseFeeScalar = 200;
uint256 l2ChainId = 300;
OPStackManager opsm = OPStackManager(address(0));
function setUp() public virtual {
// Initialize deploy scripts.
DeploySuperchain deploySuperchain = new DeploySuperchain();
(DeploySuperchainInput dsi, DeploySuperchainOutput dso) = deploySuperchain.etchIOContracts();
......@@ -376,21 +361,31 @@ contract DeployOPChain_TestBase is Test {
dsi.set(dsi.recommendedProtocolVersion.selector, recommendedProtocolVersion);
DeployImplementations deployImplementations = new DeployImplementations();
(DeployImplementationsInput dii, DeployImplementationsOutput dio) = deployImplementations.etchIOContracts();
deployOPChain = new DeployOPChain();
(doi, doo) = deployOPChain.getIOContracts();
(doi, doo) = deployOPChain.etchIOContracts();
// Deploy the superchain contracts.
deploySuperchain.run(dsi, dso);
// Populate the input struct for DeployImplementations based on the output of DeploySuperchain.
deployImplementationsInput.superchainConfigProxy = dso.superchainConfigProxy();
deployImplementationsInput.protocolVersionsProxy = dso.protocolVersionsProxy();
// Deploy the implementations using the updated DeployImplementations input struct.
deployImplementationsOutput = deployImplementations.run(deployImplementationsInput);
// Set the OPStackManager on the input struct for DeployOPChain.
deployOPChainInput.opsm = deployImplementationsOutput.opsm;
// Populate the inputs for DeployImplementations based on the output of DeploySuperchain.
superchainConfigProxy = dso.superchainConfigProxy();
protocolVersionsProxy = dso.protocolVersionsProxy();
// Deploy the implementations.
dii.set(dii.withdrawalDelaySeconds.selector, withdrawalDelaySeconds);
dii.set(dii.minProposalSizeBytes.selector, minProposalSizeBytes);
dii.set(dii.challengePeriodSeconds.selector, challengePeriodSeconds);
dii.set(dii.proofMaturityDelaySeconds.selector, proofMaturityDelaySeconds);
dii.set(dii.disputeGameFinalityDelaySeconds.selector, disputeGameFinalityDelaySeconds);
dii.set(dii.release.selector, release);
dii.set(dii.superchainConfigProxy.selector, address(superchainConfigProxy));
dii.set(dii.protocolVersionsProxy.selector, address(protocolVersionsProxy));
deployImplementations.run(dii, dio);
// Set the OPStackManager input for DeployOPChain.
opsm = dio.opsm();
}
// See the function of the same name in the `DeployImplementations_Test` contract of
......@@ -401,56 +396,55 @@ contract DeployOPChain_TestBase is Test {
}
contract DeployOPChain_Test is DeployOPChain_TestBase {
function testFuzz_run_succeeds(DeployOPChainInput.Input memory _input) public {
vm.assume(_input.roles.opChainProxyAdminOwner != address(0));
vm.assume(_input.roles.systemConfigOwner != address(0));
vm.assume(_input.roles.batcher != address(0));
vm.assume(_input.roles.unsafeBlockSigner != address(0));
vm.assume(_input.roles.proposer != address(0));
vm.assume(_input.roles.challenger != address(0));
vm.assume(_input.l2ChainId != 0 && _input.l2ChainId != block.chainid);
_input.opsm = deployOPChainInput.opsm;
function hash(bytes32 _seed, uint256 _i) internal pure returns (bytes32) {
return keccak256(abi.encode(_seed, _i));
}
DeployOPChainOutput.Output memory output = deployOPChain.run(_input);
function testFuzz_run_memory_succeeds(bytes32 _seed) public {
opChainProxyAdminOwner = address(uint160(uint256(hash(_seed, 0))));
systemConfigOwner = address(uint160(uint256(hash(_seed, 1))));
batcher = address(uint160(uint256(hash(_seed, 2))));
unsafeBlockSigner = address(uint160(uint256(hash(_seed, 3))));
proposer = address(uint160(uint256(hash(_seed, 4))));
challenger = address(uint160(uint256(hash(_seed, 5))));
basefeeScalar = uint32(uint256(hash(_seed, 6)));
blobBaseFeeScalar = uint32(uint256(hash(_seed, 7)));
l2ChainId = uint256(uint256(hash(_seed, 8)));
doi.set(doi.opChainProxyAdminOwner.selector, opChainProxyAdminOwner);
doi.set(doi.systemConfigOwner.selector, systemConfigOwner);
doi.set(doi.batcher.selector, batcher);
doi.set(doi.unsafeBlockSigner.selector, unsafeBlockSigner);
doi.set(doi.proposer.selector, proposer);
doi.set(doi.challenger.selector, challenger);
doi.set(doi.basefeeScalar.selector, basefeeScalar);
doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar);
doi.set(doi.l2ChainId.selector, l2ChainId);
doi.set(doi.opsm.selector, address(opsm)); // Not fuzzed since it must be an actual instance.
deployOPChain.run(doi, doo);
// TODO Add fault proof contract assertions below once OPSM fully supports them.
// Assert that individual input fields were properly set based on the input struct.
assertEq(_input.roles.opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "100");
assertEq(_input.roles.systemConfigOwner, doi.systemConfigOwner(), "200");
assertEq(_input.roles.batcher, doi.batcher(), "300");
assertEq(_input.roles.unsafeBlockSigner, doi.unsafeBlockSigner(), "400");
assertEq(_input.roles.proposer, doi.proposer(), "500");
assertEq(_input.roles.challenger, doi.challenger(), "600");
assertEq(_input.basefeeScalar, doi.basefeeScalar(), "700");
assertEq(_input.blobBaseFeeScalar, doi.blobBaseFeeScalar(), "800");
assertEq(_input.l2ChainId, doi.l2ChainId(), "900");
// Assert that individual output fields were properly set based on the output struct.
assertEq(address(output.opChainProxyAdmin), address(doo.opChainProxyAdmin()), "1100");
assertEq(address(output.addressManager), address(doo.addressManager()), "1200");
assertEq(address(output.l1ERC721BridgeProxy), address(doo.l1ERC721BridgeProxy()), "1300");
assertEq(address(output.systemConfigProxy), address(doo.systemConfigProxy()), "1400");
assertEq(
address(output.optimismMintableERC20FactoryProxy), address(doo.optimismMintableERC20FactoryProxy()), "1500"
);
assertEq(address(output.l1StandardBridgeProxy), address(doo.l1StandardBridgeProxy()), "1600");
assertEq(address(output.l1CrossDomainMessengerProxy), address(doo.l1CrossDomainMessengerProxy()), "1700");
assertEq(address(output.optimismPortalProxy), address(doo.optimismPortalProxy()), "1800");
// Assert that the full input and output structs were properly set.
assertEq(keccak256(abi.encode(_input)), keccak256(abi.encode(DeployOPChainInput(doi).input())), "1900");
assertEq(keccak256(abi.encode(output)), keccak256(abi.encode(DeployOPChainOutput(doo).output())), "2000");
// Assert that individual input fields were properly set based on the inputs.
assertEq(opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "100");
assertEq(systemConfigOwner, doi.systemConfigOwner(), "200");
assertEq(batcher, doi.batcher(), "300");
assertEq(unsafeBlockSigner, doi.unsafeBlockSigner(), "400");
assertEq(proposer, doi.proposer(), "500");
assertEq(challenger, doi.challenger(), "600");
assertEq(basefeeScalar, doi.basefeeScalar(), "700");
assertEq(blobBaseFeeScalar, doi.blobBaseFeeScalar(), "800");
assertEq(l2ChainId, doi.l2ChainId(), "900");
// Assert inputs were properly passed through to the contract initializers.
assertEq(address(output.opChainProxyAdmin.owner()), _input.roles.opChainProxyAdminOwner, "2100");
assertEq(address(output.systemConfigProxy.owner()), _input.roles.systemConfigOwner, "2200");
address batcher = address(uint160(uint256(output.systemConfigProxy.batcherHash())));
assertEq(batcher, _input.roles.batcher, "2300");
assertEq(address(output.systemConfigProxy.unsafeBlockSigner()), _input.roles.unsafeBlockSigner, "2400");
// assertEq(address(...proposer()), _input.roles.proposer, "2500"); // TODO once we deploy dispute games.
// assertEq(address(...challenger()), _input.roles.challenger, "2600"); // TODO once we deploy dispute games.
assertEq(address(doo.opChainProxyAdmin().owner()), opChainProxyAdminOwner, "2100");
assertEq(address(doo.systemConfigProxy().owner()), systemConfigOwner, "2200");
address batcherActual = address(uint160(uint256(doo.systemConfigProxy().batcherHash())));
assertEq(batcherActual, batcher, "2300");
assertEq(address(doo.systemConfigProxy().unsafeBlockSigner()), unsafeBlockSigner, "2400");
// assertEq(address(...proposer()), proposer, "2500"); // TODO once we deploy dispute games.
// assertEq(address(...challenger()), challenger, "2600"); // TODO once we deploy dispute games.
// Most architecture assertions are handled within the OP Stack Manager itself and therefore
// we only assert on the things that are not visible onchain.
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol";
import { Test, stdStorage, StdStorage } from "forge-std/Test.sol";
import { DeployOPChainInput } from "scripts/DeployOPChain.s.sol";
import { DeployOPChain_TestBase } from "test/DeployOPChain.t.sol";
......@@ -32,42 +32,58 @@ contract OPStackManager_Harness is OPStackManager {
// we can use its setup to deploy the implementations similarly to how a real deployment would
// happen.
contract OPStackManager_Deploy_Test is DeployOPChain_TestBase {
using stdStorage for StdStorage;
function setUp() public override {
DeployOPChain_TestBase.setUp();
doi.set(doi.opChainProxyAdminOwner.selector, opChainProxyAdminOwner);
doi.set(doi.systemConfigOwner.selector, systemConfigOwner);
doi.set(doi.batcher.selector, batcher);
doi.set(doi.unsafeBlockSigner.selector, unsafeBlockSigner);
doi.set(doi.proposer.selector, proposer);
doi.set(doi.challenger.selector, challenger);
doi.set(doi.basefeeScalar.selector, basefeeScalar);
doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar);
doi.set(doi.l2ChainId.selector, l2ChainId);
doi.set(doi.opsm.selector, address(opsm));
}
// This helper function is used to convert the input struct type defined in DeployOPChain.s.sol
// to the input struct type defined in OPStackManager.sol.
function toOPSMDeployInput(DeployOPChainInput.Input memory input)
internal
pure
returns (OPStackManager.DeployInput memory)
{
function toOPSMDeployInput(DeployOPChainInput _doi) internal view returns (OPStackManager.DeployInput memory) {
return OPStackManager.DeployInput({
roles: OPStackManager.Roles({
opChainProxyAdminOwner: input.roles.opChainProxyAdminOwner,
systemConfigOwner: input.roles.systemConfigOwner,
batcher: input.roles.batcher,
unsafeBlockSigner: input.roles.unsafeBlockSigner,
proposer: input.roles.proposer,
challenger: input.roles.challenger
opChainProxyAdminOwner: _doi.opChainProxyAdminOwner(),
systemConfigOwner: _doi.systemConfigOwner(),
batcher: _doi.batcher(),
unsafeBlockSigner: _doi.unsafeBlockSigner(),
proposer: _doi.proposer(),
challenger: _doi.challenger()
}),
basefeeScalar: input.basefeeScalar,
blobBasefeeScalar: input.blobBaseFeeScalar,
l2ChainId: input.l2ChainId
basefeeScalar: _doi.basefeeScalar(),
blobBasefeeScalar: _doi.blobBaseFeeScalar(),
l2ChainId: _doi.l2ChainId()
});
}
function test_deploy_l2ChainIdEqualsZero_reverts() public {
deployOPChainInput.l2ChainId = 0;
OPStackManager.DeployInput memory deployInput = toOPSMDeployInput(doi);
deployInput.l2ChainId = 0;
vm.expectRevert(OPStackManager.InvalidChainId.selector);
deployImplementationsOutput.opsm.deploy(toOPSMDeployInput(deployOPChainInput));
opsm.deploy(deployInput);
}
function test_deploy_l2ChainIdEqualsCurrentChainId_reverts() public {
deployOPChainInput.l2ChainId = block.chainid;
OPStackManager.DeployInput memory deployInput = toOPSMDeployInput(doi);
deployInput.l2ChainId = block.chainid;
vm.expectRevert(OPStackManager.InvalidChainId.selector);
deployImplementationsOutput.opsm.deploy(toOPSMDeployInput(deployOPChainInput));
opsm.deploy(deployInput);
}
function test_deploy_succeeds() public {
deployImplementationsOutput.opsm.deploy(toOPSMDeployInput(deployOPChainInput));
opsm.deploy(toOPSMDeployInput(doi));
}
}
......
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