Commit 71036728 authored by Wyatt Barnes's avatar Wyatt Barnes Committed by GitHub

L2 genesis generation updates (#8285)

parent c2cb2344
......@@ -26,6 +26,16 @@ const (
SchemaRegistry = "0x4200000000000000000000000000000000000020"
EAS = "0x4200000000000000000000000000000000000021"
Create2Deployer = "0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2"
MultiCall3 = "0xcA11bde05977b3631167028862bE2a173976CA11"
Safe_v130 = "0x69f4D1788e39c87893C980c06EdF4b7f686e2938"
SafeL2_v130 = "0xfb1bffC9d739B8D520DaF37dF666da4C687191EA"
MultiSendCallOnly_v130 = "0xA1dabEF33b3B82c7814B6D82A79e50F4AC44102B"
SafeSingletonFactory = "0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7"
DeterministicDeploymentProxy = "0x4e59b44847b379578588920cA78FbF26c0B4956C"
MultiSend_v130 = "0x998739BFdAAdde7C933B942a68053933098f9EDa"
Permit2 = "0x000000000022D473030F116dDEE9F6B43aC78BA3"
SenderCreator = "0x7fc98430eaedbb6070b35b39d798725049088348"
EntryPoint = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"
)
var (
......@@ -49,6 +59,16 @@ var (
SchemaRegistryAddr = common.HexToAddress(SchemaRegistry)
EASAddr = common.HexToAddress(EAS)
Create2DeployerAddr = common.HexToAddress(Create2Deployer)
MultiCall3Addr = common.HexToAddress(MultiCall3)
Safe_v130Addr = common.HexToAddress(Safe_v130)
SafeL2_v130Addr = common.HexToAddress(SafeL2_v130)
MultiSendCallOnly_v130Addr = common.HexToAddress(MultiSendCallOnly_v130)
SafeSingletonFactoryAddr = common.HexToAddress(SafeSingletonFactory)
DeterministicDeploymentProxyAddr = common.HexToAddress(DeterministicDeploymentProxy)
MultiSend_v130Addr = common.HexToAddress(MultiSend_v130)
Permit2Addr = common.HexToAddress(Permit2)
SenderCreatorAddr = common.HexToAddress(SenderCreator)
EntryPointAddr = common.HexToAddress(EntryPoint)
Predeploys = make(map[string]*Predeploy)
PredeploysByAddress = make(map[common.Address]*Predeploy)
......@@ -83,10 +103,46 @@ func init() {
Predeploys["Create2Deployer"] = &Predeploy{
Address: Create2DeployerAddr,
ProxyDisabled: true,
Enabled: func(config DeployConfig) bool {
canyonTime := config.CanyonTime(0)
return canyonTime != nil && *canyonTime == 0
},
}
Predeploys["MultiCall3"] = &Predeploy{
Address: MultiCall3Addr,
ProxyDisabled: true,
}
Predeploys["Safe_v130"] = &Predeploy{
Address: Safe_v130Addr,
ProxyDisabled: true,
}
Predeploys["SafeL2_v130"] = &Predeploy{
Address: SafeL2_v130Addr,
ProxyDisabled: true,
}
Predeploys["MultiSendCallOnly_v130"] = &Predeploy{
Address: MultiSendCallOnly_v130Addr,
ProxyDisabled: true,
}
Predeploys["SafeSingletonFactory"] = &Predeploy{
Address: SafeSingletonFactoryAddr,
ProxyDisabled: true,
}
Predeploys["DeterministicDeploymentProxy"] = &Predeploy{
Address: DeterministicDeploymentProxyAddr,
ProxyDisabled: true,
}
Predeploys["MultiSend_v130"] = &Predeploy{
Address: MultiSend_v130Addr,
ProxyDisabled: true,
}
Predeploys["Permit2"] = &Predeploy{
Address: Permit2Addr,
ProxyDisabled: true,
}
Predeploys["SenderCreator"] = &Predeploy{
Address: SenderCreatorAddr,
ProxyDisabled: true,
}
Predeploys["EntryPoint"] = &Predeploy{
Address: EntryPointAddr,
ProxyDisabled: true,
}
for _, predeploy := range Predeploys {
......
......@@ -15,7 +15,9 @@ import (
"github.com/urfave/cli/v2"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
......@@ -276,6 +278,127 @@ func checkPredeployConfig(client *ethclient.Client, name string) error {
if err := checkEAS(p, client); err != nil {
return fmt.Errorf("EAS: %w", err)
}
case predeploys.Create2DeployerAddr:
bytecode, err := bindings.GetDeployedBytecode("Create2Deployer")
if err != nil {
return err
}
if err := checkPredeployBytecode(p, client, bytecode); err != nil {
return fmt.Errorf("Create2Deployer :%w", err)
}
case predeploys.MultiCall3Addr:
bytecode, err := bindings.GetDeployedBytecode("MultiCall3")
if err != nil {
return err
}
if err := checkPredeployBytecode(p, client, bytecode); err != nil {
return fmt.Errorf("MultiCall3 :%w", err)
}
case predeploys.Safe_v130Addr:
bytecode, err := bindings.GetDeployedBytecode("Safe_v130")
if err != nil {
return err
}
if err := checkPredeployBytecode(p, client, bytecode); err != nil {
return fmt.Errorf("Safe_v130 :%w", err)
}
case predeploys.SafeL2_v130Addr:
bytecode, err := bindings.GetDeployedBytecode("SafeL2_v130")
if err != nil {
return err
}
if err := checkPredeployBytecode(p, client, bytecode); err != nil {
return fmt.Errorf("SafeL2_v130 :%w", err)
}
case predeploys.MultiSendCallOnly_v130Addr:
bytecode, err := bindings.GetDeployedBytecode("MultiSendCallOnly_v130")
if err != nil {
return err
}
if err := checkPredeployBytecode(p, client, bytecode); err != nil {
return fmt.Errorf("MultiSendCallOnly_v130 :%w", err)
}
case predeploys.SafeSingletonFactoryAddr:
bytecode, err := bindings.GetDeployedBytecode("SafeSingletonFactory")
if err != nil {
return err
}
if err := checkPredeployBytecode(p, client, bytecode); err != nil {
return fmt.Errorf("SafeSingletonFactory :%w", err)
}
case predeploys.DeterministicDeploymentProxyAddr:
bytecode, err := bindings.GetDeployedBytecode("DeterministicDeploymentProxy")
if err != nil {
return err
}
if err := checkPredeployBytecode(p, client, bytecode); err != nil {
return fmt.Errorf("DeterministicDeploymentProxy :%w", err)
}
case predeploys.MultiSend_v130Addr:
bytecode, err := bindings.GetDeployedBytecode("MultiSend_v130")
if err != nil {
return err
}
if err := checkPredeployBytecode(p, client, bytecode); err != nil {
return fmt.Errorf("MultiSend_v130 :%w", err)
}
case predeploys.Permit2Addr:
const domainABI = `[{"inputs":[{"name":"typeHash","type":"bytes32"},{"name":"nameHash","type":"bytes32"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"name":"EIP712Domain","outputs":[],"stateMutability":"nonpayable","type":"constructor"}]`
parsedABI, err := abi.JSON(strings.NewReader(domainABI))
if err != nil {
return fmt.Errorf("Permit2 failed to parse ABI: %w", err)
}
typeHash := crypto.Keccak256Hash([]byte("EIP712Domain(string name,uint256 chainId,address verifyingContract)"))
nameHash := crypto.Keccak256Hash([]byte("Permit2"))
chainId, err := client.ChainID(context.Background())
if err != nil {
return fmt.Errorf("Permit2: %w", err)
}
data, err := parsedABI.Constructor.Inputs.Pack(typeHash, nameHash, chainId, predeploys.Predeploys["Permit2"].Address)
if err != nil {
return fmt.Errorf("Permit2: %w", err)
}
calculatedDomainSeparator := crypto.Keccak256Hash(data)
permit2Caller, err := bindings.NewPermit2Caller(predeploys.Predeploys["Permit2"].Address, client)
if err != nil {
return fmt.Errorf("Permit2: %w", err)
}
retrievedDomainSeparator, err := permit2Caller.DOMAINSEPARATOR(&bind.CallOpts{})
if err != nil {
return fmt.Errorf("Permit2: %w", err)
}
if [32]byte(calculatedDomainSeparator.Bytes()) != retrievedDomainSeparator {
return fmt.Errorf("Permit2: EIP-712 domain separators don't match")
}
case predeploys.SenderCreatorAddr:
bytecode, err := bindings.GetDeployedBytecode("SenderCreator")
if err != nil {
return err
}
if err := checkPredeployBytecode(p, client, bytecode); err != nil {
return fmt.Errorf("SenderCreator :%w", err)
}
case predeploys.EntryPointAddr:
bytecode, err := bindings.GetDeployedBytecode("EntryPoint")
if err != nil {
return err
}
if err := checkPredeployBytecode(p, client, bytecode); err != nil {
return fmt.Errorf("EntryPoint :%w", err)
}
}
return nil
})
......@@ -847,6 +970,17 @@ func checkEAS(addr common.Address, client *ethclient.Client) error {
return nil
}
func checkPredeployBytecode(addr common.Address, client *ethclient.Client, expectedBytecode []byte) error {
code, err := client.CodeAt(context.Background(), addr, nil)
if err != nil {
return err
}
if !bytes.Equal(code, expectedBytecode) {
return fmt.Errorf("deployed bytecode at %s, doesn't match expected", addr)
}
return nil
}
func getEIP1967AdminAddress(client *ethclient.Client, addr common.Address) (common.Address, error) {
slot, err := client.StorageAt(context.Background(), addr, genesis.AdminSlot, nil)
if err != nil {
......
......@@ -2,9 +2,11 @@ package deployer
import (
"context"
"errors"
"fmt"
"math/big"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
......@@ -47,19 +49,28 @@ type Deployer func(*backends.SimulatedBackend, *bind.TransactOpts, Constructor)
// NewL1Backend returns a SimulatedBackend suitable for L1. It has
// the latest L1 hardforks enabled.
func NewL1Backend() *backends.SimulatedBackend {
return NewBackendWithGenesisTimestamp(0, true)
func NewL1Backend() (*backends.SimulatedBackend, error) {
backend, err := NewBackendWithGenesisTimestamp(ChainID, 0, true, nil)
return backend, err
}
// NewL2Backend returns a SimulatedBackend suitable for L2.
// It has the latest L2 hardforks enabled.
func NewL2Backend() *backends.SimulatedBackend {
return NewBackendWithGenesisTimestamp(0, false)
func NewL2Backend() (*backends.SimulatedBackend, error) {
backend, err := NewBackendWithGenesisTimestamp(ChainID, 0, false, nil)
return backend, err
}
func NewBackendWithGenesisTimestamp(ts uint64, shanghai bool) *backends.SimulatedBackend {
// NewL2BackendWithChainIDAndPredeploys returns a SimulatedBackend suitable for L2.
// It has the latest L2 hardforks enabled, and allows for the configuration of the network's chain ID and predeploys.
func NewL2BackendWithChainIDAndPredeploys(chainID *big.Int, predeploys map[string]*common.Address) (*backends.SimulatedBackend, error) {
backend, err := NewBackendWithGenesisTimestamp(chainID, 0, false, predeploys)
return backend, err
}
func NewBackendWithGenesisTimestamp(chainID *big.Int, ts uint64, shanghai bool, predeploys map[string]*common.Address) (*backends.SimulatedBackend, error) {
chainConfig := params.ChainConfig{
ChainID: ChainID,
ChainID: chainID,
HomesteadBlock: big.NewInt(0),
DAOForkBlock: nil,
DAOForkSupport: false,
......@@ -75,8 +86,6 @@ func NewBackendWithGenesisTimestamp(ts uint64, shanghai bool) *backends.Simulate
LondonBlock: big.NewInt(0),
ArrowGlacierBlock: big.NewInt(0),
GrayGlacierBlock: big.NewInt(0),
ShanghaiTime: nil,
CancunTime: nil,
// Activated proof of stake. We manually build/commit blocks in the simulator anyway,
// and the timestamp verification of PoS is not against the wallclock,
// preventing blocks from getting stuck temporarily in the future-blocks queue, decreasing setup time a lot.
......@@ -89,6 +98,21 @@ func NewBackendWithGenesisTimestamp(ts uint64, shanghai bool) *backends.Simulate
chainConfig.ShanghaiTime = u64ptr(0)
}
alloc := core.GenesisAlloc{
crypto.PubkeyToAddress(TestKey.PublicKey): core.GenesisAccount{
Balance: thousandETH,
},
}
for name, address := range predeploys {
bytecode, err := bindings.GetDeployedBytecode(name)
if err != nil {
return nil, err
}
alloc[*address] = core.GenesisAccount{
Code: bytecode,
}
}
return backends.NewSimulatedBackendWithOpts(
backends.WithCacheConfig(&core.CacheConfig{
Preimages: true,
......@@ -97,13 +121,11 @@ func NewBackendWithGenesisTimestamp(ts uint64, shanghai bool) *backends.Simulate
Config: &chainConfig,
Timestamp: ts,
Difficulty: big.NewInt(0),
Alloc: core.GenesisAlloc{
crypto.PubkeyToAddress(TestKey.PublicKey): {Balance: thousandETH},
},
GasLimit: 15000000,
Alloc: alloc,
GasLimit: 30_000_000,
}),
backends.WithConsensus(beacon.New(ethash.NewFaker())),
)
), nil
}
func Deploy(backend *backends.SimulatedBackend, constructors []Constructor, cb Deployer) ([]Deployment, error) {
......@@ -152,6 +174,95 @@ func Deploy(backend *backends.SimulatedBackend, constructors []Constructor, cb D
return results, nil
}
// DeployWithDeterministicDeployer deploys a smart contract on a simulated Ethereum blockchain using a deterministic deployment proxy (Arachnid's).
//
// Parameters:
// - backend: A pointer to backends.SimulatedBackend, representing the simulated Ethereum blockchain.
// Expected to have Arachnid's proxy deployer predeploys at 0x4e59b44847b379578588920cA78FbF26c0B4956C, NewL2BackendWithChainIDAndPredeploys handles this for you.
// - contractName: A string representing the name of the contract to be deployed.
//
// Returns:
// - []byte: The deployed bytecode of the contract.
// - error: An error object indicating any issues encountered during the deployment process.
//
// The function logs a fatal error and exits if there are any issues with transaction mining, if the deployment fails,
// or if the deployed bytecode is not found at the computed address.
func DeployWithDeterministicDeployer(backend *backends.SimulatedBackend, contractName string) ([]byte, error) {
opts, err := bind.NewKeyedTransactorWithChainID(TestKey, backend.Blockchain().Config().ChainID)
if err != nil {
return nil, err
}
deployerAddress, err := bindings.GetDeployerAddress(contractName)
if err != nil {
return nil, err
}
deploymentSalt, err := bindings.GetDeploymentSalt(contractName)
if err != nil {
return nil, err
}
initBytecode, err := bindings.GetInitBytecode(contractName)
if err != nil {
return nil, err
}
transactor, err := bindings.NewDeterministicDeploymentProxyTransactor(common.BytesToAddress(deployerAddress), backend)
if err != nil {
return nil, fmt.Errorf("failed to initialize deployment proxy transactor at %s: %w", deployerAddress, err)
}
tx, err := transactor.Fallback(opts, append(deploymentSalt, initBytecode...))
if err != nil {
return nil, err
}
backend.Commit()
receipt, err := bind.WaitMined(context.Background(), backend, tx)
if err != nil {
return nil, fmt.Errorf("failed to get transaction receipt: %w", err)
}
if receipt.Status == 0 {
return nil, errors.New("failed to deploy contract using proxy deployer")
}
address := create2Address(
deployerAddress,
deploymentSalt,
initBytecode,
)
code, _ := backend.CodeAt(context.Background(), address, nil)
if len(code) == 0 {
return nil, fmt.Errorf("no code found for %s at: %s", contractName, address)
}
return code, nil
}
func u64ptr(n uint64) *uint64 {
return &n
}
// create2Address computes the Ethereum address for a contract created using the CREATE2 opcode.
//
// The CREATE2 opcode allows for more deterministic address generation in Ethereum, as it computes the
// address based on the creator's address, a salt value, and the contract's initialization code.
//
// Parameters:
// - creatorAddress: A byte slice representing the address of the account creating the contract.
// - salt: A byte slice representing the salt used in the address generation process. This can be any 32-byte value.
// - initCode: A byte slice representing the contract's initialization bytecode.
//
// Returns:
// - common.Address: The Ethereum address calculated using the CREATE2 opcode logic.
func create2Address(creatorAddress, salt, initCode []byte) common.Address {
payload := append([]byte{0xff}, creatorAddress...)
payload = append(payload, salt...)
initCodeHash := crypto.Keccak256(initCode)
payload = append(payload, initCodeHash...)
return common.BytesToAddress(crypto.Keccak256(payload)[12:])
}
package deployer
import (
"testing"
"github.com/ethereum/go-ethereum/common"
)
func TestCreate2Address(t *testing.T) {
tests := []struct {
name string
creatorAddress []byte
salt []byte
initCode []byte
expectedAddress common.Address
}{
{
name: "SafeL2",
creatorAddress: common.HexToAddress("0x4e59b44847b379578588920cA78FbF26c0B4956C").Bytes(),
salt: common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000"),
expectedAddress: common.HexToAddress("0x3E5c63644E683549055b9Be8653de26E0B4CD36E"),
},
{
name: "MultiSendCallOnly",
creatorAddress: common.HexToAddress("0x4e59b44847b379578588920cA78FbF26c0B4956C").Bytes(),
salt: common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000"),
expectedAddress: common.HexToAddress("0x40A2aCCbd92BCA938b02010E17A5b8929b49130D"),
},
{
name: "MultiSend",
creatorAddress: common.HexToAddress("0x4e59b44847b379578588920cA78FbF26c0B4956C").Bytes(),
salt: common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000"),
expectedAddress: common.HexToAddress("0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761"),
},
{
name: "Permit2",
creatorAddress: common.HexToAddress("0x4e59b44847b379578588920cA78FbF26c0B4956C").Bytes(),
salt: common.Hex2Bytes("0000000000000000000000000000000000000000d3af2663da51c10215000000"),
expectedAddress: common.HexToAddress("0x000000000022D473030F116dDEE9F6B43aC78BA3"),
},
{
name: "EntryPoint",
creatorAddress: common.HexToAddress("0x4e59b44847b379578588920cA78FbF26c0B4956C").Bytes(),
salt: common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000"),
expectedAddress: common.HexToAddress("0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"),
},
}
for _, test := range tests {
var err error
test.initCode, err = getInitCode(test.name)
if err != nil {
t.Error(err)
}
t.Run(test.name, func(t *testing.T) {
if got := create2Address(test.creatorAddress, test.salt, test.initCode); got != test.expectedAddress {
t.Errorf("expected: %x, want: %x", got, test.expectedAddress)
}
})
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -2,12 +2,16 @@ package genesis
import (
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/deployer"
"github.com/ethereum-optimism/optimism/op-chain-ops/immutables"
"github.com/ethereum-optimism/optimism/op-chain-ops/state"
"github.com/ethereum-optimism/optimism/op-service/eth"
......@@ -54,18 +58,51 @@ func BuildL2Genesis(config *DeployConfig, l1StartBlock *types.Block) (*core.Gene
log.Warn("Skipping disabled predeploy.", "name", name, "address", predeploy.Address)
continue
}
codeAddr := predeploy.Address
if !predeploy.ProxyDisabled {
codeAddr, err = AddressToCodeNamespace(predeploy.Address)
switch name {
case "Permit2":
deployerAddressBytes, err := bindings.GetDeployerAddress(name)
if err != nil {
return nil, err
}
deployerAddress := common.BytesToAddress(deployerAddressBytes)
predeploys := map[string]*common.Address{
"DeterministicDeploymentProxy": &deployerAddress,
}
backend, err := deployer.NewL2BackendWithChainIDAndPredeploys(
new(big.Int).SetUint64(config.L2ChainID),
predeploys,
)
if err != nil {
return nil, err
}
deployedBin, err := deployer.DeployWithDeterministicDeployer(backend, name)
if err != nil {
return nil, fmt.Errorf("error converting to code namespace: %w", err)
return nil, err
}
deployResults[name] = deployedBin
fallthrough
case "MultiCall3", "Create2Deployer", "Safe_v130",
"SafeL2_v130", "MultiSendCallOnly_v130", "SafeSingletonFactory",
"DeterministicDeploymentProxy", "MultiSend_v130", "SenderCreator", "EntryPoint":
db.CreateAccount(codeAddr)
db.SetState(predeploy.Address, ImplementationSlot, eth.AddressAsLeftPaddedHash(codeAddr))
log.Info("Set proxy", "name", name, "address", predeploy.Address, "implementation", codeAddr)
} else if db.Exist(predeploy.Address) {
default:
if !predeploy.ProxyDisabled {
codeAddr, err = AddressToCodeNamespace(predeploy.Address)
if err != nil {
return nil, fmt.Errorf("error converting to code namespace: %w", err)
}
db.CreateAccount(codeAddr)
db.SetState(predeploy.Address, ImplementationSlot, eth.AddressAsLeftPaddedHash(codeAddr))
log.Info("Set proxy", "name", name, "address", predeploy.Address, "implementation", codeAddr)
}
}
if predeploy.ProxyDisabled && db.Exist(predeploy.Address) {
db.DeleteState(predeploy.Address, AdminSlot)
}
if err := setupPredeploy(db, deployResults, storage, name, predeploy.Address, codeAddr); err != nil {
return nil, err
}
......
......@@ -90,7 +90,7 @@ func TestBuildL2MainnetGenesis(t *testing.T) {
config.EnableGovernance = true
config.FundDevAccounts = false
gen := testBuildL2Genesis(t, config)
require.Equal(t, 2323, len(gen.Alloc))
require.Equal(t, 2333, len(gen.Alloc))
}
func TestBuildL2MainnetNoGovernanceGenesis(t *testing.T) {
......@@ -99,5 +99,5 @@ func TestBuildL2MainnetNoGovernanceGenesis(t *testing.T) {
config.EnableGovernance = false
config.FundDevAccounts = false
gen := testBuildL2Genesis(t, config)
require.Equal(t, 2323, len(gen.Alloc))
require.Equal(t, 2333, len(gen.Alloc))
}
......@@ -67,7 +67,17 @@ type PredeploysImmutableConfig struct {
EAS struct {
Name string
}
Create2Deployer struct{}
Create2Deployer struct{}
MultiCall3 struct{}
Safe_v130 struct{}
SafeL2_v130 struct{}
MultiSendCallOnly_v130 struct{}
SafeSingletonFactory struct{}
DeterministicDeploymentProxy struct{}
MultiSend_v130 struct{}
Permit2 struct{}
SenderCreator struct{}
EntryPoint struct{}
}
// Check will ensure that the required fields are set on the config.
......@@ -163,7 +173,11 @@ func Deploy(config *PredeploysImmutableConfig) (DeploymentResults, error) {
// can be properly set. The bytecode returned in the results is suitable to be
// inserted into the state via state surgery.
func deployContractsWithImmutables(constructors []deployer.Constructor) (DeploymentResults, error) {
deployments, err := deployer.Deploy(deployer.NewL2Backend(), constructors, l2ImmutableDeployer)
backend, err := deployer.NewL2Backend()
if err != nil {
return nil, err
}
deployments, err := deployer.Deploy(backend, constructors, l2ImmutableDeployer)
if err != nil {
return nil, err
}
......
......@@ -84,7 +84,17 @@ func TestBuildOptimism(t *testing.T) {
EAS: struct{ Name string }{
Name: "EAS",
},
Create2Deployer: struct{}{},
Create2Deployer: struct{}{},
MultiCall3: struct{}{},
Safe_v130: struct{}{},
SafeL2_v130: struct{}{},
MultiSendCallOnly_v130: struct{}{},
SafeSingletonFactory: struct{}{},
DeterministicDeploymentProxy: struct{}{},
MultiSend_v130: struct{}{},
Permit2: struct{}{},
SenderCreator: struct{}{},
EntryPoint: struct{}{},
}
require.NoError(t, cfg.Check())
......
......@@ -77,4 +77,37 @@ library Predeploys {
/// @notice Address of the EAS predeploy.
address internal constant EAS = 0x4200000000000000000000000000000000000021;
/// @notice Address of the MultiCall3 predeploy.
address internal constant MultiCall3 = 0xcA11bde05977b3631167028862bE2a173976CA11;
/// @notice Address of the Create2Deployer predeploy.
address internal constant Create2Deployer = 0xF49600926c7109BD66Ab97a2c036bf696e58Dbc2;
/// @notice Address of the Safe_v130 predeploy.
address internal constant Safe_v130 = 0x69f4D1788e39c87893C980c06EdF4b7f686e2938;
/// @notice Address of the SafeL2_v130 predeploy.
address internal constant SafeL2_v130 = 0xfb1bffC9d739B8D520DaF37dF666da4C687191EA;
/// @notice Address of the MultiSendCallOnly_v130 predeploy.
address internal constant MultiSendCallOnly_v130 = 0xA1dabEF33b3B82c7814B6D82A79e50F4AC44102B;
/// @notice Address of the SafeSingletonFactory predeploy.
address internal constant SafeSingletonFactory = 0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7;
/// @notice Address of the DeterministicDeploymentProxy predeploy.
address internal constant DeterministicDeploymentProxy = 0x4e59b44847b379578588920cA78FbF26c0B4956C;
/// @notice Address of the MultiSend_v130 predeploy.
address internal constant MultiSend_v130 = 0x998739BFdAAdde7C933B942a68053933098f9EDa;
/// @notice Address of the Permit2 predeploy.
address internal constant Permit2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;
/// @notice Address of the SenderCreator predeploy.
address internal constant SenderCreator = 0x7fc98430eAEdbb6070B35B39D798725049088348;
/// @notice Address of the EntryPoint predeploy.
address internal constant EntryPoint = 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789;
}
......@@ -16,8 +16,14 @@ contract PredeploysTest is CommonTest {
bytes memory code = addr.code;
assertTrue(code.length > 0);
// Skip the accounts that do not have a proxy
if (addr == Predeploys.LEGACY_ERC20_ETH || addr == Predeploys.GOVERNANCE_TOKEN || addr == Predeploys.WETH9)
{
if (
addr == Predeploys.LEGACY_ERC20_ETH || addr == Predeploys.GOVERNANCE_TOKEN || addr == Predeploys.WETH9
|| addr == Predeploys.MultiCall3 || addr == Predeploys.Create2Deployer || addr == Predeploys.Safe_v130
|| addr == Predeploys.SafeL2_v130 || addr == Predeploys.MultiSendCallOnly_v130
|| addr == Predeploys.SafeSingletonFactory || addr == Predeploys.DeterministicDeploymentProxy
|| addr == Predeploys.MultiSend_v130 || addr == Predeploys.Permit2 || addr == Predeploys.SenderCreator
|| addr == Predeploys.EntryPoint
) {
continue;
}
assertTrue(EIP1967Helper.getAdmin(addr) == Predeploys.PROXY_ADMIN, "Admin mismatch");
......
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