Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

contracts upgrade #243

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
3 changes: 3 additions & 0 deletions op-chain-ops/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ receipt-reference-builder:
op-upgrade:
go build -o ./bin/op-upgrade ./cmd/op-upgrade/main.go

opbnb-upgrade:
go build -o ./bin/opbnb-upgrade ./cmd/opbnb-upgrade/main.go

test:
go test ./...

Expand Down
11 changes: 11 additions & 0 deletions op-chain-ops/cmd/opbnb-upgrade/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

```sh
make opbnb-upgrade
```


```sh
./bin/opbnb-upgrade \
--l1-rpc-url http://127.0.0.1 \
--outfile input.json
```
172 changes: 172 additions & 0 deletions op-chain-ops/cmd/opbnb-upgrade/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package main

import (
"encoding/json"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/mattn/go-isatty"
"github.com/urfave/cli/v2"
"os"
"time"

"github.com/ethereum-optimism/optimism/op-chain-ops/opbnb-upgrades"
oldBindings "github.com/ethereum-optimism/optimism/op-chain-ops/opbnb-upgrades/old-contracts/bindings"
"github.com/ethereum-optimism/optimism/op-chain-ops/safe"
"github.com/ethereum-optimism/optimism/op-service/jsonutil"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
)

func main() {
color := isatty.IsTerminal(os.Stderr.Fd())
oplog.SetGlobalLogHandler(log.NewTerminalHandler(os.Stderr, color))

app := &cli.App{
Name: "opbnb-upgrade",
Usage: "Build transactions useful for upgrading the opBNB",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "l1-rpc-url",
Value: "http://127.0.0.1:8545",
Usage: "L1 RPC URL, the chain ID will be used to determine the opBNB",
EnvVars: []string{"L1_RPC_URL"},
},
&cli.PathFlag{
Name: "outfile",
Usage: "The file to write the output to. If not specified, output is written to stdout",
EnvVars: []string{"OUTFILE"},
},
&cli.PathFlag{
Name: "transfer_owner",
Usage: "Transfer proxyAdmin contract owner to the address",
EnvVars: []string{"TRANSFER_OWNER"},
},
&cli.PathFlag{
Name: "private_key",
Usage: "Owner private key to transfer new owner",
EnvVars: []string{"PRIVATE_KEY"},
},
&cli.PathFlag{
Name: "qa_net",
Usage: "set network is qanet",
EnvVars: []string{"QA_NET"},
},
},
Action: entrypoint,
}

if err := app.Run(os.Args); err != nil {
log.Crit("error opBNB-upgrade", "err", err)
}
}

