Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions op-bindings/hardhat/hardhat.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package hardhat

import (
"encoding/json"
"errors"
"fmt"
"io/fs"
"os"
Expand All @@ -12,6 +13,11 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)

var (
ErrCannotFindDeployment = errors.New("cannot find deployment")
ErrCannotFindArtifact = errors.New("cannot find artifact")
)

// `Hardhat` encapsulates all of the functionality required to interact
// with hardhat style artifacts.
type Hardhat struct {
Expand Down Expand Up @@ -163,7 +169,7 @@ func (h *Hardhat) GetArtifact(name string) (*Artifact, error) {
return artifact, nil
}
}
return nil, fmt.Errorf("cannot find artifact %s", name)
return nil, fmt.Errorf("%w: %s", ErrCannotFindArtifact, name)
}

for _, artifact := range h.artifacts {
Expand All @@ -172,7 +178,7 @@ func (h *Hardhat) GetArtifact(name string) (*Artifact, error) {
}
}

return nil, fmt.Errorf("cannot find artifact %s", name)
return nil, fmt.Errorf("%w: %s", ErrCannotFindArtifact, name)
}

// GetDeployment returns the deployment that corresponds to the contract.
Expand All @@ -188,7 +194,7 @@ func (h *Hardhat) GetDeployment(name string) (*Deployment, error) {
}
}

return nil, fmt.Errorf("cannot find deployment %s", name)
return nil, fmt.Errorf("%w: %s", ErrCannotFindDeployment, name)
}

// GetBuildInfo returns the build info that corresponds to the contract.
Expand Down
22 changes: 10 additions & 12 deletions op-chain-ops/cmd/migrate/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,25 +143,23 @@ func main() {
return err
}

