Commit ce2ce43b authored by smartcontracts's avatar smartcontracts Committed by GitHub

feat: have AnchorStateRegistry use a single root (#13700)

* feat: have AnchorStateRegistry use a single root

Updates the AnchorStateRegistry to use a single unified anchor
root by checking with the OptimismPortal for the currently
respected game type. Additionally makes the AnchorStateRegistry
MCP ready.

Users MUST deploy this contract as a new proxy and cannot upgrade
their existing proxy.

* Update snapshots post-merge

* op-deployer: Support single ASR

* Update semver

* updates after rebase

* rename method

* make isGameProper comment more obvious

* update semver

* semver bump

* simpler api for boolean functions

* comment updates

* address wildmolasses comments

* add test for not guardian

* a few more tests

---------
Co-authored-by: default avatarMatthew Slipper <me@matthewslipper.com>
parent 544c42b3
...@@ -196,7 +196,7 @@ func DeployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme ...@@ -196,7 +196,7 @@ func DeployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme
l1Host.SetTxOrigin(cfg.Deployer) l1Host.SetTxOrigin(cfg.Deployer)
output, err := opcm.DeployOPChainV160(l1Host, opcm.DeployOPChainInputV160{ output, err := opcm.DeployOPChain(l1Host, opcm.DeployOPChainInput{
OpChainProxyAdminOwner: cfg.ProxyAdminOwner, OpChainProxyAdminOwner: cfg.ProxyAdminOwner,
SystemConfigOwner: cfg.SystemConfigOwner, SystemConfigOwner: cfg.SystemConfigOwner,
Batcher: cfg.BatchSenderAddress, Batcher: cfg.BatchSenderAddress,
...@@ -215,7 +215,6 @@ func DeployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme ...@@ -215,7 +215,6 @@ func DeployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme
DisputeSplitDepth: cfg.DisputeSplitDepth, DisputeSplitDepth: cfg.DisputeSplitDepth,
DisputeClockExtension: cfg.DisputeClockExtension, DisputeClockExtension: cfg.DisputeClockExtension,
DisputeMaxClockDuration: cfg.DisputeMaxClockDuration, DisputeMaxClockDuration: cfg.DisputeMaxClockDuration,
StartingAnchorRoots: opcm.PermissionedGameStartingAnchorRoots,
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to deploy L2 OP chain: %w", err) return nil, fmt.Errorf("failed to deploy L2 OP chain: %w", err)
......
...@@ -20,6 +20,7 @@ type Implementations struct { ...@@ -20,6 +20,7 @@ type Implementations struct {
L1StandardBridgeImpl common.Address `json:"L1StandardBridgeImpl"` L1StandardBridgeImpl common.Address `json:"L1StandardBridgeImpl"`
OptimismMintableERC20FactoryImpl common.Address `json:"OptimismMintableERC20FactoryImpl"` OptimismMintableERC20FactoryImpl common.Address `json:"OptimismMintableERC20FactoryImpl"`
DisputeGameFactoryImpl common.Address `json:"DisputeGameFactoryImpl"` DisputeGameFactoryImpl common.Address `json:"DisputeGameFactoryImpl"`
AnchorStateRegistryImpl common.Address `json:"AnchorStateRegistryImpl"`
} }
type SuperchainDeployment struct { type SuperchainDeployment struct {
......
...@@ -9,46 +9,23 @@ import ( ...@@ -9,46 +9,23 @@ import (
) )
var anchorRootFunc = w3.MustNewFunc(` var anchorRootFunc = w3.MustNewFunc(`
dummy((uint32 gameType, (bytes32 root, uint256 l2BlockNumber) outputRoot)[] roots) dummy((bytes32 root, uint256 l2BlockNumber) outputRoot)
`, "") `, "")
type StartingAnchorRoot struct { type StartingAnchorRoot struct {
GameType uint32
Root common.Hash Root common.Hash
L2BlockNumber *big.Int L2BlockNumber *big.Int
} }
var DefaultStartingAnchorRoot = StartingAnchorRoot{ var DefaultStartingAnchorRoot = StartingAnchorRoot{
GameType: 1,
Root: common.Hash{0xde, 0xad}, Root: common.Hash{0xde, 0xad},
L2BlockNumber: common.Big0, L2BlockNumber: common.Big0,
} }
type encodingStartingAnchorRoot struct { func EncodeStartingAnchorRoot(root StartingAnchorRoot) ([]byte, error) {
GameType uint32 encoded, err := anchorRootFunc.EncodeArgs(root)
OutputRoot struct {
Root common.Hash
L2BlockNumber *big.Int
}
}
func EncodeStartingAnchorRoots(roots []StartingAnchorRoot) ([]byte, error) {
args := make([]encodingStartingAnchorRoot, len(roots))
for i, root := range roots {
args[i] = encodingStartingAnchorRoot{
GameType: root.GameType,
OutputRoot: struct {
Root common.Hash
L2BlockNumber *big.Int
}{
Root: root.Root,
L2BlockNumber: root.L2BlockNumber,
},
}
}
encoded, err := anchorRootFunc.EncodeArgs(args)
if err != nil { if err != nil {
return nil, fmt.Errorf("error encoding anchor roots: %w", err) return nil, fmt.Errorf("error encoding anchor root: %w", err)
} }
// Chop off the function selector since w3 can't serialize structs directly // Chop off the function selector since w3 can't serialize structs directly
return encoded[4:], nil return encoded[4:], nil
......
...@@ -9,34 +9,22 @@ import ( ...@@ -9,34 +9,22 @@ import (
) )
func TestEncodeStartingAnchorRoots(t *testing.T) { func TestEncodeStartingAnchorRoots(t *testing.T) {
encoded, err := EncodeStartingAnchorRoots([]StartingAnchorRoot{ encoded, err := EncodeStartingAnchorRoot(DefaultStartingAnchorRoot)
DefaultStartingAnchorRoot,
})
require.NoError(t, err) require.NoError(t, err)
require.EqualValues(t, PermissionedGameStartingAnchorRoots, encoded) require.EqualValues(t, PermissionedGameStartingAnchorRoot, encoded)
encoded, err = EncodeStartingAnchorRoots([]StartingAnchorRoot{ encoded, err = EncodeStartingAnchorRoot(StartingAnchorRoot{
{ Root: common.Hash{0xde, 0xad, 0xbe, 0xef},
GameType: 0, L2BlockNumber: big.NewInt(9),
L2BlockNumber: common.Big0,
},
{
GameType: 1,
Root: common.Hash{0xde, 0xad},
L2BlockNumber: big.NewInt(0),
},
}) })
require.NoError(t, err) require.NoError(t, err)
require.EqualValues(t, require.EqualValues(t,
common.Hex2Bytes( []byte{
"0000000000000000000000000000000000000000000000000000000000000020"+ 0xde, 0xad, 0xbe, 0xef, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
"0000000000000000000000000000000000000000000000000000000000000002"+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
"0000000000000000000000000000000000000000000000000000000000000000"+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
"0000000000000000000000000000000000000000000000000000000000000000"+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x09,
"0000000000000000000000000000000000000000000000000000000000000000"+ },
"0000000000000000000000000000000000000000000000000000000000000001"+
"dead000000000000000000000000000000000000000000000000000000000000"+
"0000000000000000000000000000000000000000000000000000000000000000"),
encoded, encoded,
) )
} }
...@@ -39,6 +39,7 @@ type DeployImplementationsOutput struct { ...@@ -39,6 +39,7 @@ type DeployImplementationsOutput struct {
L1StandardBridgeImpl common.Address L1StandardBridgeImpl common.Address
OptimismMintableERC20FactoryImpl common.Address OptimismMintableERC20FactoryImpl common.Address
DisputeGameFactoryImpl common.Address DisputeGameFactoryImpl common.Address
AnchorStateRegistryImpl common.Address
} }
func (output *DeployImplementationsOutput) CheckOutput(input common.Address) error { func (output *DeployImplementationsOutput) CheckOutput(input common.Address) error {
......
...@@ -9,13 +9,16 @@ import ( ...@@ -9,13 +9,16 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
) )
// PermissionedGameStartingAnchorRoots is a root of bytes32(hex"dead") for the permissioned game at block 0, // PermissionedGameStartingAnchorRoot is a root of bytes32(hex"dead") for the permissioned game at block 0,
// and no root for the permissionless game. // and no root for the permissionless game.
var PermissionedGameStartingAnchorRoots = []byte{ var PermissionedGameStartingAnchorRoot = []byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xde, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
} }
type DeployOPChainInputV160 struct { type DeployOPChainInput struct {
OpChainProxyAdminOwner common.Address OpChainProxyAdminOwner common.Address
SystemConfigOwner common.Address SystemConfigOwner common.Address
Batcher common.Address Batcher common.Address
...@@ -36,14 +39,17 @@ type DeployOPChainInputV160 struct { ...@@ -36,14 +39,17 @@ type DeployOPChainInputV160 struct {
DisputeSplitDepth uint64 DisputeSplitDepth uint64
DisputeClockExtension uint64 DisputeClockExtension uint64
DisputeMaxClockDuration uint64 DisputeMaxClockDuration uint64
StartingAnchorRoots []byte
AllowCustomDisputeParameters bool AllowCustomDisputeParameters bool
} }
func (input *DeployOPChainInputV160) InputSet() bool { func (input *DeployOPChainInput) InputSet() bool {
return true return true
} }
func (input *DeployOPChainInput) StartingAnchorRoot() []byte {
return PermissionedGameStartingAnchorRoot
}
type DeployOPChainOutput struct { type DeployOPChainOutput struct {
OpChainProxyAdmin common.Address OpChainProxyAdmin common.Address
AddressManager common.Address AddressManager common.Address
...@@ -71,8 +77,8 @@ type DeployOPChainScript struct { ...@@ -71,8 +77,8 @@ type DeployOPChainScript struct {
Run func(input, output common.Address) error Run func(input, output common.Address) error
} }
func DeployOPChainV160(host *script.Host, input DeployOPChainInputV160) (DeployOPChainOutput, error) { func DeployOPChain(host *script.Host, input DeployOPChainInput) (DeployOPChainOutput, error) {
return RunScriptSingle[DeployOPChainInputV160, DeployOPChainOutput](host, input, "DeployOPChain.s.sol", "DeployOPChain") return RunScriptSingle[DeployOPChainInput, DeployOPChainOutput](host, input, "DeployOPChain.s.sol", "DeployOPChain")
} }
type ReadImplementationAddressesInput struct { type ReadImplementationAddressesInput struct {
......
...@@ -17,7 +17,6 @@ type DeployOPCMInput struct { ...@@ -17,7 +17,6 @@ type DeployOPCMInput struct {
ProxyAdminBlueprint common.Address ProxyAdminBlueprint common.Address
L1ChugSplashProxyBlueprint common.Address L1ChugSplashProxyBlueprint common.Address
ResolvedDelegateProxyBlueprint common.Address ResolvedDelegateProxyBlueprint common.Address
AnchorStateRegistryBlueprint common.Address
PermissionedDisputeGame1Blueprint common.Address PermissionedDisputeGame1Blueprint common.Address
PermissionedDisputeGame2Blueprint common.Address PermissionedDisputeGame2Blueprint common.Address
...@@ -28,6 +27,7 @@ type DeployOPCMInput struct { ...@@ -28,6 +27,7 @@ type DeployOPCMInput struct {
L1CrossDomainMessengerImpl common.Address L1CrossDomainMessengerImpl common.Address
L1StandardBridgeImpl common.Address L1StandardBridgeImpl common.Address
DisputeGameFactoryImpl common.Address DisputeGameFactoryImpl common.Address
AnchorStateRegistryImpl common.Address
DelayedWETHImpl common.Address DelayedWETHImpl common.Address
MipsImpl common.Address MipsImpl common.Address
} }
......
...@@ -75,6 +75,7 @@ func DeployImplementations(env *Env, intent *state.Intent, st *state.State) erro ...@@ -75,6 +75,7 @@ func DeployImplementations(env *Env, intent *state.Intent, st *state.State) erro
L1StandardBridgeImplAddress: dio.L1StandardBridgeImpl, L1StandardBridgeImplAddress: dio.L1StandardBridgeImpl,
OptimismMintableERC20FactoryImplAddress: dio.OptimismMintableERC20FactoryImpl, OptimismMintableERC20FactoryImplAddress: dio.OptimismMintableERC20FactoryImpl,
DisputeGameFactoryImplAddress: dio.DisputeGameFactoryImpl, DisputeGameFactoryImplAddress: dio.DisputeGameFactoryImpl,
AnchorStateRegistryImplAddress: dio.AnchorStateRegistryImpl,
} }
return nil return nil
......
...@@ -27,12 +27,12 @@ func DeployOPChain(env *Env, intent *state.Intent, st *state.State, chainID comm ...@@ -27,12 +27,12 @@ func DeployOPChain(env *Env, intent *state.Intent, st *state.State, chainID comm
var dco opcm.DeployOPChainOutput var dco opcm.DeployOPChainOutput
lgr.Info("deploying OP chain using local allocs", "id", chainID.Hex()) lgr.Info("deploying OP chain using local allocs", "id", chainID.Hex())
dci, err := makeDCIV160(intent, thisIntent, chainID, st) dci, err := makeDCI(intent, thisIntent, chainID, st)
if err != nil { if err != nil {
return fmt.Errorf("error making deploy OP chain input: %w", err) return fmt.Errorf("error making deploy OP chain input: %w", err)
} }
dco, err = opcm.DeployOPChainV160(env.L1ScriptHost, dci) dco, err = opcm.DeployOPChain(env.L1ScriptHost, dci)
if err != nil { if err != nil {
return fmt.Errorf("error deploying OP chain: %w", err) return fmt.Errorf("error deploying OP chain: %w", err)
} }
...@@ -70,7 +70,7 @@ func DeployOPChain(env *Env, intent *state.Intent, st *state.State, chainID comm ...@@ -70,7 +70,7 @@ func DeployOPChain(env *Env, intent *state.Intent, st *state.State, chainID comm
return nil return nil
} }
func makeDCIV160(intent *state.Intent, thisIntent *state.ChainIntent, chainID common.Hash, st *state.State) (opcm.DeployOPChainInputV160, error) { func makeDCI(intent *state.Intent, thisIntent *state.ChainIntent, chainID common.Hash, st *state.State) (opcm.DeployOPChainInput, error) {
proofParams, err := jsonutil.MergeJSON( proofParams, err := jsonutil.MergeJSON(
state.ChainProofParams{ state.ChainProofParams{
DisputeGameType: standard.DisputeGameType, DisputeGameType: standard.DisputeGameType,
...@@ -84,31 +84,10 @@ func makeDCIV160(intent *state.Intent, thisIntent *state.ChainIntent, chainID co ...@@ -84,31 +84,10 @@ func makeDCIV160(intent *state.Intent, thisIntent *state.ChainIntent, chainID co
thisIntent.DeployOverrides, thisIntent.DeployOverrides,
) )
if err != nil { if err != nil {
return opcm.DeployOPChainInputV160{}, fmt.Errorf("error merging proof params from overrides: %w", err) return opcm.DeployOPChainInput{}, fmt.Errorf("error merging proof params from overrides: %w", err)
} }
startingAnchorRoots := opcm.PermissionedGameStartingAnchorRoots return opcm.DeployOPChainInput{
if len(thisIntent.AdditionalDisputeGames) > 0 {
anchorRoots := []opcm.StartingAnchorRoot{
opcm.DefaultStartingAnchorRoot,
}
for _, game := range thisIntent.AdditionalDisputeGames {
anchorRoots = append(anchorRoots, opcm.StartingAnchorRoot{
GameType: game.DisputeGameType,
Root: game.StartingAnchorRoot,
L2BlockNumber: common.Big0,
})
}
encoded, err := opcm.EncodeStartingAnchorRoots(anchorRoots)
if err != nil {
return opcm.DeployOPChainInputV160{}, fmt.Errorf("error encoding starting anchor roots: %w", err)
}
startingAnchorRoots = encoded
}
return opcm.DeployOPChainInputV160{
OpChainProxyAdminOwner: thisIntent.Roles.L1ProxyAdminOwner, OpChainProxyAdminOwner: thisIntent.Roles.L1ProxyAdminOwner,
SystemConfigOwner: thisIntent.Roles.SystemConfigOwner, SystemConfigOwner: thisIntent.Roles.SystemConfigOwner,
Batcher: thisIntent.Roles.Batcher, Batcher: thisIntent.Roles.Batcher,
...@@ -128,7 +107,6 @@ func makeDCIV160(intent *state.Intent, thisIntent *state.ChainIntent, chainID co ...@@ -128,7 +107,6 @@ func makeDCIV160(intent *state.Intent, thisIntent *state.ChainIntent, chainID co
DisputeClockExtension: proofParams.DisputeClockExtension, // 3 hours (input in seconds) DisputeClockExtension: proofParams.DisputeClockExtension, // 3 hours (input in seconds)
DisputeMaxClockDuration: proofParams.DisputeMaxClockDuration, // 3.5 days (input in seconds) DisputeMaxClockDuration: proofParams.DisputeMaxClockDuration, // 3.5 days (input in seconds)
AllowCustomDisputeParameters: proofParams.DangerouslyAllowCustomDisputeParameters, AllowCustomDisputeParameters: proofParams.DangerouslyAllowCustomDisputeParameters,
StartingAnchorRoots: startingAnchorRoots,
}, nil }, nil
} }
......
...@@ -33,7 +33,6 @@ type AdditionalDisputeGame struct { ...@@ -33,7 +33,6 @@ type AdditionalDisputeGame struct {
OracleMinProposalSize uint64 OracleMinProposalSize uint64
OracleChallengePeriodSeconds uint64 OracleChallengePeriodSeconds uint64
MakeRespected bool MakeRespected bool
StartingAnchorRoot common.Hash
} }
type ChainIntent struct { type ChainIntent struct {
......
...@@ -81,6 +81,7 @@ type ImplementationsDeployment struct { ...@@ -81,6 +81,7 @@ type ImplementationsDeployment struct {
L1StandardBridgeImplAddress common.Address `json:"l1StandardBridgeImplAddress"` L1StandardBridgeImplAddress common.Address `json:"l1StandardBridgeImplAddress"`
OptimismMintableERC20FactoryImplAddress common.Address `json:"optimismMintableERC20FactoryImplAddress"` OptimismMintableERC20FactoryImplAddress common.Address `json:"optimismMintableERC20FactoryImplAddress"`
DisputeGameFactoryImplAddress common.Address `json:"disputeGameFactoryImplAddress"` DisputeGameFactoryImplAddress common.Address `json:"disputeGameFactoryImplAddress"`
AnchorStateRegistryImplAddress common.Address `json:"anchorStateRegistryImplAddress"`
} }
type AdditionalDisputeGameState struct { type AdditionalDisputeGameState struct {
......
...@@ -443,7 +443,6 @@ func defaultIntent(root string, loc *artifacts.Locator, deployer common.Address, ...@@ -443,7 +443,6 @@ func defaultIntent(root string, loc *artifacts.Locator, deployer common.Address,
OracleMinProposalSize: 10000, OracleMinProposalSize: 10000,
OracleChallengePeriodSeconds: 0, OracleChallengePeriodSeconds: 0,
MakeRespected: true, MakeRespected: true,
StartingAnchorRoot: genesisOutputRoot,
}, },
{ {
ChainProofParams: state.ChainProofParams{ ChainProofParams: state.ChainProofParams{
...@@ -455,8 +454,7 @@ func defaultIntent(root string, loc *artifacts.Locator, deployer common.Address, ...@@ -455,8 +454,7 @@ func defaultIntent(root string, loc *artifacts.Locator, deployer common.Address,
DisputeClockExtension: 0, DisputeClockExtension: 0,
DisputeMaxClockDuration: 1200, DisputeMaxClockDuration: 1200,
}, },
VMType: state.VMTypeAlphabet, VMType: state.VMTypeAlphabet,
StartingAnchorRoot: genesisOutputRoot,
}, },
{ {
ChainProofParams: state.ChainProofParams{ ChainProofParams: state.ChainProofParams{
...@@ -467,8 +465,7 @@ func defaultIntent(root string, loc *artifacts.Locator, deployer common.Address, ...@@ -467,8 +465,7 @@ func defaultIntent(root string, loc *artifacts.Locator, deployer common.Address,
DisputeClockExtension: 0, DisputeClockExtension: 0,
DisputeMaxClockDuration: 1200, DisputeMaxClockDuration: 1200,
}, },
VMType: cannonVMType(allocType), VMType: cannonVMType(allocType),
StartingAnchorRoot: genesisOutputRoot,
}, },
}, },
}, },
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import { IDisputeGame } from "interfaces/dispute/IDisputeGame.sol";
import { IFaultDisputeGame } from "interfaces/dispute/IFaultDisputeGame.sol"; import { IFaultDisputeGame } from "interfaces/dispute/IFaultDisputeGame.sol";
import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol"; import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol";
import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol";
import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol";
import { GameType, Hash, OutputRoot } from "src/dispute/lib/Types.sol"; import { GameType, Hash, OutputRoot } from "src/dispute/lib/Types.sol";
interface IAnchorStateRegistry { interface IAnchorStateRegistry {
struct StartingAnchorRoot { error AnchorStateRegistry_Unauthorized();
GameType gameType; error AnchorStateRegistry_ImproperAnchorGame();
OutputRoot outputRoot; error AnchorStateRegistry_InvalidAnchorGame();
}
error InvalidGameStatus();
error Unauthorized();
error UnregisteredGame();
event AnchorNotUpdated(IFaultDisputeGame indexed game);
event AnchorUpdated(IFaultDisputeGame indexed game);
event Initialized(uint8 version); event Initialized(uint8 version);
function anchors(GameType) external view returns (Hash root, uint256 l2BlockNumber); // nosemgrep function anchorGame() external view returns (IFaultDisputeGame);
function anchors(GameType) external view returns (Hash, uint256);
function getAnchorRoot() external view returns (Hash, uint256);
function disputeGameFactory() external view returns (IDisputeGameFactory); function disputeGameFactory() external view returns (IDisputeGameFactory);
function initialize( function initialize(ISuperchainConfig _superchainConfig, IDisputeGameFactory _disputeGameFactory, IOptimismPortal2 _portal, OutputRoot memory _startingAnchorRoot) external;
StartingAnchorRoot[] memory _startingAnchorRoots, function isGameRegistered(IDisputeGame _game) external view returns (bool);
ISuperchainConfig _superchainConfig function isGameBlacklisted(IDisputeGame _game) external view returns (bool);
) function isGameRespected(IDisputeGame _game) external view returns (bool);
external; function isGameRetired(IDisputeGame _game) external view returns (bool);
function isGameProper(IDisputeGame _game) external view returns (bool);
function portal() external view returns (IOptimismPortal2);
function setAnchorState(IFaultDisputeGame _game) external; function setAnchorState(IFaultDisputeGame _game) external;
function superchainConfig() external view returns (ISuperchainConfig); function superchainConfig() external view returns (ISuperchainConfig);
function tryUpdateAnchorState() external; function tryUpdateAnchorState() external;
function version() external view returns (string memory); function version() external view returns (string memory);
function __constructor__(IDisputeGameFactory _disputeGameFactory) external; function __constructor__() external;
} }
...@@ -73,11 +73,13 @@ test-upgrade *ARGS: build-go-ffi ...@@ -73,11 +73,13 @@ test-upgrade *ARGS: build-go-ffi
#!/bin/bash #!/bin/bash
echo "Running upgrade tests at block $pinnedBlockNumber" echo "Running upgrade tests at block $pinnedBlockNumber"
export FORK_BLOCK_NUMBER=$pinnedBlockNumber export FORK_BLOCK_NUMBER=$pinnedBlockNumber
export NO_MATCH_CONTRACTS="OptimismPortal2WithMockERC20_Test|OptimismPortal2_FinalizeWithdrawal_Test|AnchorStateRegistry_Initialize_Test|AnchorStateRegistry_TryUpdateAnchorState_Test|FaultDisputeGame_Test|FaultDispute_1v1_Actors_Test" export NO_MATCH_CONTRACTS="OptimismPortal2WithMockERC20_Test|OptimismPortal2_FinalizeWithdrawal_Test|'AnchorStateRegistry_*'|FaultDisputeGame_Test|FaultDispute_1v1_Actors_Test"
export NO_MATCH_PATHS="test/dispute/AnchorStateRegistry.t.sol"
FORK_RPC_URL=$ETH_RPC_URL \ FORK_RPC_URL=$ETH_RPC_URL \
FORK_TEST=true \ FORK_TEST=true \
forge test --match-path "test/{L1,dispute}/**" \ forge test --match-path "test/{L1,dispute}/**" \
--no-match-contract "$NO_MATCH_CONTRACTS" \ --no-match-contract "$NO_MATCH_CONTRACTS" \
--no-match-path "$NO_MATCH_PATHS" \
{{ARGS}} {{ARGS}}
test-upgrade-rerun *ARGS: build-go-ffi test-upgrade-rerun *ARGS: build-go-ffi
......
...@@ -529,10 +529,6 @@ library ChainAssertions { ...@@ -529,10 +529,6 @@ library ChainAssertions {
Blueprint.parseBlueprintPreamble(address(blueprints.resolvedDelegateProxy).code); Blueprint.parseBlueprintPreamble(address(blueprints.resolvedDelegateProxy).code);
require(keccak256(rdProxyPreamble.initcode) == keccak256(vm.getCode("ResolvedDelegateProxy")), "CHECK-OPCM-180"); require(keccak256(rdProxyPreamble.initcode) == keccak256(vm.getCode("ResolvedDelegateProxy")), "CHECK-OPCM-180");
Blueprint.Preamble memory asrPreamble =
Blueprint.parseBlueprintPreamble(address(blueprints.anchorStateRegistry).code);
require(keccak256(asrPreamble.initcode) == keccak256(vm.getCode("AnchorStateRegistry")), "CHECK-OPCM-190");
Blueprint.Preamble memory pdg1Preamble = Blueprint.Preamble memory pdg1Preamble =
Blueprint.parseBlueprintPreamble(address(blueprints.permissionedDisputeGame1).code); Blueprint.parseBlueprintPreamble(address(blueprints.permissionedDisputeGame1).code);
Blueprint.Preamble memory pdg2Preamble = Blueprint.Preamble memory pdg2Preamble =
......
...@@ -380,7 +380,6 @@ contract Deploy is Deployer { ...@@ -380,7 +380,6 @@ contract Deploy is Deployer {
artifacts.save("DisputeGameFactoryProxy", address(deployOutput.disputeGameFactoryProxy)); artifacts.save("DisputeGameFactoryProxy", address(deployOutput.disputeGameFactoryProxy));
artifacts.save("PermissionedDelayedWETHProxy", address(deployOutput.delayedWETHPermissionedGameProxy)); artifacts.save("PermissionedDelayedWETHProxy", address(deployOutput.delayedWETHPermissionedGameProxy));
artifacts.save("AnchorStateRegistryProxy", address(deployOutput.anchorStateRegistryProxy)); artifacts.save("AnchorStateRegistryProxy", address(deployOutput.anchorStateRegistryProxy));
artifacts.save("AnchorStateRegistryImpl", address(deployOutput.anchorStateRegistryImpl));
artifacts.save("PermissionedDisputeGame", address(deployOutput.permissionedDisputeGame)); artifacts.save("PermissionedDisputeGame", address(deployOutput.permissionedDisputeGame));
artifacts.save("OptimismPortalProxy", address(deployOutput.optimismPortalProxy)); artifacts.save("OptimismPortalProxy", address(deployOutput.optimismPortalProxy));
artifacts.save("OptimismPortal2Proxy", address(deployOutput.optimismPortalProxy)); artifacts.save("OptimismPortal2Proxy", address(deployOutput.optimismPortalProxy));
...@@ -854,24 +853,6 @@ contract Deploy is Deployer { ...@@ -854,24 +853,6 @@ contract Deploy is Deployer {
/// @notice Get the DeployInput struct to use for testing /// @notice Get the DeployInput struct to use for testing
function getDeployInput() public view returns (OPContractsManager.DeployInput memory) { function getDeployInput() public view returns (OPContractsManager.DeployInput memory) {
OutputRoot memory testOutputRoot = OutputRoot({
root: Hash.wrap(cfg.faultGameGenesisOutputRoot()),
l2BlockNumber: cfg.faultGameGenesisBlock()
});
IAnchorStateRegistry.StartingAnchorRoot[] memory startingAnchorRoots =
new IAnchorStateRegistry.StartingAnchorRoot[](5);
startingAnchorRoots[0] =
IAnchorStateRegistry.StartingAnchorRoot({ gameType: GameTypes.CANNON, outputRoot: testOutputRoot });
startingAnchorRoots[1] = IAnchorStateRegistry.StartingAnchorRoot({
gameType: GameTypes.PERMISSIONED_CANNON,
outputRoot: testOutputRoot
});
startingAnchorRoots[2] =
IAnchorStateRegistry.StartingAnchorRoot({ gameType: GameTypes.ASTERISC, outputRoot: testOutputRoot });
startingAnchorRoots[3] =
IAnchorStateRegistry.StartingAnchorRoot({ gameType: GameTypes.FAST, outputRoot: testOutputRoot });
startingAnchorRoots[4] =
IAnchorStateRegistry.StartingAnchorRoot({ gameType: GameTypes.ALPHABET, outputRoot: testOutputRoot });
string memory saltMixer = "salt mixer"; string memory saltMixer = "salt mixer";
return OPContractsManager.DeployInput({ return OPContractsManager.DeployInput({
roles: OPContractsManager.Roles({ roles: OPContractsManager.Roles({
...@@ -885,7 +866,9 @@ contract Deploy is Deployer { ...@@ -885,7 +866,9 @@ contract Deploy is Deployer {
basefeeScalar: cfg.basefeeScalar(), basefeeScalar: cfg.basefeeScalar(),
blobBasefeeScalar: cfg.blobbasefeeScalar(), blobBasefeeScalar: cfg.blobbasefeeScalar(),
l2ChainId: cfg.l2ChainID(), l2ChainId: cfg.l2ChainID(),
startingAnchorRoots: abi.encode(startingAnchorRoots), startingAnchorRoot: abi.encode(
OutputRoot({ root: Hash.wrap(cfg.faultGameGenesisOutputRoot()), l2BlockNumber: cfg.faultGameGenesisBlock() })
),
saltMixer: saltMixer, saltMixer: saltMixer,
gasLimit: uint64(cfg.l2GenesisBlockGasLimit()), gasLimit: uint64(cfg.l2GenesisBlockGasLimit()),
disputeGameType: GameTypes.PERMISSIONED_CANNON, disputeGameType: GameTypes.PERMISSIONED_CANNON,
......
...@@ -13,7 +13,7 @@ import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol"; ...@@ -13,7 +13,7 @@ import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol";
import { IPreimageOracle } from "interfaces/cannon/IPreimageOracle.sol"; import { IPreimageOracle } from "interfaces/cannon/IPreimageOracle.sol";
import { IMIPS } from "interfaces/cannon/IMIPS.sol"; import { IMIPS } from "interfaces/cannon/IMIPS.sol";
import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol"; import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol";
import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol";
import { OPContractsManager } from "src/L1/OPContractsManager.sol"; import { OPContractsManager } from "src/L1/OPContractsManager.sol";
import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol"; import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol";
import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol";
...@@ -142,6 +142,7 @@ contract DeployImplementationsOutput is BaseDeployIO { ...@@ -142,6 +142,7 @@ contract DeployImplementationsOutput is BaseDeployIO {
IL1StandardBridge internal _l1StandardBridgeImpl; IL1StandardBridge internal _l1StandardBridgeImpl;
IOptimismMintableERC20Factory internal _optimismMintableERC20FactoryImpl; IOptimismMintableERC20Factory internal _optimismMintableERC20FactoryImpl;
IDisputeGameFactory internal _disputeGameFactoryImpl; IDisputeGameFactory internal _disputeGameFactoryImpl;
IAnchorStateRegistry internal _anchorStateRegistryImpl;
function set(bytes4 _sel, address _addr) public { function set(bytes4 _sel, address _addr) public {
require(_addr != address(0), "DeployImplementationsOutput: cannot set zero address"); require(_addr != address(0), "DeployImplementationsOutput: cannot set zero address");
...@@ -158,6 +159,7 @@ contract DeployImplementationsOutput is BaseDeployIO { ...@@ -158,6 +159,7 @@ contract DeployImplementationsOutput is BaseDeployIO {
else if (_sel == this.l1StandardBridgeImpl.selector) _l1StandardBridgeImpl = IL1StandardBridge(payable(_addr)); else if (_sel == this.l1StandardBridgeImpl.selector) _l1StandardBridgeImpl = IL1StandardBridge(payable(_addr));
else if (_sel == this.optimismMintableERC20FactoryImpl.selector) _optimismMintableERC20FactoryImpl = IOptimismMintableERC20Factory(_addr); else if (_sel == this.optimismMintableERC20FactoryImpl.selector) _optimismMintableERC20FactoryImpl = IOptimismMintableERC20Factory(_addr);
else if (_sel == this.disputeGameFactoryImpl.selector) _disputeGameFactoryImpl = IDisputeGameFactory(_addr); else if (_sel == this.disputeGameFactoryImpl.selector) _disputeGameFactoryImpl = IDisputeGameFactory(_addr);
else if (_sel == this.anchorStateRegistryImpl.selector) _anchorStateRegistryImpl = IAnchorStateRegistry(_addr);
else revert("DeployImplementationsOutput: unknown selector"); else revert("DeployImplementationsOutput: unknown selector");
// forgefmt: disable-end // forgefmt: disable-end
} }
...@@ -179,7 +181,8 @@ contract DeployImplementationsOutput is BaseDeployIO { ...@@ -179,7 +181,8 @@ contract DeployImplementationsOutput is BaseDeployIO {
address(this.l1ERC721BridgeImpl()), address(this.l1ERC721BridgeImpl()),
address(this.l1StandardBridgeImpl()), address(this.l1StandardBridgeImpl()),
address(this.optimismMintableERC20FactoryImpl()), address(this.optimismMintableERC20FactoryImpl()),
address(this.disputeGameFactoryImpl()) address(this.disputeGameFactoryImpl()),
address(this.anchorStateRegistryImpl())
); );
DeployUtils.assertValidContractAddresses(Solarray.extend(addrs1, addrs2)); DeployUtils.assertValidContractAddresses(Solarray.extend(addrs1, addrs2));
...@@ -242,10 +245,16 @@ contract DeployImplementationsOutput is BaseDeployIO { ...@@ -242,10 +245,16 @@ contract DeployImplementationsOutput is BaseDeployIO {
return _disputeGameFactoryImpl; return _disputeGameFactoryImpl;
} }
function anchorStateRegistryImpl() public view returns (IAnchorStateRegistry) {
DeployUtils.assertValidContractAddress(address(_anchorStateRegistryImpl));
return _anchorStateRegistryImpl;
}
// -------- Deployment Assertions -------- // -------- Deployment Assertions --------
function assertValidDeploy(DeployImplementationsInput _dii) public view { function assertValidDeploy(DeployImplementationsInput _dii) public view {
assertValidDelayedWETHImpl(_dii); assertValidDelayedWETHImpl(_dii);
assertValidDisputeGameFactoryImpl(_dii); assertValidDisputeGameFactoryImpl(_dii);
assertValidAnchorStateRegistryImpl(_dii);
assertValidL1CrossDomainMessengerImpl(_dii); assertValidL1CrossDomainMessengerImpl(_dii);
assertValidL1ERC721BridgeImpl(_dii); assertValidL1ERC721BridgeImpl(_dii);
assertValidL1StandardBridgeImpl(_dii); assertValidL1StandardBridgeImpl(_dii);
...@@ -387,6 +396,12 @@ contract DeployImplementationsOutput is BaseDeployIO { ...@@ -387,6 +396,12 @@ contract DeployImplementationsOutput is BaseDeployIO {
require(address(factory.owner()) == address(0), "DG-10"); require(address(factory.owner()) == address(0), "DG-10");
} }
function assertValidAnchorStateRegistryImpl(DeployImplementationsInput) internal view {
IAnchorStateRegistry registry = anchorStateRegistryImpl();
DeployUtils.assertInitialized({ _contractAddress: address(registry), _isProxy: false, _slot: 0, _offset: 0 });
}
} }
contract DeployImplementations is Script { contract DeployImplementations is Script {
...@@ -406,6 +421,7 @@ contract DeployImplementations is Script { ...@@ -406,6 +421,7 @@ contract DeployImplementations is Script {
deployPreimageOracleSingleton(_dii, _dio); deployPreimageOracleSingleton(_dii, _dio);
deployMipsSingleton(_dii, _dio); deployMipsSingleton(_dii, _dio);
deployDisputeGameFactoryImpl(_dio); deployDisputeGameFactoryImpl(_dio);
deployAnchorStateRegistryImpl(_dio);
// Deploy the OP Contracts Manager with the new implementations set. // Deploy the OP Contracts Manager with the new implementations set.
deployOPContractsManager(_dii, _dio); deployOPContractsManager(_dii, _dio);
...@@ -438,6 +454,7 @@ contract DeployImplementations is Script { ...@@ -438,6 +454,7 @@ contract DeployImplementations is Script {
l1CrossDomainMessengerImpl: address(_dio.l1CrossDomainMessengerImpl()), l1CrossDomainMessengerImpl: address(_dio.l1CrossDomainMessengerImpl()),
l1StandardBridgeImpl: address(_dio.l1StandardBridgeImpl()), l1StandardBridgeImpl: address(_dio.l1StandardBridgeImpl()),
disputeGameFactoryImpl: address(_dio.disputeGameFactoryImpl()), disputeGameFactoryImpl: address(_dio.disputeGameFactoryImpl()),
anchorStateRegistryImpl: address(_dio.anchorStateRegistryImpl()),
delayedWETHImpl: address(_dio.delayedWETHImpl()), delayedWETHImpl: address(_dio.delayedWETHImpl()),
mipsImpl: address(_dio.mipsSingleton()) mipsImpl: address(_dio.mipsSingleton())
}); });
...@@ -481,8 +498,6 @@ contract DeployImplementations is Script { ...@@ -481,8 +498,6 @@ contract DeployImplementations is Script {
require(checkAddress == address(0), "OPCM-40"); require(checkAddress == address(0), "OPCM-40");
(blueprints.resolvedDelegateProxy, checkAddress) = DeployUtils.createDeterministicBlueprint(vm.getCode("ResolvedDelegateProxy"), _salt); (blueprints.resolvedDelegateProxy, checkAddress) = DeployUtils.createDeterministicBlueprint(vm.getCode("ResolvedDelegateProxy"), _salt);
require(checkAddress == address(0), "OPCM-50"); require(checkAddress == address(0), "OPCM-50");
(blueprints.anchorStateRegistry, checkAddress) = DeployUtils.createDeterministicBlueprint(vm.getCode("AnchorStateRegistry"), _salt);
require(checkAddress == address(0), "OPCM-60");
// The max initcode/runtimecode size is 48KB/24KB. // The max initcode/runtimecode size is 48KB/24KB.
// But for Blueprint, the initcode is stored as runtime code, that's why it's necessary to split into 2 parts. // But for Blueprint, the initcode is stored as runtime code, that's why it's necessary to split into 2 parts.
(blueprints.permissionedDisputeGame1, blueprints.permissionedDisputeGame2) = DeployUtils.createDeterministicBlueprint(vm.getCode("PermissionedDisputeGame"), _salt); (blueprints.permissionedDisputeGame1, blueprints.permissionedDisputeGame2) = DeployUtils.createDeterministicBlueprint(vm.getCode("PermissionedDisputeGame"), _salt);
...@@ -569,7 +584,7 @@ contract DeployImplementations is Script { ...@@ -569,7 +584,7 @@ contract DeployImplementations is Script {
// | Contract | Proxied | Deployment | MCP Ready | // | Contract | Proxied | Deployment | MCP Ready |
// |-------------------------|---------|-----------------------------------|------------| // |-------------------------|---------|-----------------------------------|------------|
// | DisputeGameFactory | Yes | Bespoke | Yes | // | DisputeGameFactory | Yes | Bespoke | Yes |
// | AnchorStateRegistry | Yes | Bespoke | No | // | AnchorStateRegistry | Yes | Bespoke | Yes |
// | FaultDisputeGame | No | Bespoke | No | Not yet supported by OPCM // | FaultDisputeGame | No | Bespoke | No | Not yet supported by OPCM
// | PermissionedDisputeGame | No | Bespoke | No | // | PermissionedDisputeGame | No | Bespoke | No |
// | DelayedWETH | Yes | Two bespoke (one per DisputeGame) | Yes *️⃣ | // | DelayedWETH | Yes | Two bespoke (one per DisputeGame) | Yes *️⃣ |
...@@ -586,6 +601,7 @@ contract DeployImplementations is Script { ...@@ -586,6 +601,7 @@ contract DeployImplementations is Script {
// here we deploy: // here we deploy:
// //
// - DisputeGameFactory (implementation) // - DisputeGameFactory (implementation)
// - AnchorStateRegistry (implementation)
// - OptimismPortal2 (implementation) // - OptimismPortal2 (implementation)
// - DelayedWETH (implementation) // - DelayedWETH (implementation)
// - PreimageOracle (singleton) // - PreimageOracle (singleton)
...@@ -594,7 +610,6 @@ contract DeployImplementations is Script { ...@@ -594,7 +610,6 @@ contract DeployImplementations is Script {
// For contracts which are not MCP ready neither the Proxy nor the implementation can be shared, therefore they // For contracts which are not MCP ready neither the Proxy nor the implementation can be shared, therefore they
// are deployed by `DeployOpChain.s.sol`. // are deployed by `DeployOpChain.s.sol`.
// These are: // These are:
// - AnchorStateRegistry (proxy and implementation)
// - FaultDisputeGame (not proxied) // - FaultDisputeGame (not proxied)
// - PermissionedDisputeGame (not proxied) // - PermissionedDisputeGame (not proxied)
// - DelayedWeth (proxies only) // - DelayedWeth (proxies only)
...@@ -690,6 +705,19 @@ contract DeployImplementations is Script { ...@@ -690,6 +705,19 @@ contract DeployImplementations is Script {
_dio.set(_dio.disputeGameFactoryImpl.selector, address(impl)); _dio.set(_dio.disputeGameFactoryImpl.selector, address(impl));
} }
function deployAnchorStateRegistryImpl(DeployImplementationsOutput _dio) public virtual {
vm.broadcast(msg.sender);
IAnchorStateRegistry impl = IAnchorStateRegistry(
DeployUtils.createDeterministic({
_name: "AnchorStateRegistry",
_args: DeployUtils.encodeConstructor(abi.encodeCall(IAnchorStateRegistry.__constructor__, ())),
_salt: _salt
})
);
vm.label(address(impl), "AnchorStateRegistryImpl");
_dio.set(_dio.anchorStateRegistryImpl.selector, address(impl));
}
// -------- Utilities -------- // -------- Utilities --------
function etchIOContracts() public returns (DeployImplementationsInput dii_, DeployImplementationsOutput dio_) { function etchIOContracts() public returns (DeployImplementationsInput dii_, DeployImplementationsOutput dio_) {
...@@ -769,6 +797,7 @@ contract DeployImplementationsInterop is DeployImplementations { ...@@ -769,6 +797,7 @@ contract DeployImplementationsInterop is DeployImplementations {
l1CrossDomainMessengerImpl: address(_dio.l1CrossDomainMessengerImpl()), l1CrossDomainMessengerImpl: address(_dio.l1CrossDomainMessengerImpl()),
l1StandardBridgeImpl: address(_dio.l1StandardBridgeImpl()), l1StandardBridgeImpl: address(_dio.l1StandardBridgeImpl()),
disputeGameFactoryImpl: address(_dio.disputeGameFactoryImpl()), disputeGameFactoryImpl: address(_dio.disputeGameFactoryImpl()),
anchorStateRegistryImpl: address(_dio.anchorStateRegistryImpl()),
delayedWETHImpl: address(_dio.delayedWETHImpl()), delayedWETHImpl: address(_dio.delayedWETHImpl()),
mipsImpl: address(_dio.mipsSingleton()) mipsImpl: address(_dio.mipsSingleton())
}); });
......
...@@ -22,7 +22,6 @@ contract DeployOPCMInput is BaseDeployIO { ...@@ -22,7 +22,6 @@ contract DeployOPCMInput is BaseDeployIO {
address internal _proxyAdminBlueprint; address internal _proxyAdminBlueprint;
address internal _l1ChugSplashProxyBlueprint; address internal _l1ChugSplashProxyBlueprint;
address internal _resolvedDelegateProxyBlueprint; address internal _resolvedDelegateProxyBlueprint;
address internal _anchorStateRegistryBlueprint;
address internal _permissionedDisputeGame1Blueprint; address internal _permissionedDisputeGame1Blueprint;
address internal _permissionedDisputeGame2Blueprint; address internal _permissionedDisputeGame2Blueprint;
...@@ -33,6 +32,7 @@ contract DeployOPCMInput is BaseDeployIO { ...@@ -33,6 +32,7 @@ contract DeployOPCMInput is BaseDeployIO {
address internal _l1CrossDomainMessengerImpl; address internal _l1CrossDomainMessengerImpl;
address internal _l1StandardBridgeImpl; address internal _l1StandardBridgeImpl;
address internal _disputeGameFactoryImpl; address internal _disputeGameFactoryImpl;
address internal _anchorStateRegistryImpl;
address internal _delayedWETHImpl; address internal _delayedWETHImpl;
address internal _mipsImpl; address internal _mipsImpl;
...@@ -47,7 +47,6 @@ contract DeployOPCMInput is BaseDeployIO { ...@@ -47,7 +47,6 @@ contract DeployOPCMInput is BaseDeployIO {
else if (_sel == this.proxyAdminBlueprint.selector) _proxyAdminBlueprint = _addr; else if (_sel == this.proxyAdminBlueprint.selector) _proxyAdminBlueprint = _addr;
else if (_sel == this.l1ChugSplashProxyBlueprint.selector) _l1ChugSplashProxyBlueprint = _addr; else if (_sel == this.l1ChugSplashProxyBlueprint.selector) _l1ChugSplashProxyBlueprint = _addr;
else if (_sel == this.resolvedDelegateProxyBlueprint.selector) _resolvedDelegateProxyBlueprint = _addr; else if (_sel == this.resolvedDelegateProxyBlueprint.selector) _resolvedDelegateProxyBlueprint = _addr;
else if (_sel == this.anchorStateRegistryBlueprint.selector) _anchorStateRegistryBlueprint = _addr;
else if (_sel == this.permissionedDisputeGame1Blueprint.selector) _permissionedDisputeGame1Blueprint = _addr; else if (_sel == this.permissionedDisputeGame1Blueprint.selector) _permissionedDisputeGame1Blueprint = _addr;
else if (_sel == this.permissionedDisputeGame2Blueprint.selector) _permissionedDisputeGame2Blueprint = _addr; else if (_sel == this.permissionedDisputeGame2Blueprint.selector) _permissionedDisputeGame2Blueprint = _addr;
else if (_sel == this.l1ERC721BridgeImpl.selector) _l1ERC721BridgeImpl = _addr; else if (_sel == this.l1ERC721BridgeImpl.selector) _l1ERC721BridgeImpl = _addr;
...@@ -57,6 +56,7 @@ contract DeployOPCMInput is BaseDeployIO { ...@@ -57,6 +56,7 @@ contract DeployOPCMInput is BaseDeployIO {
else if (_sel == this.l1CrossDomainMessengerImpl.selector) _l1CrossDomainMessengerImpl = _addr; else if (_sel == this.l1CrossDomainMessengerImpl.selector) _l1CrossDomainMessengerImpl = _addr;
else if (_sel == this.l1StandardBridgeImpl.selector) _l1StandardBridgeImpl = _addr; else if (_sel == this.l1StandardBridgeImpl.selector) _l1StandardBridgeImpl = _addr;
else if (_sel == this.disputeGameFactoryImpl.selector) _disputeGameFactoryImpl = _addr; else if (_sel == this.disputeGameFactoryImpl.selector) _disputeGameFactoryImpl = _addr;
else if (_sel == this.anchorStateRegistryImpl.selector) _anchorStateRegistryImpl = _addr;
else if (_sel == this.delayedWETHImpl.selector) _delayedWETHImpl = _addr; else if (_sel == this.delayedWETHImpl.selector) _delayedWETHImpl = _addr;
else if (_sel == this.mipsImpl.selector) _mipsImpl = _addr; else if (_sel == this.mipsImpl.selector) _mipsImpl = _addr;
else revert("DeployOPCMInput: unknown selector"); else revert("DeployOPCMInput: unknown selector");
...@@ -110,11 +110,6 @@ contract DeployOPCMInput is BaseDeployIO { ...@@ -110,11 +110,6 @@ contract DeployOPCMInput is BaseDeployIO {
return _resolvedDelegateProxyBlueprint; return _resolvedDelegateProxyBlueprint;
} }
function anchorStateRegistryBlueprint() public view returns (address) {
require(_anchorStateRegistryBlueprint != address(0), "DeployOPCMInput: not set");
return _anchorStateRegistryBlueprint;
}
function permissionedDisputeGame1Blueprint() public view returns (address) { function permissionedDisputeGame1Blueprint() public view returns (address) {
require(_permissionedDisputeGame1Blueprint != address(0), "DeployOPCMInput: not set"); require(_permissionedDisputeGame1Blueprint != address(0), "DeployOPCMInput: not set");
return _permissionedDisputeGame1Blueprint; return _permissionedDisputeGame1Blueprint;
...@@ -160,6 +155,11 @@ contract DeployOPCMInput is BaseDeployIO { ...@@ -160,6 +155,11 @@ contract DeployOPCMInput is BaseDeployIO {
return _disputeGameFactoryImpl; return _disputeGameFactoryImpl;
} }
function anchorStateRegistryImpl() public view returns (address) {
require(_anchorStateRegistryImpl != address(0), "DeployOPCMInput: not set");
return _anchorStateRegistryImpl;
}
function delayedWETHImpl() public view returns (address) { function delayedWETHImpl() public view returns (address) {
require(_delayedWETHImpl != address(0), "DeployOPCMInput: not set"); require(_delayedWETHImpl != address(0), "DeployOPCMInput: not set");
return _delayedWETHImpl; return _delayedWETHImpl;
...@@ -196,7 +196,6 @@ contract DeployOPCM is Script { ...@@ -196,7 +196,6 @@ contract DeployOPCM is Script {
proxyAdmin: _doi.proxyAdminBlueprint(), proxyAdmin: _doi.proxyAdminBlueprint(),
l1ChugSplashProxy: _doi.l1ChugSplashProxyBlueprint(), l1ChugSplashProxy: _doi.l1ChugSplashProxyBlueprint(),
resolvedDelegateProxy: _doi.resolvedDelegateProxyBlueprint(), resolvedDelegateProxy: _doi.resolvedDelegateProxyBlueprint(),
anchorStateRegistry: _doi.anchorStateRegistryBlueprint(),
permissionedDisputeGame1: _doi.permissionedDisputeGame1Blueprint(), permissionedDisputeGame1: _doi.permissionedDisputeGame1Blueprint(),
permissionedDisputeGame2: _doi.permissionedDisputeGame2Blueprint(), permissionedDisputeGame2: _doi.permissionedDisputeGame2Blueprint(),
permissionlessDisputeGame1: address(0), permissionlessDisputeGame1: address(0),
...@@ -210,6 +209,7 @@ contract DeployOPCM is Script { ...@@ -210,6 +209,7 @@ contract DeployOPCM is Script {
l1CrossDomainMessengerImpl: address(_doi.l1CrossDomainMessengerImpl()), l1CrossDomainMessengerImpl: address(_doi.l1CrossDomainMessengerImpl()),
l1StandardBridgeImpl: address(_doi.l1StandardBridgeImpl()), l1StandardBridgeImpl: address(_doi.l1StandardBridgeImpl()),
disputeGameFactoryImpl: address(_doi.disputeGameFactoryImpl()), disputeGameFactoryImpl: address(_doi.disputeGameFactoryImpl()),
anchorStateRegistryImpl: address(_doi.anchorStateRegistryImpl()),
delayedWETHImpl: address(_doi.delayedWETHImpl()), delayedWETHImpl: address(_doi.delayedWETHImpl()),
mipsImpl: address(_doi.mipsImpl()) mipsImpl: address(_doi.mipsImpl())
}); });
...@@ -251,7 +251,6 @@ contract DeployOPCM is Script { ...@@ -251,7 +251,6 @@ contract DeployOPCM is Script {
require(blueprints.proxyAdmin == _doi.proxyAdminBlueprint(), "OPCMI-60"); require(blueprints.proxyAdmin == _doi.proxyAdminBlueprint(), "OPCMI-60");
require(blueprints.l1ChugSplashProxy == _doi.l1ChugSplashProxyBlueprint(), "OPCMI-70"); require(blueprints.l1ChugSplashProxy == _doi.l1ChugSplashProxyBlueprint(), "OPCMI-70");
require(blueprints.resolvedDelegateProxy == _doi.resolvedDelegateProxyBlueprint(), "OPCMI-80"); require(blueprints.resolvedDelegateProxy == _doi.resolvedDelegateProxyBlueprint(), "OPCMI-80");
require(blueprints.anchorStateRegistry == _doi.anchorStateRegistryBlueprint(), "OPCMI-90");
require(blueprints.permissionedDisputeGame1 == _doi.permissionedDisputeGame1Blueprint(), "OPCMI-100"); require(blueprints.permissionedDisputeGame1 == _doi.permissionedDisputeGame1Blueprint(), "OPCMI-100");
require(blueprints.permissionedDisputeGame2 == _doi.permissionedDisputeGame2Blueprint(), "OPCMI-110"); require(blueprints.permissionedDisputeGame2 == _doi.permissionedDisputeGame2Blueprint(), "OPCMI-110");
...@@ -265,8 +264,9 @@ contract DeployOPCM is Script { ...@@ -265,8 +264,9 @@ contract DeployOPCM is Script {
require(implementations.l1CrossDomainMessengerImpl == _doi.l1CrossDomainMessengerImpl(), "OPCMI-160"); require(implementations.l1CrossDomainMessengerImpl == _doi.l1CrossDomainMessengerImpl(), "OPCMI-160");
require(implementations.l1StandardBridgeImpl == _doi.l1StandardBridgeImpl(), "OPCMI-170"); require(implementations.l1StandardBridgeImpl == _doi.l1StandardBridgeImpl(), "OPCMI-170");
require(implementations.disputeGameFactoryImpl == _doi.disputeGameFactoryImpl(), "OPCMI-180"); require(implementations.disputeGameFactoryImpl == _doi.disputeGameFactoryImpl(), "OPCMI-180");
require(implementations.delayedWETHImpl == _doi.delayedWETHImpl(), "OPCMI-190"); require(implementations.anchorStateRegistryImpl == _doi.anchorStateRegistryImpl(), "OPCMI-190");
require(implementations.mipsImpl == _doi.mipsImpl(), "OPCMI-200"); require(implementations.delayedWETHImpl == _doi.delayedWETHImpl(), "OPCMI-200");
require(implementations.mipsImpl == _doi.mipsImpl(), "OPCMI-210");
} }
function etchIOContracts() public returns (DeployOPCMInput doi_, DeployOPCMOutput doo_) { function etchIOContracts() public returns (DeployOPCMInput doi_, DeployOPCMOutput doo_) {
......
...@@ -159,7 +159,7 @@ contract DeployOPChainInput is BaseDeployIO { ...@@ -159,7 +159,7 @@ contract DeployOPChainInput is BaseDeployIO {
return _l2ChainId; return _l2ChainId;
} }
function startingAnchorRoots() public pure returns (bytes memory) { function startingAnchorRoot() public pure returns (bytes memory) {
// WARNING: For now always hardcode the starting permissioned game anchor root to 0xdead, // WARNING: For now always hardcode the starting permissioned game anchor root to 0xdead,
// and we do not set anything for the permissioned game. This is because we currently only // and we do not set anything for the permissioned game. This is because we currently only
// support deploying straight to permissioned games, and the starting root does not // support deploying straight to permissioned games, and the starting root does not
...@@ -168,10 +168,10 @@ contract DeployOPChainInput is BaseDeployIO { ...@@ -168,10 +168,10 @@ contract DeployOPChainInput is BaseDeployIO {
// because to to update to the permissionless game, we will need to update its starting // because to to update to the permissionless game, we will need to update its starting
// anchor root and deploy a new permissioned dispute game contract anyway. // anchor root and deploy a new permissioned dispute game contract anyway.
// //
// You can `console.logBytes(abi.encode(ScriptConstants.DEFAULT_STARTING_ANCHOR_ROOTS()))` to get the bytes that // You can `console.logBytes(abi.encode(ScriptConstants.DEFAULT_OUTPUT_ROOT()))` to get the bytes that
// are hardcoded into `op-chain-ops/deployer/opcm/opchain.go` // are hardcoded into `op-chain-ops/deployer/opcm/opchain.go`
return abi.encode(ScriptConstants.DEFAULT_STARTING_ANCHOR_ROOTS()); return abi.encode(ScriptConstants.DEFAULT_OUTPUT_ROOT());
} }
function opcm() public view returns (OPContractsManager) { function opcm() public view returns (OPContractsManager) {
...@@ -228,7 +228,6 @@ contract DeployOPChainOutput is BaseDeployIO { ...@@ -228,7 +228,6 @@ contract DeployOPChainOutput is BaseDeployIO {
IOptimismPortal2 internal _optimismPortalProxy; IOptimismPortal2 internal _optimismPortalProxy;
IDisputeGameFactory internal _disputeGameFactoryProxy; IDisputeGameFactory internal _disputeGameFactoryProxy;
IAnchorStateRegistry internal _anchorStateRegistryProxy; IAnchorStateRegistry internal _anchorStateRegistryProxy;
IAnchorStateRegistry internal _anchorStateRegistryImpl;
IFaultDisputeGame internal _faultDisputeGame; IFaultDisputeGame internal _faultDisputeGame;
IPermissionedDisputeGame internal _permissionedDisputeGame; IPermissionedDisputeGame internal _permissionedDisputeGame;
IDelayedWETH internal _delayedWETHPermissionedGameProxy; IDelayedWETH internal _delayedWETHPermissionedGameProxy;
...@@ -247,7 +246,6 @@ contract DeployOPChainOutput is BaseDeployIO { ...@@ -247,7 +246,6 @@ contract DeployOPChainOutput is BaseDeployIO {
else if (_sel == this.optimismPortalProxy.selector) _optimismPortalProxy = IOptimismPortal2(payable(_addr)) ; else if (_sel == this.optimismPortalProxy.selector) _optimismPortalProxy = IOptimismPortal2(payable(_addr)) ;
else if (_sel == this.disputeGameFactoryProxy.selector) _disputeGameFactoryProxy = IDisputeGameFactory(_addr) ; else if (_sel == this.disputeGameFactoryProxy.selector) _disputeGameFactoryProxy = IDisputeGameFactory(_addr) ;
else if (_sel == this.anchorStateRegistryProxy.selector) _anchorStateRegistryProxy = IAnchorStateRegistry(_addr) ; else if (_sel == this.anchorStateRegistryProxy.selector) _anchorStateRegistryProxy = IAnchorStateRegistry(_addr) ;
else if (_sel == this.anchorStateRegistryImpl.selector) _anchorStateRegistryImpl = IAnchorStateRegistry(_addr) ;
else if (_sel == this.faultDisputeGame.selector) _faultDisputeGame = IFaultDisputeGame(_addr) ; else if (_sel == this.faultDisputeGame.selector) _faultDisputeGame = IFaultDisputeGame(_addr) ;
else if (_sel == this.permissionedDisputeGame.selector) _permissionedDisputeGame = IPermissionedDisputeGame(_addr) ; else if (_sel == this.permissionedDisputeGame.selector) _permissionedDisputeGame = IPermissionedDisputeGame(_addr) ;
else if (_sel == this.delayedWETHPermissionedGameProxy.selector) _delayedWETHPermissionedGameProxy = IDelayedWETH(payable(_addr)) ; else if (_sel == this.delayedWETHPermissionedGameProxy.selector) _delayedWETHPermissionedGameProxy = IDelayedWETH(payable(_addr)) ;
...@@ -314,11 +312,6 @@ contract DeployOPChainOutput is BaseDeployIO { ...@@ -314,11 +312,6 @@ contract DeployOPChainOutput is BaseDeployIO {
return _anchorStateRegistryProxy; return _anchorStateRegistryProxy;
} }
function anchorStateRegistryImpl() public view returns (IAnchorStateRegistry) {
DeployUtils.assertValidContractAddress(address(_anchorStateRegistryImpl));
return _anchorStateRegistryImpl;
}
function faultDisputeGame() public view returns (IFaultDisputeGame) { function faultDisputeGame() public view returns (IFaultDisputeGame) {
DeployUtils.assertValidContractAddress(address(_faultDisputeGame)); DeployUtils.assertValidContractAddress(address(_faultDisputeGame));
return _faultDisputeGame; return _faultDisputeGame;
...@@ -361,7 +354,7 @@ contract DeployOPChain is Script { ...@@ -361,7 +354,7 @@ contract DeployOPChain is Script {
basefeeScalar: _doi.basefeeScalar(), basefeeScalar: _doi.basefeeScalar(),
blobBasefeeScalar: _doi.blobBaseFeeScalar(), blobBasefeeScalar: _doi.blobBaseFeeScalar(),
l2ChainId: _doi.l2ChainId(), l2ChainId: _doi.l2ChainId(),
startingAnchorRoots: _doi.startingAnchorRoots(), startingAnchorRoot: _doi.startingAnchorRoot(),
saltMixer: _doi.saltMixer(), saltMixer: _doi.saltMixer(),
gasLimit: _doi.gasLimit(), gasLimit: _doi.gasLimit(),
disputeGameType: _doi.disputeGameType(), disputeGameType: _doi.disputeGameType(),
...@@ -385,7 +378,6 @@ contract DeployOPChain is Script { ...@@ -385,7 +378,6 @@ contract DeployOPChain is Script {
vm.label(address(deployOutput.optimismPortalProxy), "optimismPortalProxy"); vm.label(address(deployOutput.optimismPortalProxy), "optimismPortalProxy");
vm.label(address(deployOutput.disputeGameFactoryProxy), "disputeGameFactoryProxy"); vm.label(address(deployOutput.disputeGameFactoryProxy), "disputeGameFactoryProxy");
vm.label(address(deployOutput.anchorStateRegistryProxy), "anchorStateRegistryProxy"); vm.label(address(deployOutput.anchorStateRegistryProxy), "anchorStateRegistryProxy");
vm.label(address(deployOutput.anchorStateRegistryImpl), "anchorStateRegistryImpl");
// vm.label(address(deployOutput.faultDisputeGame), "faultDisputeGame"); // vm.label(address(deployOutput.faultDisputeGame), "faultDisputeGame");
vm.label(address(deployOutput.permissionedDisputeGame), "permissionedDisputeGame"); vm.label(address(deployOutput.permissionedDisputeGame), "permissionedDisputeGame");
vm.label(address(deployOutput.delayedWETHPermissionedGameProxy), "delayedWETHPermissionedGameProxy"); vm.label(address(deployOutput.delayedWETHPermissionedGameProxy), "delayedWETHPermissionedGameProxy");
...@@ -404,7 +396,6 @@ contract DeployOPChain is Script { ...@@ -404,7 +396,6 @@ contract DeployOPChain is Script {
_doo.set(_doo.optimismPortalProxy.selector, address(deployOutput.optimismPortalProxy)); _doo.set(_doo.optimismPortalProxy.selector, address(deployOutput.optimismPortalProxy));
_doo.set(_doo.disputeGameFactoryProxy.selector, address(deployOutput.disputeGameFactoryProxy)); _doo.set(_doo.disputeGameFactoryProxy.selector, address(deployOutput.disputeGameFactoryProxy));
_doo.set(_doo.anchorStateRegistryProxy.selector, address(deployOutput.anchorStateRegistryProxy)); _doo.set(_doo.anchorStateRegistryProxy.selector, address(deployOutput.anchorStateRegistryProxy));
_doo.set(_doo.anchorStateRegistryImpl.selector, address(deployOutput.anchorStateRegistryImpl));
// _doo.set(_doo.faultDisputeGame.selector, address(deployOutput.faultDisputeGame)); // _doo.set(_doo.faultDisputeGame.selector, address(deployOutput.faultDisputeGame));
_doo.set(_doo.permissionedDisputeGame.selector, address(deployOutput.permissionedDisputeGame)); _doo.set(_doo.permissionedDisputeGame.selector, address(deployOutput.permissionedDisputeGame));
_doo.set(_doo.delayedWETHPermissionedGameProxy.selector, address(deployOutput.delayedWETHPermissionedGameProxy)); _doo.set(_doo.delayedWETHPermissionedGameProxy.selector, address(deployOutput.delayedWETHPermissionedGameProxy));
...@@ -433,7 +424,6 @@ contract DeployOPChain is Script { ...@@ -433,7 +424,6 @@ contract DeployOPChain is Script {
address(_doo.optimismPortalProxy()), address(_doo.optimismPortalProxy()),
address(_doo.disputeGameFactoryProxy()), address(_doo.disputeGameFactoryProxy()),
address(_doo.anchorStateRegistryProxy()), address(_doo.anchorStateRegistryProxy()),
address(_doo.anchorStateRegistryImpl()),
address(_doo.permissionedDisputeGame()), address(_doo.permissionedDisputeGame()),
// address(_doo.faultDisputeGame()), // address(_doo.faultDisputeGame()),
address(_doo.delayedWETHPermissionedGameProxy()) address(_doo.delayedWETHPermissionedGameProxy())
...@@ -447,7 +437,6 @@ contract DeployOPChain is Script { ...@@ -447,7 +437,6 @@ contract DeployOPChain is Script {
// -------- Deployment Assertions -------- // -------- Deployment Assertions --------
function assertValidDeploy(DeployOPChainInput _doi, DeployOPChainOutput _doo) internal { function assertValidDeploy(DeployOPChainInput _doi, DeployOPChainOutput _doo) internal {
assertValidAnchorStateRegistryImpl(_doi, _doo);
assertValidAnchorStateRegistryProxy(_doi, _doo); assertValidAnchorStateRegistryProxy(_doi, _doo);
assertValidDelayedWETH(_doi, _doo); assertValidDelayedWETH(_doi, _doo);
assertValidDisputeGameFactory(_doi, _doo); assertValidDisputeGameFactory(_doi, _doo);
...@@ -508,9 +497,6 @@ contract DeployOPChain is Script { ...@@ -508,9 +497,6 @@ contract DeployOPChain is Script {
_offset: 0 _offset: 0
}); });
vm.prank(address(0));
address impl = proxy.implementation();
require(impl == address(_doo.anchorStateRegistryImpl()), "ANCHORP-20");
require( require(
address(_doo.anchorStateRegistryProxy().disputeGameFactory()) == address(_doo.disputeGameFactoryProxy()), address(_doo.anchorStateRegistryProxy().disputeGameFactory()) == address(_doo.disputeGameFactoryProxy()),
"ANCHORP-30" "ANCHORP-30"
...@@ -521,14 +507,6 @@ contract DeployOPChain is Script { ...@@ -521,14 +507,6 @@ contract DeployOPChain is Script {
require(Hash.unwrap(actualRoot) == expectedRoot, "ANCHORP-40"); require(Hash.unwrap(actualRoot) == expectedRoot, "ANCHORP-40");
} }
function assertValidAnchorStateRegistryImpl(DeployOPChainInput, DeployOPChainOutput _doo) internal {
IAnchorStateRegistry registry = _doo.anchorStateRegistryImpl();
DeployUtils.assertInitialized({ _contractAddress: address(registry), _isProxy: false, _slot: 0, _offset: 0 });
require(address(registry.disputeGameFactory()) == address(_doo.disputeGameFactoryProxy()), "ANCHORI-10");
}
function assertValidSystemConfig(DeployOPChainInput _doi, DeployOPChainOutput _doo) internal { function assertValidSystemConfig(DeployOPChainInput _doi, DeployOPChainOutput _doo) internal {
ISystemConfig systemConfig = _doo.systemConfigProxy(); ISystemConfig systemConfig = _doo.systemConfigProxy();
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol"; import { OutputRoot, Hash } from "src/dispute/lib/Types.sol";
import { GameTypes, OutputRoot, Hash } from "src/dispute/lib/Types.sol";
/// @title Constants /// @title Constants
/// @notice Constants is a library for storing constants. Simple! Don't put everything in here, just /// @notice Constants is a library for storing constants. Simple! Don't put everything in here, just
...@@ -13,14 +12,4 @@ library Constants { ...@@ -13,14 +12,4 @@ library Constants {
function DEFAULT_OUTPUT_ROOT() internal pure returns (OutputRoot memory) { function DEFAULT_OUTPUT_ROOT() internal pure returns (OutputRoot memory) {
return OutputRoot({ root: Hash.wrap(bytes32(hex"dead")), l2BlockNumber: 0 }); return OutputRoot({ root: Hash.wrap(bytes32(hex"dead")), l2BlockNumber: 0 });
} }
function DEFAULT_STARTING_ANCHOR_ROOTS() internal pure returns (IAnchorStateRegistry.StartingAnchorRoot[] memory) {
IAnchorStateRegistry.StartingAnchorRoot[] memory defaultStartingAnchorRoots =
new IAnchorStateRegistry.StartingAnchorRoot[](1);
defaultStartingAnchorRoots[0] = IAnchorStateRegistry.StartingAnchorRoot({
gameType: GameTypes.PERMISSIONED_CANNON,
outputRoot: DEFAULT_OUTPUT_ROOT()
});
return defaultStartingAnchorRoots;
}
} }
[ [
{ {
"inputs": [ "inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "anchorGame",
"outputs": [
{ {
"internalType": "contract IDisputeGameFactory", "internalType": "contract IFaultDisputeGame",
"name": "_disputeGameFactory", "name": "",
"type": "address" "type": "address"
} }
], ],
"stateMutability": "nonpayable", "stateMutability": "view",
"type": "constructor" "type": "function"
}, },
{ {
"inputs": [ "inputs": [
...@@ -22,12 +29,12 @@ ...@@ -22,12 +29,12 @@
"outputs": [ "outputs": [
{ {
"internalType": "Hash", "internalType": "Hash",
"name": "root", "name": "",
"type": "bytes32" "type": "bytes32"
}, },
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "l2BlockNumber", "name": "",
"type": "uint256" "type": "uint256"
} }
], ],
...@@ -47,41 +54,57 @@ ...@@ -47,41 +54,57 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "getAnchorRoot",
"outputs": [
{
"internalType": "Hash",
"name": "",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{
"internalType": "contract ISuperchainConfig",
"name": "_superchainConfig",
"type": "address"
},
{
"internalType": "contract IDisputeGameFactory",
"name": "_disputeGameFactory",
"type": "address"
},
{
"internalType": "contract IOptimismPortal2",
"name": "_portal",
"type": "address"
},
{ {
"components": [ "components": [
{ {
"internalType": "GameType", "internalType": "Hash",
"name": "gameType", "name": "root",
"type": "uint32" "type": "bytes32"
}, },
{ {
"components": [ "internalType": "uint256",
{ "name": "l2BlockNumber",
"internalType": "Hash", "type": "uint256"
"name": "root",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "l2BlockNumber",
"type": "uint256"
}
],
"internalType": "struct OutputRoot",
"name": "outputRoot",
"type": "tuple"
} }
], ],
"internalType": "struct AnchorStateRegistry.StartingAnchorRoot[]", "internalType": "struct OutputRoot",
"name": "_startingAnchorRoots", "name": "_startingAnchorRoot",
"type": "tuple[]" "type": "tuple"
},
{
"internalType": "contract ISuperchainConfig",
"name": "_superchainConfig",
"type": "address"
} }
], ],
"name": "initialize", "name": "initialize",
...@@ -89,6 +112,114 @@ ...@@ -89,6 +112,114 @@
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "contract IDisputeGame",
"name": "_game",
"type": "address"
}
],
"name": "isGameBlacklisted",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract IDisputeGame",
"name": "_game",
"type": "address"
}
],
"name": "isGameProper",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract IDisputeGame",
"name": "_game",
"type": "address"
}
],
"name": "isGameRegistered",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract IDisputeGame",
"name": "_game",
"type": "address"
}
],
"name": "isGameRespected",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract IDisputeGame",
"name": "_game",
"type": "address"
}
],
"name": "isGameRetired",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "portal",
"outputs": [
{
"internalType": "contract IOptimismPortal2",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
...@@ -135,6 +266,32 @@ ...@@ -135,6 +266,32 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "contract IFaultDisputeGame",
"name": "game",
"type": "address"
}
],
"name": "AnchorNotUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "contract IFaultDisputeGame",
"name": "game",
"type": "address"
}
],
"name": "AnchorUpdated",
"type": "event"
},
{ {
"anonymous": false, "anonymous": false,
"inputs": [ "inputs": [
...@@ -150,17 +307,17 @@ ...@@ -150,17 +307,17 @@
}, },
{ {
"inputs": [], "inputs": [],
"name": "InvalidGameStatus", "name": "AnchorStateRegistry_ImproperAnchorGame",
"type": "error" "type": "error"
}, },
{ {
"inputs": [], "inputs": [],
"name": "Unauthorized", "name": "AnchorStateRegistry_InvalidAnchorGame",
"type": "error" "type": "error"
}, },
{ {
"inputs": [], "inputs": [],
"name": "UnregisteredGame", "name": "AnchorStateRegistry_Unauthorized",
"type": "error" "type": "error"
} }
] ]
\ No newline at end of file
...@@ -43,11 +43,6 @@ ...@@ -43,11 +43,6 @@
"name": "resolvedDelegateProxy", "name": "resolvedDelegateProxy",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "anchorStateRegistry",
"type": "address"
},
{ {
"internalType": "address", "internalType": "address",
"name": "permissionedDisputeGame1", "name": "permissionedDisputeGame1",
...@@ -110,6 +105,11 @@ ...@@ -110,6 +105,11 @@
"name": "disputeGameFactoryImpl", "name": "disputeGameFactoryImpl",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "anchorStateRegistryImpl",
"type": "address"
},
{ {
"internalType": "address", "internalType": "address",
"name": "delayedWETHImpl", "name": "delayedWETHImpl",
...@@ -271,11 +271,6 @@ ...@@ -271,11 +271,6 @@
"name": "resolvedDelegateProxy", "name": "resolvedDelegateProxy",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "anchorStateRegistry",
"type": "address"
},
{ {
"internalType": "address", "internalType": "address",
"name": "permissionedDisputeGame1", "name": "permissionedDisputeGame1",
...@@ -382,7 +377,7 @@ ...@@ -382,7 +377,7 @@
}, },
{ {
"internalType": "bytes", "internalType": "bytes",
"name": "startingAnchorRoots", "name": "startingAnchorRoot",
"type": "bytes" "type": "bytes"
}, },
{ {
...@@ -485,11 +480,6 @@ ...@@ -485,11 +480,6 @@
"name": "anchorStateRegistryProxy", "name": "anchorStateRegistryProxy",
"type": "address" "type": "address"
}, },
{
"internalType": "contract IAnchorStateRegistry",
"name": "anchorStateRegistryImpl",
"type": "address"
},
{ {
"internalType": "contract IFaultDisputeGame", "internalType": "contract IFaultDisputeGame",
"name": "faultDisputeGame", "name": "faultDisputeGame",
...@@ -560,6 +550,11 @@ ...@@ -560,6 +550,11 @@
"name": "disputeGameFactoryImpl", "name": "disputeGameFactoryImpl",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "anchorStateRegistryImpl",
"type": "address"
},
{ {
"internalType": "address", "internalType": "address",
"name": "delayedWETHImpl", "name": "delayedWETHImpl",
...@@ -732,7 +727,7 @@ ...@@ -732,7 +727,7 @@
}, },
{ {
"inputs": [], "inputs": [],
"name": "InvalidStartingAnchorRoots", "name": "InvalidStartingAnchorRoot",
"type": "error" "type": "error"
}, },
{ {
......
...@@ -43,11 +43,6 @@ ...@@ -43,11 +43,6 @@
"name": "resolvedDelegateProxy", "name": "resolvedDelegateProxy",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "anchorStateRegistry",
"type": "address"
},
{ {
"internalType": "address", "internalType": "address",
"name": "permissionedDisputeGame1", "name": "permissionedDisputeGame1",
...@@ -110,6 +105,11 @@ ...@@ -110,6 +105,11 @@
"name": "disputeGameFactoryImpl", "name": "disputeGameFactoryImpl",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "anchorStateRegistryImpl",
"type": "address"
},
{ {
"internalType": "address", "internalType": "address",
"name": "delayedWETHImpl", "name": "delayedWETHImpl",
...@@ -271,11 +271,6 @@ ...@@ -271,11 +271,6 @@
"name": "resolvedDelegateProxy", "name": "resolvedDelegateProxy",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "anchorStateRegistry",
"type": "address"
},
{ {
"internalType": "address", "internalType": "address",
"name": "permissionedDisputeGame1", "name": "permissionedDisputeGame1",
...@@ -382,7 +377,7 @@ ...@@ -382,7 +377,7 @@
}, },
{ {
"internalType": "bytes", "internalType": "bytes",
"name": "startingAnchorRoots", "name": "startingAnchorRoot",
"type": "bytes" "type": "bytes"
}, },
{ {
...@@ -485,11 +480,6 @@ ...@@ -485,11 +480,6 @@
"name": "anchorStateRegistryProxy", "name": "anchorStateRegistryProxy",
"type": "address" "type": "address"
}, },
{
"internalType": "contract IAnchorStateRegistry",
"name": "anchorStateRegistryImpl",
"type": "address"
},
{ {
"internalType": "contract IFaultDisputeGame", "internalType": "contract IFaultDisputeGame",
"name": "faultDisputeGame", "name": "faultDisputeGame",
...@@ -560,6 +550,11 @@ ...@@ -560,6 +550,11 @@
"name": "disputeGameFactoryImpl", "name": "disputeGameFactoryImpl",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "anchorStateRegistryImpl",
"type": "address"
},
{ {
"internalType": "address", "internalType": "address",
"name": "delayedWETHImpl", "name": "delayedWETHImpl",
...@@ -732,7 +727,7 @@ ...@@ -732,7 +727,7 @@
}, },
{ {
"inputs": [], "inputs": [],
"name": "InvalidStartingAnchorRoots", "name": "InvalidStartingAnchorRoot",
"type": "error" "type": "error"
}, },
{ {
......
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
"sourceCodeHash": "0x51f0876ab8410ce32838483f8f59ad6d1c5b4a368e47415b30e44baf291a394b" "sourceCodeHash": "0x51f0876ab8410ce32838483f8f59ad6d1c5b4a368e47415b30e44baf291a394b"
}, },
"src/L1/OPContractsManager.sol": { "src/L1/OPContractsManager.sol": {
"initCodeHash": "0x8bef0b53e7102491957d3ea12ff4857d735dada6af3ef122376bcf3f5489c9b9", "initCodeHash": "0x88a6d99e668340e3af5c728c29e94e7229d89da0762b4bbf93bc10e596795c9f",
"sourceCodeHash": "0x819e5e9867e09d16346daf81cfc9c129bf9026308055d1fbb6623b4f8818e613" "sourceCodeHash": "0x2d21506cc51ebe0b60bcf89883aff5e9b1269567ce44ee779de3d3940e23fb65"
}, },
"src/L1/OptimismPortal2.sol": { "src/L1/OptimismPortal2.sol": {
"initCodeHash": "0x2121a97875875150106a54a71c6c4c03afe90b3364e416be047f55fdeab57204", "initCodeHash": "0x2121a97875875150106a54a71c6c4c03afe90b3364e416be047f55fdeab57204",
...@@ -152,8 +152,8 @@ ...@@ -152,8 +152,8 @@
"sourceCodeHash": "0xb7b0a06cd971c4647247dc19ce997d0c64a73e87c81d30731da9cf9efa1b952a" "sourceCodeHash": "0xb7b0a06cd971c4647247dc19ce997d0c64a73e87c81d30731da9cf9efa1b952a"
}, },
"src/dispute/AnchorStateRegistry.sol": { "src/dispute/AnchorStateRegistry.sol": {
"initCodeHash": "0x2d831d6afc62df024eb2df22eaca3c7378171e63d87c608bb53c0020d30c3dee", "initCodeHash": "0xfbeeac40d86d13e71c7add66eef6357576a93b6a175c9cff6ec6ef587fe3acc4",
"sourceCodeHash": "0xf1ce12bed377624e43697ae316646493e8df73a064bc4e250936964448326a70" "sourceCodeHash": "0xbb2e08da74d470fc30dd35dc39834e19f676a45974aa2403eb97e84bc5bed0a8"
}, },
"src/dispute/DelayedWETH.sol": { "src/dispute/DelayedWETH.sol": {
"initCodeHash": "0x759d7f9c52b7c13ce4502f39dae3a75d130c6278240cde0b60ae84616aa2bd48", "initCodeHash": "0x759d7f9c52b7c13ce4502f39dae3a75d130c6278240cde0b60ae84616aa2bd48",
......
...@@ -14,17 +14,38 @@ ...@@ -14,17 +14,38 @@
"type": "bool" "type": "bool"
}, },
{ {
"bytes": "32", "bytes": "20",
"label": "anchors", "label": "superchainConfig",
"offset": 2,
"slot": "0",
"type": "contract ISuperchainConfig"
},
{
"bytes": "20",
"label": "disputeGameFactory",
"offset": 0, "offset": 0,
"slot": "1", "slot": "1",
"type": "mapping(GameType => struct OutputRoot)" "type": "contract IDisputeGameFactory"
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "superchainConfig", "label": "portal",
"offset": 0, "offset": 0,
"slot": "2", "slot": "2",
"type": "contract ISuperchainConfig" "type": "contract IOptimismPortal2"
},
{
"bytes": "20",
"label": "anchorGame",
"offset": 0,
"slot": "3",
"type": "contract IFaultDisputeGame"
},
{
"bytes": "64",
"label": "startingAnchorRoot",
"offset": 0,
"slot": "4",
"type": "struct OutputRoot"
} }
] ]
\ No newline at end of file
...@@ -7,17 +7,17 @@ ...@@ -7,17 +7,17 @@
"type": "string" "type": "string"
}, },
{ {
"bytes": "320", "bytes": "288",
"label": "blueprint", "label": "blueprint",
"offset": 0, "offset": 0,
"slot": "1", "slot": "1",
"type": "struct OPContractsManager.Blueprints" "type": "struct OPContractsManager.Blueprints"
}, },
{ {
"bytes": "288", "bytes": "320",
"label": "implementation", "label": "implementation",
"offset": 0, "offset": 0,
"slot": "11", "slot": "10",
"type": "struct OPContractsManager.Implementations" "type": "struct OPContractsManager.Implementations"
} }
] ]
\ No newline at end of file
...@@ -7,17 +7,17 @@ ...@@ -7,17 +7,17 @@
"type": "string" "type": "string"
}, },
{ {
"bytes": "320", "bytes": "288",
"label": "blueprint", "label": "blueprint",
"offset": 0, "offset": 0,
"slot": "1", "slot": "1",
"type": "struct OPContractsManager.Blueprints" "type": "struct OPContractsManager.Blueprints"
}, },
{ {
"bytes": "288", "bytes": "320",
"label": "implementation", "label": "implementation",
"offset": 0, "offset": 0,
"slot": "11", "slot": "10",
"type": "struct OPContractsManager.Implementations" "type": "struct OPContractsManager.Implementations"
} }
] ]
\ No newline at end of file
...@@ -5,7 +5,7 @@ pragma solidity 0.8.15; ...@@ -5,7 +5,7 @@ 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 { Bytes } from "src/libraries/Bytes.sol"; import { Bytes } from "src/libraries/Bytes.sol";
import { Claim, Duration, GameType, GameTypes } from "src/dispute/lib/Types.sol"; import { Claim, Duration, GameType, GameTypes, OutputRoot } from "src/dispute/lib/Types.sol";
// Interfaces // Interfaces
import { ISemver } from "interfaces/universal/ISemver.sol"; import { ISemver } from "interfaces/universal/ISemver.sol";
...@@ -18,7 +18,6 @@ import { IAddressManager } from "interfaces/legacy/IAddressManager.sol"; ...@@ -18,7 +18,6 @@ import { IAddressManager } from "interfaces/legacy/IAddressManager.sol";
import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol";
import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol"; import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol";
import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol"; import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol";
import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol";
import { IFaultDisputeGame } from "interfaces/dispute/IFaultDisputeGame.sol"; import { IFaultDisputeGame } from "interfaces/dispute/IFaultDisputeGame.sol";
import { IPermissionedDisputeGame } from "interfaces/dispute/IPermissionedDisputeGame.sol"; import { IPermissionedDisputeGame } from "interfaces/dispute/IPermissionedDisputeGame.sol";
import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol";
...@@ -49,9 +48,8 @@ contract OPContractsManager is ISemver { ...@@ -49,9 +48,8 @@ contract OPContractsManager is ISemver {
uint32 basefeeScalar; uint32 basefeeScalar;
uint32 blobBasefeeScalar; uint32 blobBasefeeScalar;
uint256 l2ChainId; uint256 l2ChainId;
// The correct type is AnchorStateRegistry.StartingAnchorRoot[] memory, // The correct type is OutputRoot memory but OP Deployer does not yet support structs.
// but OP Deployer does not yet support structs. bytes startingAnchorRoot;
bytes startingAnchorRoots;
// The salt mixer is used as part of making the resulting salt unique. // The salt mixer is used as part of making the resulting salt unique.
string saltMixer; string saltMixer;
uint64 gasLimit; uint64 gasLimit;
...@@ -77,7 +75,6 @@ contract OPContractsManager is ISemver { ...@@ -77,7 +75,6 @@ contract OPContractsManager is ISemver {
IOptimismPortal2 optimismPortalProxy; IOptimismPortal2 optimismPortalProxy;
IDisputeGameFactory disputeGameFactoryProxy; IDisputeGameFactory disputeGameFactoryProxy;
IAnchorStateRegistry anchorStateRegistryProxy; IAnchorStateRegistry anchorStateRegistryProxy;
IAnchorStateRegistry anchorStateRegistryImpl;
IFaultDisputeGame faultDisputeGame; IFaultDisputeGame faultDisputeGame;
IPermissionedDisputeGame permissionedDisputeGame; IPermissionedDisputeGame permissionedDisputeGame;
IDelayedWETH delayedWETHPermissionedGameProxy; IDelayedWETH delayedWETHPermissionedGameProxy;
...@@ -95,7 +92,6 @@ contract OPContractsManager is ISemver { ...@@ -95,7 +92,6 @@ contract OPContractsManager is ISemver {
address proxyAdmin; address proxyAdmin;
address l1ChugSplashProxy; address l1ChugSplashProxy;
address resolvedDelegateProxy; address resolvedDelegateProxy;
address anchorStateRegistry;
address permissionedDisputeGame1; address permissionedDisputeGame1;
address permissionedDisputeGame2; address permissionedDisputeGame2;
address permissionlessDisputeGame1; address permissionlessDisputeGame1;
...@@ -111,6 +107,7 @@ contract OPContractsManager is ISemver { ...@@ -111,6 +107,7 @@ contract OPContractsManager is ISemver {
address l1CrossDomainMessengerImpl; address l1CrossDomainMessengerImpl;
address l1StandardBridgeImpl; address l1StandardBridgeImpl;
address disputeGameFactoryImpl; address disputeGameFactoryImpl;
address anchorStateRegistryImpl;
address delayedWETHImpl; address delayedWETHImpl;
address mipsImpl; address mipsImpl;
} }
...@@ -138,8 +135,8 @@ contract OPContractsManager is ISemver { ...@@ -138,8 +135,8 @@ contract OPContractsManager is ISemver {
// -------- Constants and Variables -------- // -------- Constants and Variables --------
/// @custom:semver 1.0.0-beta.29 /// @custom:semver 1.0.0-beta.30
string public constant version = "1.0.0-beta.29"; string public constant version = "1.0.0-beta.30";
/// @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.
...@@ -198,8 +195,8 @@ contract OPContractsManager is ISemver { ...@@ -198,8 +195,8 @@ contract OPContractsManager is ISemver {
/// @notice Thrown when the latest release is not set upon initialization. /// @notice Thrown when the latest release is not set upon initialization.
error LatestReleaseNotSet(); error LatestReleaseNotSet();
/// @notice Thrown when the starting anchor roots are not provided. /// @notice Thrown when the starting anchor root is not provided.
error InvalidStartingAnchorRoots(); error InvalidStartingAnchorRoot();
/// @notice Thrown when certain methods are called outside of a DELEGATECALL. /// @notice Thrown when certain methods are called outside of a DELEGATECALL.
error OnlyDelegatecall(); error OnlyDelegatecall();
...@@ -293,15 +290,6 @@ contract OPContractsManager is ISemver { ...@@ -293,15 +290,6 @@ contract OPContractsManager is ISemver {
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.
// It must be deployed after the DisputeGameFactoryProxy so that it can be provided as a constructor argument.
output.anchorStateRegistryImpl = IAnchorStateRegistry(
Blueprint.deployFrom(
blueprint.anchorStateRegistry,
computeSalt(l2ChainId, saltMixer, "AnchorStateRegistry"),
abi.encode(output.disputeGameFactoryProxy)
)
);
// Eventually we will switch from DelayedWETHPermissionedGameProxy to DelayedWETHPermissionlessGameProxy. // Eventually we will switch from DelayedWETHPermissionedGameProxy to DelayedWETHPermissionlessGameProxy.
output.delayedWETHPermissionedGameProxy = IDelayedWETH( output.delayedWETHPermissionedGameProxy = IDelayedWETH(
...@@ -397,11 +385,11 @@ contract OPContractsManager is ISemver { ...@@ -397,11 +385,11 @@ contract OPContractsManager is ISemver {
); );
output.disputeGameFactoryProxy.transferOwnership(address(_input.roles.opChainProxyAdminOwner)); output.disputeGameFactoryProxy.transferOwnership(address(_input.roles.opChainProxyAdminOwner));
data = encodeAnchorStateRegistryInitializer(_input); data = encodeAnchorStateRegistryInitializer(_input, output);
upgradeAndCall( upgradeAndCall(
output.opChainProxyAdmin, output.opChainProxyAdmin,
address(output.anchorStateRegistryProxy), address(output.anchorStateRegistryProxy),
address(output.anchorStateRegistryImpl), implementation.anchorStateRegistryImpl,
data data
); );
...@@ -539,7 +527,7 @@ contract OPContractsManager is ISemver { ...@@ -539,7 +527,7 @@ contract OPContractsManager is ISemver {
if (_input.roles.proposer == address(0)) revert InvalidRoleAddress("proposer"); if (_input.roles.proposer == address(0)) revert InvalidRoleAddress("proposer");
if (_input.roles.challenger == address(0)) revert InvalidRoleAddress("challenger"); if (_input.roles.challenger == address(0)) revert InvalidRoleAddress("challenger");
if (_input.startingAnchorRoots.length == 0) revert InvalidStartingAnchorRoots(); if (_input.startingAnchorRoot.length == 0) revert InvalidStartingAnchorRoot();
} }
/// @notice Maps an L2 chain ID to an L1 batch inbox address as defined by the standard /// @notice Maps an L2 chain ID to an L1 batch inbox address as defined by the standard
...@@ -686,15 +674,20 @@ contract OPContractsManager is ISemver { ...@@ -686,15 +674,20 @@ contract OPContractsManager is ISemver {
return abi.encodeCall(IDisputeGameFactory.initialize, (address(this))); return abi.encodeCall(IDisputeGameFactory.initialize, (address(this)));
} }
function encodeAnchorStateRegistryInitializer(DeployInput memory _input) function encodeAnchorStateRegistryInitializer(
DeployInput memory _input,
DeployOutput memory _output
)
internal internal
view view
virtual virtual
returns (bytes memory) returns (bytes memory)
{ {
IAnchorStateRegistry.StartingAnchorRoot[] memory startingAnchorRoots = OutputRoot memory startingAnchorRoot = abi.decode(_input.startingAnchorRoot, (OutputRoot));
abi.decode(_input.startingAnchorRoots, (IAnchorStateRegistry.StartingAnchorRoot[])); return abi.encodeCall(
return abi.encodeCall(IAnchorStateRegistry.initialize, (startingAnchorRoots, superchainConfig)); IAnchorStateRegistry.initialize,
(superchainConfig, _output.disputeGameFactoryProxy, _output.optimismPortalProxy, startingAnchorRoot)
);
} }
function encodeDelayedWETHInitializer(DeployInput memory _input) internal view virtual returns (bytes memory) { function encodeDelayedWETHInitializer(DeployInput memory _input) internal view virtual returns (bytes memory) {
......
...@@ -127,13 +127,3 @@ error L2BlockNumberChallenged(); ...@@ -127,13 +127,3 @@ error L2BlockNumberChallenged();
/// @notice Thrown when an unauthorized address attempts to interact with the game. /// @notice Thrown when an unauthorized address attempts to interact with the game.
error BadAuth(); error BadAuth();
////////////////////////////////////////////////////////////////
// `AnchorStateRegistry` Errors //
////////////////////////////////////////////////////////////////
/// @notice Thrown when attempting to set an anchor state using an unregistered game.
error UnregisteredGame();
/// @notice Thrown when attempting to set an anchor state using an invalid game result.
error InvalidGameStatus();
...@@ -98,7 +98,7 @@ contract OPContractsManager_Deploy_Test is DeployOPChain_TestBase { ...@@ -98,7 +98,7 @@ contract OPContractsManager_Deploy_Test is DeployOPChain_TestBase {
basefeeScalar: _doi.basefeeScalar(), basefeeScalar: _doi.basefeeScalar(),
blobBasefeeScalar: _doi.blobBaseFeeScalar(), blobBasefeeScalar: _doi.blobBaseFeeScalar(),
l2ChainId: _doi.l2ChainId(), l2ChainId: _doi.l2ChainId(),
startingAnchorRoots: _doi.startingAnchorRoots(), startingAnchorRoot: _doi.startingAnchorRoot(),
saltMixer: _doi.saltMixer(), saltMixer: _doi.saltMixer(),
gasLimit: _doi.gasLimit(), gasLimit: _doi.gasLimit(),
disputeGameType: _doi.disputeGameType(), disputeGameType: _doi.disputeGameType(),
...@@ -184,7 +184,6 @@ contract OPContractsManager_AddGameType_Test is Test { ...@@ -184,7 +184,6 @@ contract OPContractsManager_AddGameType_Test is Test {
(blueprints.proxyAdmin,) = Blueprint.create(vm.getCode("ProxyAdmin"), salt); (blueprints.proxyAdmin,) = Blueprint.create(vm.getCode("ProxyAdmin"), salt);
(blueprints.l1ChugSplashProxy,) = Blueprint.create(vm.getCode("L1ChugSplashProxy"), salt); (blueprints.l1ChugSplashProxy,) = Blueprint.create(vm.getCode("L1ChugSplashProxy"), salt);
(blueprints.resolvedDelegateProxy,) = Blueprint.create(vm.getCode("ResolvedDelegateProxy"), salt); (blueprints.resolvedDelegateProxy,) = Blueprint.create(vm.getCode("ResolvedDelegateProxy"), salt);
(blueprints.anchorStateRegistry,) = Blueprint.create(vm.getCode("AnchorStateRegistry"), salt);
(blueprints.permissionedDisputeGame1, blueprints.permissionedDisputeGame2) = (blueprints.permissionedDisputeGame1, blueprints.permissionedDisputeGame2) =
Blueprint.create(vm.getCode("PermissionedDisputeGame"), salt); Blueprint.create(vm.getCode("PermissionedDisputeGame"), salt);
(blueprints.permissionlessDisputeGame1, blueprints.permissionlessDisputeGame2) = (blueprints.permissionlessDisputeGame1, blueprints.permissionlessDisputeGame2) =
...@@ -200,6 +199,7 @@ contract OPContractsManager_AddGameType_Test is Test { ...@@ -200,6 +199,7 @@ contract OPContractsManager_AddGameType_Test is Test {
l1CrossDomainMessengerImpl: address(new L1CrossDomainMessenger()), l1CrossDomainMessengerImpl: address(new L1CrossDomainMessenger()),
l1StandardBridgeImpl: address(new L1StandardBridge()), l1StandardBridgeImpl: address(new L1StandardBridge()),
disputeGameFactoryImpl: address(new DisputeGameFactory()), disputeGameFactoryImpl: address(new DisputeGameFactory()),
anchorStateRegistryImpl: address(new AnchorStateRegistry()),
delayedWETHImpl: address(new DelayedWETH(3)), delayedWETHImpl: address(new DelayedWETH(3)),
mipsImpl: address(new MIPS(oracle)) mipsImpl: address(new MIPS(oracle))
}); });
...@@ -209,12 +209,6 @@ contract OPContractsManager_AddGameType_Test is Test { ...@@ -209,12 +209,6 @@ contract OPContractsManager_AddGameType_Test is Test {
opcm = new OPContractsManager(superchainConfigProxy, protocolVersionsProxy, "dev", blueprints, impls); opcm = new OPContractsManager(superchainConfigProxy, protocolVersionsProxy, "dev", blueprints, impls);
AnchorStateRegistry.StartingAnchorRoot[] memory roots = new AnchorStateRegistry.StartingAnchorRoot[](1);
roots[0] = AnchorStateRegistry.StartingAnchorRoot({
outputRoot: OutputRoot({ root: Hash.wrap(hex"dead"), l2BlockNumber: 0 }),
gameType: GameType.wrap(1)
});
chainDeployOutput = opcm.deploy( chainDeployOutput = opcm.deploy(
OPContractsManager.DeployInput({ OPContractsManager.DeployInput({
roles: OPContractsManager.Roles({ roles: OPContractsManager.Roles({
...@@ -227,7 +221,7 @@ contract OPContractsManager_AddGameType_Test is Test { ...@@ -227,7 +221,7 @@ contract OPContractsManager_AddGameType_Test is Test {
}), }),
basefeeScalar: 1, basefeeScalar: 1,
blobBasefeeScalar: 1, blobBasefeeScalar: 1,
startingAnchorRoots: abi.encode(roots), startingAnchorRoot: abi.encode(OutputRoot({ root: Hash.wrap(hex"dead"), l2BlockNumber: 0 })),
l2ChainId: 100, l2ChainId: 100,
saltMixer: "hello", saltMixer: "hello",
gasLimit: 30_000_000, gasLimit: 30_000_000,
......
...@@ -8,6 +8,7 @@ import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol"; ...@@ -8,6 +8,7 @@ import { IDelayedWETH } from "interfaces/dispute/IDelayedWETH.sol";
import { IPreimageOracle } from "interfaces/cannon/IPreimageOracle.sol"; import { IPreimageOracle } from "interfaces/cannon/IPreimageOracle.sol";
import { IMIPS } from "interfaces/cannon/IMIPS.sol"; import { IMIPS } from "interfaces/cannon/IMIPS.sol";
import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol"; import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol";
import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol";
import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol";
import { IProtocolVersions } from "interfaces/L1/IProtocolVersions.sol"; import { IProtocolVersions } from "interfaces/L1/IProtocolVersions.sol";
...@@ -92,6 +93,7 @@ contract DeployImplementationsOutput_Test is Test { ...@@ -92,6 +93,7 @@ contract DeployImplementationsOutput_Test is Test {
IOptimismMintableERC20Factory optimismMintableERC20FactoryImpl = IOptimismMintableERC20Factory optimismMintableERC20FactoryImpl =
IOptimismMintableERC20Factory(makeAddr("optimismMintableERC20FactoryImpl")); IOptimismMintableERC20Factory(makeAddr("optimismMintableERC20FactoryImpl"));
IDisputeGameFactory disputeGameFactoryImpl = IDisputeGameFactory(makeAddr("disputeGameFactoryImpl")); IDisputeGameFactory disputeGameFactoryImpl = IDisputeGameFactory(makeAddr("disputeGameFactoryImpl"));
IAnchorStateRegistry anchorStateRegistryImpl = IAnchorStateRegistry(makeAddr("anchorStateRegistryImpl"));
vm.etch(address(opcm), hex"01"); vm.etch(address(opcm), hex"01");
vm.etch(address(optimismPortalImpl), hex"01"); vm.etch(address(optimismPortalImpl), hex"01");
...@@ -104,6 +106,7 @@ contract DeployImplementationsOutput_Test is Test { ...@@ -104,6 +106,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");
vm.etch(address(anchorStateRegistryImpl), hex"01");
dio.set(dio.opcm.selector, address(opcm)); 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));
...@@ -115,6 +118,7 @@ contract DeployImplementationsOutput_Test is Test { ...@@ -115,6 +118,7 @@ contract DeployImplementationsOutput_Test is Test {
dio.set(dio.l1StandardBridgeImpl.selector, address(l1StandardBridgeImpl)); dio.set(dio.l1StandardBridgeImpl.selector, address(l1StandardBridgeImpl));
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));
dio.set(dio.anchorStateRegistryImpl.selector, address(anchorStateRegistryImpl));
assertEq(address(opcm), address(dio.opcm()), "50"); assertEq(address(opcm), address(dio.opcm()), "50");
assertEq(address(optimismPortalImpl), address(dio.optimismPortalImpl()), "100"); assertEq(address(optimismPortalImpl), address(dio.optimismPortalImpl()), "100");
...@@ -127,6 +131,7 @@ contract DeployImplementationsOutput_Test is Test { ...@@ -127,6 +131,7 @@ contract DeployImplementationsOutput_Test is Test {
assertEq(address(l1StandardBridgeImpl), address(dio.l1StandardBridgeImpl()), "800"); assertEq(address(l1StandardBridgeImpl), address(dio.l1StandardBridgeImpl()), "800");
assertEq(address(optimismMintableERC20FactoryImpl), address(dio.optimismMintableERC20FactoryImpl()), "900"); assertEq(address(optimismMintableERC20FactoryImpl), address(dio.optimismMintableERC20FactoryImpl()), "900");
assertEq(address(disputeGameFactoryImpl), address(dio.disputeGameFactoryImpl()), "950"); assertEq(address(disputeGameFactoryImpl), address(dio.disputeGameFactoryImpl()), "950");
assertEq(address(anchorStateRegistryImpl), address(dio.anchorStateRegistryImpl()), "960");
} }
function test_getters_whenNotSet_reverts() public { function test_getters_whenNotSet_reverts() public {
...@@ -161,6 +166,9 @@ contract DeployImplementationsOutput_Test is Test { ...@@ -161,6 +166,9 @@ contract DeployImplementationsOutput_Test is Test {
vm.expectRevert(expectedErr); vm.expectRevert(expectedErr);
dio.disputeGameFactoryImpl(); dio.disputeGameFactoryImpl();
vm.expectRevert(expectedErr);
dio.anchorStateRegistryImpl();
} }
function test_getters_whenAddrHasNoCode_reverts() public { function test_getters_whenAddrHasNoCode_reverts() public {
...@@ -267,6 +275,7 @@ contract DeployImplementations_Test is Test { ...@@ -267,6 +275,7 @@ contract DeployImplementations_Test is Test {
deployImplementations.deployPreimageOracleSingleton(dii, dio); deployImplementations.deployPreimageOracleSingleton(dii, dio);
deployImplementations.deployMipsSingleton(dii, dio); deployImplementations.deployMipsSingleton(dii, dio);
deployImplementations.deployDisputeGameFactoryImpl(dio); deployImplementations.deployDisputeGameFactoryImpl(dio);
deployImplementations.deployAnchorStateRegistryImpl(dio);
deployImplementations.deployOPContractsManager(dii, dio); deployImplementations.deployOPContractsManager(dii, dio);
// Store the original addresses. // Store the original addresses.
...@@ -280,6 +289,7 @@ contract DeployImplementations_Test is Test { ...@@ -280,6 +289,7 @@ contract DeployImplementations_Test is Test {
address preimageOracleSingleton = address(dio.preimageOracleSingleton()); address preimageOracleSingleton = address(dio.preimageOracleSingleton());
address mipsSingleton = address(dio.mipsSingleton()); address mipsSingleton = address(dio.mipsSingleton());
address disputeGameFactoryImpl = address(dio.disputeGameFactoryImpl()); address disputeGameFactoryImpl = address(dio.disputeGameFactoryImpl());
address anchorStateRegistryImpl = address(dio.anchorStateRegistryImpl());
address opcm = address(dio.opcm()); address opcm = address(dio.opcm());
// Do the deployments again. Thi should be a noop. // Do the deployments again. Thi should be a noop.
...@@ -293,6 +303,7 @@ contract DeployImplementations_Test is Test { ...@@ -293,6 +303,7 @@ contract DeployImplementations_Test is Test {
deployImplementations.deployPreimageOracleSingleton(dii, dio); deployImplementations.deployPreimageOracleSingleton(dii, dio);
deployImplementations.deployMipsSingleton(dii, dio); deployImplementations.deployMipsSingleton(dii, dio);
deployImplementations.deployDisputeGameFactoryImpl(dio); deployImplementations.deployDisputeGameFactoryImpl(dio);
deployImplementations.deployAnchorStateRegistryImpl(dio);
deployImplementations.deployOPContractsManager(dii, dio); deployImplementations.deployOPContractsManager(dii, dio);
// Assert that the addresses did not change. // Assert that the addresses did not change.
...@@ -306,7 +317,8 @@ contract DeployImplementations_Test is Test { ...@@ -306,7 +317,8 @@ contract DeployImplementations_Test is Test {
assertEq(preimageOracleSingleton, address(dio.preimageOracleSingleton()), "800"); assertEq(preimageOracleSingleton, address(dio.preimageOracleSingleton()), "800");
assertEq(mipsSingleton, address(dio.mipsSingleton()), "900"); assertEq(mipsSingleton, address(dio.mipsSingleton()), "900");
assertEq(disputeGameFactoryImpl, address(dio.disputeGameFactoryImpl()), "1000"); assertEq(disputeGameFactoryImpl, address(dio.disputeGameFactoryImpl()), "1000");
assertEq(opcm, address(dio.opcm()), "1100"); assertEq(anchorStateRegistryImpl, address(dio.anchorStateRegistryImpl()), "1100");
assertEq(opcm, address(dio.opcm()), "1200");
} }
function testFuzz_run_memory_succeeds(bytes32 _seed) public { function testFuzz_run_memory_succeeds(bytes32 _seed) public {
......
...@@ -40,9 +40,6 @@ contract DeployOPCMInput_Test is Test { ...@@ -40,9 +40,6 @@ contract DeployOPCMInput_Test is Test {
vm.expectRevert("DeployOPCMInput: not set"); vm.expectRevert("DeployOPCMInput: not set");
dii.resolvedDelegateProxyBlueprint(); dii.resolvedDelegateProxyBlueprint();
vm.expectRevert("DeployOPCMInput: not set");
dii.anchorStateRegistryBlueprint();
vm.expectRevert("DeployOPCMInput: not set"); vm.expectRevert("DeployOPCMInput: not set");
dii.permissionedDisputeGame1Blueprint(); dii.permissionedDisputeGame1Blueprint();
...@@ -70,6 +67,9 @@ contract DeployOPCMInput_Test is Test { ...@@ -70,6 +67,9 @@ contract DeployOPCMInput_Test is Test {
vm.expectRevert("DeployOPCMInput: not set"); vm.expectRevert("DeployOPCMInput: not set");
dii.disputeGameFactoryImpl(); dii.disputeGameFactoryImpl();
vm.expectRevert("DeployOPCMInput: not set");
dii.anchorStateRegistryImpl();
vm.expectRevert("DeployOPCMInput: not set"); vm.expectRevert("DeployOPCMInput: not set");
dii.delayedWETHImpl(); dii.delayedWETHImpl();
...@@ -87,7 +87,6 @@ contract DeployOPCMInput_Test is Test { ...@@ -87,7 +87,6 @@ contract DeployOPCMInput_Test is Test {
address proxyAdminBlueprint = makeAddr("proxyAdminBlueprint"); address proxyAdminBlueprint = makeAddr("proxyAdminBlueprint");
address l1ChugSplashProxyBlueprint = makeAddr("l1ChugSplashProxyBlueprint"); address l1ChugSplashProxyBlueprint = makeAddr("l1ChugSplashProxyBlueprint");
address resolvedDelegateProxyBlueprint = makeAddr("resolvedDelegateProxyBlueprint"); address resolvedDelegateProxyBlueprint = makeAddr("resolvedDelegateProxyBlueprint");
address anchorStateRegistryBlueprint = makeAddr("anchorStateRegistryBlueprint");
address permissionedDisputeGame1Blueprint = makeAddr("permissionedDisputeGame1Blueprint"); address permissionedDisputeGame1Blueprint = makeAddr("permissionedDisputeGame1Blueprint");
address permissionedDisputeGame2Blueprint = makeAddr("permissionedDisputeGame2Blueprint"); address permissionedDisputeGame2Blueprint = makeAddr("permissionedDisputeGame2Blueprint");
...@@ -99,7 +98,6 @@ contract DeployOPCMInput_Test is Test { ...@@ -99,7 +98,6 @@ contract DeployOPCMInput_Test is Test {
dii.set(dii.proxyAdminBlueprint.selector, proxyAdminBlueprint); dii.set(dii.proxyAdminBlueprint.selector, proxyAdminBlueprint);
dii.set(dii.l1ChugSplashProxyBlueprint.selector, l1ChugSplashProxyBlueprint); dii.set(dii.l1ChugSplashProxyBlueprint.selector, l1ChugSplashProxyBlueprint);
dii.set(dii.resolvedDelegateProxyBlueprint.selector, resolvedDelegateProxyBlueprint); dii.set(dii.resolvedDelegateProxyBlueprint.selector, resolvedDelegateProxyBlueprint);
dii.set(dii.anchorStateRegistryBlueprint.selector, anchorStateRegistryBlueprint);
dii.set(dii.permissionedDisputeGame1Blueprint.selector, permissionedDisputeGame1Blueprint); dii.set(dii.permissionedDisputeGame1Blueprint.selector, permissionedDisputeGame1Blueprint);
dii.set(dii.permissionedDisputeGame2Blueprint.selector, permissionedDisputeGame2Blueprint); dii.set(dii.permissionedDisputeGame2Blueprint.selector, permissionedDisputeGame2Blueprint);
...@@ -111,7 +109,6 @@ contract DeployOPCMInput_Test is Test { ...@@ -111,7 +109,6 @@ contract DeployOPCMInput_Test is Test {
assertEq(dii.proxyAdminBlueprint(), proxyAdminBlueprint, "300"); assertEq(dii.proxyAdminBlueprint(), proxyAdminBlueprint, "300");
assertEq(dii.l1ChugSplashProxyBlueprint(), l1ChugSplashProxyBlueprint, "350"); assertEq(dii.l1ChugSplashProxyBlueprint(), l1ChugSplashProxyBlueprint, "350");
assertEq(dii.resolvedDelegateProxyBlueprint(), resolvedDelegateProxyBlueprint, "400"); assertEq(dii.resolvedDelegateProxyBlueprint(), resolvedDelegateProxyBlueprint, "400");
assertEq(dii.anchorStateRegistryBlueprint(), anchorStateRegistryBlueprint, "450");
assertEq(dii.permissionedDisputeGame1Blueprint(), permissionedDisputeGame1Blueprint, "500"); assertEq(dii.permissionedDisputeGame1Blueprint(), permissionedDisputeGame1Blueprint, "500");
assertEq(dii.permissionedDisputeGame2Blueprint(), permissionedDisputeGame2Blueprint, "550"); assertEq(dii.permissionedDisputeGame2Blueprint(), permissionedDisputeGame2Blueprint, "550");
} }
...@@ -124,6 +121,7 @@ contract DeployOPCMInput_Test is Test { ...@@ -124,6 +121,7 @@ contract DeployOPCMInput_Test is Test {
address l1CrossDomainMessengerImpl = makeAddr("l1CrossDomainMessengerImpl"); address l1CrossDomainMessengerImpl = makeAddr("l1CrossDomainMessengerImpl");
address l1StandardBridgeImpl = makeAddr("l1StandardBridgeImpl"); address l1StandardBridgeImpl = makeAddr("l1StandardBridgeImpl");
address disputeGameFactoryImpl = makeAddr("disputeGameFactoryImpl"); address disputeGameFactoryImpl = makeAddr("disputeGameFactoryImpl");
address anchorStateRegistryImpl = makeAddr("anchorStateRegistryImpl");
address delayedWETHImpl = makeAddr("delayedWETHImpl"); address delayedWETHImpl = makeAddr("delayedWETHImpl");
address mipsImpl = makeAddr("mipsImpl"); address mipsImpl = makeAddr("mipsImpl");
...@@ -134,6 +132,7 @@ contract DeployOPCMInput_Test is Test { ...@@ -134,6 +132,7 @@ contract DeployOPCMInput_Test is Test {
dii.set(dii.l1CrossDomainMessengerImpl.selector, l1CrossDomainMessengerImpl); dii.set(dii.l1CrossDomainMessengerImpl.selector, l1CrossDomainMessengerImpl);
dii.set(dii.l1StandardBridgeImpl.selector, l1StandardBridgeImpl); dii.set(dii.l1StandardBridgeImpl.selector, l1StandardBridgeImpl);
dii.set(dii.disputeGameFactoryImpl.selector, disputeGameFactoryImpl); dii.set(dii.disputeGameFactoryImpl.selector, disputeGameFactoryImpl);
dii.set(dii.anchorStateRegistryImpl.selector, anchorStateRegistryImpl);
dii.set(dii.delayedWETHImpl.selector, delayedWETHImpl); dii.set(dii.delayedWETHImpl.selector, delayedWETHImpl);
dii.set(dii.mipsImpl.selector, mipsImpl); dii.set(dii.mipsImpl.selector, mipsImpl);
...@@ -225,7 +224,6 @@ contract DeployOPCMTest is Test { ...@@ -225,7 +224,6 @@ contract DeployOPCMTest is Test {
doi.set(doi.proxyAdminBlueprint.selector, makeAddr("proxyAdminBlueprint")); doi.set(doi.proxyAdminBlueprint.selector, makeAddr("proxyAdminBlueprint"));
doi.set(doi.l1ChugSplashProxyBlueprint.selector, makeAddr("l1ChugSplashProxyBlueprint")); doi.set(doi.l1ChugSplashProxyBlueprint.selector, makeAddr("l1ChugSplashProxyBlueprint"));
doi.set(doi.resolvedDelegateProxyBlueprint.selector, makeAddr("resolvedDelegateProxyBlueprint")); doi.set(doi.resolvedDelegateProxyBlueprint.selector, makeAddr("resolvedDelegateProxyBlueprint"));
doi.set(doi.anchorStateRegistryBlueprint.selector, makeAddr("anchorStateRegistryBlueprint"));
doi.set(doi.permissionedDisputeGame1Blueprint.selector, makeAddr("permissionedDisputeGame1Blueprint")); doi.set(doi.permissionedDisputeGame1Blueprint.selector, makeAddr("permissionedDisputeGame1Blueprint"));
doi.set(doi.permissionedDisputeGame2Blueprint.selector, makeAddr("permissionedDisputeGame2Blueprint")); doi.set(doi.permissionedDisputeGame2Blueprint.selector, makeAddr("permissionedDisputeGame2Blueprint"));
...@@ -237,6 +235,7 @@ contract DeployOPCMTest is Test { ...@@ -237,6 +235,7 @@ contract DeployOPCMTest is Test {
doi.set(doi.l1CrossDomainMessengerImpl.selector, makeAddr("l1CrossDomainMessengerImpl")); doi.set(doi.l1CrossDomainMessengerImpl.selector, makeAddr("l1CrossDomainMessengerImpl"));
doi.set(doi.l1StandardBridgeImpl.selector, makeAddr("l1StandardBridgeImpl")); doi.set(doi.l1StandardBridgeImpl.selector, makeAddr("l1StandardBridgeImpl"));
doi.set(doi.disputeGameFactoryImpl.selector, makeAddr("disputeGameFactoryImpl")); doi.set(doi.disputeGameFactoryImpl.selector, makeAddr("disputeGameFactoryImpl"));
doi.set(doi.anchorStateRegistryImpl.selector, makeAddr("anchorStateRegistryImpl"));
doi.set(doi.delayedWETHImpl.selector, makeAddr("delayedWETHImpl")); doi.set(doi.delayedWETHImpl.selector, makeAddr("delayedWETHImpl"));
doi.set(doi.mipsImpl.selector, makeAddr("mipsImpl")); doi.set(doi.mipsImpl.selector, makeAddr("mipsImpl"));
...@@ -249,7 +248,6 @@ contract DeployOPCMTest is Test { ...@@ -249,7 +248,6 @@ contract DeployOPCMTest is Test {
vm.etch(doi.proxyAdminBlueprint(), hex"01"); vm.etch(doi.proxyAdminBlueprint(), hex"01");
vm.etch(doi.l1ChugSplashProxyBlueprint(), hex"01"); vm.etch(doi.l1ChugSplashProxyBlueprint(), hex"01");
vm.etch(doi.resolvedDelegateProxyBlueprint(), hex"01"); vm.etch(doi.resolvedDelegateProxyBlueprint(), hex"01");
vm.etch(doi.anchorStateRegistryBlueprint(), hex"01");
vm.etch(doi.permissionedDisputeGame1Blueprint(), hex"01"); vm.etch(doi.permissionedDisputeGame1Blueprint(), hex"01");
vm.etch(doi.permissionedDisputeGame2Blueprint(), hex"01"); vm.etch(doi.permissionedDisputeGame2Blueprint(), hex"01");
......
...@@ -155,7 +155,6 @@ contract DeployOPChainOutput_Test is Test { ...@@ -155,7 +155,6 @@ contract DeployOPChainOutput_Test is Test {
doo.set(doo.optimismPortalProxy.selector, address(optimismPortalProxy)); doo.set(doo.optimismPortalProxy.selector, address(optimismPortalProxy));
doo.set(doo.disputeGameFactoryProxy.selector, address(disputeGameFactoryProxy)); doo.set(doo.disputeGameFactoryProxy.selector, address(disputeGameFactoryProxy));
doo.set(doo.anchorStateRegistryProxy.selector, address(anchorStateRegistryProxy)); doo.set(doo.anchorStateRegistryProxy.selector, address(anchorStateRegistryProxy));
doo.set(doo.anchorStateRegistryImpl.selector, address(anchorStateRegistryImpl));
doo.set(doo.faultDisputeGame.selector, address(faultDisputeGame)); doo.set(doo.faultDisputeGame.selector, address(faultDisputeGame));
doo.set(doo.permissionedDisputeGame.selector, address(permissionedDisputeGame)); doo.set(doo.permissionedDisputeGame.selector, address(permissionedDisputeGame));
doo.set(doo.delayedWETHPermissionedGameProxy.selector, address(delayedWETHPermissionedGameProxy)); doo.set(doo.delayedWETHPermissionedGameProxy.selector, address(delayedWETHPermissionedGameProxy));
...@@ -172,7 +171,6 @@ contract DeployOPChainOutput_Test is Test { ...@@ -172,7 +171,6 @@ contract DeployOPChainOutput_Test is Test {
assertEq(address(optimismPortalProxy), address(doo.optimismPortalProxy()), "800"); assertEq(address(optimismPortalProxy), address(doo.optimismPortalProxy()), "800");
assertEq(address(disputeGameFactoryProxy), address(doo.disputeGameFactoryProxy()), "900"); assertEq(address(disputeGameFactoryProxy), address(doo.disputeGameFactoryProxy()), "900");
assertEq(address(anchorStateRegistryProxy), address(doo.anchorStateRegistryProxy()), "1100"); assertEq(address(anchorStateRegistryProxy), address(doo.anchorStateRegistryProxy()), "1100");
assertEq(address(anchorStateRegistryImpl), address(doo.anchorStateRegistryImpl()), "1200");
assertEq(address(faultDisputeGame), address(doo.faultDisputeGame()), "1300"); assertEq(address(faultDisputeGame), address(doo.faultDisputeGame()), "1300");
assertEq(address(permissionedDisputeGame), address(doo.permissionedDisputeGame()), "1400"); assertEq(address(permissionedDisputeGame), address(doo.permissionedDisputeGame()), "1400");
assertEq(address(delayedWETHPermissionedGameProxy), address(doo.delayedWETHPermissionedGameProxy()), "1500"); assertEq(address(delayedWETHPermissionedGameProxy), address(doo.delayedWETHPermissionedGameProxy()), "1500");
...@@ -214,9 +212,6 @@ contract DeployOPChainOutput_Test is Test { ...@@ -214,9 +212,6 @@ contract DeployOPChainOutput_Test is Test {
vm.expectRevert(expectedErr); vm.expectRevert(expectedErr);
doo.anchorStateRegistryProxy(); doo.anchorStateRegistryProxy();
vm.expectRevert(expectedErr);
doo.anchorStateRegistryImpl();
vm.expectRevert(expectedErr); vm.expectRevert(expectedErr);
doo.faultDisputeGame(); doo.faultDisputeGame();
...@@ -275,10 +270,6 @@ contract DeployOPChainOutput_Test is Test { ...@@ -275,10 +270,6 @@ contract DeployOPChainOutput_Test is Test {
vm.expectRevert(expectedErr); vm.expectRevert(expectedErr);
doo.anchorStateRegistryProxy(); doo.anchorStateRegistryProxy();
doo.set(doo.anchorStateRegistryImpl.selector, emptyAddr);
vm.expectRevert(expectedErr);
doo.anchorStateRegistryImpl();
doo.set(doo.faultDisputeGame.selector, emptyAddr); doo.set(doo.faultDisputeGame.selector, emptyAddr);
vm.expectRevert(expectedErr); vm.expectRevert(expectedErr);
doo.faultDisputeGame(); doo.faultDisputeGame();
...@@ -336,7 +327,7 @@ contract DeployOPChain_TestBase is Test { ...@@ -336,7 +327,7 @@ contract DeployOPChain_TestBase is Test {
uint32 basefeeScalar = 100; uint32 basefeeScalar = 100;
uint32 blobBaseFeeScalar = 200; uint32 blobBaseFeeScalar = 200;
uint256 l2ChainId = 300; uint256 l2ChainId = 300;
IAnchorStateRegistry.StartingAnchorRoot[] startingAnchorRoots; OutputRoot startingAnchorRoot = OutputRoot({ root: Hash.wrap(keccak256("defaultOutputRoot")), l2BlockNumber: 400 });
OPContractsManager opcm = OPContractsManager(address(0)); OPContractsManager opcm = OPContractsManager(address(0));
string saltMixer = "defaultSaltMixer"; string saltMixer = "defaultSaltMixer";
uint64 gasLimit = 60_000_000; uint64 gasLimit = 60_000_000;
...@@ -349,25 +340,6 @@ contract DeployOPChain_TestBase is Test { ...@@ -349,25 +340,6 @@ contract DeployOPChain_TestBase is Test {
uint64 disputeMaxClockDuration = Duration.unwrap(Duration.wrap(3.5 days)); uint64 disputeMaxClockDuration = Duration.unwrap(Duration.wrap(3.5 days));
function setUp() public virtual { function setUp() public virtual {
// Set defaults for reference types
uint256 cannonBlock = 400;
uint256 permissionedBlock = 500;
startingAnchorRoots.push(
IAnchorStateRegistry.StartingAnchorRoot({
gameType: GameTypes.CANNON,
outputRoot: OutputRoot({ root: Hash.wrap(keccak256("defaultOutputRootCannon")), l2BlockNumber: cannonBlock })
})
);
startingAnchorRoots.push(
IAnchorStateRegistry.StartingAnchorRoot({
gameType: GameTypes.PERMISSIONED_CANNON,
outputRoot: OutputRoot({
root: Hash.wrap(keccak256("defaultOutputRootPermissioned")),
l2BlockNumber: permissionedBlock
})
})
);
// Configure and deploy Superchain contracts // Configure and deploy Superchain contracts
DeploySuperchain deploySuperchain = new DeploySuperchain(); DeploySuperchain deploySuperchain = new DeploySuperchain();
(DeploySuperchainInput dsi, DeploySuperchainOutput dso) = deploySuperchain.etchIOContracts(); (DeploySuperchainInput dsi, DeploySuperchainOutput dso) = deploySuperchain.etchIOContracts();
...@@ -432,25 +404,6 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { ...@@ -432,25 +404,6 @@ contract DeployOPChain_Test is DeployOPChain_TestBase {
blobBaseFeeScalar = uint32(uint256(hash(_seed, 7))); blobBaseFeeScalar = uint32(uint256(hash(_seed, 7)));
l2ChainId = uint256(hash(_seed, 8)); l2ChainId = uint256(hash(_seed, 8));
// Set the initial anchor states. The typical usage we expect is to pass in one root per game type.
uint256 cannonBlock = uint256(hash(_seed, 9));
uint256 permissionedBlock = uint256(hash(_seed, 10));
startingAnchorRoots.push(
IAnchorStateRegistry.StartingAnchorRoot({
gameType: GameTypes.CANNON,
outputRoot: OutputRoot({ root: Hash.wrap(keccak256(abi.encode(_seed, 11))), l2BlockNumber: cannonBlock })
})
);
startingAnchorRoots.push(
IAnchorStateRegistry.StartingAnchorRoot({
gameType: GameTypes.PERMISSIONED_CANNON,
outputRoot: OutputRoot({
root: Hash.wrap(keccak256(abi.encode(_seed, 12))),
l2BlockNumber: permissionedBlock
})
})
);
doi.set(doi.opChainProxyAdminOwner.selector, opChainProxyAdminOwner); doi.set(doi.opChainProxyAdminOwner.selector, opChainProxyAdminOwner);
doi.set(doi.systemConfigOwner.selector, systemConfigOwner); doi.set(doi.systemConfigOwner.selector, systemConfigOwner);
doi.set(doi.batcher.selector, batcher); doi.set(doi.batcher.selector, batcher);
......
...@@ -554,11 +554,19 @@ contract Specification_Test is CommonTest { ...@@ -554,11 +554,19 @@ contract Specification_Test is CommonTest {
// AnchorStateRegistry // AnchorStateRegistry
_addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("anchors(uint32)") }); _addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("anchors(uint32)") });
_addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("getAnchorRoot()") });
_addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("disputeGameFactory()") }); _addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("disputeGameFactory()") });
_addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("initialize((uint32,(bytes32,uint256))[],address)") }); _addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("portal()") });
_addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("anchorGame()") });
_addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("initialize(address,address,address,(bytes32,uint256))") });
_addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("tryUpdateAnchorState()") }); _addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("tryUpdateAnchorState()") });
_addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("setAnchorState(address)"), _auth: Role.GUARDIAN }); _addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("setAnchorState(address)"), _auth: Role.GUARDIAN });
_addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("version()") }); _addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("version()") });
_addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("isGameRegistered(address)") });
_addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("isGameRespected(address)") });
_addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("isGameBlacklisted(address)") });
_addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("isGameRetired(address)") });
_addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("isGameProper(address)") });
_addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("superchainConfig()") }); _addSpec({ _name: "AnchorStateRegistry", _sel: _getSel("superchainConfig()") });
// PermissionedDisputeGame // PermissionedDisputeGame
......
...@@ -10,15 +10,16 @@ import { Process } from "scripts/libraries/Process.sol"; ...@@ -10,15 +10,16 @@ import { Process } from "scripts/libraries/Process.sol";
// Libraries // Libraries
import { LibString } from "@solady/utils/LibString.sol"; import { LibString } from "@solady/utils/LibString.sol";
import { GameType } from "src/dispute/lib/Types.sol"; import { GameType, Hash, OutputRoot } from "src/dispute/lib/Types.sol";
import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
// Interfaces // Interfaces
import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol";
import { IResourceMetering } from "interfaces/L1/IResourceMetering.sol"; import { IResourceMetering } from "interfaces/L1/IResourceMetering.sol";
import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol";
import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol";
import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol";
import { ProtocolVersion } from "interfaces/L1/IProtocolVersions.sol"; import { ProtocolVersion } from "interfaces/L1/IProtocolVersions.sol";
import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol";
/// @title Initializer_Test /// @title Initializer_Test
/// @dev Ensures that the `initialize()` function on contracts cannot be called more than /// @dev Ensures that the `initialize()` function on contracts cannot be called more than
...@@ -318,7 +319,12 @@ contract Initializer_Test is CommonTest { ...@@ -318,7 +319,12 @@ contract Initializer_Test is CommonTest {
target: EIP1967Helper.getImplementation(address(anchorStateRegistry)), target: EIP1967Helper.getImplementation(address(anchorStateRegistry)),
initCalldata: abi.encodeCall( initCalldata: abi.encodeCall(
anchorStateRegistry.initialize, anchorStateRegistry.initialize,
(new IAnchorStateRegistry.StartingAnchorRoot[](1), ISuperchainConfig(address(0))) (
ISuperchainConfig(address(0)),
IDisputeGameFactory(address(0)),
IOptimismPortal2(payable(0)),
OutputRoot({ root: Hash.wrap(bytes32(0)), l2BlockNumber: 0 })
)
) )
}) })
); );
...@@ -329,7 +335,12 @@ contract Initializer_Test is CommonTest { ...@@ -329,7 +335,12 @@ contract Initializer_Test is CommonTest {
target: address(anchorStateRegistry), target: address(anchorStateRegistry),
initCalldata: abi.encodeCall( initCalldata: abi.encodeCall(
anchorStateRegistry.initialize, anchorStateRegistry.initialize,
(new IAnchorStateRegistry.StartingAnchorRoot[](1), ISuperchainConfig(address(0))) (
ISuperchainConfig(address(0)),
IDisputeGameFactory(address(0)),
IOptimismPortal2(payable(0)),
OutputRoot({ root: Hash.wrap(bytes32(0)), l2BlockNumber: 0 })
)
) )
}) })
); );
......
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