// entrypoint contains the main logic of the script
func entrypoint(ctx *cli.Context) error {
client, err := ethclient.Dial(ctx.String("l1-rpc-url"))
if err != nil {
return err
}

// Fetch the L1 chain ID to determine the superchain name
l1ChainID, err := client.ChainID(ctx.Context)
if err != nil {
return err
}

proxyAddresses := opbnb_upgrades.BscQAnetProxyContracts
implAddresses := opbnb_upgrades.BscQAnetImplContracts
if l1ChainID.Uint64() == opbnb_upgrades.BscTestnet && !ctx.IsSet("qa_net") {
proxyAddresses = opbnb_upgrades.BscTestnetProxyContracts
implAddresses = opbnb_upgrades.BscTestnetImplContracts
fmt.Println("upgrade bscTestnet")
} else if l1ChainID.Uint64() == opbnb_upgrades.BscMainnet {
proxyAddresses = opbnb_upgrades.BscMainnetProxyContracts
implAddresses = opbnb_upgrades.BscMainnetImplContracts
fmt.Println("upgrade bscMainnet")
} else {
fmt.Println("upgrade bscQAnet")
}

if ctx.IsSet("transfer_owner") {
if !ctx.IsSet("private_key") {
return errors.New("must set private key")
}
proxyAdmin, err := oldBindings.NewProxyAdmin(implAddresses["ProxyAdmin"], client)
if err != nil {
return err
}
owner, err := proxyAdmin.Owner(&bind.CallOpts{})
if err != nil {
return err
}
fmt.Printf("old proxyAdmin owner is %s\n", owner.String())
transferOwner := ctx.String("transfer_owner")
privateKeyHex := ctx.String("private_key")
privateKey, err := crypto.HexToECDSA(privateKeyHex)
if err != nil {
return err
}
txOpts, err := bind.NewKeyedTransactorWithChainID(privateKey, l1ChainID)
if err != nil {
return err
}
tx, err := proxyAdmin.TransferOwnership(txOpts, common.HexToAddress(transferOwner))
if err != nil {
return err
}
fmt.Printf("TransferOwnership tx hash is %s\n", tx.Hash())
time.Sleep(5 * time.Second)
redhdx marked this conversation as resolved.
Show resolved Hide resolved
owner, err = proxyAdmin.Owner(&bind.CallOpts{})
if err != nil {
return err
}
fmt.Printf("new proxyAdmin owner is %s\n", owner.String())
}

versions, err := opbnb_upgrades.GetProxyContractVersions(ctx.Context, proxyAddresses, client)
log.Info("current contract versions")
log.Info("L1CrossDomainMessenger", "version", versions.L1CrossDomainMessenger, "address", proxyAddresses["L1CrossDomainMessengerProxy"])
log.Info("L1ERC721Bridge", "version", versions.L1ERC721Bridge, "address", proxyAddresses["L1ERC721BridgeProxy"])
log.Info("L1StandardBridge", "version", versions.L1StandardBridge, "address", proxyAddresses["L1StandardBridgeProxy"])
log.Info("L2OutputOracle", "version", versions.L2OutputOracle, "address", proxyAddresses["L2OutputOracleProxy"])
log.Info("OptimismMintableERC20Factory", "version", versions.OptimismMintableERC20Factory, "address", proxyAddresses["OptimismMintableERC20FactoryProxy"])
log.Info("OptimismPortal", "version", versions.OptimismPortal, "address", proxyAddresses["OptimismPortalProxy"])
log.Info("SystemConfig", "version", versions.SystemConfig, "address", proxyAddresses["SystemConfigProxy"])

versions, err = opbnb_upgrades.GetImplContractVersions(ctx.Context, implAddresses, client)
log.Info("Upgrading to the following versions")
log.Info("L1CrossDomainMessenger", "version", versions.L1CrossDomainMessenger, "address", proxyAddresses["L1CrossDomainMessengerProxy"])
log.Info("L1ERC721Bridge", "version", versions.L1ERC721Bridge, "address", proxyAddresses["L1ERC721BridgeProxy"])
log.Info("L1StandardBridge", "version", versions.L1StandardBridge, "address", proxyAddresses["L1StandardBridgeProxy"])
log.Info("L2OutputOracle", "version", versions.L2OutputOracle, "address", proxyAddresses["L2OutputOracleProxy"])
log.Info("OptimismMintableERC20Factory", "version", versions.OptimismMintableERC20Factory, "address", proxyAddresses["OptimismMintableERC20FactoryProxy"])
log.Info("OptimismPortal", "version", versions.OptimismPortal, "address", proxyAddresses["OptimismPortalProxy"])
log.Info("SystemConfig", "version", versions.SystemConfig, "address", proxyAddresses["SystemConfigProxy"])

// Create a batch of transactions
batch := safe.Batch{}

// Build the batch
if err := opbnb_upgrades.L1(&batch, proxyAddresses, implAddresses, client, l1ChainID); err != nil {
return err
}

// Write the batch to disk or stdout
if outfile := ctx.Path("outfile"); outfile != "" {
if err := jsonutil.WriteJSON(outfile, batch, 0o666); err != nil {
return err
}
} else {
data, err := json.MarshalIndent(batch, "", " ")
if err != nil {
return err
}
fmt.Println(string(data))
}
return nil

}
21 changes: 21 additions & 0 deletions op-chain-ops/opbnb-upgrades/abi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package opbnb_upgrades