// Get the addresses from the hardhat deploy artifacts
l1StandardBridgeProxyDeployment, err := hh.GetDeployment("Proxy__OVM_L1StandardBridge")
if err != nil {
return err
}
l1CrossDomainMessengerProxyDeployment, err := hh.GetDeployment("Proxy__OVM_L1CrossdomainMessenger")
if err != nil {
// Read the required deployment addresses from disk if required
if err := config.GetDeployedAddresses(hh); err != nil {
return err
}
l1ERC721BridgeProxyDeployment, err := hh.GetDeployment("L1ERC721BridgeProxy")
if err != nil {

if err := config.Check(); err != nil {
return err
}

l2Addrs := genesis.L2Addresses{
ProxyAdminOwner: config.ProxyAdminOwner,
L1StandardBridgeProxy: l1StandardBridgeProxyDeployment.Address,
L1CrossDomainMessengerProxy: l1CrossDomainMessengerProxyDeployment.Address,
L1ERC721BridgeProxy: l1ERC721BridgeProxyDeployment.Address,
L1StandardBridgeProxy: config.L1StandardBridgeProxy,
L1CrossDomainMessengerProxy: config.L1CrossDomainMessengerProxy,
L1ERC721BridgeProxy: config.L1ERC721BridgeProxy,
BaseFeeVaultRecipient: config.BaseFeeVaultRecipient,
L1FeeVaultRecipient: config.L1FeeVaultRecipient,
SequencerFeeVaultRecipient: config.SequencerFeeVaultRecipient,
}

dryRun := ctx.Bool("dry-run")
Expand Down
174 changes: 171 additions & 3 deletions op-chain-ops/genesis/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc"

"github.com/ethereum-optimism/optimism/op-bindings/hardhat"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/immutables"
"github.com/ethereum-optimism/optimism/op-chain-ops/state"
)

var ErrInvalidDeployConfig = errors.New("invalid deploy config")

// DeployConfig represents the deployment configuration for Optimism
type DeployConfig struct {
L1StartingBlockTag *rpc.BlockNumberOrHash `json:"l1StartingBlockTag"`
Expand Down Expand Up @@ -65,10 +69,26 @@ type DeployConfig struct {
L2GenesisBlockParentHash common.Hash `json:"l2GenesisBlockParentHash"`
L2GenesisBlockBaseFeePerGas *hexutil.Big `json:"l2GenesisBlockBaseFeePerGas"`

ProxyAdminOwner common.Address `json:"proxyAdminOwner"`
// Owner of the ProxyAdmin predeploy
ProxyAdminOwner common.Address `json:"proxyAdminOwner"`
// Owner of the L1CrossDomainMessenger predeploy
L2CrossDomainMessengerOwner common.Address `json:"l2CrossDomainMessengerOwner"`
OptimismBaseFeeRecipient common.Address `json:"optimismBaseFeeRecipient"`
OptimismL1FeeRecipient common.Address `json:"optimismL1FeeRecipient"`
// L1 recipient of fees accumulated in the BaseFeeVault
BaseFeeVaultRecipient common.Address `json:"baseFeeVaultRecipient"`
// L1 recipient of fees accumulated in the L1FeeVault
L1FeeVaultRecipient common.Address `json:"l1FeeVaultRecipient"`
// L1 recipient of fees accumulated in the SequencerFeeVault
SequencerFeeVaultRecipient common.Address `json:"sequencerFeeVaultRecipient"`
// L1StandardBridge proxy address on L1
L1StandardBridgeProxy common.Address `json:"l1StandardBridgeProxy"`
// L1CrossDomainMessenger proxy address on L1
L1CrossDomainMessengerProxy common.Address `json:"l1CrossDomainMessengerProxy"`
// L1ERC721Bridge proxy address on L1
L1ERC721BridgeProxy common.Address `json:"l1ERC721BridgeProxy"`
// SystemConfig proxy address on L1
SystemConfigProxy common.Address `json:"systemConfigProxy"`
// OptimismPortal proxy address on L1
OptimismPortalProxy common.Address `json:"optimismPortalProxy"`

GasPriceOracleOverhead uint64 `json:"gasPriceOracleOverhead"`
GasPriceOracleScalar uint64 `json:"gasPriceOracleScalar"`
Expand All @@ -81,6 +101,154 @@ type DeployConfig struct {
FundDevAccounts bool `json:"fundDevAccounts"`
}

// Check will ensure that the config is sane and return an error when it is not
func (d *DeployConfig) Check() error {
if d.L1ChainID == 0 {
return fmt.Errorf("%w: L1ChainID cannot be 0", ErrInvalidDeployConfig)
}
if d.L2ChainID == 0 {
return fmt.Errorf("%w: L2ChainID cannot be 0", ErrInvalidDeployConfig)
}
if d.L2BlockTime == 0 {
return fmt.Errorf("%w: L2BlockTime cannot be 0", ErrInvalidDeployConfig)
}
if d.FinalizationPeriodSeconds == 0 {
return fmt.Errorf("%w: FinalizationPeriodSeconds cannot be 0", ErrInvalidDeployConfig)
}
if d.MaxSequencerDrift == 0 {
return fmt.Errorf("%w: MaxSequencerDrift cannot be 0", ErrInvalidDeployConfig)
}
if d.SequencerWindowSize == 0 {
return fmt.Errorf("%w: SequencerWindowSize cannot be 0", ErrInvalidDeployConfig)
}
if d.ChannelTimeout == 0 {
return fmt.Errorf("%w: ChannelTimeout cannot be 0", ErrInvalidDeployConfig)
}
if d.P2PSequencerAddress == (common.Address{}) {
return fmt.Errorf("%w: P2PSequencerAddress cannot be address(0)", ErrInvalidDeployConfig)
}
if d.BatchInboxAddress == (common.Address{}) {
return fmt.Errorf("%w: BatchInboxAddress cannot be address(0)", ErrInvalidDeployConfig)
}
if d.BatchSenderAddress == (common.Address{}) {
return fmt.Errorf("%w: BatchSenderAddress cannot be address(0)", ErrInvalidDeployConfig)
}
if d.L2OutputOracleSubmissionInterval == 0 {
return fmt.Errorf("%w: L2OutputOracleSubmissionInterval cannot be 0", ErrInvalidDeployConfig)
}
if d.L2OutputOracleStartingTimestamp == 0 {
log.Warn("L2OutputOracleStartingTimestamp is 0")
}
if d.L2OutputOracleProposer == (common.Address{}) {
return fmt.Errorf("%w: L2OutputOracleProposer cannot be address(0)", ErrInvalidDeployConfig)
}
if d.L2OutputOracleOwner == (common.Address{}) {
return fmt.Errorf("%w: L2OutputOracleOwner cannot be address(0)", ErrInvalidDeployConfig)
}
if d.L2OutputOracleGenesisL2Output == (common.Hash{}) {
log.Warn("L2OutputOracleGenesisL2Output is bytes32(0)")
}
if d.SystemConfigOwner == (common.Address{}) {
return fmt.Errorf("%w: SystemConfigOwner cannot be address(0)", ErrInvalidDeployConfig)
}
if d.ProxyAdminOwner == (common.Address{}) {
return fmt.Errorf("%w: ProxyAdminOwner cannot be address(0)", ErrInvalidDeployConfig)
}
if d.L2CrossDomainMessengerOwner == (common.Address{}) {
return fmt.Errorf("%w: L2CrossDomainMessengerOwner cannot be address(0)", ErrInvalidDeployConfig)
}
if d.BaseFeeVaultRecipient == (common.Address{}) {
log.Warn("BaseFeeVaultRecipient is address(0)")
}
if d.L1FeeVaultRecipient == (common.Address{}) {
log.Warn("L1FeeVaultRecipient is address(0)")
}
if d.SequencerFeeVaultRecipient == (common.Address{}) {
log.Warn("SequencerFeeVaultRecipient is address(0)")
}
if d.GasPriceOracleOverhead == 0 {
log.Warn("GasPriceOracleOverhead is 0")
}
if d.GasPriceOracleScalar == 0 {
log.Warn("GasPriceOracleScalar is address(0)")
}
if d.L1StandardBridgeProxy == (common.Address{}) {
log.Warn("L1StandardBridgeProxy is address(0)")
}
if d.L1CrossDomainMessengerProxy == (common.Address{}) {
log.Warn("L1CrossDomainMessengerProxy is address(0)")
}
if d.L1ERC721BridgeProxy == (common.Address{}) {
log.Warn("L1ERC721BridgeProxy is address(0)")
}
if d.SystemConfigProxy == (common.Address{}) {
log.Warn("SystemConfigProxy is address(0)")
}
if d.OptimismPortalProxy == (common.Address{}) {
log.Warn("OptimismPortalProxy is address(0)")
}
return nil
}

// GetDeployedAddresses will get the deployed addresses of deployed L1 contracts
// required for the L2 genesis creation. Legacy systems use the `Proxy__` prefix
// while modern systems use the `Proxy` suffix. First check for the legacy
// deployments so that this works with upgrading a system.
func (d *DeployConfig) GetDeployedAddresses(hh *hardhat.Hardhat) error {
var err error

if d.L1StandardBridgeProxy == (common.Address{}) {
var l1StandardBridgeProxyDeployment *hardhat.Deployment
l1StandardBridgeProxyDeployment, err = hh.GetDeployment("Proxy__OVM_L1StandardBridge")
if errors.Is(err, hardhat.ErrCannotFindDeployment) {
l1StandardBridgeProxyDeployment, err = hh.GetDeployment("L1StandardBridgeProxy")
if err != nil {
return err
}
}
d.L1StandardBridgeProxy = l1StandardBridgeProxyDeployment.Address
}

if d.L1CrossDomainMessengerProxy == (common.Address{}) {
var l1CrossDomainMessengerProxyDeployment *hardhat.Deployment
l1CrossDomainMessengerProxyDeployment, err = hh.GetDeployment("Proxy__OVM_L1CrossdomainMessenger")
if errors.Is(err, hardhat.ErrCannotFindDeployment) {
l1CrossDomainMessengerProxyDeployment, err = hh.GetDeployment("L1CrossDomainMessengerProxy")
if err != nil {
return err
}
}
d.L1CrossDomainMessengerProxy = l1CrossDomainMessengerProxyDeployment.Address
}

if d.L1ERC721BridgeProxy == (common.Address{}) {
// There is no legacy deployment of this contract
l1ERC721BridgeProxyDeployment, err := hh.GetDeployment("L1ERC721BridgeProxy")
if err != nil {
return err
}
d.L1ERC721BridgeProxy = l1ERC721BridgeProxyDeployment.Address
}

if d.SystemConfigProxy == (common.Address{}) {
systemConfigProxyDeployment, err := hh.GetDeployment("SystemConfigProxy")
if err != nil {
return err
}
d.SystemConfigProxy = systemConfigProxyDeployment.Address
}

if d.OptimismPortalProxy == (common.Address{}) {
optimismPortalProxyDeployment, err := hh.GetDeployment("OptimismPortalProxy")
if err != nil {
return err
}
d.OptimismPortalProxy = optimismPortalProxyDeployment.Address
}

return nil
}

// NewDeployConfig reads a config file given a path on the filesystem.
func NewDeployConfig(path string) (*DeployConfig, error) {
file, err := os.ReadFile(path)
Expand Down
13 changes: 8 additions & 5 deletions op-chain-ops/genesis/layer_two.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ type L2Addresses struct {
L1FeeVaultRecipient common.Address
// BaseFeeVaultRecipient represents the L1 address that the BaseFeeVault can withdraw to
BaseFeeVaultRecipient common.Address
// SystemConfigProxy represents the L1 contract address of the SystemConfigProxy
SystemConfigProxy common.Address
}

// BuildL2DeveloperGenesis will build the developer Optimism Genesis
Expand All @@ -46,14 +48,15 @@ func BuildL2DeveloperGenesis(config *DeployConfig, l1StartBlock *types.Block, l2
// Use the known developer addresses if they are not set
if l2Addrs == nil {
l2Addrs = &L2Addresses{
// Hardcoded address corresponds to m/44'/60'/0'/0/1 in the 'test test... junk' mnemonic
ProxyAdminOwner: common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"),
L1StandardBridgeProxy: predeploys.DevL1StandardBridgeAddr,
L1CrossDomainMessengerProxy: predeploys.DevL1CrossDomainMessengerAddr,
L1ERC721BridgeProxy: predeploys.DevL1ERC721BridgeAddr,
SequencerFeeVaultRecipient: common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"),
L1FeeVaultRecipient: common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"),
BaseFeeVaultRecipient: common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"),
SystemConfigProxy: predeploys.DevSystemConfigAddr,
// Hardcoded address corresponds to m/44'/60'/0'/0/1 in the 'test test... junk' mnemonic
ProxyAdminOwner: common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"),
SequencerFeeVaultRecipient: common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"),
L1FeeVaultRecipient: common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"),
BaseFeeVaultRecipient: common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
"l1BlockTime": 15,
"cliqueSignerAddress": "0xca062b0fd91172d89bcd4bb084ac4e21972cc467",

"optimismBaseFeeRecipient": "0xBcd4042DE499D14e55001CcbB24a551F3b954096",
"optimismL1FeeRecipient": "0x71bE63f3384f5fb98995898A86B02Fb2426c5788",
"baseFeeVaultRecipient": "0xBcd4042DE499D14e55001CcbB24a551F3b954096",
"l1FeeVaultRecipient": "0x71bE63f3384f5fb98995898A86B02Fb2426c5788",
"sequencerFeeVaultRecipient": "0x71bE63f3384f5fb98995898A86B02Fb2426c5788",

"deploymentWaitConfirmations": 1,
"fundDevAccounts": true
Expand Down
10 changes: 8 additions & 2 deletions op-chain-ops/genesis/testdata/test-deploy-config-full.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,15 @@
"l2GenesisBlockGasUsed": "0x0",
"l2GenesisBlockParentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"l2GenesisBlockBaseFeePerGas": "0x3b9aca00",
"optimismBaseFeeRecipient": "0x42000000000000000000000000000000000000f1",
"optimismL1FeeRecipient": "0x0000000000000000000000000000000000000000",
"l2CrossDomainMessengerOwner": "0x42000000000000000000000000000000000000f2",
"baseFeeVaultRecipient": "0x42000000000000000000000000000000000000f5",
"l1FeeVaultRecipient": "0x42000000000000000000000000000000000000f6",
"sequencerFeeVaultRecipient": "0x42000000000000000000000000000000000000f7",
"l1StandardBridgeProxy": "0x42000000000000000000000000000000000000f8",
"l1CrossDomainMessengerProxy": "0x42000000000000000000000000000000000000f9",
"l1ERC721BridgeProxy": "0x4200000000000000000000000000000000000060",
"systemConfigProxy": "0x4200000000000000000000000000000000000061",
"optimismPortalProxy": "0x4200000000000000000000000000000000000062",
"proxyAdminOwner": "0x0000000000000000000000000000000000000000",
"gasPriceOracleOverhead": 2100,
"gasPriceOracleScalar": 1000000,
Expand Down
4 changes: 0 additions & 4 deletions op-e2e/e2eutils/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,6 @@ func MakeDeployParams(t require.TestingT, tp *TestParams) *DeployParams {
L2GenesisBlockParentHash: common.Hash{},
L2GenesisBlockBaseFeePerGas: uint64ToBig(1000_000_000),

// TODO: remove these config values once the addresses are hardcoded in
// geth
OptimismBaseFeeRecipient: predeploys.BaseFeeVaultAddr,
OptimismL1FeeRecipient: predeploys.L1FeeVaultAddr,
L2CrossDomainMessengerOwner: common.Address{0: 0x42, 19: 0xf2}, // tbd
GasPriceOracleOverhead: 2100,
GasPriceOracleScalar: 1000_000,
Expand Down
2 changes: 0 additions & 2 deletions op-e2e/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,6 @@ func DefaultSystemConfig(t *testing.T) SystemConfig {
L2GenesisBlockParentHash: common.Hash{},
L2GenesisBlockBaseFeePerGas: uint642big(7),

OptimismBaseFeeRecipient: predeploys.BaseFeeVaultAddr,
OptimismL1FeeRecipient: predeploys.L1FeeVaultAddr,
L2CrossDomainMessengerOwner: common.Address{0: 0x52, 19: 0xf3}, // tbd

GasPriceOracleOverhead: 2100,
Expand Down
8 changes: 4 additions & 4 deletions op-e2e/system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -910,13 +910,13 @@ func TestFees(t *testing.T) {
// BaseFee Recipient
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
baseFeeRecipientStartBalance, err := l2Seq.BalanceAt(ctx, cfg.DeployConfig.OptimismBaseFeeRecipient, nil)
baseFeeRecipientStartBalance, err := l2Seq.BalanceAt(ctx, predeploys.BaseFeeVaultAddr, nil)
require.Nil(t, err)

// L1Fee Recipient
ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
l1FeeRecipientStartBalance, err := l2Seq.BalanceAt(ctx, cfg.DeployConfig.OptimismL1FeeRecipient, nil)
l1FeeRecipientStartBalance, err := l2Seq.BalanceAt(ctx, predeploys.L1FeeVaultAddr, nil)
require.Nil(t, err)

// Simple transfer from signer to random account
Expand Down Expand Up @@ -972,15 +972,15 @@ func TestFees(t *testing.T) {

ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
baseFeeRecipientEndBalance, err := l2Seq.BalanceAt(ctx, cfg.DeployConfig.OptimismBaseFeeRecipient, header.Number)
baseFeeRecipientEndBalance, err := l2Seq.BalanceAt(ctx, predeploys.BaseFeeVaultAddr, header.Number)
require.Nil(t, err)

l1Header, err := sys.Clients["l1"].HeaderByNumber(ctx, nil)
require.Nil(t, err)

ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
l1FeeRecipientEndBalance, err := l2Seq.BalanceAt(ctx, cfg.DeployConfig.OptimismL1FeeRecipient, header.Number)
l1FeeRecipientEndBalance, err := l2Seq.BalanceAt(ctx, predeploys.L1FeeVaultAddr, header.Number)
require.Nil(t, err)

// Diff fee recipient + coinbase balances
Expand Down
Loading