Commit 8f0a9b2d authored by blaine's avatar blaine Committed by GitHub

opcm-redesign: opcm targets a single release (#12851)

* fix: semver locking.

* fix: semver locking.

* feat: opcm impl contracts now type safe.

* feat: fixing test.

* fix: removing unused imports.

* fix: address didn't need to be payable.

* fix: moving all smart contract changes to first pr.

* fix: pr comments addressed.

* fix: removed InputContracts struct.

* fix: ran pre-pr

* fix: deploy implementations renaming version.

* fix: adding solidity changes to this pr.

* fix: adding v160 initializer back in.

* fix: removed branching logic from opcm.

* fix: removed SystemConfigV160.

* opcm-redesign: op-deployer changes

* fix: linting fix.

* fix: semver lock

---------
Co-authored-by: default avatarMatthew Slipper <me@matthewslipper.com>
parent c267d98b
...@@ -35,7 +35,7 @@ type SuperFaultProofConfig struct { ...@@ -35,7 +35,7 @@ type SuperFaultProofConfig struct {
} }
type OPCMImplementationsConfig struct { type OPCMImplementationsConfig struct {
Release string L1ContractsRelease string
FaultProof SuperFaultProofConfig FaultProof SuperFaultProofConfig
......
...@@ -170,10 +170,9 @@ func DeploySuperchainToL1(l1Host *script.Host, superCfg *SuperchainConfig) (*Sup ...@@ -170,10 +170,9 @@ func DeploySuperchainToL1(l1Host *script.Host, superCfg *SuperchainConfig) (*Sup
ProofMaturityDelaySeconds: superCfg.Implementations.FaultProof.ProofMaturityDelaySeconds, ProofMaturityDelaySeconds: superCfg.Implementations.FaultProof.ProofMaturityDelaySeconds,
DisputeGameFinalityDelaySeconds: superCfg.Implementations.FaultProof.DisputeGameFinalityDelaySeconds, DisputeGameFinalityDelaySeconds: superCfg.Implementations.FaultProof.DisputeGameFinalityDelaySeconds,
MipsVersion: superCfg.Implementations.FaultProof.MipsVersion, MipsVersion: superCfg.Implementations.FaultProof.MipsVersion,
Release: superCfg.Implementations.Release, L1ContractsRelease: superCfg.Implementations.L1ContractsRelease,
SuperchainConfigProxy: superDeployment.SuperchainConfigProxy, SuperchainConfigProxy: superDeployment.SuperchainConfigProxy,
ProtocolVersionsProxy: superDeployment.ProtocolVersionsProxy, ProtocolVersionsProxy: superDeployment.ProtocolVersionsProxy,
OpcmProxyOwner: superDeployment.SuperchainProxyAdmin,
UseInterop: superCfg.Implementations.UseInterop, UseInterop: superCfg.Implementations.UseInterop,
StandardVersionsToml: standard.VersionsMainnetData, StandardVersionsToml: standard.VersionsMainnetData,
}) })
...@@ -210,7 +209,7 @@ func DeployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme ...@@ -210,7 +209,7 @@ func DeployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme
BasefeeScalar: cfg.GasPriceOracleBaseFeeScalar, BasefeeScalar: cfg.GasPriceOracleBaseFeeScalar,
BlobBaseFeeScalar: cfg.GasPriceOracleBlobBaseFeeScalar, BlobBaseFeeScalar: cfg.GasPriceOracleBlobBaseFeeScalar,
L2ChainId: new(big.Int).SetUint64(cfg.L2ChainID), L2ChainId: new(big.Int).SetUint64(cfg.L2ChainID),
OpcmProxy: superDeployment.OpcmProxy, Opcm: superDeployment.Opcm,
SaltMixer: cfg.SaltMixer, SaltMixer: cfg.SaltMixer,
GasLimit: cfg.GasLimit, GasLimit: cfg.GasLimit,
DisputeGameType: cfg.DisputeGameType, DisputeGameType: cfg.DisputeGameType,
......
...@@ -9,8 +9,7 @@ type L1Deployment struct { ...@@ -9,8 +9,7 @@ type L1Deployment struct {
} }
type Implementations struct { type Implementations struct {
OpcmProxy common.Address `json:"OPCMProxy"` Opcm common.Address `json:"OPCM"`
OpcmImpl common.Address `json:"OPCMImpl"`
DelayedWETHImpl common.Address `json:"DelayedWETHImpl"` DelayedWETHImpl common.Address `json:"DelayedWETHImpl"`
OptimismPortalImpl common.Address `json:"OptimismPortalImpl"` OptimismPortalImpl common.Address `json:"OptimismPortalImpl"`
PreimageOracleSingleton common.Address `json:"PreimageOracleSingleton"` PreimageOracleSingleton common.Address `json:"PreimageOracleSingleton"`
......
...@@ -69,7 +69,7 @@ func (r *InteropDevRecipe) Build(addrs devkeys.Addresses) (*WorldConfig, error) ...@@ -69,7 +69,7 @@ func (r *InteropDevRecipe) Build(addrs devkeys.Addresses) (*WorldConfig, error)
ProtocolVersionsOwner: superchainProtocolVersionsOwner, ProtocolVersionsOwner: superchainProtocolVersionsOwner,
Deployer: superchainDeployer, Deployer: superchainDeployer,
Implementations: OPCMImplementationsConfig{ Implementations: OPCMImplementationsConfig{
Release: "dev", L1ContractsRelease: "dev",
FaultProof: SuperFaultProofConfig{ FaultProof: SuperFaultProofConfig{
WithdrawalDelaySeconds: big.NewInt(604800), WithdrawalDelaySeconds: big.NewInt(604800),
MinProposalSizeBytes: big.NewInt(10000), MinProposalSizeBytes: big.NewInt(10000),
......
...@@ -164,10 +164,6 @@ func OPCM(ctx context.Context, cfg OPCMConfig) error { ...@@ -164,10 +164,6 @@ func OPCM(ctx context.Context, cfg OPCMConfig) error {
if err != nil { if err != nil {
return fmt.Errorf("error getting standard versions TOML: %w", err) return fmt.Errorf("error getting standard versions TOML: %w", err)
} }
opcmProxyOwnerAddr, err := standard.ManagerOwnerAddrFor(chainIDU64)
if err != nil {
return fmt.Errorf("error getting superchain proxy admin: %w", err)
}
signer := opcrypto.SignerFnFromBind(opcrypto.PrivateKeySignerFn(cfg.privateKeyECDSA, chainID)) signer := opcrypto.SignerFnFromBind(opcrypto.PrivateKeySignerFn(cfg.privateKeyECDSA, chainID))
chainDeployer := crypto.PubkeyToAddress(cfg.privateKeyECDSA.PublicKey) chainDeployer := crypto.PubkeyToAddress(cfg.privateKeyECDSA.PublicKey)
...@@ -199,14 +195,14 @@ func OPCM(ctx context.Context, cfg OPCMConfig) error { ...@@ -199,14 +195,14 @@ func OPCM(ctx context.Context, cfg OPCMConfig) error {
} }
host.SetNonce(chainDeployer, nonce) host.SetNonce(chainDeployer, nonce)
var release string var l1ContractsRelease string
if cfg.ArtifactsLocator.IsTag() { if cfg.ArtifactsLocator.IsTag() {
release = cfg.ArtifactsLocator.Tag l1ContractsRelease = cfg.ArtifactsLocator.Tag
} else { } else {
release = "dev" l1ContractsRelease = "dev"
} }
lgr.Info("deploying OPCM", "release", release) lgr.Info("deploying OPCM", "l1ContractsRelease", l1ContractsRelease)
// We need to etch the Superchain addresses so that they have nonzero code // We need to etch the Superchain addresses so that they have nonzero code
// and the checks in the OPCM constructor pass. // and the checks in the OPCM constructor pass.
...@@ -238,10 +234,9 @@ func OPCM(ctx context.Context, cfg OPCMConfig) error { ...@@ -238,10 +234,9 @@ func OPCM(ctx context.Context, cfg OPCMConfig) error {
ProofMaturityDelaySeconds: new(big.Int).SetUint64(cfg.ProofMaturityDelaySeconds), ProofMaturityDelaySeconds: new(big.Int).SetUint64(cfg.ProofMaturityDelaySeconds),
DisputeGameFinalityDelaySeconds: new(big.Int).SetUint64(cfg.DisputeGameFinalityDelaySeconds), DisputeGameFinalityDelaySeconds: new(big.Int).SetUint64(cfg.DisputeGameFinalityDelaySeconds),
MipsVersion: new(big.Int).SetUint64(cfg.MIPSVersion), MipsVersion: new(big.Int).SetUint64(cfg.MIPSVersion),
Release: release, L1ContractsRelease: l1ContractsRelease,
SuperchainConfigProxy: superchainConfigAddr, SuperchainConfigProxy: superchainConfigAddr,
ProtocolVersionsProxy: protocolVersionsAddr, ProtocolVersionsProxy: protocolVersionsAddr,
OpcmProxyOwner: opcmProxyOwnerAddr,
StandardVersionsToml: standardVersionsTOML, StandardVersionsToml: standardVersionsTOML,
UseInterop: false, UseInterop: false,
}, },
......
...@@ -45,7 +45,7 @@ type OpChainDeployment struct { ...@@ -45,7 +45,7 @@ type OpChainDeployment struct {
} }
type ImplementationsDeployment struct { type ImplementationsDeployment struct {
OpcmProxyAddress common.Address `json:"opcmProxyAddress"` OpcmAddress common.Address `json:"opcmAddress"`
DelayedWETHImplAddress common.Address `json:"delayedWETHImplAddress"` DelayedWETHImplAddress common.Address `json:"delayedWETHImplAddress"`
OptimismPortalImplAddress common.Address `json:"optimismPortalImplAddress"` OptimismPortalImplAddress common.Address `json:"optimismPortalImplAddress"`
PreimageOracleSingletonAddress common.Address `json:"preimageOracleSingletonAddress"` PreimageOracleSingletonAddress common.Address `json:"preimageOracleSingletonAddress"`
...@@ -113,7 +113,7 @@ func L1(globalState *state.State, chainID common.Hash) (*L1Contracts, error) { ...@@ -113,7 +113,7 @@ func L1(globalState *state.State, chainID common.Hash) (*L1Contracts, error) {
// DelayedWETHPermissionlessGameProxyAddress: chainState.DelayedWETHPermissionlessGameProxyAddress, // DelayedWETHPermissionlessGameProxyAddress: chainState.DelayedWETHPermissionlessGameProxyAddress,
}, },
ImplementationsDeployment: ImplementationsDeployment{ ImplementationsDeployment: ImplementationsDeployment{
OpcmProxyAddress: globalState.ImplementationsDeployment.OpcmProxyAddress, OpcmAddress: globalState.ImplementationsDeployment.OpcmAddress,
DelayedWETHImplAddress: globalState.ImplementationsDeployment.DelayedWETHImplAddress, DelayedWETHImplAddress: globalState.ImplementationsDeployment.DelayedWETHImplAddress,
OptimismPortalImplAddress: globalState.ImplementationsDeployment.OptimismPortalImplAddress, OptimismPortalImplAddress: globalState.ImplementationsDeployment.OptimismPortalImplAddress,
PreimageOracleSingletonAddress: globalState.ImplementationsDeployment.PreimageOracleSingletonAddress, PreimageOracleSingletonAddress: globalState.ImplementationsDeployment.PreimageOracleSingletonAddress,
......
...@@ -207,6 +207,30 @@ func TestApplyExistingOPCM(t *testing.T) { ...@@ -207,6 +207,30 @@ func TestApplyExistingOPCM(t *testing.T) {
)) ))
validateOPChainDeployment(t, ethClientCodeGetter(ctx, l1Client), st, intent) validateOPChainDeployment(t, ethClientCodeGetter(ctx, l1Client), st, intent)
releases := standard.L1VersionsSepolia.Releases["op-contracts/v1.6.0"]
implTests := []struct {
name string
expAddr common.Address
actAddr common.Address
}{
{"OptimismPortal", releases.OptimismPortal.ImplementationAddress, st.ImplementationsDeployment.OptimismPortalImplAddress},
{"SystemConfig,", releases.SystemConfig.ImplementationAddress, st.ImplementationsDeployment.SystemConfigImplAddress},
{"L1CrossDomainMessenger", releases.L1CrossDomainMessenger.ImplementationAddress, st.ImplementationsDeployment.L1CrossDomainMessengerImplAddress},
{"L1ERC721Bridge", releases.L1ERC721Bridge.ImplementationAddress, st.ImplementationsDeployment.L1ERC721BridgeImplAddress},
{"L1StandardBridge", releases.L1StandardBridge.ImplementationAddress, st.ImplementationsDeployment.L1StandardBridgeImplAddress},
{"OptimismMintableERC20Factory", releases.OptimismMintableERC20Factory.ImplementationAddress, st.ImplementationsDeployment.OptimismMintableERC20FactoryImplAddress},
{"DisputeGameFactory", releases.DisputeGameFactory.ImplementationAddress, st.ImplementationsDeployment.DisputeGameFactoryImplAddress},
{"MIPS", releases.MIPS.Address, st.ImplementationsDeployment.MipsSingletonAddress},
{"PreimageOracle", releases.PreimageOracle.Address, st.ImplementationsDeployment.PreimageOracleSingletonAddress},
{"DelayedWETH", releases.DelayedWETH.ImplementationAddress, st.ImplementationsDeployment.DelayedWETHImplAddress},
}
for _, tt := range implTests {
t.Run(tt.name, func(t *testing.T) {
require.Equal(t, tt.expAddr, tt.actAddr)
})
}
} }
func TestL2BlockTimeOverride(t *testing.T) { func TestL2BlockTimeOverride(t *testing.T) {
...@@ -571,7 +595,7 @@ func validateSuperchainDeployment(t *testing.T, st *state.State, cg codeGetter) ...@@ -571,7 +595,7 @@ func validateSuperchainDeployment(t *testing.T, st *state.State, cg codeGetter)
{"SuperchainConfigImpl", st.SuperchainDeployment.SuperchainConfigImplAddress}, {"SuperchainConfigImpl", st.SuperchainDeployment.SuperchainConfigImplAddress},
{"ProtocolVersionsProxy", st.SuperchainDeployment.ProtocolVersionsProxyAddress}, {"ProtocolVersionsProxy", st.SuperchainDeployment.ProtocolVersionsProxyAddress},
{"ProtocolVersionsImpl", st.SuperchainDeployment.ProtocolVersionsImplAddress}, {"ProtocolVersionsImpl", st.SuperchainDeployment.ProtocolVersionsImplAddress},
{"OpcmProxy", st.ImplementationsDeployment.OpcmProxyAddress}, {"Opcm", st.ImplementationsDeployment.OpcmAddress},
{"PreimageOracleSingleton", st.ImplementationsDeployment.PreimageOracleSingletonAddress}, {"PreimageOracleSingleton", st.ImplementationsDeployment.PreimageOracleSingletonAddress},
{"MipsSingleton", st.ImplementationsDeployment.MipsSingletonAddress}, {"MipsSingleton", st.ImplementationsDeployment.MipsSingletonAddress},
} }
......
...@@ -48,57 +48,6 @@ func (c *Contract) GenericAddressGetter(ctx context.Context, functionName string ...@@ -48,57 +48,6 @@ func (c *Contract) GenericAddressGetter(ctx context.Context, functionName string
return c.callContractMethod(ctx, functionName, abi.Arguments{}) return c.callContractMethod(ctx, functionName, abi.Arguments{})
} }
// GetImplementation retrieves the Implementation struct for a given release and contract name.
func (c *Contract) GetOPCMImplementationAddress(ctx context.Context, release, contractName string) (common.Address, error) {
methodName := "implementations"
method := abi.NewMethod(
methodName,
methodName,
abi.Function,
"view",
true,
false,
abi.Arguments{
{Name: "release", Type: mustType("string")},
{Name: "contractName", Type: mustType("string")},
},
abi.Arguments{
{Name: "logic", Type: mustType("address")},
{Name: "initializer", Type: mustType("bytes4")},
},
)
calldata, err := method.Inputs.Pack(release, contractName)
if err != nil {
return common.Address{}, fmt.Errorf("failed to pack inputs: %w", err)
}
msg := ethereum.CallMsg{
To: &c.addr,
Data: append(bytes.Clone(method.ID), calldata...),
}
result, err := c.client.CallContract(ctx, msg, nil)
if err != nil {
return common.Address{}, fmt.Errorf("failed to call contract: %w", err)
}
out, err := method.Outputs.Unpack(result)
if err != nil {
return common.Address{}, fmt.Errorf("failed to unpack result: %w", err)
}
if len(out) != 2 {
return common.Address{}, fmt.Errorf("unexpected output length: %d", len(out))
}
logic, ok := out[0].(common.Address)
if !ok {
return common.Address{}, fmt.Errorf("unexpected type for logic: %T", out[0])
}
return logic, nil
}
func (c *Contract) callContractMethod(ctx context.Context, methodName string, inputs abi.Arguments, args ...interface{}) (common.Address, error) { func (c *Contract) callContractMethod(ctx context.Context, methodName string, inputs abi.Arguments, args ...interface{}) (common.Address, error) {
method := abi.NewMethod( method := abi.NewMethod(
methodName, methodName,
......
...@@ -18,12 +18,11 @@ type DeployImplementationsInput struct { ...@@ -18,12 +18,11 @@ type DeployImplementationsInput struct {
DisputeGameFinalityDelaySeconds *big.Int DisputeGameFinalityDelaySeconds *big.Int
MipsVersion *big.Int MipsVersion *big.Int
// Release version to set OPCM implementations for, of the format `op-contracts/vX.Y.Z`. // Release version to set OPCM implementations for, of the format `op-contracts/vX.Y.Z`.
Release string L1ContractsRelease string
SuperchainConfigProxy common.Address SuperchainConfigProxy common.Address
ProtocolVersionsProxy common.Address ProtocolVersionsProxy common.Address
UseInterop bool // if true, deploy Interop implementations UseInterop bool // if true, deploy Interop implementations
OpcmProxyOwner common.Address
StandardVersionsToml string // contents of 'standard-versions-mainnet.toml' or 'standard-versions-sepolia.toml' file StandardVersionsToml string // contents of 'standard-versions-mainnet.toml' or 'standard-versions-sepolia.toml' file
} }
...@@ -32,8 +31,7 @@ func (input *DeployImplementationsInput) InputSet() bool { ...@@ -32,8 +31,7 @@ func (input *DeployImplementationsInput) InputSet() bool {
} }
type DeployImplementationsOutput struct { type DeployImplementationsOutput struct {
OpcmProxy common.Address Opcm common.Address
OpcmImpl common.Address
DelayedWETHImpl common.Address DelayedWETHImpl common.Address
OptimismPortalImpl common.Address OptimismPortalImpl common.Address
PreimageOracleSingleton common.Address PreimageOracleSingleton common.Address
......
...@@ -26,7 +26,7 @@ type DeployOPChainInputV160 struct { ...@@ -26,7 +26,7 @@ type DeployOPChainInputV160 struct {
BasefeeScalar uint32 BasefeeScalar uint32
BlobBaseFeeScalar uint32 BlobBaseFeeScalar uint32
L2ChainId *big.Int L2ChainId *big.Int
OpcmProxy common.Address Opcm common.Address
SaltMixer string SaltMixer string
GasLimit uint64 GasLimit uint64
...@@ -122,8 +122,8 @@ func deployOPChain[T any](host *script.Host, input T) (DeployOPChainOutput, erro ...@@ -122,8 +122,8 @@ func deployOPChain[T any](host *script.Host, input T) (DeployOPChainOutput, erro
type ReadImplementationAddressesInput struct { type ReadImplementationAddressesInput struct {
DeployOPChainOutput DeployOPChainOutput
OpcmProxy common.Address Opcm common.Address
Release string Release string
} }
type ReadImplementationAddressesOutput struct { type ReadImplementationAddressesOutput struct {
......
...@@ -31,7 +31,7 @@ func DeployAltDA(env *Env, intent *state.Intent, st *state.State, chainID common ...@@ -31,7 +31,7 @@ func DeployAltDA(env *Env, intent *state.Intent, st *state.State, chainID common
lgr.Info("deploying alt-da contracts") lgr.Info("deploying alt-da contracts")
dao, err = opcm.DeployAltDA(env.L1ScriptHost, opcm.DeployAltDAInput{ dao, err = opcm.DeployAltDA(env.L1ScriptHost, opcm.DeployAltDAInput{
Salt: st.Create2Salt, Salt: st.Create2Salt,
ProxyAdmin: st.ImplementationsDeployment.OpcmProxyAddress, ProxyAdmin: chainState.ProxyAdminAddress,
ChallengeContractOwner: chainIntent.Roles.L1ProxyAdminOwner, ChallengeContractOwner: chainIntent.Roles.L1ProxyAdminOwner,
ChallengeWindow: new(big.Int).SetUint64(chainIntent.DangerousAltDAConfig.DAChallengeWindow), ChallengeWindow: new(big.Int).SetUint64(chainIntent.DangerousAltDAConfig.DAChallengeWindow),
ResolveWindow: new(big.Int).SetUint64(chainIntent.DangerousAltDAConfig.DAResolveWindow), ResolveWindow: new(big.Int).SetUint64(chainIntent.DangerousAltDAConfig.DAResolveWindow),
......
...@@ -68,10 +68,9 @@ func DeployImplementations(env *Env, intent *state.Intent, st *state.State) erro ...@@ -68,10 +68,9 @@ func DeployImplementations(env *Env, intent *state.Intent, st *state.State) erro
ProofMaturityDelaySeconds: new(big.Int).SetUint64(proofParams.ProofMaturityDelaySeconds), ProofMaturityDelaySeconds: new(big.Int).SetUint64(proofParams.ProofMaturityDelaySeconds),
DisputeGameFinalityDelaySeconds: new(big.Int).SetUint64(proofParams.DisputeGameFinalityDelaySeconds), DisputeGameFinalityDelaySeconds: new(big.Int).SetUint64(proofParams.DisputeGameFinalityDelaySeconds),
MipsVersion: new(big.Int).SetUint64(proofParams.MIPSVersion), MipsVersion: new(big.Int).SetUint64(proofParams.MIPSVersion),
Release: contractsRelease, L1ContractsRelease: contractsRelease,
SuperchainConfigProxy: st.SuperchainDeployment.SuperchainConfigProxyAddress, SuperchainConfigProxy: st.SuperchainDeployment.SuperchainConfigProxyAddress,
ProtocolVersionsProxy: st.SuperchainDeployment.ProtocolVersionsProxyAddress, ProtocolVersionsProxy: st.SuperchainDeployment.ProtocolVersionsProxyAddress,
OpcmProxyOwner: st.SuperchainDeployment.ProxyAdminAddress,
StandardVersionsToml: standardVersionsTOML, StandardVersionsToml: standardVersionsTOML,
UseInterop: intent.UseInterop, UseInterop: intent.UseInterop,
}, },
...@@ -81,7 +80,7 @@ func DeployImplementations(env *Env, intent *state.Intent, st *state.State) erro ...@@ -81,7 +80,7 @@ func DeployImplementations(env *Env, intent *state.Intent, st *state.State) erro
} }
st.ImplementationsDeployment = &state.ImplementationsDeployment{ st.ImplementationsDeployment = &state.ImplementationsDeployment{
OpcmProxyAddress: dio.OpcmProxy, OpcmAddress: dio.Opcm,
DelayedWETHImplAddress: dio.DelayedWETHImpl, DelayedWETHImplAddress: dio.DelayedWETHImpl,
OptimismPortalImplAddress: dio.OptimismPortalImpl, OptimismPortalImplAddress: dio.OptimismPortalImpl,
PreimageOracleSingletonAddress: dio.PreimageOracleSingleton, PreimageOracleSingletonAddress: dio.PreimageOracleSingleton,
......
...@@ -45,12 +45,12 @@ func InitLiveStrategy(ctx context.Context, env *Env, intent *state.Intent, st *s ...@@ -45,12 +45,12 @@ func InitLiveStrategy(ctx context.Context, env *Env, intent *state.Intent, st *s
SuperchainConfigProxyAddress: common.Address(*superCfg.Config.SuperchainConfigAddr), SuperchainConfigProxyAddress: common.Address(*superCfg.Config.SuperchainConfigAddr),
} }
opcmProxy, err := standard.ManagerImplementationAddrFor(intent.L1ChainID) opcmAddress, err := standard.ManagerImplementationAddrFor(intent.L1ChainID)
if err != nil { if err != nil {
return fmt.Errorf("error getting OPCM proxy address: %w", err) return fmt.Errorf("error getting OPCM proxy address: %w", err)
} }
st.ImplementationsDeployment = &state.ImplementationsDeployment{ st.ImplementationsDeployment = &state.ImplementationsDeployment{
OpcmProxyAddress: opcmProxy, OpcmAddress: opcmAddress,
} }
} }
......
...@@ -34,7 +34,7 @@ func DeployOPChain(env *Env, intent *state.Intent, st *state.State, chainID comm ...@@ -34,7 +34,7 @@ func DeployOPChain(env *Env, intent *state.Intent, st *state.State, chainID comm
return opcm.DeployOPChainOutput{}, fmt.Errorf("error making deploy OP chain input: %w", err) return opcm.DeployOPChainOutput{}, fmt.Errorf("error making deploy OP chain input: %w", err)
} }
opcmAddr = input.OpcmProxy opcmAddr = input.Opcm
return opcm.DeployOPChainV160(env.L1ScriptHost, input) return opcm.DeployOPChainV160(env.L1ScriptHost, input)
} }
default: default:
...@@ -44,7 +44,7 @@ func DeployOPChain(env *Env, intent *state.Intent, st *state.State, chainID comm ...@@ -44,7 +44,7 @@ func DeployOPChain(env *Env, intent *state.Intent, st *state.State, chainID comm
return opcm.DeployOPChainOutput{}, fmt.Errorf("error making deploy OP chain input: %w", err) return opcm.DeployOPChainOutput{}, fmt.Errorf("error making deploy OP chain input: %w", err)
} }
opcmAddr = input.OpcmProxy opcmAddr = input.Opcm
return opcm.DeployOPChainIsthmus(env.L1ScriptHost, input) return opcm.DeployOPChainIsthmus(env.L1ScriptHost, input)
} }
} }
...@@ -67,7 +67,7 @@ func DeployOPChain(env *Env, intent *state.Intent, st *state.State, chainID comm ...@@ -67,7 +67,7 @@ func DeployOPChain(env *Env, intent *state.Intent, st *state.State, chainID comm
readInput := opcm.ReadImplementationAddressesInput{ readInput := opcm.ReadImplementationAddressesInput{
DeployOPChainOutput: dco, DeployOPChainOutput: dco,
OpcmProxy: opcmAddr, Opcm: opcmAddr,
Release: release, Release: release,
} }
impls, err := opcm.ReadImplementationAddresses(env.L1ScriptHost, readInput) impls, err := opcm.ReadImplementationAddresses(env.L1ScriptHost, readInput)
...@@ -126,7 +126,7 @@ func makeDCIV160(intent *state.Intent, thisIntent *state.ChainIntent, chainID co ...@@ -126,7 +126,7 @@ func makeDCIV160(intent *state.Intent, thisIntent *state.ChainIntent, chainID co
BasefeeScalar: standard.BasefeeScalar, BasefeeScalar: standard.BasefeeScalar,
BlobBaseFeeScalar: standard.BlobBaseFeeScalar, BlobBaseFeeScalar: standard.BlobBaseFeeScalar,
L2ChainId: chainID.Big(), L2ChainId: chainID.Big(),
OpcmProxy: st.ImplementationsDeployment.OpcmProxyAddress, Opcm: st.ImplementationsDeployment.OpcmAddress,
SaltMixer: st.Create2Salt.String(), // passing through salt generated at state initialization SaltMixer: st.Create2Salt.String(), // passing through salt generated at state initialization
GasLimit: standard.GasLimit, GasLimit: standard.GasLimit,
DisputeGameType: proofParams.DisputeGameType, DisputeGameType: proofParams.DisputeGameType,
......
...@@ -134,10 +134,11 @@ func ManagerImplementationAddrFor(chainID uint64) (common.Address, error) { ...@@ -134,10 +134,11 @@ func ManagerImplementationAddrFor(chainID uint64) (common.Address, error) {
switch chainID { switch chainID {
case 1: case 1:
// Generated using the bootstrap command on 10/18/2024. // Generated using the bootstrap command on 10/18/2024.
return common.HexToAddress("0x18cec91779995ad14c880e4095456b9147160790"), nil // TODO: @blmalone this needs re-bootstrapped because it's still proxied
return common.HexToAddress(""), nil
case 11155111: case 11155111:
// Generated using the bootstrap command on 10/18/2024. // Generated using the bootstrap command on 11/15/2024.
return common.HexToAddress("0xf564eea7960ea244bfebcbbb17858748606147bf"), nil return common.HexToAddress("0xde9eacb994a6eb12997445f8a63a22772c5c4313"), nil
default: default:
return common.Address{}, fmt.Errorf("unsupported chain ID: %d", chainID) return common.Address{}, fmt.Errorf("unsupported chain ID: %d", chainID)
} }
...@@ -172,7 +173,7 @@ func SystemOwnerAddrFor(chainID uint64) (common.Address, error) { ...@@ -172,7 +173,7 @@ func SystemOwnerAddrFor(chainID uint64) (common.Address, error) {
func ArtifactsURLForTag(tag string) (*url.URL, error) { func ArtifactsURLForTag(tag string) (*url.URL, error) {
switch tag { switch tag {
case "op-contracts/v1.6.0": case "op-contracts/v1.6.0":
return url.Parse(standardArtifactsURL("3a27c6dc0cb61b36feaac26def98c64b4a48ec8f5c5ba6965e8ae3157606043c")) return url.Parse(standardArtifactsURL("e1f0c4020618c4a98972e7124c39686cab2e31d5d7846f9ce5e0d5eed0f5ff32"))
case "op-contracts/v1.7.0-beta.1+l2-contracts": case "op-contracts/v1.7.0-beta.1+l2-contracts":
return url.Parse(standardArtifactsURL("b0fb1f6f674519d637cff39a22187a5993d7f81a6d7b7be6507a0b50a5e38597")) return url.Parse(standardArtifactsURL("b0fb1f6f674519d637cff39a22187a5993d7f81a6d7b7be6507a0b50a5e38597"))
default: default:
......
...@@ -64,7 +64,7 @@ type SuperchainDeployment struct { ...@@ -64,7 +64,7 @@ type SuperchainDeployment struct {
} }
type ImplementationsDeployment struct { type ImplementationsDeployment struct {
OpcmProxyAddress common.Address `json:"opcmProxyAddress"` OpcmAddress common.Address `json:"opcmAddress"`
DelayedWETHImplAddress common.Address `json:"delayedWETHImplAddress"` DelayedWETHImplAddress common.Address `json:"delayedWETHImplAddress"`
OptimismPortalImplAddress common.Address `json:"optimismPortalImplAddress"` OptimismPortalImplAddress common.Address `json:"optimismPortalImplAddress"`
PreimageOracleSingletonAddress common.Address `json:"preimageOracleSingletonAddress"` PreimageOracleSingletonAddress common.Address `json:"preimageOracleSingletonAddress"`
......
...@@ -162,7 +162,7 @@ contract Deploy is Deployer { ...@@ -162,7 +162,7 @@ contract Deploy is Deployer {
L1ERC721Bridge: getAddress("L1ERC721BridgeProxy"), L1ERC721Bridge: getAddress("L1ERC721BridgeProxy"),
ProtocolVersions: getAddress("ProtocolVersionsProxy"), ProtocolVersions: getAddress("ProtocolVersionsProxy"),
SuperchainConfig: getAddress("SuperchainConfigProxy"), SuperchainConfig: getAddress("SuperchainConfigProxy"),
OPContractsManager: getAddress("OPContractsManagerProxy") OPContractsManager: getAddress("OPContractsManager")
}); });
} }
...@@ -378,13 +378,12 @@ contract Deploy is Deployer { ...@@ -378,13 +378,12 @@ contract Deploy is Deployer {
dii.set(dii.disputeGameFinalityDelaySeconds.selector, cfg.disputeGameFinalityDelaySeconds()); dii.set(dii.disputeGameFinalityDelaySeconds.selector, cfg.disputeGameFinalityDelaySeconds());
dii.set(dii.mipsVersion.selector, Config.useMultithreadedCannon() ? 2 : 1); dii.set(dii.mipsVersion.selector, Config.useMultithreadedCannon() ? 2 : 1);
string memory release = "dev"; string memory release = "dev";
dii.set(dii.release.selector, release); dii.set(dii.l1ContractsRelease.selector, release);
dii.set( dii.set(
dii.standardVersionsToml.selector, string.concat(vm.projectRoot(), "/test/fixtures/standard-versions.toml") dii.standardVersionsToml.selector, string.concat(vm.projectRoot(), "/test/fixtures/standard-versions.toml")
); );
dii.set(dii.superchainConfigProxy.selector, mustGetAddress("SuperchainConfigProxy")); dii.set(dii.superchainConfigProxy.selector, mustGetAddress("SuperchainConfigProxy"));
dii.set(dii.protocolVersionsProxy.selector, mustGetAddress("ProtocolVersionsProxy")); dii.set(dii.protocolVersionsProxy.selector, mustGetAddress("ProtocolVersionsProxy"));
dii.set(dii.opcmProxyOwner.selector, cfg.finalSystemOwner());
if (_isInterop) { if (_isInterop) {
di = DeployImplementations(new DeployImplementationsInterop()); di = DeployImplementations(new DeployImplementationsInterop());
...@@ -409,8 +408,7 @@ contract Deploy is Deployer { ...@@ -409,8 +408,7 @@ contract Deploy is Deployer {
save("DelayedWETH", address(dio.delayedWETHImpl())); save("DelayedWETH", address(dio.delayedWETHImpl()));
save("PreimageOracle", address(dio.preimageOracleSingleton())); save("PreimageOracle", address(dio.preimageOracleSingleton()));
save("Mips", address(dio.mipsSingleton())); save("Mips", address(dio.mipsSingleton()));
save("OPContractsManagerProxy", address(dio.opcmProxy())); save("OPContractsManager", address(dio.opcm()));
save("OPContractsManager", address(dio.opcmImpl()));
Types.ContractSet memory contracts = _impls(); Types.ContractSet memory contracts = _impls();
ChainAssertions.checkL1CrossDomainMessenger({ _contracts: contracts, _vm: vm, _isProxy: false }); ChainAssertions.checkL1CrossDomainMessenger({ _contracts: contracts, _vm: vm, _isProxy: false });
...@@ -446,7 +444,7 @@ contract Deploy is Deployer { ...@@ -446,7 +444,7 @@ contract Deploy is Deployer {
// Ensure that the requisite contracts are deployed // Ensure that the requisite contracts are deployed
address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy");
OPContractsManager opcm = OPContractsManager(mustGetAddress("OPContractsManagerProxy")); OPContractsManager opcm = OPContractsManager(mustGetAddress("OPContractsManager"));
OPContractsManager.DeployInput memory deployInput = getDeployInput(); OPContractsManager.DeployInput memory deployInput = getDeployInput();
OPContractsManager.DeployOutput memory deployOutput = opcm.deploy(deployInput); OPContractsManager.DeployOutput memory deployOutput = opcm.deploy(deployInput);
......
...@@ -8,16 +8,11 @@ import { LibString } from "@solady/utils/LibString.sol"; ...@@ -8,16 +8,11 @@ import { LibString } from "@solady/utils/LibString.sol";
import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol";
import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol";
import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol"; import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol";
import { ISystemConfigV160 } from "src/L1/interfaces/ISystemConfigV160.sol";
import { IL1CrossDomainMessengerV160 } from "src/L1/interfaces/IL1CrossDomainMessengerV160.sol";
import { IL1StandardBridgeV160 } from "src/L1/interfaces/IL1StandardBridgeV160.sol";
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { Bytes } from "src/libraries/Bytes.sol"; import { Bytes } from "src/libraries/Bytes.sol";
import { IProxy } from "src/universal/interfaces/IProxy.sol";
import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol";
import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol";
import { IMIPS } from "src/cannon/interfaces/IMIPS.sol"; import { IMIPS } from "src/cannon/interfaces/IMIPS.sol";
...@@ -51,8 +46,9 @@ contract DeployImplementationsInput is BaseDeployIO { ...@@ -51,8 +46,9 @@ contract DeployImplementationsInput is BaseDeployIO {
uint256 internal _disputeGameFinalityDelaySeconds; uint256 internal _disputeGameFinalityDelaySeconds;
uint256 internal _mipsVersion; uint256 internal _mipsVersion;
// The release version to set OPCM implementations for, of the format `op-contracts/vX.Y.Z`. // This is used in opcm to signal which version of the L1 smart contracts is deployed.
string internal _release; // It takes the format of `op-contracts/v*.*.*`.
string internal _l1ContractsRelease;
// Outputs from DeploySuperchain.s.sol. // Outputs from DeploySuperchain.s.sol.
ISuperchainConfig internal _superchainConfigProxy; ISuperchainConfig internal _superchainConfigProxy;
...@@ -60,8 +56,6 @@ contract DeployImplementationsInput is BaseDeployIO { ...@@ -60,8 +56,6 @@ contract DeployImplementationsInput is BaseDeployIO {
string internal _standardVersionsToml; string internal _standardVersionsToml;
address internal _opcmProxyOwner;
function set(bytes4 _sel, uint256 _value) public { function set(bytes4 _sel, uint256 _value) public {
require(_value != 0, "DeployImplementationsInput: cannot set zero value"); require(_value != 0, "DeployImplementationsInput: cannot set zero value");
...@@ -85,7 +79,7 @@ contract DeployImplementationsInput is BaseDeployIO { ...@@ -85,7 +79,7 @@ contract DeployImplementationsInput is BaseDeployIO {
function set(bytes4 _sel, string memory _value) public { function set(bytes4 _sel, string memory _value) public {
require(!LibString.eq(_value, ""), "DeployImplementationsInput: cannot set empty string"); require(!LibString.eq(_value, ""), "DeployImplementationsInput: cannot set empty string");
if (_sel == this.release.selector) _release = _value; if (_sel == this.l1ContractsRelease.selector) _l1ContractsRelease = _value;
else if (_sel == this.standardVersionsToml.selector) _standardVersionsToml = _value; else if (_sel == this.standardVersionsToml.selector) _standardVersionsToml = _value;
else revert("DeployImplementationsInput: unknown selector"); else revert("DeployImplementationsInput: unknown selector");
} }
...@@ -94,7 +88,6 @@ contract DeployImplementationsInput is BaseDeployIO { ...@@ -94,7 +88,6 @@ contract DeployImplementationsInput is BaseDeployIO {
require(_addr != address(0), "DeployImplementationsInput: cannot set zero address"); require(_addr != address(0), "DeployImplementationsInput: cannot set zero address");
if (_sel == this.superchainConfigProxy.selector) _superchainConfigProxy = ISuperchainConfig(_addr); if (_sel == this.superchainConfigProxy.selector) _superchainConfigProxy = ISuperchainConfig(_addr);
else if (_sel == this.protocolVersionsProxy.selector) _protocolVersionsProxy = IProtocolVersions(_addr); else if (_sel == this.protocolVersionsProxy.selector) _protocolVersionsProxy = IProtocolVersions(_addr);
else if (_sel == this.opcmProxyOwner.selector) _opcmProxyOwner = _addr;
else revert("DeployImplementationsInput: unknown selector"); else revert("DeployImplementationsInput: unknown selector");
} }
...@@ -141,9 +134,9 @@ contract DeployImplementationsInput is BaseDeployIO { ...@@ -141,9 +134,9 @@ contract DeployImplementationsInput is BaseDeployIO {
return _mipsVersion; return _mipsVersion;
} }
function release() public view returns (string memory) { function l1ContractsRelease() public view returns (string memory) {
require(!LibString.eq(_release, ""), "DeployImplementationsInput: not set"); require(!LibString.eq(_l1ContractsRelease, ""), "DeployImplementationsInput: not set");
return _release; return _l1ContractsRelease;
} }
function standardVersionsToml() public view returns (string memory) { function standardVersionsToml() public view returns (string memory) {
...@@ -160,16 +153,10 @@ contract DeployImplementationsInput is BaseDeployIO { ...@@ -160,16 +153,10 @@ contract DeployImplementationsInput is BaseDeployIO {
require(address(_protocolVersionsProxy) != address(0), "DeployImplementationsInput: not set"); require(address(_protocolVersionsProxy) != address(0), "DeployImplementationsInput: not set");
return _protocolVersionsProxy; return _protocolVersionsProxy;
} }
function opcmProxyOwner() public view returns (address) {
require(address(_opcmProxyOwner) != address(0), "DeployImplementationsInput: not set");
return _opcmProxyOwner;
}
} }
contract DeployImplementationsOutput is BaseDeployIO { contract DeployImplementationsOutput is BaseDeployIO {
OPContractsManager internal _opcmProxy; OPContractsManager internal _opcm;
OPContractsManager internal _opcmImpl;
IDelayedWETH internal _delayedWETHImpl; IDelayedWETH internal _delayedWETHImpl;
IOptimismPortal2 internal _optimismPortalImpl; IOptimismPortal2 internal _optimismPortalImpl;
IPreimageOracle internal _preimageOracleSingleton; IPreimageOracle internal _preimageOracleSingleton;
...@@ -185,8 +172,7 @@ contract DeployImplementationsOutput is BaseDeployIO { ...@@ -185,8 +172,7 @@ contract DeployImplementationsOutput is BaseDeployIO {
require(_addr != address(0), "DeployImplementationsOutput: cannot set zero address"); require(_addr != address(0), "DeployImplementationsOutput: cannot set zero address");
// forgefmt: disable-start // forgefmt: disable-start
if (_sel == this.opcmProxy.selector) _opcmProxy = OPContractsManager(payable(_addr)); if (_sel == this.opcm.selector) _opcm = OPContractsManager(_addr);
else if (_sel == this.opcmImpl.selector) _opcmImpl = OPContractsManager(payable(_addr));
else if (_sel == this.optimismPortalImpl.selector) _optimismPortalImpl = IOptimismPortal2(payable(_addr)); else if (_sel == this.optimismPortalImpl.selector) _optimismPortalImpl = IOptimismPortal2(payable(_addr));
else if (_sel == this.delayedWETHImpl.selector) _delayedWETHImpl = IDelayedWETH(payable(_addr)); else if (_sel == this.delayedWETHImpl.selector) _delayedWETHImpl = IDelayedWETH(payable(_addr));
else if (_sel == this.preimageOracleSingleton.selector) _preimageOracleSingleton = IPreimageOracle(_addr); else if (_sel == this.preimageOracleSingleton.selector) _preimageOracleSingleton = IPreimageOracle(_addr);
...@@ -201,12 +187,11 @@ contract DeployImplementationsOutput is BaseDeployIO { ...@@ -201,12 +187,11 @@ contract DeployImplementationsOutput is BaseDeployIO {
// forgefmt: disable-end // forgefmt: disable-end
} }
function checkOutput(DeployImplementationsInput _dii) public { function checkOutput(DeployImplementationsInput _dii) public view {
// With 12 addresses, we'd get a stack too deep error if we tried to do this inline as a // With 12 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. // single call to `Solarray.addresses`. So we split it into two calls.
address[] memory addrs1 = Solarray.addresses( address[] memory addrs1 = Solarray.addresses(
address(this.opcmProxy()), address(this.opcm()),
address(this.opcmImpl()),
address(this.optimismPortalImpl()), address(this.optimismPortalImpl()),
address(this.delayedWETHImpl()), address(this.delayedWETHImpl()),
address(this.preimageOracleSingleton()), address(this.preimageOracleSingleton()),
...@@ -227,15 +212,9 @@ contract DeployImplementationsOutput is BaseDeployIO { ...@@ -227,15 +212,9 @@ contract DeployImplementationsOutput is BaseDeployIO {
assertValidDeploy(_dii); assertValidDeploy(_dii);
} }
function opcmProxy() public returns (OPContractsManager) { function opcm() public view returns (OPContractsManager) {
DeployUtils.assertValidContractAddress(address(_opcmProxy)); DeployUtils.assertValidContractAddress(address(_opcm));
DeployUtils.assertERC1967ImplementationSet(address(_opcmProxy)); return _opcm;
return _opcmProxy;
}
function opcmImpl() public view returns (OPContractsManager) {
DeployUtils.assertValidContractAddress(address(_opcmImpl));
return _opcmImpl;
} }
function optimismPortalImpl() public view returns (IOptimismPortal2) { function optimismPortalImpl() public view returns (IOptimismPortal2) {
...@@ -289,40 +268,22 @@ contract DeployImplementationsOutput is BaseDeployIO { ...@@ -289,40 +268,22 @@ contract DeployImplementationsOutput is BaseDeployIO {
} }
// -------- Deployment Assertions -------- // -------- Deployment Assertions --------
function assertValidDeploy(DeployImplementationsInput _dii) public { function assertValidDeploy(DeployImplementationsInput _dii) public view {
assertValidDelayedWETHImpl(_dii); assertValidDelayedWETHImpl(_dii);
assertValidDisputeGameFactoryImpl(_dii); assertValidDisputeGameFactoryImpl(_dii);
assertValidL1CrossDomainMessengerImpl(_dii); assertValidL1CrossDomainMessengerImpl(_dii);
assertValidL1ERC721BridgeImpl(_dii); assertValidL1ERC721BridgeImpl(_dii);
assertValidL1StandardBridgeImpl(_dii); assertValidL1StandardBridgeImpl(_dii);
assertValidMipsSingleton(_dii); assertValidMipsSingleton(_dii);
assertValidOpcmProxy(_dii); assertValidOpcm(_dii);
assertValidOpcmImpl(_dii);
assertValidOptimismMintableERC20FactoryImpl(_dii); assertValidOptimismMintableERC20FactoryImpl(_dii);
assertValidOptimismPortalImpl(_dii); assertValidOptimismPortalImpl(_dii);
assertValidPreimageOracleSingleton(_dii); assertValidPreimageOracleSingleton(_dii);
assertValidSystemConfigImpl(_dii); assertValidSystemConfigImpl(_dii);
} }
function assertValidOpcmProxy(DeployImplementationsInput _dii) internal { function assertValidOpcm(DeployImplementationsInput _dii) internal view {
// First we check the proxy as itself. OPContractsManager impl = OPContractsManager(address(opcm()));
IProxy proxy = IProxy(payable(address(opcmProxy())));
vm.prank(address(0));
address admin = proxy.admin();
require(admin == address(_dii.opcmProxyOwner()), "OPCMP-10");
// Then we check the proxy as OPCM.
DeployUtils.assertInitialized({ _contractAddress: address(opcmProxy()), _slot: 0, _offset: 0 });
require(address(opcmProxy().superchainConfig()) == address(_dii.superchainConfigProxy()), "OPCMP-20");
require(address(opcmProxy().protocolVersions()) == address(_dii.protocolVersionsProxy()), "OPCMP-30");
require(LibString.eq(opcmProxy().latestRelease(), _dii.release()), "OPCMP-50"); // Initial release is latest.
}
function assertValidOpcmImpl(DeployImplementationsInput _dii) internal {
IProxy proxy = IProxy(payable(address(opcmProxy())));
vm.prank(address(0));
OPContractsManager impl = OPContractsManager(proxy.implementation());
DeployUtils.assertInitialized({ _contractAddress: address(impl), _slot: 0, _offset: 0 });
require(address(impl.superchainConfig()) == address(_dii.superchainConfigProxy()), "OPCMI-10"); require(address(impl.superchainConfig()) == address(_dii.superchainConfigProxy()), "OPCMI-10");
require(address(impl.protocolVersions()) == address(_dii.protocolVersionsProxy()), "OPCMI-20"); require(address(impl.protocolVersions()) == address(_dii.protocolVersionsProxy()), "OPCMI-20");
} }
...@@ -361,7 +322,6 @@ contract DeployImplementationsOutput is BaseDeployIO { ...@@ -361,7 +322,6 @@ contract DeployImplementationsOutput is BaseDeployIO {
function assertValidMipsSingleton(DeployImplementationsInput) internal view { function assertValidMipsSingleton(DeployImplementationsInput) internal view {
IMIPS mips = mipsSingleton(); IMIPS mips = mipsSingleton();
require(address(mips.oracle()) == address(preimageOracleSingleton()), "MIPS-10"); require(address(mips.oracle()) == address(preimageOracleSingleton()), "MIPS-10");
} }
...@@ -480,102 +440,38 @@ contract DeployImplementations is Script { ...@@ -480,102 +440,38 @@ contract DeployImplementations is Script {
// --- OP Contracts Manager --- // --- OP Contracts Manager ---
function opcmSystemConfigSetter(
DeployImplementationsInput _dii,
DeployImplementationsOutput _dio
)
internal
view
virtual
returns (OPContractsManager.ImplementationSetter memory)
{
// When configuring OPCM during Solidity tests, we are using the latest SystemConfig.sol
// version in this repo, which contains Custom Gas Token (CGT) features. This CGT version
// has a different `initialize` signature than the SystemConfig version that was released
// as part of `op-contracts/v1.6.0`, which is no longer in the repo. When running this
// script's bytecode for a production deploy of OPCM at `op-contracts/v1.6.0`, we need to
// use the ISystemConfigV160 interface instead of ISystemConfig. Therefore the selector used
// is a function of the `release` passed in by the caller.
bytes4 selector = LibString.eq(_dii.release(), "op-contracts/v1.6.0")
? ISystemConfigV160.initialize.selector
: ISystemConfig.initialize.selector;
return OPContractsManager.ImplementationSetter({
name: "SystemConfig",
info: OPContractsManager.Implementation(address(_dio.systemConfigImpl()), selector)
});
}
function l1CrossDomainMessengerConfigSetter(
DeployImplementationsInput _dii,
DeployImplementationsOutput _dio
)
internal
view
virtual
returns (OPContractsManager.ImplementationSetter memory)
{
bytes4 selector = LibString.eq(_dii.release(), "op-contracts/v1.6.0")
? IL1CrossDomainMessengerV160.initialize.selector
: IL1CrossDomainMessenger.initialize.selector;
return OPContractsManager.ImplementationSetter({
name: "L1CrossDomainMessenger",
info: OPContractsManager.Implementation(address(_dio.l1CrossDomainMessengerImpl()), selector)
});
}
function l1StandardBridgeConfigSetter(
DeployImplementationsInput _dii,
DeployImplementationsOutput _dio
)
internal
view
virtual
returns (OPContractsManager.ImplementationSetter memory)
{
bytes4 selector = LibString.eq(_dii.release(), "op-contracts/v1.6.0")
? IL1StandardBridgeV160.initialize.selector
: IL1StandardBridge.initialize.selector;
return OPContractsManager.ImplementationSetter({
name: "L1StandardBridge",
info: OPContractsManager.Implementation(address(_dio.l1StandardBridgeImpl()), selector)
});
}
// Deploy and initialize a proxied OPContractsManager.
function createOPCMContract( function createOPCMContract(
DeployImplementationsInput _dii, DeployImplementationsInput _dii,
DeployImplementationsOutput _dio, DeployImplementationsOutput _dio,
OPContractsManager.Blueprints memory _blueprints, OPContractsManager.Blueprints memory _blueprints,
string memory _release, string memory _l1ContractsRelease
OPContractsManager.ImplementationSetter[] memory _setters
) )
internal internal
virtual virtual
returns (OPContractsManager opcmProxy_) returns (OPContractsManager opcm_)
{ {
address opcmProxyOwner = _dii.opcmProxyOwner(); ISuperchainConfig superchainConfigProxy = _dii.superchainConfigProxy();
IProtocolVersions protocolVersionsProxy = _dii.protocolVersionsProxy();
OPContractsManager.Implementations memory implementations = OPContractsManager.Implementations({
l1ERC721BridgeImpl: address(_dio.l1ERC721BridgeImpl()),
optimismPortalImpl: address(_dio.optimismPortalImpl()),
systemConfigImpl: address(_dio.systemConfigImpl()),
optimismMintableERC20FactoryImpl: address(_dio.optimismMintableERC20FactoryImpl()),
l1CrossDomainMessengerImpl: address(_dio.l1CrossDomainMessengerImpl()),
l1StandardBridgeImpl: address(_dio.l1StandardBridgeImpl()),
disputeGameFactoryImpl: address(_dio.disputeGameFactoryImpl()),
delayedWETHImpl: address(_dio.delayedWETHImpl()),
mipsImpl: address(_dio.mipsSingleton())
});
vm.broadcast(msg.sender); vm.broadcast(msg.sender);
IProxy proxy = IProxy( opcm_ = new OPContractsManager(
DeployUtils.create1({ superchainConfigProxy, protocolVersionsProxy, _l1ContractsRelease, _blueprints, implementations
_name: "Proxy",
_args: DeployUtils.encodeConstructor(abi.encodeCall(IProxy.__constructor__, (msg.sender)))
})
); );
deployOPContractsManagerImpl(_dii, _dio); vm.label(address(opcm_), "OPContractsManager");
OPContractsManager opcmImpl = _dio.opcmImpl(); _dio.set(_dio.opcm.selector, address(opcm_));
OPContractsManager.InitializerInputs memory initializerInputs =
OPContractsManager.InitializerInputs(_blueprints, _setters, _release, true);
vm.startBroadcast(msg.sender);
proxy.upgradeToAndCall(address(opcmImpl), abi.encodeCall(opcmImpl.initialize, (initializerInputs)));
proxy.changeAdmin(address(opcmProxyOwner)); // transfer ownership of Proxy contract to the ProxyAdmin contract
vm.stopBroadcast();
opcmProxy_ = OPContractsManager(address(proxy));
} }
function deployOPContractsManager( function deployOPContractsManager(
...@@ -585,72 +481,42 @@ contract DeployImplementations is Script { ...@@ -585,72 +481,42 @@ contract DeployImplementations is Script {
public public
virtual virtual
{ {
string memory release = _dii.release(); string memory l1ContractsRelease = _dii.l1ContractsRelease();
string memory stdVerToml = _dii.standardVersionsToml();
// First we deploy the blueprints for the singletons deployed by OPCM. string memory contractName = "op_contracts_manager";
// forgefmt: disable-start OPContractsManager opcm;
bytes32 salt = _dii.salt();
OPContractsManager.Blueprints memory blueprints;
vm.startBroadcast(msg.sender);
blueprints.addressManager = deployBytecode(Blueprint.blueprintDeployerBytecode(vm.getCode("AddressManager")), salt);
blueprints.proxy = deployBytecode(Blueprint.blueprintDeployerBytecode(vm.getCode("Proxy")), salt);
blueprints.proxyAdmin = deployBytecode(Blueprint.blueprintDeployerBytecode(vm.getCode("ProxyAdmin")), salt);
blueprints.l1ChugSplashProxy = deployBytecode(Blueprint.blueprintDeployerBytecode(vm.getCode("L1ChugSplashProxy")), salt);
blueprints.resolvedDelegateProxy = deployBytecode(Blueprint.blueprintDeployerBytecode(vm.getCode("ResolvedDelegateProxy")), salt);
blueprints.anchorStateRegistry = deployBytecode(Blueprint.blueprintDeployerBytecode(vm.getCode("AnchorStateRegistry")), salt);
(blueprints.permissionedDisputeGame1, blueprints.permissionedDisputeGame2) = deployBigBytecode(vm.getCode("PermissionedDisputeGame"), salt);
vm.stopBroadcast();
// forgefmt: disable-end
OPContractsManager.ImplementationSetter[] memory setters = new OPContractsManager.ImplementationSetter[](9);
setters[0] = OPContractsManager.ImplementationSetter({
name: "L1ERC721Bridge",
info: OPContractsManager.Implementation(address(_dio.l1ERC721BridgeImpl()), IL1ERC721Bridge.initialize.selector)
});
setters[1] = OPContractsManager.ImplementationSetter({
name: "OptimismPortal",
info: OPContractsManager.Implementation(
address(_dio.optimismPortalImpl()), IOptimismPortal2.initialize.selector
)
});
setters[2] = opcmSystemConfigSetter(_dii, _dio);
setters[3] = OPContractsManager.ImplementationSetter({
name: "OptimismMintableERC20Factory",
info: OPContractsManager.Implementation(
address(_dio.optimismMintableERC20FactoryImpl()), IOptimismMintableERC20Factory.initialize.selector
)
});
setters[4] = l1CrossDomainMessengerConfigSetter(_dii, _dio);
setters[5] = l1StandardBridgeConfigSetter(_dii, _dio);
setters[6] = OPContractsManager.ImplementationSetter({
name: "DisputeGameFactory",
info: OPContractsManager.Implementation(
address(_dio.disputeGameFactoryImpl()), IDisputeGameFactory.initialize.selector
)
});
setters[7] = OPContractsManager.ImplementationSetter({
name: "DelayedWETH",
info: OPContractsManager.Implementation(address(_dio.delayedWETHImpl()), IDelayedWETH.initialize.selector)
});
setters[8] = OPContractsManager.ImplementationSetter({
name: "MIPS",
// MIPS is a singleton for all chains, so it doesn't need to be initialized, so the
// selector is just `bytes4(0)`.
info: OPContractsManager.Implementation(address(_dio.mipsSingleton()), bytes4(0))
});
// This call contains a broadcast to deploy OPCM which is proxied. address existingImplementation = getReleaseAddress(l1ContractsRelease, contractName, stdVerToml);
OPContractsManager opcmProxy = createOPCMContract(_dii, _dio, blueprints, release, setters); if (existingImplementation != address(0)) {
opcm = OPContractsManager(existingImplementation);
} else {
// First we deploy the blueprints for the singletons deployed by OPCM.
// forgefmt: disable-start
bytes32 salt = _dii.salt();
OPContractsManager.Blueprints memory blueprints;
vm.startBroadcast(msg.sender);
blueprints.addressManager = deployBytecode(Blueprint.blueprintDeployerBytecode(vm.getCode("AddressManager")), salt);
blueprints.proxy = deployBytecode(Blueprint.blueprintDeployerBytecode(vm.getCode("Proxy")), salt);
blueprints.proxyAdmin = deployBytecode(Blueprint.blueprintDeployerBytecode(vm.getCode("ProxyAdmin")), salt);
blueprints.l1ChugSplashProxy = deployBytecode(Blueprint.blueprintDeployerBytecode(vm.getCode("L1ChugSplashProxy")), salt);
blueprints.resolvedDelegateProxy = deployBytecode(Blueprint.blueprintDeployerBytecode(vm.getCode("ResolvedDelegateProxy")), salt);
blueprints.anchorStateRegistry = deployBytecode(Blueprint.blueprintDeployerBytecode(vm.getCode("AnchorStateRegistry")), salt);
(blueprints.permissionedDisputeGame1, blueprints.permissionedDisputeGame2) = deployBigBytecode(vm.getCode("PermissionedDisputeGame"), salt);
vm.stopBroadcast();
// forgefmt: disable-end
opcm = createOPCMContract(_dii, _dio, blueprints, l1ContractsRelease);
}
vm.label(address(opcmProxy), "OPContractsManager"); vm.label(address(opcm), "OPContractsManager");
_dio.set(_dio.opcmProxy.selector, address(opcmProxy)); _dio.set(_dio.opcm.selector, address(opcm));
} }
// --- Core Contracts --- // --- Core Contracts ---
function deploySystemConfigImpl(DeployImplementationsInput _dii, DeployImplementationsOutput _dio) public virtual { function deploySystemConfigImpl(DeployImplementationsInput _dii, DeployImplementationsOutput _dio) public virtual {
string memory release = _dii.release(); string memory release = _dii.l1ContractsRelease();
string memory stdVerToml = _dii.standardVersionsToml(); string memory stdVerToml = _dii.standardVersionsToml();
// Using snake case for contract name to match the TOML file in superchain-registry. // Using snake case for contract name to match the TOML file in superchain-registry.
string memory contractName = "system_config"; string memory contractName = "system_config";
...@@ -659,7 +525,7 @@ contract DeployImplementations is Script { ...@@ -659,7 +525,7 @@ contract DeployImplementations is Script {
address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); address existingImplementation = getReleaseAddress(release, contractName, stdVerToml);
if (existingImplementation != address(0)) { if (existingImplementation != address(0)) {
impl = ISystemConfig(existingImplementation); impl = ISystemConfig(existingImplementation);
} else if (isDevelopRelease(release)) { } else {
// Deploy a new implementation for development builds. // Deploy a new implementation for development builds.
vm.broadcast(msg.sender); vm.broadcast(msg.sender);
impl = ISystemConfig( impl = ISystemConfig(
...@@ -668,8 +534,6 @@ contract DeployImplementations is Script { ...@@ -668,8 +534,6 @@ contract DeployImplementations is Script {
_args: DeployUtils.encodeConstructor(abi.encodeCall(ISystemConfig.__constructor__, ())) _args: DeployUtils.encodeConstructor(abi.encodeCall(ISystemConfig.__constructor__, ()))
}) })
); );
} else {
revert(string.concat("DeployImplementations: failed to deploy release ", release));
} }
vm.label(address(impl), "SystemConfigImpl"); vm.label(address(impl), "SystemConfigImpl");
...@@ -683,7 +547,7 @@ contract DeployImplementations is Script { ...@@ -683,7 +547,7 @@ contract DeployImplementations is Script {
public public
virtual virtual
{ {
string memory release = _dii.release(); string memory release = _dii.l1ContractsRelease();
string memory stdVerToml = _dii.standardVersionsToml(); string memory stdVerToml = _dii.standardVersionsToml();
string memory contractName = "l1_cross_domain_messenger"; string memory contractName = "l1_cross_domain_messenger";
IL1CrossDomainMessenger impl; IL1CrossDomainMessenger impl;
...@@ -691,7 +555,7 @@ contract DeployImplementations is Script { ...@@ -691,7 +555,7 @@ contract DeployImplementations is Script {
address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); address existingImplementation = getReleaseAddress(release, contractName, stdVerToml);
if (existingImplementation != address(0)) { if (existingImplementation != address(0)) {
impl = IL1CrossDomainMessenger(existingImplementation); impl = IL1CrossDomainMessenger(existingImplementation);
} else if (isDevelopRelease(release)) { } else {
vm.broadcast(msg.sender); vm.broadcast(msg.sender);
impl = IL1CrossDomainMessenger( impl = IL1CrossDomainMessenger(
DeployUtils.create1({ DeployUtils.create1({
...@@ -699,8 +563,6 @@ contract DeployImplementations is Script { ...@@ -699,8 +563,6 @@ contract DeployImplementations is Script {
_args: DeployUtils.encodeConstructor(abi.encodeCall(IL1CrossDomainMessenger.__constructor__, ())) _args: DeployUtils.encodeConstructor(abi.encodeCall(IL1CrossDomainMessenger.__constructor__, ()))
}) })
); );
} else {
revert(string.concat("DeployImplementations: failed to deploy release ", release));
} }
vm.label(address(impl), "L1CrossDomainMessengerImpl"); vm.label(address(impl), "L1CrossDomainMessengerImpl");
...@@ -714,7 +576,7 @@ contract DeployImplementations is Script { ...@@ -714,7 +576,7 @@ contract DeployImplementations is Script {
public public
virtual virtual
{ {
string memory release = _dii.release(); string memory release = _dii.l1ContractsRelease();
string memory stdVerToml = _dii.standardVersionsToml(); string memory stdVerToml = _dii.standardVersionsToml();
string memory contractName = "l1_erc721_bridge"; string memory contractName = "l1_erc721_bridge";
IL1ERC721Bridge impl; IL1ERC721Bridge impl;
...@@ -722,7 +584,7 @@ contract DeployImplementations is Script { ...@@ -722,7 +584,7 @@ contract DeployImplementations is Script {
address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); address existingImplementation = getReleaseAddress(release, contractName, stdVerToml);
if (existingImplementation != address(0)) { if (existingImplementation != address(0)) {
impl = IL1ERC721Bridge(existingImplementation); impl = IL1ERC721Bridge(existingImplementation);
} else if (isDevelopRelease(release)) { } else {
vm.broadcast(msg.sender); vm.broadcast(msg.sender);
impl = IL1ERC721Bridge( impl = IL1ERC721Bridge(
DeployUtils.create1({ DeployUtils.create1({
...@@ -730,8 +592,6 @@ contract DeployImplementations is Script { ...@@ -730,8 +592,6 @@ contract DeployImplementations is Script {
_args: DeployUtils.encodeConstructor(abi.encodeCall(IL1ERC721Bridge.__constructor__, ())) _args: DeployUtils.encodeConstructor(abi.encodeCall(IL1ERC721Bridge.__constructor__, ()))
}) })
); );
} else {
revert(string.concat("DeployImplementations: failed to deploy release ", release));
} }
vm.label(address(impl), "L1ERC721BridgeImpl"); vm.label(address(impl), "L1ERC721BridgeImpl");
...@@ -745,7 +605,7 @@ contract DeployImplementations is Script { ...@@ -745,7 +605,7 @@ contract DeployImplementations is Script {
public public
virtual virtual
{ {
string memory release = _dii.release(); string memory release = _dii.l1ContractsRelease();
string memory stdVerToml = _dii.standardVersionsToml(); string memory stdVerToml = _dii.standardVersionsToml();
string memory contractName = "l1_standard_bridge"; string memory contractName = "l1_standard_bridge";
IL1StandardBridge impl; IL1StandardBridge impl;
...@@ -753,7 +613,7 @@ contract DeployImplementations is Script { ...@@ -753,7 +613,7 @@ contract DeployImplementations is Script {
address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); address existingImplementation = getReleaseAddress(release, contractName, stdVerToml);
if (existingImplementation != address(0)) { if (existingImplementation != address(0)) {
impl = IL1StandardBridge(payable(existingImplementation)); impl = IL1StandardBridge(payable(existingImplementation));
} else if (isDevelopRelease(release)) { } else {
vm.broadcast(msg.sender); vm.broadcast(msg.sender);
impl = IL1StandardBridge( impl = IL1StandardBridge(
DeployUtils.create1({ DeployUtils.create1({
...@@ -761,8 +621,6 @@ contract DeployImplementations is Script { ...@@ -761,8 +621,6 @@ contract DeployImplementations is Script {
_args: DeployUtils.encodeConstructor(abi.encodeCall(IL1StandardBridge.__constructor__, ())) _args: DeployUtils.encodeConstructor(abi.encodeCall(IL1StandardBridge.__constructor__, ()))
}) })
); );
} else {
revert(string.concat("DeployImplementations: failed to deploy release ", release));
} }
vm.label(address(impl), "L1StandardBridgeImpl"); vm.label(address(impl), "L1StandardBridgeImpl");
...@@ -776,7 +634,7 @@ contract DeployImplementations is Script { ...@@ -776,7 +634,7 @@ contract DeployImplementations is Script {
public public
virtual virtual
{ {
string memory release = _dii.release(); string memory release = _dii.l1ContractsRelease();
string memory stdVerToml = _dii.standardVersionsToml(); string memory stdVerToml = _dii.standardVersionsToml();
string memory contractName = "optimism_mintable_erc20_factory"; string memory contractName = "optimism_mintable_erc20_factory";
IOptimismMintableERC20Factory impl; IOptimismMintableERC20Factory impl;
...@@ -784,7 +642,7 @@ contract DeployImplementations is Script { ...@@ -784,7 +642,7 @@ contract DeployImplementations is Script {
address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); address existingImplementation = getReleaseAddress(release, contractName, stdVerToml);
if (existingImplementation != address(0)) { if (existingImplementation != address(0)) {
impl = IOptimismMintableERC20Factory(existingImplementation); impl = IOptimismMintableERC20Factory(existingImplementation);
} else if (isDevelopRelease(release)) { } else {
vm.broadcast(msg.sender); vm.broadcast(msg.sender);
impl = IOptimismMintableERC20Factory( impl = IOptimismMintableERC20Factory(
DeployUtils.create1({ DeployUtils.create1({
...@@ -792,32 +650,12 @@ contract DeployImplementations is Script { ...@@ -792,32 +650,12 @@ contract DeployImplementations is Script {
_args: DeployUtils.encodeConstructor(abi.encodeCall(IOptimismMintableERC20Factory.__constructor__, ())) _args: DeployUtils.encodeConstructor(abi.encodeCall(IOptimismMintableERC20Factory.__constructor__, ()))
}) })
); );
} else {
revert(string.concat("DeployImplementations: failed to deploy release ", release));
} }
vm.label(address(impl), "OptimismMintableERC20FactoryImpl"); vm.label(address(impl), "OptimismMintableERC20FactoryImpl");
_dio.set(_dio.optimismMintableERC20FactoryImpl.selector, address(impl)); _dio.set(_dio.optimismMintableERC20FactoryImpl.selector, address(impl));
} }
function deployOPContractsManagerImpl(
DeployImplementationsInput _dii,
DeployImplementationsOutput _dio
)
public
virtual
{
ISuperchainConfig superchainConfigProxy = _dii.superchainConfigProxy();
IProtocolVersions protocolVersionsProxy = _dii.protocolVersionsProxy();
vm.broadcast(msg.sender);
// TODO: Eventually we will want to select the correct implementation based on the release.
OPContractsManager impl = new OPContractsManager(superchainConfigProxy, protocolVersionsProxy);
vm.label(address(impl), "OPContractsManagerImpl");
_dio.set(_dio.opcmImpl.selector, address(impl));
}
// --- Fault Proofs Contracts --- // --- Fault Proofs Contracts ---
// The fault proofs contracts are configured as follows: // The fault proofs contracts are configured as follows:
...@@ -862,7 +700,7 @@ contract DeployImplementations is Script { ...@@ -862,7 +700,7 @@ contract DeployImplementations is Script {
public public
virtual virtual
{ {
string memory release = _dii.release(); string memory release = _dii.l1ContractsRelease();
string memory stdVerToml = _dii.standardVersionsToml(); string memory stdVerToml = _dii.standardVersionsToml();
string memory contractName = "optimism_portal"; string memory contractName = "optimism_portal";
IOptimismPortal2 impl; IOptimismPortal2 impl;
...@@ -870,7 +708,7 @@ contract DeployImplementations is Script { ...@@ -870,7 +708,7 @@ contract DeployImplementations is Script {
address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); address existingImplementation = getReleaseAddress(release, contractName, stdVerToml);
if (existingImplementation != address(0)) { if (existingImplementation != address(0)) {
impl = IOptimismPortal2(payable(existingImplementation)); impl = IOptimismPortal2(payable(existingImplementation));
} else if (isDevelopRelease(release)) { } else {
uint256 proofMaturityDelaySeconds = _dii.proofMaturityDelaySeconds(); uint256 proofMaturityDelaySeconds = _dii.proofMaturityDelaySeconds();
uint256 disputeGameFinalityDelaySeconds = _dii.disputeGameFinalityDelaySeconds(); uint256 disputeGameFinalityDelaySeconds = _dii.disputeGameFinalityDelaySeconds();
vm.broadcast(msg.sender); vm.broadcast(msg.sender);
...@@ -884,8 +722,6 @@ contract DeployImplementations is Script { ...@@ -884,8 +722,6 @@ contract DeployImplementations is Script {
) )
}) })
); );
} else {
revert(string.concat("DeployImplementations: failed to deploy release ", release));
} }
vm.label(address(impl), "OptimismPortalImpl"); vm.label(address(impl), "OptimismPortalImpl");
...@@ -893,7 +729,7 @@ contract DeployImplementations is Script { ...@@ -893,7 +729,7 @@ contract DeployImplementations is Script {
} }
function deployDelayedWETHImpl(DeployImplementationsInput _dii, DeployImplementationsOutput _dio) public virtual { function deployDelayedWETHImpl(DeployImplementationsInput _dii, DeployImplementationsOutput _dio) public virtual {
string memory release = _dii.release(); string memory release = _dii.l1ContractsRelease();
string memory stdVerToml = _dii.standardVersionsToml(); string memory stdVerToml = _dii.standardVersionsToml();
string memory contractName = "delayed_weth"; string memory contractName = "delayed_weth";
IDelayedWETH impl; IDelayedWETH impl;
...@@ -901,7 +737,7 @@ contract DeployImplementations is Script { ...@@ -901,7 +737,7 @@ contract DeployImplementations is Script {
address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); address existingImplementation = getReleaseAddress(release, contractName, stdVerToml);
if (existingImplementation != address(0)) { if (existingImplementation != address(0)) {
impl = IDelayedWETH(payable(existingImplementation)); impl = IDelayedWETH(payable(existingImplementation));
} else if (isDevelopRelease(release)) { } else {
uint256 withdrawalDelaySeconds = _dii.withdrawalDelaySeconds(); uint256 withdrawalDelaySeconds = _dii.withdrawalDelaySeconds();
vm.broadcast(msg.sender); vm.broadcast(msg.sender);
impl = IDelayedWETH( impl = IDelayedWETH(
...@@ -912,8 +748,6 @@ contract DeployImplementations is Script { ...@@ -912,8 +748,6 @@ contract DeployImplementations is Script {
) )
}) })
); );
} else {
revert(string.concat("DeployImplementations: failed to deploy release ", release));
} }
vm.label(address(impl), "DelayedWETHImpl"); vm.label(address(impl), "DelayedWETHImpl");
...@@ -927,7 +761,7 @@ contract DeployImplementations is Script { ...@@ -927,7 +761,7 @@ contract DeployImplementations is Script {
public public
virtual virtual
{ {
string memory release = _dii.release(); string memory release = _dii.l1ContractsRelease();
string memory stdVerToml = _dii.standardVersionsToml(); string memory stdVerToml = _dii.standardVersionsToml();
string memory contractName = "preimage_oracle"; string memory contractName = "preimage_oracle";
IPreimageOracle singleton; IPreimageOracle singleton;
...@@ -935,7 +769,7 @@ contract DeployImplementations is Script { ...@@ -935,7 +769,7 @@ contract DeployImplementations is Script {
address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); address existingImplementation = getReleaseAddress(release, contractName, stdVerToml);
if (existingImplementation != address(0)) { if (existingImplementation != address(0)) {
singleton = IPreimageOracle(payable(existingImplementation)); singleton = IPreimageOracle(payable(existingImplementation));
} else if (isDevelopRelease(release)) { } else {
uint256 minProposalSizeBytes = _dii.minProposalSizeBytes(); uint256 minProposalSizeBytes = _dii.minProposalSizeBytes();
uint256 challengePeriodSeconds = _dii.challengePeriodSeconds(); uint256 challengePeriodSeconds = _dii.challengePeriodSeconds();
vm.broadcast(msg.sender); vm.broadcast(msg.sender);
...@@ -947,8 +781,6 @@ contract DeployImplementations is Script { ...@@ -947,8 +781,6 @@ contract DeployImplementations is Script {
) )
}) })
); );
} else {
revert(string.concat("DeployImplementations: failed to deploy release ", release));
} }
vm.label(address(singleton), "PreimageOracleSingleton"); vm.label(address(singleton), "PreimageOracleSingleton");
...@@ -956,7 +788,7 @@ contract DeployImplementations is Script { ...@@ -956,7 +788,7 @@ contract DeployImplementations is Script {
} }
function deployMipsSingleton(DeployImplementationsInput _dii, DeployImplementationsOutput _dio) public virtual { function deployMipsSingleton(DeployImplementationsInput _dii, DeployImplementationsOutput _dio) public virtual {
string memory release = _dii.release(); string memory release = _dii.l1ContractsRelease();
string memory stdVerToml = _dii.standardVersionsToml(); string memory stdVerToml = _dii.standardVersionsToml();
string memory contractName = "mips"; string memory contractName = "mips";
IMIPS singleton; IMIPS singleton;
...@@ -964,7 +796,7 @@ contract DeployImplementations is Script { ...@@ -964,7 +796,7 @@ contract DeployImplementations is Script {
address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); address existingImplementation = getReleaseAddress(release, contractName, stdVerToml);
if (existingImplementation != address(0)) { if (existingImplementation != address(0)) {
singleton = IMIPS(payable(existingImplementation)); singleton = IMIPS(payable(existingImplementation));
} else if (isDevelopRelease(release)) { } else {
uint256 mipsVersion = _dii.mipsVersion(); uint256 mipsVersion = _dii.mipsVersion();
IPreimageOracle preimageOracle = IPreimageOracle(address(_dio.preimageOracleSingleton())); IPreimageOracle preimageOracle = IPreimageOracle(address(_dio.preimageOracleSingleton()));
vm.broadcast(msg.sender); vm.broadcast(msg.sender);
...@@ -974,8 +806,6 @@ contract DeployImplementations is Script { ...@@ -974,8 +806,6 @@ contract DeployImplementations is Script {
_args: DeployUtils.encodeConstructor(abi.encodeCall(IMIPS.__constructor__, (preimageOracle))) _args: DeployUtils.encodeConstructor(abi.encodeCall(IMIPS.__constructor__, (preimageOracle)))
}) })
); );
} else {
revert(string.concat("DeployImplementations: failed to deploy release ", release));
} }
vm.label(address(singleton), "MIPSSingleton"); vm.label(address(singleton), "MIPSSingleton");
...@@ -989,7 +819,7 @@ contract DeployImplementations is Script { ...@@ -989,7 +819,7 @@ contract DeployImplementations is Script {
public public
virtual virtual
{ {
string memory release = _dii.release(); string memory release = _dii.l1ContractsRelease();
string memory stdVerToml = _dii.standardVersionsToml(); string memory stdVerToml = _dii.standardVersionsToml();
string memory contractName = "dispute_game_factory"; string memory contractName = "dispute_game_factory";
IDisputeGameFactory impl; IDisputeGameFactory impl;
...@@ -997,7 +827,7 @@ contract DeployImplementations is Script { ...@@ -997,7 +827,7 @@ contract DeployImplementations is Script {
address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); address existingImplementation = getReleaseAddress(release, contractName, stdVerToml);
if (existingImplementation != address(0)) { if (existingImplementation != address(0)) {
impl = IDisputeGameFactory(payable(existingImplementation)); impl = IDisputeGameFactory(payable(existingImplementation));
} else if (isDevelopRelease(release)) { } else {
vm.broadcast(msg.sender); vm.broadcast(msg.sender);
impl = IDisputeGameFactory( impl = IDisputeGameFactory(
DeployUtils.create1({ DeployUtils.create1({
...@@ -1005,8 +835,6 @@ contract DeployImplementations is Script { ...@@ -1005,8 +835,6 @@ contract DeployImplementations is Script {
_args: DeployUtils.encodeConstructor(abi.encodeCall(IDisputeGameFactory.__constructor__, ())) _args: DeployUtils.encodeConstructor(abi.encodeCall(IDisputeGameFactory.__constructor__, ()))
}) })
); );
} else {
revert(string.concat("DeployImplementations: failed to deploy release ", release));
} }
vm.label(address(impl), "DisputeGameFactoryImpl"); vm.label(address(impl), "DisputeGameFactoryImpl");
...@@ -1076,11 +904,6 @@ contract DeployImplementations is Script { ...@@ -1076,11 +904,6 @@ contract DeployImplementations is Script {
} }
} }
} }
// A release is considered a 'develop' release if it does not start with 'op-contracts'.
function isDevelopRelease(string memory _release) internal pure returns (bool) {
return !LibString.startsWith(_release, "op-contracts");
}
} }
// Similar to how DeploySuperchain.s.sol contains a lot of comments to thoroughly document the script // Similar to how DeploySuperchain.s.sol contains a lot of comments to thoroughly document the script
...@@ -1120,36 +943,35 @@ contract DeployImplementationsInterop is DeployImplementations { ...@@ -1120,36 +943,35 @@ contract DeployImplementationsInterop is DeployImplementations {
DeployImplementationsInput _dii, DeployImplementationsInput _dii,
DeployImplementationsOutput _dio, DeployImplementationsOutput _dio,
OPContractsManager.Blueprints memory _blueprints, OPContractsManager.Blueprints memory _blueprints,
string memory _release, string memory _l1ContractsRelease
OPContractsManager.ImplementationSetter[] memory _setters
) )
internal internal
virtual
override override
returns (OPContractsManager opcmProxy_) returns (OPContractsManager opcm_)
{ {
address opcmProxyOwner = _dii.opcmProxyOwner(); ISuperchainConfig superchainConfigProxy = _dii.superchainConfigProxy();
IProtocolVersions protocolVersionsProxy = _dii.protocolVersionsProxy();
OPContractsManager.Implementations memory implementations = OPContractsManager.Implementations({
l1ERC721BridgeImpl: address(_dio.l1ERC721BridgeImpl()),
optimismPortalImpl: address(_dio.optimismPortalImpl()),
systemConfigImpl: address(_dio.systemConfigImpl()),
optimismMintableERC20FactoryImpl: address(_dio.optimismMintableERC20FactoryImpl()),
l1CrossDomainMessengerImpl: address(_dio.l1CrossDomainMessengerImpl()),
l1StandardBridgeImpl: address(_dio.l1StandardBridgeImpl()),
disputeGameFactoryImpl: address(_dio.disputeGameFactoryImpl()),
delayedWETHImpl: address(_dio.delayedWETHImpl()),
mipsImpl: address(_dio.mipsSingleton())
});
vm.broadcast(msg.sender); vm.broadcast(msg.sender);
IProxy proxy = IProxy( opcm_ = new OPContractsManagerInterop(
DeployUtils.create1({ superchainConfigProxy, protocolVersionsProxy, _l1ContractsRelease, _blueprints, implementations
_name: "Proxy",
_args: DeployUtils.encodeConstructor(abi.encodeCall(IProxy.__constructor__, (msg.sender)))
})
); );
deployOPContractsManagerImpl(_dii, _dio); // overriding function vm.label(address(opcm_), "OPContractsManager");
OPContractsManager opcmImpl = _dio.opcmImpl(); _dio.set(_dio.opcm.selector, address(opcm_));
OPContractsManager.InitializerInputs memory initializerInputs =
OPContractsManager.InitializerInputs(_blueprints, _setters, _release, true);
vm.startBroadcast(msg.sender);
proxy.upgradeToAndCall(address(opcmImpl), abi.encodeCall(opcmImpl.initialize, (initializerInputs)));
proxy.changeAdmin(opcmProxyOwner); // transfer ownership of Proxy contract to the ProxyAdmin contract
vm.stopBroadcast();
opcmProxy_ = OPContractsManagerInterop(address(proxy));
} }
function deployOptimismPortalImpl( function deployOptimismPortalImpl(
...@@ -1159,7 +981,7 @@ contract DeployImplementationsInterop is DeployImplementations { ...@@ -1159,7 +981,7 @@ contract DeployImplementationsInterop is DeployImplementations {
public public
override override
{ {
string memory release = _dii.release(); string memory release = _dii.l1ContractsRelease();
string memory stdVerToml = _dii.standardVersionsToml(); string memory stdVerToml = _dii.standardVersionsToml();
string memory contractName = "optimism_portal"; string memory contractName = "optimism_portal";
IOptimismPortalInterop impl; IOptimismPortalInterop impl;
...@@ -1167,7 +989,7 @@ contract DeployImplementationsInterop is DeployImplementations { ...@@ -1167,7 +989,7 @@ contract DeployImplementationsInterop is DeployImplementations {
address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); address existingImplementation = getReleaseAddress(release, contractName, stdVerToml);
if (existingImplementation != address(0)) { if (existingImplementation != address(0)) {
impl = IOptimismPortalInterop(payable(existingImplementation)); impl = IOptimismPortalInterop(payable(existingImplementation));
} else if (isDevelopRelease(release)) { } else {
uint256 proofMaturityDelaySeconds = _dii.proofMaturityDelaySeconds(); uint256 proofMaturityDelaySeconds = _dii.proofMaturityDelaySeconds();
uint256 disputeGameFinalityDelaySeconds = _dii.disputeGameFinalityDelaySeconds(); uint256 disputeGameFinalityDelaySeconds = _dii.disputeGameFinalityDelaySeconds();
vm.broadcast(msg.sender); vm.broadcast(msg.sender);
...@@ -1182,8 +1004,6 @@ contract DeployImplementationsInterop is DeployImplementations { ...@@ -1182,8 +1004,6 @@ contract DeployImplementationsInterop is DeployImplementations {
) )
}) })
); );
} else {
revert(string.concat("DeployImplementations: failed to deploy release ", release));
} }
vm.label(address(impl), "OptimismPortalImpl"); vm.label(address(impl), "OptimismPortalImpl");
...@@ -1197,7 +1017,7 @@ contract DeployImplementationsInterop is DeployImplementations { ...@@ -1197,7 +1017,7 @@ contract DeployImplementationsInterop is DeployImplementations {
public public
override override
{ {
string memory release = _dii.release(); string memory release = _dii.l1ContractsRelease();
string memory stdVerToml = _dii.standardVersionsToml(); string memory stdVerToml = _dii.standardVersionsToml();
string memory contractName = "system_config"; string memory contractName = "system_config";
...@@ -1206,7 +1026,7 @@ contract DeployImplementationsInterop is DeployImplementations { ...@@ -1206,7 +1026,7 @@ contract DeployImplementationsInterop is DeployImplementations {
address existingImplementation = getReleaseAddress(release, contractName, stdVerToml); address existingImplementation = getReleaseAddress(release, contractName, stdVerToml);
if (existingImplementation != address(0)) { if (existingImplementation != address(0)) {
impl = ISystemConfigInterop(existingImplementation); impl = ISystemConfigInterop(existingImplementation);
} else if (isDevelopRelease(release)) { } else {
vm.broadcast(msg.sender); vm.broadcast(msg.sender);
impl = ISystemConfigInterop( impl = ISystemConfigInterop(
DeployUtils.create1({ DeployUtils.create1({
...@@ -1214,46 +1034,9 @@ contract DeployImplementationsInterop is DeployImplementations { ...@@ -1214,46 +1034,9 @@ contract DeployImplementationsInterop is DeployImplementations {
_args: DeployUtils.encodeConstructor(abi.encodeCall(ISystemConfigInterop.__constructor__, ())) _args: DeployUtils.encodeConstructor(abi.encodeCall(ISystemConfigInterop.__constructor__, ()))
}) })
); );
} else {
revert(string.concat("DeployImplementations: failed to deploy release ", release));
} }
vm.label(address(impl), "SystemConfigImpl"); vm.label(address(impl), "SystemConfigImpl");
_dio.set(_dio.systemConfigImpl.selector, address(impl)); _dio.set(_dio.systemConfigImpl.selector, address(impl));
} }
function deployOPContractsManagerImpl(
DeployImplementationsInput _dii,
DeployImplementationsOutput _dio
)
public
override
{
ISuperchainConfig superchainConfigProxy = _dii.superchainConfigProxy();
IProtocolVersions protocolVersionsProxy = _dii.protocolVersionsProxy();
vm.broadcast(msg.sender);
// TODO: Eventually we will want to select the correct implementation based on the release.
OPContractsManager impl = new OPContractsManagerInterop(superchainConfigProxy, protocolVersionsProxy);
vm.label(address(impl), "OPContractsManagerImpl");
_dio.set(_dio.opcmImpl.selector, address(impl));
}
function opcmSystemConfigSetter(
DeployImplementationsInput,
DeployImplementationsOutput _dio
)
internal
view
override
returns (OPContractsManager.ImplementationSetter memory)
{
return OPContractsManager.ImplementationSetter({
name: "SystemConfig",
info: OPContractsManager.Implementation(
address(_dio.systemConfigImpl()), ISystemConfigInterop.initialize.selector
)
});
}
} }
...@@ -47,7 +47,7 @@ contract DeployOPChainInput is BaseDeployIO { ...@@ -47,7 +47,7 @@ contract DeployOPChainInput is BaseDeployIO {
uint32 internal _basefeeScalar; uint32 internal _basefeeScalar;
uint32 internal _blobBaseFeeScalar; uint32 internal _blobBaseFeeScalar;
uint256 internal _l2ChainId; uint256 internal _l2ChainId;
OPContractsManager internal _opcmProxy; OPContractsManager internal _opcm;
string internal _saltMixer; string internal _saltMixer;
uint64 internal _gasLimit; uint64 internal _gasLimit;
...@@ -68,7 +68,7 @@ contract DeployOPChainInput is BaseDeployIO { ...@@ -68,7 +68,7 @@ contract DeployOPChainInput is BaseDeployIO {
else if (_sel == this.unsafeBlockSigner.selector) _unsafeBlockSigner = _addr; else if (_sel == this.unsafeBlockSigner.selector) _unsafeBlockSigner = _addr;
else if (_sel == this.proposer.selector) _proposer = _addr; else if (_sel == this.proposer.selector) _proposer = _addr;
else if (_sel == this.challenger.selector) _challenger = _addr; else if (_sel == this.challenger.selector) _challenger = _addr;
else if (_sel == this.opcmProxy.selector) _opcmProxy = OPContractsManager(_addr); else if (_sel == this.opcm.selector) _opcm = OPContractsManager(_addr);
else revert("DeployOPChainInput: unknown selector"); else revert("DeployOPChainInput: unknown selector");
} }
...@@ -174,11 +174,10 @@ contract DeployOPChainInput is BaseDeployIO { ...@@ -174,11 +174,10 @@ contract DeployOPChainInput is BaseDeployIO {
return abi.encode(ScriptConstants.DEFAULT_STARTING_ANCHOR_ROOTS()); return abi.encode(ScriptConstants.DEFAULT_STARTING_ANCHOR_ROOTS());
} }
function opcmProxy() public returns (OPContractsManager) { function opcm() public view returns (OPContractsManager) {
require(address(_opcmProxy) != address(0), "DeployOPChainInput: not set"); require(address(_opcm) != address(0), "DeployOPChainInput: not set");
DeployUtils.assertValidContractAddress(address(_opcmProxy)); DeployUtils.assertValidContractAddress(address(_opcm));
DeployUtils.assertERC1967ImplementationSet(address(_opcmProxy)); return _opcm;
return _opcmProxy;
} }
function saltMixer() public view returns (string memory) { function saltMixer() public view returns (string memory) {
...@@ -347,7 +346,7 @@ contract DeployOPChain is Script { ...@@ -347,7 +346,7 @@ contract DeployOPChain is Script {
// -------- Core Deployment Methods -------- // -------- Core Deployment Methods --------
function run(DeployOPChainInput _doi, DeployOPChainOutput _doo) public { function run(DeployOPChainInput _doi, DeployOPChainOutput _doo) public {
OPContractsManager opcmProxy = _doi.opcmProxy(); OPContractsManager opcm = _doi.opcm();
OPContractsManager.Roles memory roles = OPContractsManager.Roles({ OPContractsManager.Roles memory roles = OPContractsManager.Roles({
opChainProxyAdminOwner: _doi.opChainProxyAdminOwner(), opChainProxyAdminOwner: _doi.opChainProxyAdminOwner(),
...@@ -374,7 +373,7 @@ contract DeployOPChain is Script { ...@@ -374,7 +373,7 @@ contract DeployOPChain is Script {
}); });
vm.broadcast(msg.sender); vm.broadcast(msg.sender);
OPContractsManager.DeployOutput memory deployOutput = opcmProxy.deploy(deployInput); OPContractsManager.DeployOutput memory deployOutput = opcm.deploy(deployInput);
vm.label(address(deployOutput.opChainProxyAdmin), "opChainProxyAdmin"); vm.label(address(deployOutput.opChainProxyAdmin), "opChainProxyAdmin");
vm.label(address(deployOutput.addressManager), "addressManager"); vm.label(address(deployOutput.addressManager), "addressManager");
...@@ -480,9 +479,9 @@ contract DeployOPChain is Script { ...@@ -480,9 +479,9 @@ contract DeployOPChain is Script {
"DPG-20" "DPG-20"
); );
OPContractsManager opcm = _doi.opcmProxy(); OPContractsManager opcm = _doi.opcm();
(address mips,) = opcm.implementations(opcm.latestRelease(), "MIPS"); address mipsImpl = opcm.implementations().mipsImpl;
require(game.vm() == IBigStepper(mips), "DPG-30"); require(game.vm() == IBigStepper(mipsImpl), "DPG-30");
require(address(game.weth()) == address(_doo.delayedWETHPermissionedGameProxy()), "DPG-40"); require(address(game.weth()) == address(_doo.delayedWETHPermissionedGameProxy()), "DPG-40");
require(address(game.anchorStateRegistry()) == address(_doo.anchorStateRegistryProxy()), "DPG-50"); require(address(game.anchorStateRegistry()) == address(_doo.anchorStateRegistryProxy()), "DPG-50");
...@@ -552,9 +551,7 @@ contract DeployOPChain is Script { ...@@ -552,9 +551,7 @@ contract DeployOPChain is Script {
require(outputConfig.maximumBaseFee == rConfig.maximumBaseFee, "SYSCON-130"); require(outputConfig.maximumBaseFee == rConfig.maximumBaseFee, "SYSCON-130");
require(systemConfig.startBlock() == block.number, "SYSCON-140"); require(systemConfig.startBlock() == block.number, "SYSCON-140");
require( require(systemConfig.batchInbox() == _doi.opcm().chainIdToBatchInboxAddress(_doi.l2ChainId()), "SYSCON-150");
systemConfig.batchInbox() == _doi.opcmProxy().chainIdToBatchInboxAddress(_doi.l2ChainId()), "SYSCON-150"
);
require(systemConfig.l1CrossDomainMessenger() == address(_doo.l1CrossDomainMessengerProxy()), "SYSCON-160"); require(systemConfig.l1CrossDomainMessenger() == address(_doo.l1CrossDomainMessengerProxy()), "SYSCON-160");
require(systemConfig.l1ERC721Bridge() == address(_doo.l1ERC721BridgeProxy()), "SYSCON-170"); require(systemConfig.l1ERC721Bridge() == address(_doo.l1ERC721BridgeProxy()), "SYSCON-170");
...@@ -579,7 +576,7 @@ contract DeployOPChain is Script { ...@@ -579,7 +576,7 @@ contract DeployOPChain is Script {
require(address(messenger.PORTAL()) == address(_doo.optimismPortalProxy()), "L1xDM-30"); require(address(messenger.PORTAL()) == address(_doo.optimismPortalProxy()), "L1xDM-30");
require(address(messenger.portal()) == address(_doo.optimismPortalProxy()), "L1xDM-40"); require(address(messenger.portal()) == address(_doo.optimismPortalProxy()), "L1xDM-40");
require(address(messenger.superchainConfig()) == address(_doi.opcmProxy().superchainConfig()), "L1xDM-50"); require(address(messenger.superchainConfig()) == address(_doi.opcm().superchainConfig()), "L1xDM-50");
bytes32 xdmSenderSlot = vm.load(address(messenger), bytes32(uint256(204))); bytes32 xdmSenderSlot = vm.load(address(messenger), bytes32(uint256(204)));
require(address(uint160(uint256(xdmSenderSlot))) == Constants.DEFAULT_L2_SENDER, "L1xDM-60"); require(address(uint160(uint256(xdmSenderSlot))) == Constants.DEFAULT_L2_SENDER, "L1xDM-60");
...@@ -595,7 +592,7 @@ contract DeployOPChain is Script { ...@@ -595,7 +592,7 @@ contract DeployOPChain is Script {
require(address(bridge.messenger()) == address(messenger), "L1SB-20"); require(address(bridge.messenger()) == address(messenger), "L1SB-20");
require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_STANDARD_BRIDGE, "L1SB-30"); require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_STANDARD_BRIDGE, "L1SB-30");
require(address(bridge.otherBridge()) == Predeploys.L2_STANDARD_BRIDGE, "L1SB-40"); require(address(bridge.otherBridge()) == Predeploys.L2_STANDARD_BRIDGE, "L1SB-40");
require(address(bridge.superchainConfig()) == address(_doi.opcmProxy().superchainConfig()), "L1SB-50"); require(address(bridge.superchainConfig()) == address(_doi.opcm().superchainConfig()), "L1SB-50");
} }
function assertValidOptimismMintableERC20Factory(DeployOPChainInput, DeployOPChainOutput _doo) internal { function assertValidOptimismMintableERC20Factory(DeployOPChainInput, DeployOPChainOutput _doo) internal {
...@@ -617,12 +614,12 @@ contract DeployOPChain is Script { ...@@ -617,12 +614,12 @@ contract DeployOPChain is Script {
require(address(bridge.MESSENGER()) == address(_doo.l1CrossDomainMessengerProxy()), "L721B-30"); require(address(bridge.MESSENGER()) == address(_doo.l1CrossDomainMessengerProxy()), "L721B-30");
require(address(bridge.messenger()) == address(_doo.l1CrossDomainMessengerProxy()), "L721B-40"); require(address(bridge.messenger()) == address(_doo.l1CrossDomainMessengerProxy()), "L721B-40");
require(address(bridge.superchainConfig()) == address(_doi.opcmProxy().superchainConfig()), "L721B-50"); require(address(bridge.superchainConfig()) == address(_doi.opcm().superchainConfig()), "L721B-50");
} }
function assertValidOptimismPortal(DeployOPChainInput _doi, DeployOPChainOutput _doo) internal { function assertValidOptimismPortal(DeployOPChainInput _doi, DeployOPChainOutput _doo) internal {
IOptimismPortal2 portal = _doo.optimismPortalProxy(); IOptimismPortal2 portal = _doo.optimismPortalProxy();
ISuperchainConfig superchainConfig = ISuperchainConfig(address(_doi.opcmProxy().superchainConfig())); ISuperchainConfig superchainConfig = ISuperchainConfig(address(_doi.opcm().superchainConfig()));
require(address(portal.disputeGameFactory()) == address(_doo.disputeGameFactoryProxy()), "PORTAL-10"); require(address(portal.disputeGameFactory()) == address(_doo.disputeGameFactoryProxy()), "PORTAL-10");
require(address(portal.systemConfig()) == address(_doo.systemConfigProxy()), "PORTAL-20"); require(address(portal.systemConfig()) == address(_doo.systemConfigProxy()), "PORTAL-20");
......
...@@ -12,29 +12,18 @@ import { IAddressManager } from "src/legacy/interfaces/IAddressManager.sol"; ...@@ -12,29 +12,18 @@ import { IAddressManager } from "src/legacy/interfaces/IAddressManager.sol";
import { IStaticL1ChugSplashProxy } from "src/legacy/interfaces/IL1ChugSplashProxy.sol"; import { IStaticL1ChugSplashProxy } from "src/legacy/interfaces/IL1ChugSplashProxy.sol";
contract ReadImplementationAddressesInput is DeployOPChainOutput { contract ReadImplementationAddressesInput is DeployOPChainOutput {
OPContractsManager internal _opcmProxy; OPContractsManager internal _opcm;
string internal _release;
function set(bytes4 _sel, address _addr) public override { function set(bytes4 _sel, address _addr) public override {
require(_addr != address(0), "ReadImplementationAddressesInput: cannot set zero address"); require(_addr != address(0), "ReadImplementationAddressesInput: cannot set zero address");
if (_sel == this.opcmProxy.selector) _opcmProxy = OPContractsManager(_addr); if (_sel == this.opcm.selector) _opcm = OPContractsManager(_addr);
else if (_sel == this.addressManager.selector) _addressManager = IAddressManager(_addr); else if (_sel == this.addressManager.selector) _addressManager = IAddressManager(_addr);
else super.set(_sel, _addr); else super.set(_sel, _addr);
} }
function set(bytes4 _sel, string memory _val) public { function opcm() public view returns (OPContractsManager) {
if (_sel == this.release.selector) _release = _val; DeployUtils.assertValidContractAddress(address(_opcm));
else revert("ReadImplementationAddressesInput: unknown selector"); return _opcm;
}
function opcmProxy() public view returns (OPContractsManager) {
DeployUtils.assertValidContractAddress(address(_opcmProxy));
return _opcmProxy;
}
function release() public view returns (string memory) {
require(bytes(_release).length != 0, "ReadImplementationAddressesInput: release not set");
return _release;
} }
} }
...@@ -154,9 +143,12 @@ contract ReadImplementationAddresses is Script { ...@@ -154,9 +143,12 @@ contract ReadImplementationAddresses is Script {
vm.prank(address(0)); vm.prank(address(0));
_rio.set(_rio.l1StandardBridge.selector, l1SBImpl); _rio.set(_rio.l1StandardBridge.selector, l1SBImpl);
(address mipsLogic,) = _rii.opcmProxy().implementations(_rii.release(), "MIPS"); address mipsLogic = _rii.opcm().implementations().mipsImpl;
_rio.set(_rio.mipsSingleton.selector, mipsLogic); _rio.set(_rio.mipsSingleton.selector, mipsLogic);
address delayedWETH = _rii.opcm().implementations().delayedWETHImpl;
_rio.set(_rio.delayedWETH.selector, delayedWETH);
IAddressManager am = _rii.addressManager(); IAddressManager am = _rii.addressManager();
_rio.set(_rio.l1CrossDomainMessenger.selector, am.getAddress("OVM_L1CrossDomainMessenger")); _rio.set(_rio.l1CrossDomainMessenger.selector, am.getAddress("OVM_L1CrossDomainMessenger"));
......
...@@ -10,6 +10,110 @@ ...@@ -10,6 +10,110 @@
"internalType": "contract IProtocolVersions", "internalType": "contract IProtocolVersions",
"name": "_protocolVersions", "name": "_protocolVersions",
"type": "address" "type": "address"
},
{
"internalType": "string",
"name": "_l1ContractsRelease",
"type": "string"
},
{
"components": [
{
"internalType": "address",
"name": "addressManager",
"type": "address"
},
{
"internalType": "address",
"name": "proxy",
"type": "address"
},
{
"internalType": "address",
"name": "proxyAdmin",
"type": "address"
},
{
"internalType": "address",
"name": "l1ChugSplashProxy",
"type": "address"
},
{
"internalType": "address",
"name": "resolvedDelegateProxy",
"type": "address"
},
{
"internalType": "address",
"name": "anchorStateRegistry",
"type": "address"
},
{
"internalType": "address",
"name": "permissionedDisputeGame1",
"type": "address"
},
{
"internalType": "address",
"name": "permissionedDisputeGame2",
"type": "address"
}
],
"internalType": "struct OPContractsManager.Blueprints",
"name": "_blueprints",
"type": "tuple"
},
{
"components": [
{
"internalType": "address",
"name": "l1ERC721BridgeImpl",
"type": "address"
},
{
"internalType": "address",
"name": "optimismPortalImpl",
"type": "address"
},
{
"internalType": "address",
"name": "systemConfigImpl",
"type": "address"
},
{
"internalType": "address",
"name": "optimismMintableERC20FactoryImpl",
"type": "address"
},
{
"internalType": "address",
"name": "l1CrossDomainMessengerImpl",
"type": "address"
},
{
"internalType": "address",
"name": "l1StandardBridgeImpl",
"type": "address"
},
{
"internalType": "address",
"name": "disputeGameFactoryImpl",
"type": "address"
},
{
"internalType": "address",
"name": "delayedWETHImpl",
"type": "address"
},
{
"internalType": "address",
"name": "mipsImpl",
"type": "address"
}
],
"internalType": "struct OPContractsManager.Implementations",
"name": "_implementations",
"type": "tuple"
} }
], ],
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
...@@ -298,138 +402,68 @@ ...@@ -298,138 +402,68 @@
"type": "function" "type": "function"
}, },
{ {
"inputs": [ "inputs": [],
{
"internalType": "string",
"name": "",
"type": "string"
},
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"name": "implementations", "name": "implementations",
"outputs": [ "outputs": [
{
"internalType": "address",
"name": "logic",
"type": "address"
},
{
"internalType": "bytes4",
"name": "initializer",
"type": "bytes4"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ {
"components": [ "components": [
{ {
"components": [ "internalType": "address",
{ "name": "l1ERC721BridgeImpl",
"internalType": "address", "type": "address"
"name": "addressManager",
"type": "address"
},
{
"internalType": "address",
"name": "proxy",
"type": "address"
},
{
"internalType": "address",
"name": "proxyAdmin",
"type": "address"
},
{
"internalType": "address",
"name": "l1ChugSplashProxy",
"type": "address"
},
{
"internalType": "address",
"name": "resolvedDelegateProxy",
"type": "address"
},
{
"internalType": "address",
"name": "anchorStateRegistry",
"type": "address"
},
{
"internalType": "address",
"name": "permissionedDisputeGame1",
"type": "address"
},
{
"internalType": "address",
"name": "permissionedDisputeGame2",
"type": "address"
}
],
"internalType": "struct OPContractsManager.Blueprints",
"name": "blueprints",
"type": "tuple"
}, },
{ {
"components": [ "internalType": "address",
{ "name": "optimismPortalImpl",
"internalType": "string", "type": "address"
"name": "name",
"type": "string"
},
{
"components": [
{
"internalType": "address",
"name": "logic",
"type": "address"
},
{
"internalType": "bytes4",
"name": "initializer",
"type": "bytes4"
}
],
"internalType": "struct OPContractsManager.Implementation",
"name": "info",
"type": "tuple"
}
],
"internalType": "struct OPContractsManager.ImplementationSetter[]",
"name": "setters",
"type": "tuple[]"
}, },
{ {
"internalType": "string", "internalType": "address",
"name": "release", "name": "systemConfigImpl",
"type": "string" "type": "address"
},
{
"internalType": "address",
"name": "optimismMintableERC20FactoryImpl",
"type": "address"
},
{
"internalType": "address",
"name": "l1CrossDomainMessengerImpl",
"type": "address"
},
{
"internalType": "address",
"name": "l1StandardBridgeImpl",
"type": "address"
}, },
{ {
"internalType": "bool", "internalType": "address",
"name": "isLatest", "name": "disputeGameFactoryImpl",
"type": "bool" "type": "address"
},
{
"internalType": "address",
"name": "delayedWETHImpl",
"type": "address"
},
{
"internalType": "address",
"name": "mipsImpl",
"type": "address"
} }
], ],
"internalType": "struct OPContractsManager.InitializerInputs", "internalType": "struct OPContractsManager.Implementations",
"name": "_initializerInputs", "name": "",
"type": "tuple" "type": "tuple"
} }
], ],
"name": "initialize", "stateMutability": "view",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function" "type": "function"
}, },
{ {
"inputs": [], "inputs": [],
"name": "latestRelease", "name": "l1ContractsRelease",
"outputs": [ "outputs": [
{ {
"internalType": "string", "internalType": "string",
...@@ -529,19 +563,6 @@ ...@@ -529,19 +563,6 @@
"name": "Deployed", "name": "Deployed",
"type": "event" "type": "event"
}, },
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint8",
"name": "version",
"type": "uint8"
}
],
"name": "Initialized",
"type": "event"
},
{ {
"inputs": [ "inputs": [
{ {
......
...@@ -10,6 +10,110 @@ ...@@ -10,6 +10,110 @@
"internalType": "contract IProtocolVersions", "internalType": "contract IProtocolVersions",
"name": "_protocolVersions", "name": "_protocolVersions",
"type": "address" "type": "address"
},
{
"internalType": "string",
"name": "_l1ContractsRelease",
"type": "string"
},
{
"components": [
{
"internalType": "address",
"name": "addressManager",
"type": "address"
},
{
"internalType": "address",
"name": "proxy",
"type": "address"
},
{
"internalType": "address",
"name": "proxyAdmin",
"type": "address"
},
{
"internalType": "address",
"name": "l1ChugSplashProxy",
"type": "address"
},
{
"internalType": "address",
"name": "resolvedDelegateProxy",
"type": "address"
},
{
"internalType": "address",
"name": "anchorStateRegistry",
"type": "address"
},
{
"internalType": "address",
"name": "permissionedDisputeGame1",
"type": "address"
},
{
"internalType": "address",
"name": "permissionedDisputeGame2",
"type": "address"
}
],
"internalType": "struct OPContractsManager.Blueprints",
"name": "_blueprints",
"type": "tuple"
},
{
"components": [
{
"internalType": "address",
"name": "l1ERC721BridgeImpl",
"type": "address"
},
{
"internalType": "address",
"name": "optimismPortalImpl",
"type": "address"
},
{
"internalType": "address",
"name": "systemConfigImpl",
"type": "address"
},
{
"internalType": "address",
"name": "optimismMintableERC20FactoryImpl",
"type": "address"
},
{
"internalType": "address",
"name": "l1CrossDomainMessengerImpl",
"type": "address"
},
{
"internalType": "address",
"name": "l1StandardBridgeImpl",
"type": "address"
},
{
"internalType": "address",
"name": "disputeGameFactoryImpl",
"type": "address"
},
{
"internalType": "address",
"name": "delayedWETHImpl",
"type": "address"
},
{
"internalType": "address",
"name": "mipsImpl",
"type": "address"
}
],
"internalType": "struct OPContractsManager.Implementations",
"name": "_implementations",
"type": "tuple"
} }
], ],
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
...@@ -298,138 +402,68 @@ ...@@ -298,138 +402,68 @@
"type": "function" "type": "function"
}, },
{ {
"inputs": [ "inputs": [],
{
"internalType": "string",
"name": "",
"type": "string"
},
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"name": "implementations", "name": "implementations",
"outputs": [ "outputs": [
{
"internalType": "address",
"name": "logic",
"type": "address"
},
{
"internalType": "bytes4",
"name": "initializer",
"type": "bytes4"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ {
"components": [ "components": [
{ {
"components": [ "internalType": "address",
{ "name": "l1ERC721BridgeImpl",
"internalType": "address", "type": "address"
"name": "addressManager",
"type": "address"
},
{
"internalType": "address",
"name": "proxy",
"type": "address"
},
{
"internalType": "address",
"name": "proxyAdmin",
"type": "address"
},
{
"internalType": "address",
"name": "l1ChugSplashProxy",
"type": "address"
},
{
"internalType": "address",
"name": "resolvedDelegateProxy",
"type": "address"
},
{
"internalType": "address",
"name": "anchorStateRegistry",
"type": "address"
},
{
"internalType": "address",
"name": "permissionedDisputeGame1",
"type": "address"
},
{
"internalType": "address",
"name": "permissionedDisputeGame2",
"type": "address"
}
],
"internalType": "struct OPContractsManager.Blueprints",
"name": "blueprints",
"type": "tuple"
}, },
{ {
"components": [ "internalType": "address",
{ "name": "optimismPortalImpl",
"internalType": "string", "type": "address"
"name": "name",
"type": "string"
},
{
"components": [
{
"internalType": "address",
"name": "logic",
"type": "address"
},
{
"internalType": "bytes4",
"name": "initializer",
"type": "bytes4"
}
],
"internalType": "struct OPContractsManager.Implementation",
"name": "info",
"type": "tuple"
}
],
"internalType": "struct OPContractsManager.ImplementationSetter[]",
"name": "setters",
"type": "tuple[]"
}, },
{ {
"internalType": "string", "internalType": "address",
"name": "release", "name": "systemConfigImpl",
"type": "string" "type": "address"
},
{
"internalType": "address",
"name": "optimismMintableERC20FactoryImpl",
"type": "address"
},
{
"internalType": "address",
"name": "l1CrossDomainMessengerImpl",
"type": "address"
},
{
"internalType": "address",
"name": "l1StandardBridgeImpl",
"type": "address"
}, },
{ {
"internalType": "bool", "internalType": "address",
"name": "isLatest", "name": "disputeGameFactoryImpl",
"type": "bool" "type": "address"
},
{
"internalType": "address",
"name": "delayedWETHImpl",
"type": "address"
},
{
"internalType": "address",
"name": "mipsImpl",
"type": "address"
} }
], ],
"internalType": "struct OPContractsManager.InitializerInputs", "internalType": "struct OPContractsManager.Implementations",
"name": "_initializerInputs", "name": "",
"type": "tuple" "type": "tuple"
} }
], ],
"name": "initialize", "stateMutability": "view",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function" "type": "function"
}, },
{ {
"inputs": [], "inputs": [],
"name": "latestRelease", "name": "l1ContractsRelease",
"outputs": [ "outputs": [
{ {
"internalType": "string", "internalType": "string",
...@@ -529,19 +563,6 @@ ...@@ -529,19 +563,6 @@
"name": "Deployed", "name": "Deployed",
"type": "event" "type": "event"
}, },
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint8",
"name": "version",
"type": "uint8"
}
],
"name": "Initialized",
"type": "event"
},
{ {
"inputs": [ "inputs": [
{ {
......
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
"sourceCodeHash": "0x4132ff37d267cb12224b75ea806c0aa7d25407b0d66ce526d7fcda8f7d223882" "sourceCodeHash": "0x4132ff37d267cb12224b75ea806c0aa7d25407b0d66ce526d7fcda8f7d223882"
}, },
"src/L1/OPContractsManager.sol": { "src/L1/OPContractsManager.sol": {
"initCodeHash": "0xd58cb3978affc5c1457cdd498ff8420c90aef804d4c3b62cf42ab2691986d6d2", "initCodeHash": "0xd038cc35325d023499151264232d75fa4ecc81f04a8c8353e6b50c43af224d6e",
"sourceCodeHash": "0x7bfa6eff76176649fe600303cd60009a0f6e282cbaec55836b5ea1f8875cbeb5" "sourceCodeHash": "0xa13f3ab2b8744015290dbabe5f20fdd44774607e6a7ad3e5e016303fc4aa8c12"
}, },
"src/L1/OptimismPortal.sol": { "src/L1/OptimismPortal.sol": {
"initCodeHash": "0x152167cfa18635ae4918a6eb3371a599cfa084418c0a652799cdb48bfc0ee0cc", "initCodeHash": "0x152167cfa18635ae4918a6eb3371a599cfa084418c0a652799cdb48bfc0ee0cc",
......
[ [
{
"bytes": "1",
"label": "_initialized",
"offset": 0,
"slot": "0",
"type": "uint8"
},
{
"bytes": "1",
"label": "_initializing",
"offset": 1,
"slot": "0",
"type": "bool"
},
{ {
"bytes": "32", "bytes": "32",
"label": "latestRelease", "label": "l1ContractsRelease",
"offset": 0, "offset": 0,
"slot": "1", "slot": "0",
"type": "string" "type": "string"
}, },
{
"bytes": "32",
"label": "implementations",
"offset": 0,
"slot": "2",
"type": "mapping(string => mapping(string => struct OPContractsManager.Implementation))"
},
{ {
"bytes": "32", "bytes": "32",
"label": "systemConfigs", "label": "systemConfigs",
"offset": 0, "offset": 0,
"slot": "3", "slot": "1",
"type": "mapping(uint256 => contract ISystemConfig)" "type": "mapping(uint256 => contract ISystemConfig)"
}, },
{ {
"bytes": "256", "bytes": "256",
"label": "blueprint", "label": "blueprint",
"offset": 0, "offset": 0,
"slot": "4", "slot": "2",
"type": "struct OPContractsManager.Blueprints" "type": "struct OPContractsManager.Blueprints"
}, },
{ {
"bytes": "1600", "bytes": "288",
"label": "__gap", "label": "implementation",
"offset": 0, "offset": 0,
"slot": "12", "slot": "10",
"type": "uint256[50]" "type": "struct OPContractsManager.Implementations"
} }
] ]
\ No newline at end of file
[ [
{
"bytes": "1",
"label": "_initialized",
"offset": 0,
"slot": "0",
"type": "uint8"
},
{
"bytes": "1",
"label": "_initializing",
"offset": 1,
"slot": "0",
"type": "bool"
},
{ {
"bytes": "32", "bytes": "32",
"label": "latestRelease", "label": "l1ContractsRelease",
"offset": 0, "offset": 0,
"slot": "1", "slot": "0",
"type": "string" "type": "string"
}, },
{
"bytes": "32",
"label": "implementations",
"offset": 0,
"slot": "2",
"type": "mapping(string => mapping(string => struct OPContractsManager.Implementation))"
},
{ {
"bytes": "32", "bytes": "32",
"label": "systemConfigs", "label": "systemConfigs",
"offset": 0, "offset": 0,
"slot": "3", "slot": "1",
"type": "mapping(uint256 => contract ISystemConfig)" "type": "mapping(uint256 => contract ISystemConfig)"
}, },
{ {
"bytes": "256", "bytes": "256",
"label": "blueprint", "label": "blueprint",
"offset": 0, "offset": 0,
"slot": "4", "slot": "2",
"type": "struct OPContractsManager.Blueprints" "type": "struct OPContractsManager.Blueprints"
}, },
{ {
"bytes": "1600", "bytes": "288",
"label": "__gap", "label": "implementation",
"offset": 0, "offset": 0,
"slot": "12", "slot": "10",
"type": "uint256[50]" "type": "struct OPContractsManager.Implementations"
} }
] ]
\ No newline at end of file
...@@ -4,15 +4,12 @@ pragma solidity 0.8.15; ...@@ -4,15 +4,12 @@ pragma solidity 0.8.15;
import { Blueprint } from "src/libraries/Blueprint.sol"; import { Blueprint } from "src/libraries/Blueprint.sol";
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol";
import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol";
import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol"; import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol";
import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol";
import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol";
import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol";
import { ISystemConfigV160 } from "src/L1/interfaces/ISystemConfigV160.sol";
import { IAddressManager } from "src/legacy/interfaces/IAddressManager.sol"; import { IAddressManager } from "src/legacy/interfaces/IAddressManager.sol";
import { IProxyAdmin } from "src/universal/interfaces/IProxyAdmin.sol"; import { IProxyAdmin } from "src/universal/interfaces/IProxyAdmin.sol";
...@@ -28,14 +25,12 @@ import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; ...@@ -28,14 +25,12 @@ import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol";
import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol"; import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol";
import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol";
import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol";
import { ISystemConfigV160 } from "src/L1/interfaces/ISystemConfigV160.sol";
import { IL1CrossDomainMessenger } from "src/L1/interfaces/IL1CrossDomainMessenger.sol"; import { IL1CrossDomainMessenger } from "src/L1/interfaces/IL1CrossDomainMessenger.sol";
import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol";
import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol"; import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol";
import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol";
/// @custom:proxied true contract OPContractsManager is ISemver {
contract OPContractsManager is ISemver, Initializable {
// -------- Structs -------- // -------- Structs --------
/// @notice Represents the roles that can be set when deploying a standard OP Stack chain. /// @notice Represents the roles that can be set when deploying a standard OP Stack chain.
...@@ -89,19 +84,6 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -89,19 +84,6 @@ contract OPContractsManager is ISemver, Initializable {
IDelayedWETH delayedWETHPermissionlessGameProxy; IDelayedWETH delayedWETHPermissionlessGameProxy;
} }
/// @notice The logic address and initializer selector for an implementation contract.
struct Implementation {
address logic; // Address containing the deployed logic contract.
bytes4 initializer; // Function selector for the initializer.
}
/// @notice Used to set the implementation for a contract by mapping a contract
/// name to the implementation data.
struct ImplementationSetter {
string name; // Contract name.
Implementation info; // Implementation to set.
}
/// @notice Addresses of ERC-5202 Blueprint contracts. There are used for deploying full size /// @notice Addresses of ERC-5202 Blueprint contracts. There are used for deploying full size
/// contracts, to reduce the code size of this factory contract. If it deployed full contracts /// contracts, to reduce the code size of this factory contract. If it deployed full contracts
/// using the `new Proxy()` syntax, the code size would get large fast, since this contract would /// using the `new Proxy()` syntax, the code size would get large fast, since this contract would
...@@ -118,19 +100,23 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -118,19 +100,23 @@ contract OPContractsManager is ISemver, Initializable {
address permissionedDisputeGame2; address permissionedDisputeGame2;
} }
/// @notice Inputs required when initializing the OPContractsManager. To avoid 'StackTooDeep' errors, /// @notice The latest implementation contracts for the OP Stack.
/// all necessary inputs (excluding immutables) for initialization are bundled together in this struct. struct Implementations {
struct InitializerInputs { address l1ERC721BridgeImpl;
Blueprints blueprints; address optimismPortalImpl;
ImplementationSetter[] setters; address systemConfigImpl;
string release; address optimismMintableERC20FactoryImpl;
bool isLatest; address l1CrossDomainMessengerImpl;
address l1StandardBridgeImpl;
address disputeGameFactoryImpl;
address delayedWETHImpl;
address mipsImpl;
} }
// -------- Constants and Variables -------- // -------- Constants and Variables --------
/// @custom:semver 1.0.0-beta.20 /// @custom:semver 1.0.0-beta.21
string public constant version = "1.0.0-beta.20"; string public constant version = "1.0.0-beta.21";
/// @notice Represents the interface version so consumers know how to decode the DeployOutput struct /// @notice Represents the interface version so consumers know how to decode the DeployOutput struct
/// that's emitted in the `Deployed` event. Whenever that struct changes, a new version should be used. /// that's emitted in the `Deployed` event. Whenever that struct changes, a new version should be used.
...@@ -142,24 +128,20 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -142,24 +128,20 @@ contract OPContractsManager is ISemver, Initializable {
/// @notice Address of the ProtocolVersions contract shared by all chains. /// @notice Address of the ProtocolVersions contract shared by all chains.
IProtocolVersions public immutable protocolVersions; IProtocolVersions public immutable protocolVersions;
/// @notice The latest release of the OP Contracts Manager, as a string of the format `op-contracts/vX.Y.Z`. // @notice L1 smart contracts release deployed by this version of OPCM. This is used in opcm to signal which version
string public latestRelease; // of the L1 smart contracts is deployed. It takes the format of `op-contracts/vX.Y.Z`.
string public l1ContractsRelease;
/// @notice Maps a release version to a contract name to it's implementation data.
mapping(string => mapping(string => Implementation)) public implementations;
/// @notice Maps an L2 Chain ID to the SystemConfig for that chain. /// @notice Maps an L2 Chain ID to the SystemConfig for that chain.
mapping(uint256 => ISystemConfig) public systemConfigs; mapping(uint256 => ISystemConfig) public systemConfigs;
/// @notice Addresses of the Blueprint contracts. /// @notice Addresses of the Blueprint contracts.
/// This is internal because if public the autogenerated getter method would return a tuple of /// This is internal because if public the autogenerated getter method would return a tuple of
/// addresses, but we want it to return a struct. This is also set via `initialize` because /// addresses, but we want it to return a struct.
/// we can't make this an immutable variable as it is a non-value type.
Blueprints internal blueprint; Blueprints internal blueprint;
/// @notice Storage gap for future modifications, so we can expand the number of blueprints /// @notice Addresses of the latest implementation contracts.
/// without affecting other storage variables. Implementations internal implementation;
uint256[50] private __gap;
// -------- Events -------- // -------- Events --------
...@@ -197,37 +179,26 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -197,37 +179,26 @@ contract OPContractsManager is ISemver, Initializable {
// -------- Methods -------- // -------- Methods --------
/// @notice OPCM is proxied. Therefore the `initialize` function replaces most constructor logic for this contract. constructor(
ISuperchainConfig _superchainConfig,
constructor(ISuperchainConfig _superchainConfig, IProtocolVersions _protocolVersions) { IProtocolVersions _protocolVersions,
string memory _l1ContractsRelease,
Blueprints memory _blueprints,
Implementations memory _implementations
) {
assertValidContractAddress(address(_superchainConfig)); assertValidContractAddress(address(_superchainConfig));
assertValidContractAddress(address(_protocolVersions)); assertValidContractAddress(address(_protocolVersions));
superchainConfig = _superchainConfig; superchainConfig = _superchainConfig;
protocolVersions = _protocolVersions; protocolVersions = _protocolVersions;
_disableInitializers(); l1ContractsRelease = _l1ContractsRelease;
}
function initialize(InitializerInputs memory _initializerInputs) public initializer {
if (_initializerInputs.isLatest) latestRelease = _initializerInputs.release;
if (keccak256(bytes(latestRelease)) == keccak256("")) revert LatestReleaseNotSet();
for (uint256 i = 0; i < _initializerInputs.setters.length; i++) { blueprint = _blueprints;
ImplementationSetter memory setter = _initializerInputs.setters[i]; implementation = _implementations;
Implementation storage impl = implementations[_initializerInputs.release][setter.name];
if (impl.logic != address(0)) revert AlreadyReleased();
impl.initializer = setter.info.initializer;
impl.logic = setter.info.logic;
}
blueprint = _initializerInputs.blueprints;
} }
function deploy(DeployInput calldata _input) external returns (DeployOutput memory) { function deploy(DeployInput calldata _input) external returns (DeployOutput memory) {
assertValidInputs(_input); assertValidInputs(_input);
uint256 l2ChainId = _input.l2ChainId; uint256 l2ChainId = _input.l2ChainId;
// The salt for a non-proxy contract is a function of the chain ID and the salt mixer. // The salt for a non-proxy contract is a function of the chain ID and the salt mixer.
string memory saltMixer = _input.saltMixer; string memory saltMixer = _input.saltMixer;
bytes32 salt = keccak256(abi.encode(l2ChainId, saltMixer)); bytes32 salt = keccak256(abi.encode(l2ChainId, saltMixer));
...@@ -266,7 +237,6 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -266,7 +237,6 @@ contract OPContractsManager is ISemver, Initializable {
payable(Blueprint.deployFrom(blueprint.l1ChugSplashProxy, salt, abi.encode(output.opChainProxyAdmin))) payable(Blueprint.deployFrom(blueprint.l1ChugSplashProxy, salt, abi.encode(output.opChainProxyAdmin)))
); );
output.opChainProxyAdmin.setProxyType(address(output.l1StandardBridgeProxy), IProxyAdmin.ProxyType.CHUGSPLASH); output.opChainProxyAdmin.setProxyType(address(output.l1StandardBridgeProxy), IProxyAdmin.ProxyType.CHUGSPLASH);
string memory contractName = "OVM_L1CrossDomainMessenger"; string memory contractName = "OVM_L1CrossDomainMessenger";
output.l1CrossDomainMessengerProxy = IL1CrossDomainMessenger( output.l1CrossDomainMessengerProxy = IL1CrossDomainMessenger(
Blueprint.deployFrom(blueprint.resolvedDelegateProxy, salt, abi.encode(output.addressManager, contractName)) Blueprint.deployFrom(blueprint.resolvedDelegateProxy, salt, abi.encode(output.addressManager, contractName))
...@@ -275,10 +245,8 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -275,10 +245,8 @@ contract OPContractsManager is ISemver, Initializable {
address(output.l1CrossDomainMessengerProxy), IProxyAdmin.ProxyType.RESOLVED address(output.l1CrossDomainMessengerProxy), IProxyAdmin.ProxyType.RESOLVED
); );
output.opChainProxyAdmin.setImplementationName(address(output.l1CrossDomainMessengerProxy), contractName); output.opChainProxyAdmin.setImplementationName(address(output.l1CrossDomainMessengerProxy), contractName);
// Now that all proxies are deployed, we can transfer ownership of the AddressManager to the ProxyAdmin. // Now that all proxies are deployed, we can transfer ownership of the AddressManager to the ProxyAdmin.
output.addressManager.transferOwnership(address(output.opChainProxyAdmin)); output.addressManager.transferOwnership(address(output.opChainProxyAdmin));
// The AnchorStateRegistry Implementation is not MCP Ready, and therefore requires an implementation per chain. // The AnchorStateRegistry Implementation is not MCP Ready, and therefore requires an implementation per chain.
// It must be deployed after the DisputeGameFactoryProxy so that it can be provided as a constructor argument. // It must be deployed after the DisputeGameFactoryProxy so that it can be provided as a constructor argument.
output.anchorStateRegistryImpl = IAnchorStateRegistry( output.anchorStateRegistryImpl = IAnchorStateRegistry(
...@@ -301,54 +269,76 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -301,54 +269,76 @@ contract OPContractsManager is ISemver, Initializable {
); );
// -------- Set and Initialize Proxy Implementations -------- // -------- Set and Initialize Proxy Implementations --------
Implementation memory impl;
bytes memory data; bytes memory data;
impl = getLatestImplementation("L1ERC721Bridge"); data = encodeL1ERC721BridgeInitializer(IL1ERC721Bridge.initialize.selector, output);
data = encodeL1ERC721BridgeInitializer(impl.initializer, output); upgradeAndCall(
upgradeAndCall(output.opChainProxyAdmin, address(output.l1ERC721BridgeProxy), impl.logic, data); output.opChainProxyAdmin, address(output.l1ERC721BridgeProxy), implementation.l1ERC721BridgeImpl, data
);
impl = getLatestImplementation("OptimismPortal"); data = encodeOptimismPortalInitializer(IOptimismPortal2.initialize.selector, output);
data = encodeOptimismPortalInitializer(impl.initializer, output); upgradeAndCall(
upgradeAndCall(output.opChainProxyAdmin, address(output.optimismPortalProxy), impl.logic, data); output.opChainProxyAdmin, address(output.optimismPortalProxy), implementation.optimismPortalImpl, data
);
// First we upgrade the implementation so it's version can be retrieved, then we initialize // First we upgrade the implementation so it's version can be retrieved, then we initialize
// it afterwards. See the comments in encodeSystemConfigInitializer to learn more. // it afterwards. See the comments in encodeSystemConfigInitializer to learn more.
impl = getLatestImplementation("SystemConfig"); output.opChainProxyAdmin.upgrade(payable(address(output.systemConfigProxy)), implementation.systemConfigImpl);
output.opChainProxyAdmin.upgrade(payable(address(output.systemConfigProxy)), impl.logic); data = encodeSystemConfigInitializer(_input, output);
data = encodeSystemConfigInitializer(impl.initializer, _input, output); upgradeAndCall(
upgradeAndCall(output.opChainProxyAdmin, address(output.systemConfigProxy), impl.logic, data); output.opChainProxyAdmin, address(output.systemConfigProxy), implementation.systemConfigImpl, data
);
impl = getLatestImplementation("OptimismMintableERC20Factory"); data = encodeOptimismMintableERC20FactoryInitializer(IOptimismMintableERC20Factory.initialize.selector, output);
data = encodeOptimismMintableERC20FactoryInitializer(impl.initializer, output); upgradeAndCall(
upgradeAndCall(output.opChainProxyAdmin, address(output.optimismMintableERC20FactoryProxy), impl.logic, data); output.opChainProxyAdmin,
address(output.optimismMintableERC20FactoryProxy),
implementation.optimismMintableERC20FactoryImpl,
data
);
impl = getLatestImplementation("L1CrossDomainMessenger"); data = encodeL1CrossDomainMessengerInitializer(IL1CrossDomainMessenger.initialize.selector, output);
data = encodeL1CrossDomainMessengerInitializer(impl.initializer, output); upgradeAndCall(
upgradeAndCall(output.opChainProxyAdmin, address(output.l1CrossDomainMessengerProxy), impl.logic, data); output.opChainProxyAdmin,
address(output.l1CrossDomainMessengerProxy),
implementation.l1CrossDomainMessengerImpl,
data
);
impl = getLatestImplementation("L1StandardBridge"); data = encodeL1StandardBridgeInitializer(IL1StandardBridge.initialize.selector, output);
data = encodeL1StandardBridgeInitializer(impl.initializer, output); upgradeAndCall(
upgradeAndCall(output.opChainProxyAdmin, address(output.l1StandardBridgeProxy), impl.logic, data); output.opChainProxyAdmin, address(output.l1StandardBridgeProxy), implementation.l1StandardBridgeImpl, data
);
impl = getLatestImplementation("DelayedWETH"); data = encodeDelayedWETHInitializer(IDelayedWETH.initialize.selector, _input);
data = encodeDelayedWETHInitializer(impl.initializer, _input);
// Eventually we will switch from DelayedWETHPermissionedGameProxy to DelayedWETHPermissionlessGameProxy. // Eventually we will switch from DelayedWETHPermissionedGameProxy to DelayedWETHPermissionlessGameProxy.
upgradeAndCall(output.opChainProxyAdmin, address(output.delayedWETHPermissionedGameProxy), impl.logic, data); upgradeAndCall(
output.opChainProxyAdmin,
address(output.delayedWETHPermissionedGameProxy),
implementation.delayedWETHImpl,
data
);
// We set the initial owner to this contract, set game implementations, then transfer ownership. // We set the initial owner to this contract, set game implementations, then transfer ownership.
impl = getLatestImplementation("DisputeGameFactory"); data = encodeDisputeGameFactoryInitializer(IDisputeGameFactory.initialize.selector, _input);
data = encodeDisputeGameFactoryInitializer(impl.initializer, _input); upgradeAndCall(
upgradeAndCall(output.opChainProxyAdmin, address(output.disputeGameFactoryProxy), impl.logic, data); output.opChainProxyAdmin,
address(output.disputeGameFactoryProxy),
implementation.disputeGameFactoryImpl,
data
);
output.disputeGameFactoryProxy.setImplementation( output.disputeGameFactoryProxy.setImplementation(
GameTypes.PERMISSIONED_CANNON, IDisputeGame(address(output.permissionedDisputeGame)) GameTypes.PERMISSIONED_CANNON, IDisputeGame(address(output.permissionedDisputeGame))
); );
output.disputeGameFactoryProxy.transferOwnership(address(_input.roles.opChainProxyAdminOwner)); output.disputeGameFactoryProxy.transferOwnership(address(_input.roles.opChainProxyAdminOwner));
impl.logic = address(output.anchorStateRegistryImpl); data = encodeAnchorStateRegistryInitializer(IAnchorStateRegistry.initialize.selector, _input);
impl.initializer = IAnchorStateRegistry.initialize.selector; upgradeAndCall(
data = encodeAnchorStateRegistryInitializer(impl.initializer, _input); output.opChainProxyAdmin,
upgradeAndCall(output.opChainProxyAdmin, address(output.anchorStateRegistryProxy), impl.logic, data); address(output.anchorStateRegistryProxy),
address(output.anchorStateRegistryImpl),
data
);
// -------- Finalize Deployment -------- // -------- Finalize Deployment --------
// Transfer ownership of the ProxyAdmin from this contract to the specified owner. // Transfer ownership of the ProxyAdmin from this contract to the specified owner.
...@@ -402,13 +392,6 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -402,13 +392,6 @@ contract OPContractsManager is ISemver, Initializable {
return Blueprint.deployFrom(blueprint.proxy, salt, abi.encode(_proxyAdmin)); return Blueprint.deployFrom(blueprint.proxy, salt, abi.encode(_proxyAdmin));
} }
/// @notice Returns the implementation data for a contract name. Makes a copy of the internal
// Implementation struct in storage to prevent accidental mutation of the internal data.
function getLatestImplementation(string memory _name) internal view returns (Implementation memory) {
Implementation storage impl = implementations[latestRelease][_name];
return Implementation({ logic: impl.logic, initializer: impl.initializer });
}
// -------- Initializer Encoding -------- // -------- Initializer Encoding --------
/// @notice Helper method for encoding the L1ERC721Bridge initializer data. /// @notice Helper method for encoding the L1ERC721Bridge initializer data.
...@@ -445,7 +428,6 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -445,7 +428,6 @@ contract OPContractsManager is ISemver, Initializable {
/// @notice Helper method for encoding the SystemConfig initializer data. /// @notice Helper method for encoding the SystemConfig initializer data.
function encodeSystemConfigInitializer( function encodeSystemConfigInitializer(
bytes4 _selector,
DeployInput memory _input, DeployInput memory _input,
DeployOutput memory _output DeployOutput memory _output
) )
...@@ -454,50 +436,22 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -454,50 +436,22 @@ contract OPContractsManager is ISemver, Initializable {
virtual virtual
returns (bytes memory) returns (bytes memory)
{ {
// We inspect the SystemConfig contract and determine it's signature here. This is required bytes4 selector = ISystemConfig.initialize.selector;
// because this OPCM contract is being developed in a repository that no longer contains the (IResourceMetering.ResourceConfig memory referenceResourceConfig, ISystemConfig.Addresses memory opChainAddrs) =
// SystemConfig contract that was released as part of `op-contracts/v1.6.0`, but in production defaultSystemConfigParams(selector, _input, _output);
// it needs to support that version, in addition to the version currently on develop.
string memory semver = _output.systemConfigProxy.version(); return abi.encodeWithSelector(
if (keccak256(abi.encode(semver)) == keccak256(abi.encode(string("2.2.0")))) { selector,
// We are using the op-contracts/v1.6.0 SystemConfig contract. _input.roles.systemConfigOwner,
( _input.basefeeScalar,
IResourceMetering.ResourceConfig memory referenceResourceConfig, _input.blobBasefeeScalar,
ISystemConfigV160.Addresses memory opChainAddrs bytes32(uint256(uint160(_input.roles.batcher))), // batcherHash
) = defaultSystemConfigV160Params(_selector, _input, _output); _input.gasLimit,
_input.roles.unsafeBlockSigner,
return abi.encodeWithSelector( referenceResourceConfig,
_selector, chainIdToBatchInboxAddress(_input.l2ChainId),
_input.roles.systemConfigOwner, opChainAddrs
_input.basefeeScalar, );
_input.blobBasefeeScalar,
bytes32(uint256(uint160(_input.roles.batcher))), // batcherHash
_input.gasLimit,
_input.roles.unsafeBlockSigner,
referenceResourceConfig,
chainIdToBatchInboxAddress(_input.l2ChainId),
opChainAddrs
);
} else {
// We are using the latest SystemConfig contract from the repo.
(
IResourceMetering.ResourceConfig memory referenceResourceConfig,
ISystemConfig.Addresses memory opChainAddrs
) = defaultSystemConfigParams(_selector, _input, _output);
return abi.encodeWithSelector(
_selector,
_input.roles.systemConfigOwner,
_input.basefeeScalar,
_input.blobBasefeeScalar,
bytes32(uint256(uint160(_input.roles.batcher))), // batcherHash
_input.gasLimit,
_input.roles.unsafeBlockSigner,
referenceResourceConfig,
chainIdToBatchInboxAddress(_input.l2ChainId),
opChainAddrs
);
}
} }
/// @notice Helper method for encoding the OptimismMintableERC20Factory initializer data. /// @notice Helper method for encoding the OptimismMintableERC20Factory initializer data.
...@@ -599,7 +553,7 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -599,7 +553,7 @@ contract OPContractsManager is ISemver, Initializable {
_input.disputeSplitDepth, _input.disputeSplitDepth,
_input.disputeClockExtension, _input.disputeClockExtension,
_input.disputeMaxClockDuration, _input.disputeMaxClockDuration,
IBigStepper(getLatestImplementation("MIPS").logic), IBigStepper(implementation.mipsImpl),
IDelayedWETH(payable(address(_output.delayedWETHPermissionedGameProxy))), IDelayedWETH(payable(address(_output.delayedWETHPermissionedGameProxy))),
IAnchorStateRegistry(address(_output.anchorStateRegistryProxy)), IAnchorStateRegistry(address(_output.anchorStateRegistryProxy)),
_input.l2ChainId, _input.l2ChainId,
...@@ -645,45 +599,6 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -645,45 +599,6 @@ contract OPContractsManager is ISemver, Initializable {
assertValidContractAddress(opChainAddrs_.optimismMintableERC20Factory); assertValidContractAddress(opChainAddrs_.optimismMintableERC20Factory);
} }
/// @notice Returns default, standard config arguments for the SystemConfig initializer.
/// This is used by subclasses to reduce code duplication.
function defaultSystemConfigV160Params(
bytes4, /* selector */
DeployInput memory, /* _input */
DeployOutput memory _output
)
internal
view
virtual
returns (
IResourceMetering.ResourceConfig memory resourceConfig_,
ISystemConfigV160.Addresses memory opChainAddrs_
)
{
// We use assembly to easily convert from IResourceMetering.ResourceConfig to ResourceMetering.ResourceConfig.
// This is required because we have not yet fully migrated the codebase to be interface-based.
IResourceMetering.ResourceConfig memory resourceConfig = Constants.DEFAULT_RESOURCE_CONFIG();
assembly ("memory-safe") {
resourceConfig_ := resourceConfig
}
opChainAddrs_ = ISystemConfigV160.Addresses({
l1CrossDomainMessenger: address(_output.l1CrossDomainMessengerProxy),
l1ERC721Bridge: address(_output.l1ERC721BridgeProxy),
l1StandardBridge: address(_output.l1StandardBridgeProxy),
disputeGameFactory: address(_output.disputeGameFactoryProxy),
optimismPortal: address(_output.optimismPortalProxy),
optimismMintableERC20Factory: address(_output.optimismMintableERC20FactoryProxy)
});
assertValidContractAddress(opChainAddrs_.l1CrossDomainMessenger);
assertValidContractAddress(opChainAddrs_.l1ERC721Bridge);
assertValidContractAddress(opChainAddrs_.l1StandardBridge);
assertValidContractAddress(opChainAddrs_.disputeGameFactory);
assertValidContractAddress(opChainAddrs_.optimismPortal);
assertValidContractAddress(opChainAddrs_.optimismMintableERC20Factory);
}
/// @notice Makes an external call to the target to initialize the proxy with the specified data. /// @notice Makes an external call to the target to initialize the proxy with the specified data.
/// First performs safety checks to ensure the target, implementation, and proxy admin are valid. /// First performs safety checks to ensure the target, implementation, and proxy admin are valid.
function upgradeAndCall( function upgradeAndCall(
...@@ -710,4 +625,9 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -710,4 +625,9 @@ contract OPContractsManager is ISemver, Initializable {
function blueprints() public view returns (Blueprints memory) { function blueprints() public view returns (Blueprints memory) {
return blueprint; return blueprint;
} }
/// @notice Returns the implementation contract addresses.
function implementations() public view returns (Implementations memory) {
return implementation;
}
} }
...@@ -6,20 +6,22 @@ import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; ...@@ -6,20 +6,22 @@ import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol";
import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol"; import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol";
import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol";
import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol";
import { ISystemConfigInterop } from "src/L1/interfaces/ISystemConfigInterop.sol";
/// @custom:proxied true
contract OPContractsManagerInterop is OPContractsManager { contract OPContractsManagerInterop is OPContractsManager {
constructor( constructor(
ISuperchainConfig _superchainConfig, ISuperchainConfig _superchainConfig,
IProtocolVersions _protocolVersions IProtocolVersions _protocolVersions,
string memory _l1ContractsRelease,
Blueprints memory _blueprints,
Implementations memory _implementations
) )
OPContractsManager(_superchainConfig, _protocolVersions) OPContractsManager(_superchainConfig, _protocolVersions, _l1ContractsRelease, _blueprints, _implementations)
{ } { }
// The `SystemConfigInterop` contract has an extra `address _dependencyManager` argument // The `SystemConfigInterop` contract has an extra `address _dependencyManager` argument
// that we must account for. // that we must account for.
function encodeSystemConfigInitializer( function encodeSystemConfigInitializer(
bytes4 _selector,
DeployInput memory _input, DeployInput memory _input,
DeployOutput memory _output DeployOutput memory _output
) )
...@@ -29,8 +31,9 @@ contract OPContractsManagerInterop is OPContractsManager { ...@@ -29,8 +31,9 @@ contract OPContractsManagerInterop is OPContractsManager {
override override
returns (bytes memory) returns (bytes memory)
{ {
bytes4 selector = ISystemConfigInterop.initialize.selector;
(IResourceMetering.ResourceConfig memory referenceResourceConfig, ISystemConfig.Addresses memory opChainAddrs) = (IResourceMetering.ResourceConfig memory referenceResourceConfig, ISystemConfig.Addresses memory opChainAddrs) =
defaultSystemConfigParams(_selector, _input, _output); defaultSystemConfigParams(selector, _input, _output);
// TODO For now we assume that the dependency manager is the same as system config owner. // TODO For now we assume that the dependency manager is the same as system config owner.
// This is currently undefined since it's not part of the standard config, so we may need // This is currently undefined since it's not part of the standard config, so we may need
...@@ -40,7 +43,7 @@ contract OPContractsManagerInterop is OPContractsManager { ...@@ -40,7 +43,7 @@ contract OPContractsManagerInterop is OPContractsManager {
address dependencyManager = address(_input.roles.systemConfigOwner); address dependencyManager = address(_input.roles.systemConfigOwner);
return abi.encodeWithSelector( return abi.encodeWithSelector(
_selector, selector,
_input.roles.systemConfigOwner, _input.roles.systemConfigOwner,
_input.basefeeScalar, _input.basefeeScalar,
_input.blobBasefeeScalar, _input.blobBasefeeScalar,
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol";
/// @notice This interface corresponds to the op-contracts/v1.6.0 release of the SystemConfig
/// contract, which has a semver of 2.2.0 as specified in
/// https://github.com/ethereum-optimism/optimism/releases/tag/op-contracts%2Fv1.6.0
interface ISystemConfigV160 {
enum UpdateType {
BATCHER,
FEE_SCALARS,
GAS_LIMIT,
UNSAFE_BLOCK_SIGNER
}
struct Addresses {
address l1CrossDomainMessenger;
address l1ERC721Bridge;
address l1StandardBridge;
address disputeGameFactory;
address optimismPortal;
address optimismMintableERC20Factory;
}
event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data);
event Initialized(uint8 version);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function BATCH_INBOX_SLOT() external view returns (bytes32);
function DISPUTE_GAME_FACTORY_SLOT() external view returns (bytes32);
function L1_CROSS_DOMAIN_MESSENGER_SLOT() external view returns (bytes32);
function L1_ERC_721_BRIDGE_SLOT() external view returns (bytes32);
function L1_STANDARD_BRIDGE_SLOT() external view returns (bytes32);
function OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT() external view returns (bytes32);
function OPTIMISM_PORTAL_SLOT() external view returns (bytes32);
function START_BLOCK_SLOT() external view returns (bytes32);
function UNSAFE_BLOCK_SIGNER_SLOT() external view returns (bytes32);
function VERSION() external view returns (uint256);
function basefeeScalar() external view returns (uint32);
function batchInbox() external view returns (address addr_);
function batcherHash() external view returns (bytes32);
function blobbasefeeScalar() external view returns (uint32);
function disputeGameFactory() external view returns (address addr_);
function gasLimit() external view returns (uint64);
function gasPayingToken() external view returns (address addr_, uint8 decimals_);
function gasPayingTokenName() external view returns (string memory name_);
function gasPayingTokenSymbol() external view returns (string memory symbol_);
function initialize(
address _owner,
uint256 _basefeeScalar,
uint256 _blobbasefeeScalar,
bytes32 _batcherHash,
uint64 _gasLimit,
address _unsafeBlockSigner,
IResourceMetering.ResourceConfig memory _config,
address _batchInbox,
Addresses memory _addresses
)
external;
function isCustomGasToken() external view returns (bool);
function l1CrossDomainMessenger() external view returns (address addr_);
function l1ERC721Bridge() external view returns (address addr_);
function l1StandardBridge() external view returns (address addr_);
function maximumGasLimit() external pure returns (uint64);
function minimumGasLimit() external view returns (uint64);
function optimismMintableERC20Factory() external view returns (address addr_);
function optimismPortal() external view returns (address addr_);
function overhead() external view returns (uint256);
function owner() external view returns (address);
function renounceOwnership() external;
function resourceConfig() external view returns (IResourceMetering.ResourceConfig memory);
function scalar() external view returns (uint256);
function setBatcherHash(bytes32 _batcherHash) external;
function setGasConfig(uint256 _overhead, uint256 _scalar) external;
function setGasConfigEcotone(uint32 _basefeeScalar, uint32 _blobbasefeeScalar) external;
function setGasLimit(uint64 _gasLimit) external;
function setUnsafeBlockSigner(address _unsafeBlockSigner) external;
function startBlock() external view returns (uint256 startBlock_);
function transferOwnership(address newOwner) external; // nosemgrep
function unsafeBlockSigner() external view returns (address addr_);
function version() external pure returns (string memory);
function __constructor__() external;
}
...@@ -14,9 +14,12 @@ import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol"; ...@@ -14,9 +14,12 @@ import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol";
contract OPContractsManager_Harness is OPContractsManager { contract OPContractsManager_Harness is OPContractsManager {
constructor( constructor(
ISuperchainConfig _superchainConfig, ISuperchainConfig _superchainConfig,
IProtocolVersions _protocolVersions IProtocolVersions _protocolVersions,
string memory _l1ContractsRelease,
Blueprints memory _blueprints,
Implementations memory _implementations
) )
OPContractsManager(_superchainConfig, _protocolVersions) OPContractsManager(_superchainConfig, _protocolVersions, _l1ContractsRelease, _blueprints, _implementations)
{ } { }
function chainIdToBatchInboxAddress_exposed(uint256 l2ChainId) public pure returns (address) { function chainIdToBatchInboxAddress_exposed(uint256 l2ChainId) public pure returns (address) {
...@@ -49,7 +52,7 @@ contract OPContractsManager_Deploy_Test is DeployOPChain_TestBase { ...@@ -49,7 +52,7 @@ contract OPContractsManager_Deploy_Test is DeployOPChain_TestBase {
doi.set(doi.basefeeScalar.selector, basefeeScalar); doi.set(doi.basefeeScalar.selector, basefeeScalar);
doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar); doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar);
doi.set(doi.l2ChainId.selector, l2ChainId); doi.set(doi.l2ChainId.selector, l2ChainId);
doi.set(doi.opcmProxy.selector, address(opcm)); doi.set(doi.opcm.selector, address(opcm));
doi.set(doi.gasLimit.selector, gasLimit); doi.set(doi.gasLimit.selector, gasLimit);
doi.set(doi.disputeGameType.selector, disputeGameType); doi.set(doi.disputeGameType.selector, disputeGameType);
...@@ -116,12 +119,17 @@ contract OPContractsManager_InternalMethods_Test is Test { ...@@ -116,12 +119,17 @@ contract OPContractsManager_InternalMethods_Test is Test {
function setUp() public { function setUp() public {
ISuperchainConfig superchainConfigProxy = ISuperchainConfig(makeAddr("superchainConfig")); ISuperchainConfig superchainConfigProxy = ISuperchainConfig(makeAddr("superchainConfig"));
IProtocolVersions protocolVersionsProxy = IProtocolVersions(makeAddr("protocolVersions")); IProtocolVersions protocolVersionsProxy = IProtocolVersions(makeAddr("protocolVersions"));
OPContractsManager.Blueprints memory emptyBlueprints;
OPContractsManager.Implementations memory emptyImpls;
vm.etch(address(superchainConfigProxy), hex"01"); vm.etch(address(superchainConfigProxy), hex"01");
vm.etch(address(protocolVersionsProxy), hex"01"); vm.etch(address(protocolVersionsProxy), hex"01");
opcmHarness = new OPContractsManager_Harness({ opcmHarness = new OPContractsManager_Harness({
_superchainConfig: superchainConfigProxy, _superchainConfig: superchainConfigProxy,
_protocolVersions: protocolVersionsProxy _protocolVersions: protocolVersionsProxy,
_l1ContractsRelease: "dev",
_blueprints: emptyBlueprints,
_implementations: emptyImpls
}); });
} }
......
...@@ -61,7 +61,7 @@ contract DeployImplementationsInput_Test is Test { ...@@ -61,7 +61,7 @@ contract DeployImplementationsInput_Test is Test {
dii.disputeGameFinalityDelaySeconds(); dii.disputeGameFinalityDelaySeconds();
vm.expectRevert("DeployImplementationsInput: not set"); vm.expectRevert("DeployImplementationsInput: not set");
dii.release(); dii.l1ContractsRelease();
vm.expectRevert("DeployImplementationsInput: not set"); vm.expectRevert("DeployImplementationsInput: not set");
dii.superchainConfigProxy(); dii.superchainConfigProxy();
...@@ -69,23 +69,9 @@ contract DeployImplementationsInput_Test is Test { ...@@ -69,23 +69,9 @@ contract DeployImplementationsInput_Test is Test {
vm.expectRevert("DeployImplementationsInput: not set"); vm.expectRevert("DeployImplementationsInput: not set");
dii.protocolVersionsProxy(); dii.protocolVersionsProxy();
vm.expectRevert("DeployImplementationsInput: not set");
dii.opcmProxyOwner();
vm.expectRevert("DeployImplementationsInput: not set"); vm.expectRevert("DeployImplementationsInput: not set");
dii.standardVersionsToml(); dii.standardVersionsToml();
} }
function test_opcmProxyOwner_whenNotSet_reverts() public {
vm.expectRevert("DeployImplementationsInput: not set");
dii.opcmProxyOwner();
}
function test_opcmProxyOwner_succeeds() public {
dii.set(dii.opcmProxyOwner.selector, address(msg.sender));
address opcmProxyOwner = dii.opcmProxyOwner();
assertEq(address(msg.sender), address(opcmProxyOwner), "100");
}
} }
contract DeployImplementationsOutput_Test is Test { contract DeployImplementationsOutput_Test is Test {
...@@ -96,17 +82,7 @@ contract DeployImplementationsOutput_Test is Test { ...@@ -96,17 +82,7 @@ contract DeployImplementationsOutput_Test is Test {
} }
function test_set_succeeds() public { function test_set_succeeds() public {
IProxy proxy = IProxy( OPContractsManager opcm = OPContractsManager(address(makeAddr("opcm")));
DeployUtils.create1({
_name: "Proxy",
_args: DeployUtils.encodeConstructor(abi.encodeCall(IProxy.__constructor__, (address(0))))
})
);
address opcmImpl = address(makeAddr("opcmImpl"));
vm.prank(address(0));
proxy.upgradeTo(opcmImpl);
OPContractsManager opcmProxy = OPContractsManager(address(proxy));
IOptimismPortal2 optimismPortalImpl = IOptimismPortal2(payable(makeAddr("optimismPortalImpl"))); IOptimismPortal2 optimismPortalImpl = IOptimismPortal2(payable(makeAddr("optimismPortalImpl")));
IDelayedWETH delayedWETHImpl = IDelayedWETH(payable(makeAddr("delayedWETHImpl"))); IDelayedWETH delayedWETHImpl = IDelayedWETH(payable(makeAddr("delayedWETHImpl")));
IPreimageOracle preimageOracleSingleton = IPreimageOracle(makeAddr("preimageOracleSingleton")); IPreimageOracle preimageOracleSingleton = IPreimageOracle(makeAddr("preimageOracleSingleton"));
...@@ -120,8 +96,7 @@ contract DeployImplementationsOutput_Test is Test { ...@@ -120,8 +96,7 @@ contract DeployImplementationsOutput_Test is Test {
IOptimismMintableERC20Factory(makeAddr("optimismMintableERC20FactoryImpl")); IOptimismMintableERC20Factory(makeAddr("optimismMintableERC20FactoryImpl"));
IDisputeGameFactory disputeGameFactoryImpl = IDisputeGameFactory(makeAddr("disputeGameFactoryImpl")); IDisputeGameFactory disputeGameFactoryImpl = IDisputeGameFactory(makeAddr("disputeGameFactoryImpl"));
vm.etch(address(opcmProxy), address(opcmProxy).code); vm.etch(address(opcm), hex"01");
vm.etch(address(opcmImpl), hex"01");
vm.etch(address(optimismPortalImpl), hex"01"); vm.etch(address(optimismPortalImpl), hex"01");
vm.etch(address(delayedWETHImpl), hex"01"); vm.etch(address(delayedWETHImpl), hex"01");
vm.etch(address(preimageOracleSingleton), hex"01"); vm.etch(address(preimageOracleSingleton), hex"01");
...@@ -132,7 +107,7 @@ contract DeployImplementationsOutput_Test is Test { ...@@ -132,7 +107,7 @@ contract DeployImplementationsOutput_Test is Test {
vm.etch(address(l1StandardBridgeImpl), hex"01"); vm.etch(address(l1StandardBridgeImpl), hex"01");
vm.etch(address(optimismMintableERC20FactoryImpl), hex"01"); vm.etch(address(optimismMintableERC20FactoryImpl), hex"01");
vm.etch(address(disputeGameFactoryImpl), hex"01"); vm.etch(address(disputeGameFactoryImpl), hex"01");
dio.set(dio.opcmProxy.selector, address(opcmProxy)); dio.set(dio.opcm.selector, address(opcm));
dio.set(dio.optimismPortalImpl.selector, address(optimismPortalImpl)); dio.set(dio.optimismPortalImpl.selector, address(optimismPortalImpl));
dio.set(dio.delayedWETHImpl.selector, address(delayedWETHImpl)); dio.set(dio.delayedWETHImpl.selector, address(delayedWETHImpl));
dio.set(dio.preimageOracleSingleton.selector, address(preimageOracleSingleton)); dio.set(dio.preimageOracleSingleton.selector, address(preimageOracleSingleton));
...@@ -144,7 +119,7 @@ contract DeployImplementationsOutput_Test is Test { ...@@ -144,7 +119,7 @@ contract DeployImplementationsOutput_Test is Test {
dio.set(dio.optimismMintableERC20FactoryImpl.selector, address(optimismMintableERC20FactoryImpl)); dio.set(dio.optimismMintableERC20FactoryImpl.selector, address(optimismMintableERC20FactoryImpl));
dio.set(dio.disputeGameFactoryImpl.selector, address(disputeGameFactoryImpl)); dio.set(dio.disputeGameFactoryImpl.selector, address(disputeGameFactoryImpl));
assertEq(address(opcmProxy), address(dio.opcmProxy()), "50"); assertEq(address(opcm), address(dio.opcm()), "50");
assertEq(address(optimismPortalImpl), address(dio.optimismPortalImpl()), "100"); assertEq(address(optimismPortalImpl), address(dio.optimismPortalImpl()), "100");
assertEq(address(delayedWETHImpl), address(dio.delayedWETHImpl()), "200"); assertEq(address(delayedWETHImpl), address(dio.delayedWETHImpl()), "200");
assertEq(address(preimageOracleSingleton), address(dio.preimageOracleSingleton()), "300"); assertEq(address(preimageOracleSingleton), address(dio.preimageOracleSingleton()), "300");
...@@ -273,7 +248,7 @@ contract DeployImplementations_Test is Test { ...@@ -273,7 +248,7 @@ contract DeployImplementations_Test is Test {
function test_deployImplementation_succeeds() public { function test_deployImplementation_succeeds() public {
string memory deployContractsRelease = "dev-release"; string memory deployContractsRelease = "dev-release";
dii.set(dii.release.selector, deployContractsRelease); dii.set(dii.l1ContractsRelease.selector, deployContractsRelease);
deployImplementations.deploySystemConfigImpl(dii, dio); deployImplementations.deploySystemConfigImpl(dii, dio);
assertTrue(address(0) != address(dio.systemConfigImpl())); assertTrue(address(0) != address(dio.systemConfigImpl()));
} }
...@@ -282,7 +257,7 @@ contract DeployImplementations_Test is Test { ...@@ -282,7 +257,7 @@ contract DeployImplementations_Test is Test {
// All hardcoded addresses below are taken from the superchain-registry config: // All hardcoded addresses below are taken from the superchain-registry config:
// https://github.com/ethereum-optimism/superchain-registry/blob/be65d22f8128cf0c4e5b4e1f677daf86843426bf/validation/standard/standard-versions.toml#L11 // https://github.com/ethereum-optimism/superchain-registry/blob/be65d22f8128cf0c4e5b4e1f677daf86843426bf/validation/standard/standard-versions.toml#L11
string memory testRelease = "op-contracts/v1.6.0"; string memory testRelease = "op-contracts/v1.6.0";
dii.set(dii.release.selector, testRelease); dii.set(dii.l1ContractsRelease.selector, testRelease);
deployImplementations.deploySystemConfigImpl(dii, dio); deployImplementations.deploySystemConfigImpl(dii, dio);
address srSystemConfigImpl = address(0xF56D96B2535B932656d3c04Ebf51baBff241D886); address srSystemConfigImpl = address(0xF56D96B2535B932656d3c04Ebf51baBff241D886);
...@@ -335,71 +310,6 @@ contract DeployImplementations_Test is Test { ...@@ -335,71 +310,6 @@ contract DeployImplementations_Test is Test {
assertEq(srDisputeGameFactoryImpl, address(dio.disputeGameFactoryImpl())); assertEq(srDisputeGameFactoryImpl, address(dio.disputeGameFactoryImpl()));
} }
function test_deploy_atNonExistentRelease_reverts() public {
string memory unknownRelease = "op-contracts/v0.0.0";
dii.set(dii.release.selector, unknownRelease);
bytes memory expectedErr =
bytes(string.concat("DeployImplementations: failed to deploy release ", unknownRelease));
vm.expectRevert(expectedErr);
deployImplementations.deploySystemConfigImpl(dii, dio);
vm.expectRevert(expectedErr);
deployImplementations.deployL1CrossDomainMessengerImpl(dii, dio);
vm.expectRevert(expectedErr);
deployImplementations.deployL1ERC721BridgeImpl(dii, dio);
vm.expectRevert(expectedErr);
deployImplementations.deployL1StandardBridgeImpl(dii, dio);
vm.expectRevert(expectedErr);
deployImplementations.deployOptimismMintableERC20FactoryImpl(dii, dio);
// TODO: Uncomment the code below when OPContractsManager is deployed based on release. Superchain-registry
// doesn't contain OPContractsManager yet.
// dii.set(dii.superchainConfigProxy.selector, address(superchainConfigProxy));
// dii.set(dii.protocolVersionsProxy.selector, address(protocolVersionsProxy));
// vm.etch(address(superchainConfigProxy), hex"01");
// vm.etch(address(protocolVersionsProxy), hex"01");
// vm.expectRevert(expectedErr);
// deployImplementations.deployOPContractsManagerImpl(dii, dio);
dii.set(dii.proofMaturityDelaySeconds.selector, 1);
dii.set(dii.disputeGameFinalityDelaySeconds.selector, 2);
vm.expectRevert(expectedErr);
deployImplementations.deployOptimismPortalImpl(dii, dio);
dii.set(dii.withdrawalDelaySeconds.selector, 1);
vm.expectRevert(expectedErr);
deployImplementations.deployDelayedWETHImpl(dii, dio);
dii.set(dii.minProposalSizeBytes.selector, 1);
dii.set(dii.challengePeriodSeconds.selector, 2);
vm.expectRevert(expectedErr);
deployImplementations.deployPreimageOracleSingleton(dii, dio);
address preImageOracleSingleton = makeAddr("preImageOracleSingleton");
vm.etch(address(preImageOracleSingleton), hex"01");
dio.set(dio.preimageOracleSingleton.selector, preImageOracleSingleton);
vm.expectRevert(expectedErr);
deployImplementations.deployMipsSingleton(dii, dio);
vm.expectRevert(expectedErr); // fault proof contracts don't exist at this release
deployImplementations.deployDisputeGameFactoryImpl(dii, dio);
}
function test_deploy_noContractExistsAtRelease_reverts() public {
string memory unknownRelease = "op-contracts/v1.3.0";
dii.set(dii.release.selector, unknownRelease);
bytes memory expectedErr =
bytes(string.concat("DeployImplementations: failed to deploy release ", unknownRelease));
vm.expectRevert(expectedErr); // fault proof contracts don't exist at this release
deployImplementations.deployDisputeGameFactoryImpl(dii, dio);
}
function testFuzz_run_memory_succeeds(bytes32 _seed) public { function testFuzz_run_memory_succeeds(bytes32 _seed) public {
withdrawalDelaySeconds = uint256(hash(_seed, 0)); withdrawalDelaySeconds = uint256(hash(_seed, 0));
minProposalSizeBytes = uint256(hash(_seed, 1)); minProposalSizeBytes = uint256(hash(_seed, 1));
...@@ -409,7 +319,7 @@ contract DeployImplementations_Test is Test { ...@@ -409,7 +319,7 @@ contract DeployImplementations_Test is Test {
string memory release = string(bytes.concat(hash(_seed, 5))); string memory release = string(bytes.concat(hash(_seed, 5)));
protocolVersionsProxy = IProtocolVersions(address(uint160(uint256(hash(_seed, 7))))); protocolVersionsProxy = IProtocolVersions(address(uint160(uint256(hash(_seed, 7)))));
// Must configure the ProxyAdmin contract which is used to upgrade the OPCM's proxy contract. // Must configure the ProxyAdmin contract.
IProxyAdmin superchainProxyAdmin = IProxyAdmin( IProxyAdmin superchainProxyAdmin = IProxyAdmin(
DeployUtils.create1({ DeployUtils.create1({
_name: "ProxyAdmin", _name: "ProxyAdmin",
...@@ -439,10 +349,9 @@ contract DeployImplementations_Test is Test { ...@@ -439,10 +349,9 @@ contract DeployImplementations_Test is Test {
dii.set(dii.proofMaturityDelaySeconds.selector, proofMaturityDelaySeconds); dii.set(dii.proofMaturityDelaySeconds.selector, proofMaturityDelaySeconds);
dii.set(dii.disputeGameFinalityDelaySeconds.selector, disputeGameFinalityDelaySeconds); dii.set(dii.disputeGameFinalityDelaySeconds.selector, disputeGameFinalityDelaySeconds);
dii.set(dii.mipsVersion.selector, 1); dii.set(dii.mipsVersion.selector, 1);
dii.set(dii.release.selector, release); dii.set(dii.l1ContractsRelease.selector, release);
dii.set(dii.superchainConfigProxy.selector, address(superchainConfigProxy)); dii.set(dii.superchainConfigProxy.selector, address(superchainConfigProxy));
dii.set(dii.protocolVersionsProxy.selector, address(protocolVersionsProxy)); dii.set(dii.protocolVersionsProxy.selector, address(protocolVersionsProxy));
dii.set(dii.opcmProxyOwner.selector, msg.sender);
deployImplementations.run(dii, dio); deployImplementations.run(dii, dio);
...@@ -453,10 +362,9 @@ contract DeployImplementations_Test is Test { ...@@ -453,10 +362,9 @@ contract DeployImplementations_Test is Test {
assertEq(proofMaturityDelaySeconds, dii.proofMaturityDelaySeconds(), "400"); assertEq(proofMaturityDelaySeconds, dii.proofMaturityDelaySeconds(), "400");
assertEq(disputeGameFinalityDelaySeconds, dii.disputeGameFinalityDelaySeconds(), "500"); assertEq(disputeGameFinalityDelaySeconds, dii.disputeGameFinalityDelaySeconds(), "500");
assertEq(1, dii.mipsVersion(), "512"); assertEq(1, dii.mipsVersion(), "512");
assertEq(release, dii.release(), "525"); assertEq(release, dii.l1ContractsRelease(), "525");
assertEq(address(superchainConfigProxy), address(dii.superchainConfigProxy()), "550"); assertEq(address(superchainConfigProxy), address(dii.superchainConfigProxy()), "550");
assertEq(address(protocolVersionsProxy), address(dii.protocolVersionsProxy()), "575"); assertEq(address(protocolVersionsProxy), address(dii.protocolVersionsProxy()), "575");
assertEq(msg.sender, dii.opcmProxyOwner(), "580");
// Architecture assertions. // Architecture assertions.
assertEq(address(dio.mipsSingleton().oracle()), address(dio.preimageOracleSingleton()), "600"); assertEq(address(dio.mipsSingleton().oracle()), address(dio.preimageOracleSingleton()), "600");
...@@ -475,7 +383,7 @@ contract DeployImplementations_Test is Test { ...@@ -475,7 +383,7 @@ contract DeployImplementations_Test is Test {
dii.set(dii.disputeGameFinalityDelaySeconds.selector, disputeGameFinalityDelaySeconds); dii.set(dii.disputeGameFinalityDelaySeconds.selector, disputeGameFinalityDelaySeconds);
dii.set(dii.mipsVersion.selector, 1); dii.set(dii.mipsVersion.selector, 1);
string memory release = "dev-release"; string memory release = "dev-release";
dii.set(dii.release.selector, release); dii.set(dii.l1ContractsRelease.selector, release);
dii.set(dii.superchainConfigProxy.selector, address(superchainConfigProxy)); dii.set(dii.superchainConfigProxy.selector, address(superchainConfigProxy));
dii.set(dii.protocolVersionsProxy.selector, address(protocolVersionsProxy)); dii.set(dii.protocolVersionsProxy.selector, address(protocolVersionsProxy));
......
...@@ -39,10 +39,10 @@ contract DeployOPChainInput_Test is Test { ...@@ -39,10 +39,10 @@ contract DeployOPChainInput_Test is Test {
address unsafeBlockSigner = makeAddr("unsafeBlockSigner"); address unsafeBlockSigner = makeAddr("unsafeBlockSigner");
address proposer = makeAddr("proposer"); address proposer = makeAddr("proposer");
address challenger = makeAddr("challenger"); address challenger = makeAddr("challenger");
address opcm = makeAddr("opcm");
uint32 basefeeScalar = 100; uint32 basefeeScalar = 100;
uint32 blobBaseFeeScalar = 200; uint32 blobBaseFeeScalar = 200;
uint256 l2ChainId = 300; uint256 l2ChainId = 300;
OPContractsManager opcm = OPContractsManager(makeAddr("opcm"));
string saltMixer = "saltMixer"; string saltMixer = "saltMixer";
function setUp() public { function setUp() public {
...@@ -60,9 +60,8 @@ contract DeployOPChainInput_Test is Test { ...@@ -60,9 +60,8 @@ contract DeployOPChainInput_Test is Test {
doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar); doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar);
doi.set(doi.l2ChainId.selector, l2ChainId); doi.set(doi.l2ChainId.selector, l2ChainId);
doi.set(doi.allowCustomDisputeParameters.selector, true); doi.set(doi.allowCustomDisputeParameters.selector, true);
doi.set(doi.opcm.selector, opcm);
(IProxy opcmProxy) = DeployUtils.buildERC1967ProxyWithImpl("opcmProxy"); vm.etch(opcm, hex"01");
doi.set(doi.opcmProxy.selector, address(opcmProxy));
// Compare the default inputs to the getter methods. // Compare the default inputs to the getter methods.
assertEq(opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "200"); assertEq(opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "200");
...@@ -74,7 +73,7 @@ contract DeployOPChainInput_Test is Test { ...@@ -74,7 +73,7 @@ contract DeployOPChainInput_Test is Test {
assertEq(basefeeScalar, doi.basefeeScalar(), "800"); assertEq(basefeeScalar, doi.basefeeScalar(), "800");
assertEq(blobBaseFeeScalar, doi.blobBaseFeeScalar(), "900"); assertEq(blobBaseFeeScalar, doi.blobBaseFeeScalar(), "900");
assertEq(l2ChainId, doi.l2ChainId(), "1000"); assertEq(l2ChainId, doi.l2ChainId(), "1000");
assertEq(address(opcmProxy), address(doi.opcmProxy()), "1100"); assertEq(opcm, address(doi.opcm()), "1100");
assertEq(true, doi.allowCustomDisputeParameters(), "1200"); assertEq(true, doi.allowCustomDisputeParameters(), "1200");
} }
...@@ -396,7 +395,7 @@ contract DeployOPChain_TestBase is Test { ...@@ -396,7 +395,7 @@ contract DeployOPChain_TestBase is Test {
dii.set(dii.proofMaturityDelaySeconds.selector, proofMaturityDelaySeconds); dii.set(dii.proofMaturityDelaySeconds.selector, proofMaturityDelaySeconds);
dii.set(dii.disputeGameFinalityDelaySeconds.selector, disputeGameFinalityDelaySeconds); dii.set(dii.disputeGameFinalityDelaySeconds.selector, disputeGameFinalityDelaySeconds);
dii.set(dii.mipsVersion.selector, 1); dii.set(dii.mipsVersion.selector, 1);
dii.set(dii.release.selector, release); dii.set(dii.l1ContractsRelease.selector, release);
dii.set(dii.superchainConfigProxy.selector, address(superchainConfigProxy)); dii.set(dii.superchainConfigProxy.selector, address(superchainConfigProxy));
dii.set(dii.protocolVersionsProxy.selector, address(protocolVersionsProxy)); dii.set(dii.protocolVersionsProxy.selector, address(protocolVersionsProxy));
// End users of the DeployImplementations contract will need to set the `standardVersionsToml`. // End users of the DeployImplementations contract will need to set the `standardVersionsToml`.
...@@ -404,7 +403,7 @@ contract DeployOPChain_TestBase is Test { ...@@ -404,7 +403,7 @@ contract DeployOPChain_TestBase is Test {
string.concat(vm.projectRoot(), "/test/fixtures/standard-versions.toml"); string.concat(vm.projectRoot(), "/test/fixtures/standard-versions.toml");
string memory standardVersionsToml = vm.readFile(standardVersionsTomlPath); string memory standardVersionsToml = vm.readFile(standardVersionsTomlPath);
dii.set(dii.standardVersionsToml.selector, standardVersionsToml); dii.set(dii.standardVersionsToml.selector, standardVersionsToml);
dii.set(dii.opcmProxyOwner.selector, address(1));
deployImplementations.run(dii, dio); deployImplementations.run(dii, dio);
// Deploy DeployOpChain, but defer populating the input values to the test suites inheriting this contract. // Deploy DeployOpChain, but defer populating the input values to the test suites inheriting this contract.
...@@ -412,7 +411,7 @@ contract DeployOPChain_TestBase is Test { ...@@ -412,7 +411,7 @@ contract DeployOPChain_TestBase is Test {
(doi, doo) = deployOPChain.etchIOContracts(); (doi, doo) = deployOPChain.etchIOContracts();
// Set the OPContractsManager input for DeployOPChain. // Set the OPContractsManager input for DeployOPChain.
opcm = dio.opcmProxy(); opcm = dio.opcm();
} }
// See the function of the same name in the `DeployImplementations_Test` contract of // See the function of the same name in the `DeployImplementations_Test` contract of
...@@ -466,7 +465,7 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { ...@@ -466,7 +465,7 @@ contract DeployOPChain_Test is DeployOPChain_TestBase {
doi.set(doi.basefeeScalar.selector, basefeeScalar); doi.set(doi.basefeeScalar.selector, basefeeScalar);
doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar); doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar);
doi.set(doi.l2ChainId.selector, l2ChainId); doi.set(doi.l2ChainId.selector, l2ChainId);
doi.set(doi.opcmProxy.selector, address(opcm)); // Not fuzzed since it must be an actual instance. doi.set(doi.opcm.selector, address(opcm));
doi.set(doi.saltMixer.selector, saltMixer); doi.set(doi.saltMixer.selector, saltMixer);
doi.set(doi.gasLimit.selector, gasLimit); doi.set(doi.gasLimit.selector, gasLimit);
doi.set(doi.disputeGameType.selector, disputeGameType); doi.set(doi.disputeGameType.selector, disputeGameType);
...@@ -559,7 +558,7 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { ...@@ -559,7 +558,7 @@ contract DeployOPChain_Test is DeployOPChain_TestBase {
doi.set(doi.basefeeScalar.selector, basefeeScalar); doi.set(doi.basefeeScalar.selector, basefeeScalar);
doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar); doi.set(doi.blobBaseFeeScalar.selector, blobBaseFeeScalar);
doi.set(doi.l2ChainId.selector, l2ChainId); doi.set(doi.l2ChainId.selector, l2ChainId);
doi.set(doi.opcmProxy.selector, address(opcm)); doi.set(doi.opcm.selector, address(opcm));
doi.set(doi.saltMixer.selector, saltMixer); doi.set(doi.saltMixer.selector, saltMixer);
doi.set(doi.gasLimit.selector, gasLimit); doi.set(doi.gasLimit.selector, gasLimit);
doi.set(doi.disputeGameType.selector, disputeGameType); doi.set(doi.disputeGameType.selector, disputeGameType);
......
...@@ -16,6 +16,7 @@ import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; ...@@ -16,6 +16,7 @@ import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol";
import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol";
import { IOptimismPortalInterop } from "src/L1/interfaces/IOptimismPortalInterop.sol"; import { IOptimismPortalInterop } from "src/L1/interfaces/IOptimismPortalInterop.sol";
import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol";
import { ISystemConfigInterop } from "src/L1/interfaces/ISystemConfigInterop.sol";
import { IDataAvailabilityChallenge } from "src/L1/interfaces/IDataAvailabilityChallenge.sol"; import { IDataAvailabilityChallenge } from "src/L1/interfaces/IDataAvailabilityChallenge.sol";
import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol"; import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol";
...@@ -479,36 +480,37 @@ contract Specification_Test is CommonTest { ...@@ -479,36 +480,37 @@ contract Specification_Test is CommonTest {
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("gasLimit()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("gasLimit()") });
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("eip1559Denominator()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("eip1559Denominator()") });
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("eip1559Elasticity()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("eip1559Elasticity()") });
_addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfigInterop.initialize.selector });
_addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfig.initialize.selector }); _addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfig.initialize.selector });
_addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfig.minimumGasLimit.selector }); _addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfigInterop.minimumGasLimit.selector });
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("overhead()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("overhead()") });
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("owner()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("owner()") });
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("renounceOwnership()"), _auth: Role.SYSTEMCONFIGOWNER }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("renounceOwnership()"), _auth: Role.SYSTEMCONFIGOWNER });
_addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfig.resourceConfig.selector }); _addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfigInterop.resourceConfig.selector });
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("scalar()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("scalar()") });
_addSpec({ _addSpec({
_name: "SystemConfigInterop", _name: "SystemConfigInterop",
_sel: ISystemConfig.setBatcherHash.selector, _sel: ISystemConfigInterop.setBatcherHash.selector,
_auth: Role.SYSTEMCONFIGOWNER _auth: Role.SYSTEMCONFIGOWNER
}); });
_addSpec({ _addSpec({
_name: "SystemConfigInterop", _name: "SystemConfigInterop",
_sel: ISystemConfig.setGasConfig.selector, _sel: ISystemConfigInterop.setGasConfig.selector,
_auth: Role.SYSTEMCONFIGOWNER _auth: Role.SYSTEMCONFIGOWNER
}); });
_addSpec({ _addSpec({
_name: "SystemConfigInterop", _name: "SystemConfigInterop",
_sel: ISystemConfig.setGasLimit.selector, _sel: ISystemConfigInterop.setGasLimit.selector,
_auth: Role.SYSTEMCONFIGOWNER _auth: Role.SYSTEMCONFIGOWNER
}); });
_addSpec({ _addSpec({
_name: "SystemConfigInterop", _name: "SystemConfigInterop",
_sel: ISystemConfig.setEIP1559Params.selector, _sel: ISystemConfigInterop.setEIP1559Params.selector,
_auth: Role.SYSTEMCONFIGOWNER _auth: Role.SYSTEMCONFIGOWNER
}); });
_addSpec({ _addSpec({
_name: "SystemConfigInterop", _name: "SystemConfigInterop",
_sel: ISystemConfig.setUnsafeBlockSigner.selector, _sel: ISystemConfigInterop.setUnsafeBlockSigner.selector,
_auth: Role.SYSTEMCONFIGOWNER _auth: Role.SYSTEMCONFIGOWNER
}); });
_addSpec({ _addSpec({
...@@ -516,7 +518,7 @@ contract Specification_Test is CommonTest { ...@@ -516,7 +518,7 @@ contract Specification_Test is CommonTest {
_sel: _getSel("transferOwnership(address)"), _sel: _getSel("transferOwnership(address)"),
_auth: Role.SYSTEMCONFIGOWNER _auth: Role.SYSTEMCONFIGOWNER
}); });
_addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfig.unsafeBlockSigner.selector }); _addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfigInterop.unsafeBlockSigner.selector });
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("version()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("version()") });
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("l1CrossDomainMessenger()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("l1CrossDomainMessenger()") });
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("l1ERC721Bridge()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("l1ERC721Bridge()") });
...@@ -552,12 +554,6 @@ contract Specification_Test is CommonTest { ...@@ -552,12 +554,6 @@ contract Specification_Test is CommonTest {
_auth: Role.DEPENDENCYMANAGER _auth: Role.DEPENDENCYMANAGER
}); });
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("dependencyManager()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("dependencyManager()") });
_addSpec({
_name: "SystemConfigInterop",
_sel: _getSel(
"initialize(address,uint32,uint32,bytes32,uint64,address,(uint32,uint8,uint8,uint32,uint32,uint128),address,(address,address,address,address,address,address,address),address)"
)
});
// ProxyAdmin // ProxyAdmin
_addSpec({ _name: "ProxyAdmin", _sel: _getSel("addressManager()") }); _addSpec({ _name: "ProxyAdmin", _sel: _getSel("addressManager()") });
...@@ -841,27 +837,25 @@ contract Specification_Test is CommonTest { ...@@ -841,27 +837,25 @@ contract Specification_Test is CommonTest {
_addSpec({ _name: "OPContractsManager", _sel: _getSel("version()") }); _addSpec({ _name: "OPContractsManager", _sel: _getSel("version()") });
_addSpec({ _name: "OPContractsManager", _sel: _getSel("superchainConfig()") }); _addSpec({ _name: "OPContractsManager", _sel: _getSel("superchainConfig()") });
_addSpec({ _name: "OPContractsManager", _sel: _getSel("protocolVersions()") }); _addSpec({ _name: "OPContractsManager", _sel: _getSel("protocolVersions()") });
_addSpec({ _name: "OPContractsManager", _sel: _getSel("latestRelease()") }); _addSpec({ _name: "OPContractsManager", _sel: _getSel("l1ContractsRelease()") });
_addSpec({ _name: "OPContractsManager", _sel: _getSel("implementations(string,string)") });
_addSpec({ _name: "OPContractsManager", _sel: _getSel("systemConfigs(uint256)") }); _addSpec({ _name: "OPContractsManager", _sel: _getSel("systemConfigs(uint256)") });
_addSpec({ _name: "OPContractsManager", _sel: _getSel("OUTPUT_VERSION()") }); _addSpec({ _name: "OPContractsManager", _sel: _getSel("OUTPUT_VERSION()") });
_addSpec({ _name: "OPContractsManager", _sel: OPContractsManager.initialize.selector });
_addSpec({ _name: "OPContractsManager", _sel: OPContractsManager.deploy.selector }); _addSpec({ _name: "OPContractsManager", _sel: OPContractsManager.deploy.selector });
_addSpec({ _name: "OPContractsManager", _sel: OPContractsManager.blueprints.selector }); _addSpec({ _name: "OPContractsManager", _sel: OPContractsManager.blueprints.selector });
_addSpec({ _name: "OPContractsManager", _sel: OPContractsManager.chainIdToBatchInboxAddress.selector }); _addSpec({ _name: "OPContractsManager", _sel: OPContractsManager.chainIdToBatchInboxAddress.selector });
_addSpec({ _name: "OPContractsManager", _sel: OPContractsManager.implementations.selector });
// OPContractsManagerInterop // OPContractsManagerInterop
_addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("version()") }); _addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("version()") });
_addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("superchainConfig()") }); _addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("superchainConfig()") });
_addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("protocolVersions()") }); _addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("protocolVersions()") });
_addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("latestRelease()") }); _addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("l1ContractsRelease()") });
_addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("implementations(string,string)") });
_addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("systemConfigs(uint256)") }); _addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("systemConfigs(uint256)") });
_addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("OUTPUT_VERSION()") }); _addSpec({ _name: "OPContractsManagerInterop", _sel: _getSel("OUTPUT_VERSION()") });
_addSpec({ _name: "OPContractsManagerInterop", _sel: OPContractsManager.initialize.selector });
_addSpec({ _name: "OPContractsManagerInterop", _sel: OPContractsManager.deploy.selector }); _addSpec({ _name: "OPContractsManagerInterop", _sel: OPContractsManager.deploy.selector });
_addSpec({ _name: "OPContractsManagerInterop", _sel: OPContractsManager.blueprints.selector }); _addSpec({ _name: "OPContractsManagerInterop", _sel: OPContractsManager.blueprints.selector });
_addSpec({ _name: "OPContractsManagerInterop", _sel: OPContractsManager.chainIdToBatchInboxAddress.selector }); _addSpec({ _name: "OPContractsManagerInterop", _sel: OPContractsManager.chainIdToBatchInboxAddress.selector });
_addSpec({ _name: "OPContractsManagerInterop", _sel: OPContractsManager.implementations.selector });
// DeputyGuardianModule // DeputyGuardianModule
_addSpec({ _addSpec({
......
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