//go:generate ./abigen --abi old-contracts/L1CrossDomainMessenger.json --pkg L1CrossDomainMessenger --out old-contracts/bindings/L1CrossDomainMessenger.go
//go:generate ./abigen --abi old-contracts/L1ERC721Bridge.json --pkg L1ERC721Bridge --out old-contracts/bindings/L1ERC721Bridge.go
//go:generate ./abigen --abi old-contracts/L1StandardBridge.json --pkg L1StandardBridge --out old-contracts/bindings/L1StandardBridge.go
//go:generate ./abigen --abi old-contracts/L2OutputOracle.json --pkg L2OutputOracle --out old-contracts/bindings/L2OutputOracle.go
//go:generate ./abigen --abi old-contracts/OptimismMintableERC20Factory.json --pkg OptimismMintableERC20Factory --out old-contracts/bindings/OptimismMintableERC20Factory.go
//go:generate ./abigen --abi old-contracts/OptimismPortal.json --pkg OptimismPortal --out old-contracts/bindings/OptimismPortal.go
//go:generate ./abigen --abi old-contracts/SystemConfig.json --pkg SystemConfig --out old-contracts/bindings/SystemConfig.go
//go:generate ./abigen --abi old-contracts/Semver.json --pkg Semver --out old-contracts/bindings/Semver.go
//go:generate ./abigen --abi old-contracts/ProxyAdmin.json --pkg ProxyAdmin --out old-contracts/bindings/ProxyAdmin.go

//go:generate ./abigen --abi new-contracts/SuperChainConfig.json --pkg SuperChainConfig --out new-contracts/bindings/SuperChainConfig.go
//go:generate ./abigen --abi new-contracts/StorageSetter.json --pkg StorageSetter --out new-contracts/bindings/StorageSetter.go
//go:generate ./abigen --abi new-contracts/L1CrossDomainMessenger.json --pkg L1CrossDomainMessenger --out new-contracts/bindings/L1CrossDomainMessenger.go
//go:generate ./abigen --abi new-contracts/L1ERC721Bridge.json --pkg L1ERC721Bridge --out new-contracts/bindings/L1ERC721Bridge.go
//go:generate ./abigen --abi new-contracts/L1StandardBridge.json --pkg L1StandardBridge --out new-contracts/bindings/L1StandardBridge.go
//go:generate ./abigen --abi new-contracts/L2OutputOracle.json --pkg L2OutputOracle --out new-contracts/bindings/L2OutputOracle.go
//go:generate ./abigen --abi new-contracts/OptimismMintableERC20Factory.json --pkg OptimismMintableERC20Factory --out new-contracts/bindings/OptimismMintableERC20Factory.go
//go:generate ./abigen --abi new-contracts/OptimismPortal.json --pkg OptimismPortal --out new-contracts/bindings/OptimismPortal.go
//go:generate ./abigen --abi new-contracts/SystemConfig.json --pkg SystemConfig --out new-contracts/bindings/SystemConfig.go
Binary file added op-chain-ops/opbnb-upgrades/abigen
Binary file not shown.
110 changes: 110 additions & 0 deletions op-chain-ops/opbnb-upgrades/check.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package opbnb_upgrades

import (
"context"
"fmt"
oldBindings "github.com/ethereum-optimism/optimism/op-chain-ops/opbnb-upgrades/old-contracts/bindings"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
)

// ContractVersions
type ContractVersions struct {
L1CrossDomainMessenger string `yaml:"l1_cross_domain_messenger"`
L1ERC721Bridge string `yaml:"l1_erc721_bridge"`
L1StandardBridge string `yaml:"l1_standard_bridge"`
L2OutputOracle string `yaml:"l2_output_oracle,omitempty"`
OptimismMintableERC20Factory string `yaml:"optimism_mintable_erc20_factory"`
OptimismPortal string `yaml:"optimism_portal"`
SystemConfig string `yaml:"system_config"`
// Superchain-wide contracts:
ProtocolVersions string `yaml:"protocol_versions"`
SuperchainConfig string `yaml:"superchain_config,omitempty"`
}

// GetProxyContractVersions will fetch the versions of all of the contracts.
func GetProxyContractVersions(ctx context.Context, addresses map[string]common.Address, backend bind.ContractBackend) (ContractVersions, error) {
var versions ContractVersions
var err error

versions.L1CrossDomainMessenger, err = getVersion(ctx, addresses["L1CrossDomainMessengerProxy"], backend)
if err != nil {
return versions, fmt.Errorf("L1CrossDomainMessenger: %w", err)
}
versions.L1ERC721Bridge, err = getVersion(ctx, addresses["L1ERC721BridgeProxy"], backend)
if err != nil {
return versions, fmt.Errorf("L1ERC721Bridge: %w", err)
}
versions.L1StandardBridge, err = getVersion(ctx, addresses["L1StandardBridgeProxy"], backend)
if err != nil {
return versions, fmt.Errorf("L1StandardBridge: %w", err)
}
versions.L2OutputOracle, err = getVersion(ctx, addresses["L2OutputOracleProxy"], backend)
if err != nil {
return versions, fmt.Errorf("L2OutputOracle: %w", err)
}
versions.OptimismMintableERC20Factory, err = getVersion(ctx, addresses["OptimismMintableERC20FactoryProxy"], backend)
if err != nil {
return versions, fmt.Errorf("OptimismMintableERC20Factory: %w", err)
}
versions.OptimismPortal, err = getVersion(ctx, addresses["OptimismPortalProxy"], backend)
if err != nil {
return versions, fmt.Errorf("OptimismPortal: %w", err)
}
versions.SystemConfig, err = getVersion(ctx, addresses["SystemConfigProxy"], backend)
if err != nil {
return versions, fmt.Errorf("SystemConfig: %w", err)
}
return versions, err
}

// GetImplContractVersions will fetch the versions of all of the contracts.
func GetImplContractVersions(ctx context.Context, addresses map[string]common.Address, backend bind.ContractBackend) (ContractVersions, error) {
var versions ContractVersions
var err error

versions.L1CrossDomainMessenger, err = getVersion(ctx, addresses["L1CrossDomainMessenger"], backend)
if err != nil {
return versions, fmt.Errorf("L1CrossDomainMessenger: %w", err)
}
versions.L1ERC721Bridge, err = getVersion(ctx, addresses["L1ERC721Bridge"], backend)
if err != nil {
return versions, fmt.Errorf("L1ERC721Bridge: %w", err)
}
versions.L1StandardBridge, err = getVersion(ctx, addresses["L1StandardBridge"], backend)
if err != nil {
return versions, fmt.Errorf("L1StandardBridge: %w", err)
}
versions.L2OutputOracle, err = getVersion(ctx, addresses["L2OutputOracle"], backend)
if err != nil {
return versions, fmt.Errorf("L2OutputOracle: %w", err)
}
versions.OptimismMintableERC20Factory, err = getVersion(ctx, addresses["OptimismMintableERC20Factory"], backend)
if err != nil {
return versions, fmt.Errorf("OptimismMintableERC20Factory: %w", err)
}
versions.OptimismPortal, err = getVersion(ctx, addresses["OptimismPortal"], backend)
if err != nil {
return versions, fmt.Errorf("OptimismPortal: %w", err)
}
versions.SystemConfig, err = getVersion(ctx, addresses["SystemConfig"], backend)
if err != nil {
return versions, fmt.Errorf("SystemConfig: %w", err)
}
return versions, err
}

// getVersion will get the version of a contract at a given address.
func getVersion(ctx context.Context, addr common.Address, backend bind.ContractBackend) (string, error) {
semver, err := oldBindings.NewSemver(addr, backend)
if err != nil {
return "", fmt.Errorf("%s: %w", addr, err)
}
version, err := semver.Version(&bind.CallOpts{
Context: ctx,
})
if err != nil {
return "", fmt.Errorf("%s: %w", addr, err)
}
return version, nil
}
Loading
Loading