Commit afe534c5 authored by Adrian Sutton's avatar Adrian Sutton

Merge branch 'develop' into aj/verify-more-than-block-hash

parents abba09a4 6c4a9ac4
......@@ -1420,13 +1420,6 @@ workflows:
- op-stack-go-lint
- devnet-allocs
- l1-geth-version-check
- go-e2e-test:
name: op-e2e-span-batch-tests
module: op-e2e
target: test-span-batch
requires:
- op-stack-go-lint
- devnet-allocs
- op-program-compat:
requires:
- op-program-tests
......
##################################################
# Getting Started #
##################################################
# Admin account
export GS_ADMIN_ADDRESS=
export GS_ADMIN_PRIVATE_KEY=
# Batcher account
export GS_BATCHER_ADDRESS=
export GS_BATCHER_PRIVATE_KEY=
# Proposer account
export GS_PROPOSER_ADDRESS=
export GS_PROPOSER_PRIVATE_KEY=
# Sequencer account
export GS_SEQUENCER_ADDRESS=
export GS_SEQUENCER_PRIVATE_KEY=
##################################################
# op-node Configuration #
##################################################
# The kind of RPC provider, used to inform optimal transactions receipts
# fetching. Valid options: alchemy, quicknode, infura, parity, nethermind,
# debug_geth, erigon, basic, any.
export L1_RPC_KIND=
##################################################
# Contract Deployment #
##################################################
# RPC URL for the L1 network to interact with
export L1_RPC_URL=
# Salt used via CREATE2 to determine implementation addresses
# NOTE: If you want to deploy contracts from scratch you MUST reload this
# variable to ensure the salt is regenerated and the contracts are
# deployed to new addresses (otherwise deployment will fail)
export IMPL_SALT=$(openssl rand -hex 32)
# Name for the deployed network
export DEPLOYMENT_CONTEXT=getting-started
# Optional Tenderly details for simulation link during deployment
export TENDERLY_PROJECT=
export TENDERLY_USERNAME=
# Optional Etherscan API key for contract verification
export ETHERSCAN_API_KEY=
# Private key to use for contract deployments, you don't need to worry about
# this for the Getting Started guide.
export PRIVATE_KEY=
......@@ -30,6 +30,7 @@ packages/contracts-bedrock/deployments/anvil
.env
.env*
!.env.example
!.envrc.example
*.log
.devnet
......
......@@ -8,7 +8,7 @@ require github.com/ethereum-optimism/optimism v0.0.0
require (
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/sys v0.14.0 // indirect
)
replace github.com/ethereum-optimism/optimism v0.0.0 => ../../..
......@@ -6,7 +6,7 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
......@@ -42,7 +42,7 @@ require (
golang.org/x/crypto v0.14.0
golang.org/x/exp v0.0.0-20231006140011-7918f672742d
golang.org/x/sync v0.5.0
golang.org/x/term v0.13.0
golang.org/x/term v0.14.0
golang.org/x/time v0.4.0
gorm.io/driver/postgres v1.5.4
gorm.io/gorm v1.25.5
......@@ -199,7 +199,7 @@ require (
go.uber.org/zap v1.26.0 // indirect
golang.org/x/mod v0.13.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/tools v0.14.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
......
......@@ -879,13 +879,13 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8=
golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
......
......@@ -51,3 +51,7 @@ export interface WithdrawalResponse {
hasNextPage: boolean;
items: WithdrawalItem[];
}
export interface BridgeSupplyView {
l1DepositSum: number /* float64 */;
l2WithdrawalSum: number /* float64 */;
}
......@@ -35,6 +35,8 @@ const (
HealthPath = "/healthz"
DepositsPath = "/api/v0/deposits/"
WithdrawalsPath = "/api/v0/withdrawals/"
SupplyPath = "/api/v0/supply"
)
// Api ... Indexer API struct
......@@ -140,15 +142,14 @@ func (a *APIService) initRouter(apiConfig config.ServerConfig) {
promRecorder := metrics.NewPromHTTPRecorder(a.metricsRegistry, MetricsNamespace)
// (2) Inject routing middleware
apiRouter.Use(chiMetricsMiddleware(promRecorder))
apiRouter.Use(middleware.Timeout(time.Duration(apiConfig.WriteTimeout) * time.Second))
apiRouter.Use(middleware.Recoverer)
apiRouter.Use(middleware.Heartbeat(HealthPath))
// (3) Set GET routes
apiRouter.Get(fmt.Sprintf(DepositsPath+addressParam, ethereumAddressRegex), h.L1DepositsHandler)
apiRouter.Get(fmt.Sprintf(WithdrawalsPath+addressParam, ethereumAddressRegex), h.L2WithdrawalsHandler)
apiRouter.Get(SupplyPath, h.SupplyView)
a.router = apiRouter
}
......
......@@ -95,6 +95,14 @@ func (mbv *MockBridgeTransfersView) L2BridgeWithdrawalsByAddress(address common.
},
}, nil
}
func (mbv *MockBridgeTransfersView) L1BridgeDepositSum() (float64, error) {
return 69, nil
}
func (mbv *MockBridgeTransfersView) L2BridgeWithdrawalSum() (float64, error) {
return 420, nil
}
func TestHealthz(t *testing.T) {
logger := testlog.Logger(t, log.LvlInfo)
cfg := &Config{
......
......@@ -49,6 +49,11 @@ type WithdrawalResponse struct {
Items []WithdrawalItem `json:"items"`
}
type BridgeSupplyView struct {
L1DepositSum float64 `json:"l1DepositSum"`
L2WithdrawalSum float64 `json:"l2WithdrawalSum"`
}
// FIXME make a pure function that returns a struct instead of newWithdrawalResponse
// newWithdrawalResponse ... Converts a database.L2BridgeWithdrawalsResponse to an api.WithdrawalResponse
func CreateWithdrawalResponse(withdrawals *database.L2BridgeWithdrawalsResponse) WithdrawalResponse {
......
package routes
import (
"net/http"
"github.com/ethereum-optimism/optimism/indexer/api/models"
)
// SupplyView ... Handles /api/v0/supply GET requests
func (h Routes) SupplyView(w http.ResponseWriter, r *http.Request) {
depositSum, err := h.view.L1BridgeDepositSum()
if err != nil {
http.Error(w, "internal server error reading deposits", http.StatusInternalServerError)
h.logger.Error("unable to read deposits from DB", "err", err.Error())
return
}
withdrawalSum, err := h.view.L2BridgeWithdrawalSum()
if err != nil {
http.Error(w, "internal server error reading withdrawals", http.StatusInternalServerError)
h.logger.Error("unable to read withdrawals from DB", "err", err.Error())
return
}
view := models.BridgeSupplyView{
L1DepositSum: depositSum,
L2WithdrawalSum: withdrawalSum,
}
err = jsonResponse(w, view, http.StatusOK)
if err != nil {
h.logger.Error("error writing response", "err", err)
}
}
......@@ -23,6 +23,7 @@ const (
healthz = "get_health"
deposits = "get_deposits"
withdrawals = "get_withdrawals"
sum = "get_sum"
)
// Option ... Provides configuration through callback injection
......@@ -164,6 +165,25 @@ func (c *Client) GetAllDepositsByAddress(l1Address common.Address) ([]models.Dep
}
// GetSupplyAssessment ... Returns an assessment of the current supply
// on both L1 and L2. This includes the individual sums of
// (L1/L2) deposits and withdrawals
func (c *Client) GetSupplyAssessment() (*models.BridgeSupplyView, error) {
url := c.cfg.BaseURL + api.SupplyPath
resp, err := c.doRecordRequest(sum, url)
if err != nil {
return nil, err
}
var bsv *models.BridgeSupplyView
if err := json.Unmarshal(resp, &bsv); err != nil {
return nil, err
}
return bsv, nil
}
// GetAllWithdrawalsByAddress ... Gets all withdrawals provided a L2 address
func (c *Client) GetAllWithdrawalsByAddress(l2Address common.Address) ([]models.WithdrawalItem, error) {
var withdrawals []models.WithdrawalItem
......
......@@ -61,10 +61,12 @@ type L2BridgeWithdrawalWithTransactionHashes struct {
type BridgeTransfersView interface {
L1BridgeDeposit(common.Hash) (*L1BridgeDeposit, error)
L1BridgeDepositSum() (float64, error)
L1BridgeDepositWithFilter(BridgeTransfer) (*L1BridgeDeposit, error)
L1BridgeDepositsByAddress(common.Address, string, int) (*L1BridgeDepositsResponse, error)
L2BridgeWithdrawal(common.Hash) (*L2BridgeWithdrawal, error)
L2BridgeWithdrawalSum() (float64, error)
L2BridgeWithdrawalWithFilter(BridgeTransfer) (*L2BridgeWithdrawal, error)
L2BridgeWithdrawalsByAddress(common.Address, string, int) (*L2BridgeWithdrawalsResponse, error)
}
......@@ -136,6 +138,17 @@ type L1BridgeDepositsResponse struct {
HasNextPage bool
}
// L1BridgeDepositSum ... returns the sum of all l1 bridge deposit mints in gwei
func (db *bridgeTransfersDB) L1BridgeDepositSum() (float64, error) {
var sum float64
result := db.gorm.Model(&L1TransactionDeposit{}).Select("sum(amount)").Scan(&sum)
if result.Error != nil {
return 0, result.Error
}
return sum, nil
}
// L1BridgeDepositsByAddress retrieves a list of deposits initiated by the specified address,
// coupled with the L1/L2 transaction hashes that complete the bridge transaction.
func (db *bridgeTransfersDB) L1BridgeDepositsByAddress(address common.Address, cursor string, limit int) (*L1BridgeDepositsResponse, error) {
......@@ -233,6 +246,16 @@ func (db *bridgeTransfersDB) L2BridgeWithdrawal(txWithdrawalHash common.Hash) (*
return &withdrawal, nil
}
func (db *bridgeTransfersDB) L2BridgeWithdrawalSum() (float64, error) {
var sum float64
result := db.gorm.Model(&L2TransactionWithdrawal{}).Select("sum(amount)").Scan(&sum)
if result.Error != nil {
return 0, result.Error
}
return sum, nil
}
// L2BridgeWithdrawalWithFilter queries for a bridge withdrawal with set fields in the `BridgeTransfer` filter
func (db *bridgeTransfersDB) L2BridgeWithdrawalWithFilter(filter BridgeTransfer) (*L2BridgeWithdrawal, error) {
var withdrawal L2BridgeWithdrawal
......
......@@ -8,6 +8,7 @@ import (
"testing"
"time"
"github.com/ethereum-optimism/optimism/indexer/bigint"
e2etest_utils "github.com/ethereum-optimism/optimism/indexer/e2e_tests/utils"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions"
......@@ -447,7 +448,7 @@ func TestE2EBridgeTransfersCursoredWithdrawals(t *testing.T) {
}
}
func TestClientGetWithdrawals(t *testing.T) {
func TestClientBridgeFunctions(t *testing.T) {
testSuite := createE2ETestSuite(t)
// (1) Generate contract bindings for the L1 and L2 standard bridges
......@@ -459,12 +460,16 @@ func TestClientGetWithdrawals(t *testing.T) {
// (2) Create test actors that will deposit and withdraw using the standard bridge
aliceAddr := testSuite.OpCfg.Secrets.Addresses().Alice
bobAddr := testSuite.OpCfg.Secrets.Addresses().Bob
malAddr := testSuite.OpCfg.Secrets.Addresses().Mallory
type actor struct {
addr common.Address
priv *ecdsa.PrivateKey
}
mintSum := bigint.Zero
withdrawSum := bigint.Zero
actors := []actor{
{
addr: aliceAddr,
......@@ -474,6 +479,10 @@ func TestClientGetWithdrawals(t *testing.T) {
addr: bobAddr,
priv: testSuite.OpCfg.Secrets.Bob,
},
{
addr: malAddr,
priv: testSuite.OpCfg.Secrets.Mallory,
},
}
// (3) Iterate over each actor and deposit / withdraw
......@@ -491,6 +500,8 @@ func TestClientGetWithdrawals(t *testing.T) {
_, err = wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash())
require.NoError(t, err)
mintSum = new(big.Int).Add(mintSum, depositTx.Value())
// (3.b) Initiate withdrawal transaction via L2ToL1MessagePasser contract
l2ToL1MessagePasserWithdrawTx, err := l2ToL1MessagePasser.Receive(l2Opts)
require.NoError(t, err)
......@@ -503,6 +514,8 @@ func TestClientGetWithdrawals(t *testing.T) {
return l2Header != nil && l2Header.Number.Uint64() >= l2ToL1WithdrawReceipt.BlockNumber.Uint64(), nil
}))
withdrawSum = new(big.Int).Add(withdrawSum, l2ToL1MessagePasserWithdrawTx.Value())
// (3.d) Ensure that withdrawal and deposit txs are retrievable via API
deposits, err := testSuite.Client.GetAllDepositsByAddress(actor.addr)
require.NoError(t, err)
......@@ -513,6 +526,17 @@ func TestClientGetWithdrawals(t *testing.T) {
require.NoError(t, err)
require.Len(t, withdrawals, 1)
require.Equal(t, l2ToL1MessagePasserWithdrawTx.Hash().String(), withdrawals[0].TransactionHash)
}
// (4) Ensure that supply assessment is correct
assessment, err := testSuite.Client.GetSupplyAssessment()
require.NoError(t, err)
mintFloat, _ := mintSum.Float64()
require.Equal(t, mintFloat, assessment.L1DepositSum)
withdrawFloat, _ := withdrawSum.Float64()
require.Equal(t, withdrawFloat, assessment.L2WithdrawalSum)
}
......@@ -96,8 +96,8 @@ CREATE TABLE IF NOT EXISTS l1_transaction_deposits (
-- transaction data. NOTE: `to_address` is the recipient of funds transferred in value field of the
-- L2 deposit transaction and not the amount minted on L1 from the source address. Hence the `amount`
-- column in this table does NOT indiciate the amount transferred to the recipient but instead funds
-- bridged from L1 into `from_address`.
-- column in this table does NOT indicate the amount transferred to the recipient but instead funds
-- bridged from L1 by the `from_address`.
from_address VARCHAR NOT NULL,
to_address VARCHAR NOT NULL,
......
......@@ -128,7 +128,7 @@ type Signature struct {
// EASMetaData contains all meta data concerning the EAS contract.
var EASMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessDenied\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyRevoked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyRevokedOffchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyTimestamped\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAttestations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExpirationTime\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidOffset\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRevocation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRevocations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSchema\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidVerifier\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Irrevocable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotPayable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongSchema\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"schemaUID\",\"type\":\"bytes32\"}],\"name\":\"Attested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldNonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newNonce\",\"type\":\"uint256\"}],\"name\":\"NonceIncreased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"schemaUID\",\"type\":\"bytes32\"}],\"name\":\"Revoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"revoker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"}],\"name\":\"RevokedOffchain\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"}],\"name\":\"Timestamped\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"structAttestationRequestData\",\"name\":\"data\",\"type\":\"tuple\"}],\"internalType\":\"structAttestationRequest\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"attest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"structAttestationRequestData\",\"name\":\"data\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structSignature\",\"name\":\"signature\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"deadline\",\"type\":\"uint64\"}],\"internalType\":\"structDelegatedAttestationRequest\",\"name\":\"delegatedRequest\",\"type\":\"tuple\"}],\"name\":\"attestByDelegation\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAttestTypeHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"}],\"name\":\"getAttestation\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"time\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"revocationTime\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structAttestation\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDomainSeparator\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getName\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"revoker\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"}],\"name\":\"getRevokeOffchain\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRevokeTypeHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSchemaRegistry\",\"outputs\":[{\"internalType\":\"contractISchemaRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"}],\"name\":\"getTimestamp\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newNonce\",\"type\":\"uint256\"}],\"name\":\"increaseNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"}],\"name\":\"isAttestationValid\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"structAttestationRequestData[]\",\"name\":\"data\",\"type\":\"tuple[]\"}],\"internalType\":\"structMultiAttestationRequest[]\",\"name\":\"multiRequests\",\"type\":\"tuple[]\"}],\"name\":\"multiAttest\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"expirationTime\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"revocable\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"refUID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"structAttestationRequestData[]\",\"name\":\"data\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structSignature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"attester\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"deadline\",\"type\":\"uint64\"}],\"internalType\":\"structMultiDelegatedAttestationRequest[]\",\"name\":\"multiDelegatedRequests\",\"type\":\"tuple[]\"}],\"name\":\"multiAttestByDelegation\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"structRevocationRequestData[]\",\"name\":\"data\",\"type\":\"tuple[]\"}],\"internalType\":\"structMultiRevocationRequest[]\",\"name\":\"multiRequests\",\"type\":\"tuple[]\"}],\"name\":\"multiRevoke\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"structRevocationRequestData[]\",\"name\":\"data\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structSignature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"revoker\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"deadline\",\"type\":\"uint64\"}],\"internalType\":\"structMultiDelegatedRevocationRequest[]\",\"name\":\"multiDelegatedRequests\",\"type\":\"tuple[]\"}],\"name\":\"multiRevokeByDelegation\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"data\",\"type\":\"bytes32[]\"}],\"name\":\"multiRevokeOffchain\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"data\",\"type\":\"bytes32[]\"}],\"name\":\"multiTimestamp\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"structRevocationRequestData\",\"name\":\"data\",\"type\":\"tuple\"}],\"internalType\":\"structRevocationRequest\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"revoke\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"schema\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"structRevocationRequestData\",\"name\":\"data\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structSignature\",\"name\":\"signature\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"revoker\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"deadline\",\"type\":\"uint64\"}],\"internalType\":\"structDelegatedRevocationRequest\",\"name\":\"delegatedRequest\",\"type\":\"tuple\"}],\"name\":\"revokeByDelegation\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"}],\"name\":\"revokeOffchain\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"data\",\"type\":\"bytes32\"}],\"name\":\"timestamp\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
Bin: "0x61016060405234801561001157600080fd5b50604080518082018252600381526245415360e81b60208083019182528351808501855260058152640312e322e360dc1b908201529151812060e08190527fe374587661e69268352d25204d81b23ce801573f4b09f3545e69536dc085a37a6101008190524660a081815286517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818801819052818901959095526060810193909352608080840192909252308382018190528751808503909201825260c093840190975280519501949094209093529290915261012091909152516101405260805160a05160c05160e05161010051610120516101405161454d61014b600039600061073701526000612753015260006127a20152600061277d015260006126d6015260006127000152600061272a015261454d6000f3fe60806040526004361061018b5760003560e01c806395411525116100d6578063d45c44351161007f578063ed24911d11610059578063ed24911d146104fd578063f10b5cc814610512578063f17325e71461054157600080fd5b8063d45c443514610467578063e30bb5631461049e578063e71ff365146104dd57600080fd5b8063b469318d116100b0578063b469318d146103ba578063b83010d314610414578063cf190f341461044757600080fd5b80639541152514610367578063a3112a641461037a578063a6d4dbc7146103a757600080fd5b806344adc90e116101385780634d003070116101125780634d003070146102de57806354fd4d50146102fe57806379f7573a1461034757600080fd5b806344adc90e1461029857806346926267146102b85780634cb7e9e5146102cb57600080fd5b806317d7de7c1161016957806317d7de7c146102205780632d0335ab146102425780633c0427151461028557600080fd5b80630eabf6601461019057806312b11a17146101a557806313893f61146101e7575b600080fd5b6101a361019e366004613497565b610554565b005b3480156101b157600080fd5b507ff83bb2b0ede93a840239f7e701a54d9bc35f03701f51ae153d601c6947ff3d3f5b6040519081526020015b60405180910390f35b3480156101f357600080fd5b50610207610202366004613497565b6106eb565b60405167ffffffffffffffff90911681526020016101de565b34801561022c57600080fd5b50610235610730565b6040516101de9190613547565b34801561024e57600080fd5b506101d461025d36600461358c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101d46102933660046135a9565b610760565b6102ab6102a6366004613497565b610863565b6040516101de91906135e4565b6101a36102c6366004613628565b6109e4565b6101a36102d9366004613497565b610a68565b3480156102ea57600080fd5b506102076102f9366004613640565b610b4b565b34801561030a57600080fd5b506102356040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b34801561035357600080fd5b506101a3610362366004613640565b610b58565b6102ab610375366004613497565b610bef565b34801561038657600080fd5b5061039a610395366004613640565b610e62565b6040516101de9190613740565b6101a36103b5366004613753565b611025565b3480156103c657600080fd5b506102076103d5366004613766565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152603460209081526040808320938352929052205467ffffffffffffffff1690565b34801561042057600080fd5b507f2d4116d8c9824e4c316453e5c2843a1885580374159ce8768603c49085ef424c6101d4565b34801561045357600080fd5b50610207610462366004613640565b6110ca565b34801561047357600080fd5b50610207610482366004613640565b60009081526033602052604090205467ffffffffffffffff1690565b3480156104aa57600080fd5b506104cd6104b9366004613640565b600090815260326020526040902054151590565b60405190151581526020016101de565b3480156104e957600080fd5b506102076104f8366004613497565b6110d8565b34801561050957600080fd5b506101d4611110565b34801561051e57600080fd5b5060405173420000000000000000000000000000000000002081526020016101de565b6101d461054f366004613792565b61111a565b348160005b818110156106e4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82018114600086868481811061059a5761059a6137cd565b90506020028101906105ac91906137fc565b6105b590613a92565b60208101518051919250908015806105d257508260400151518114155b15610609576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156106ad576106a56040518060a001604052808660000151815260200185848151811061063e5761063e6137cd565b6020026020010151815260200186604001518481518110610661576106616137cd565b60200260200101518152602001866060015173ffffffffffffffffffffffffffffffffffffffff168152602001866080015167ffffffffffffffff168152506111d8565b60010161060c565b506106c383600001518385606001518a886113c5565b6106cd9088613bbc565b9650505050506106dd8160010190565b9050610559565b5050505050565b60004282825b818110156107245761071c3387878481811061070f5761070f6137cd565b90506020020135856119f4565b6001016106f1565b50909150505b92915050565b606061075b7f0000000000000000000000000000000000000000000000000000000000000000611af3565b905090565b600061077361076e83613cf1565b611c81565b604080516001808252818301909252600091816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161078a5790505090506107f86020840184613d6c565b61080190613da0565b81600081518110610814576108146137cd565b602090810291909101015261083d83358261083560c0870160a0880161358c565b346001611dfe565b60200151600081518110610853576108536137cd565b6020026020010151915050919050565b60608160008167ffffffffffffffff8111156108815761088161383a565b6040519080825280602002602001820160405280156108b457816020015b606081526020019060019003908161089f5790505b509050600034815b848110156109ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85018114368989848181106108fc576108fc6137cd565b905060200281019061090e9190613dac565b905061091d6020820182613de0565b9050600003610958576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061097d823561096c6020850185613de0565b61097591613e48565b338887611dfe565b805190915061098c9086613bbc565b945080602001518785815181106109a5576109a56137cd565b6020026020010181905250806020015151860195505050506109c78160010190565b90506108bc565b506109d98383612510565b979650505050505050565b604080516001808252818301909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816109fb579050509050610a3636839003830160208401613ebc565b81600081518110610a4957610a496137cd565b6020908102919091010152610a63823582333460016113c5565b505050565b348160005b818110156106e4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201811436868684818110610aad57610aad6137cd565b9050602002810190610abf9190613dac565b9050610b2c8135610ad36020840184613ed8565b808060200260200160405190810160405280939291908181526020016000905b82821015610b1f57610b1060408302860136819003810190613ebc565b81526020019060010190610af3565b50505050503388866113c5565b610b369086613bbc565b94505050610b448160010190565b9050610a6d565b60004261072a83826125fa565b33600090815260208190526040902054808211610ba1576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152602081815260409182902084905581518381529081018490527f57b09af877df9068fd60a69d7b21f5576b8b38955812d6ae4ac52942f1e38fb7910160405180910390a15050565b60608160008167ffffffffffffffff811115610c0d57610c0d61383a565b604051908082528060200260200182016040528015610c4057816020015b6060815260200190600190039081610c2b5790505b509050600034815b848110156109ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8501811436898984818110610c8857610c886137cd565b9050602002810190610c9a91906137fc565b9050366000610cac6020840184613de0565b909250905080801580610ccd5750610cc76040850185613f40565b90508114155b15610d04576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610de557610ddd6040518060a0016040528087600001358152602001868685818110610d3957610d396137cd565b9050602002810190610d4b9190613d6c565b610d5490613da0565b8152602001610d666040890189613f40565b85818110610d7657610d766137cd565b905060600201803603810190610d8c9190613fa7565b8152602001610da16080890160608a0161358c565b73ffffffffffffffffffffffffffffffffffffffff168152602001610dcc60a0890160808a01613fc3565b67ffffffffffffffff169052611c81565b600101610d07565b506000610e0e8535610df78587613e48565b610e076080890160608a0161358c565b8b8a611dfe565b8051909150610e1d9089613bbc565b975080602001518a8881518110610e3657610e366137cd565b602002602001018190525080602001515189019850505050505050610e5b8160010190565b9050610c48565b604080516101408101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e0820183905261010082019290925261012081019190915260008281526032602090815260409182902082516101408101845281548152600182015492810192909252600281015467ffffffffffffffff808216948401949094526801000000000000000081048416606084015270010000000000000000000000000000000090049092166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff16151561010082015260068201805491929161012084019190610f9c90613fde565b80601f0160208091040260200160405190810160405280929190818152602001828054610fc890613fde565b80156110155780601f10610fea57610100808354040283529160200191611015565b820191906000526020600020905b815481529060010190602001808311610ff857829003601f168201915b5050505050815250509050919050565b61103c6110373683900383018361402b565b6111d8565b604080516001808252818301909252600091816020015b604080518082019091526000808252602082015281526020019060019003908161105357905050905061108e36839003830160208401613ebc565b816000815181106110a1576110a16137cd565b6020908102919091010152610a638235826110c260e0860160c0870161358c565b3460016113c5565b60004261072a3384836119f4565b60004282825b81811015610724576111088686838181106110fb576110fb6137cd565b90506020020135846125fa565b6001016110de565b600061075b6126bc565b604080516001808252818301909252600091829190816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816111345790505090506111a26020840184613d6c565b6111ab90613da0565b816000815181106111be576111be6137cd565b602090810291909101015261083d83358233346001611dfe565b608081015167ffffffffffffffff161580159061120c57504267ffffffffffffffff16816080015167ffffffffffffffff16105b15611243576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201516040808401518451835184860151606088015173ffffffffffffffffffffffffffffffffffffffff166000908152968790529386208054959693959394611313947f2d4116d8c9824e4c316453e5c2843a1885580374159ce8768603c49085ef424c949392876112b883614099565b909155506080808b015160408051602081019890985287019590955260608601939093529184015260a083015267ffffffffffffffff1660c082015260e0015b604051602081830303815290604052805190602001206127f0565b905061138984606001518284602001518560400151866000015160405160200161137593929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b604051602081830303815290604052612803565b6113bf576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6040517fa2ea7c6e0000000000000000000000000000000000000000000000000000000081526004810186905260009081907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611433573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261147991908101906140d1565b80519091506114b4576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b855160008167ffffffffffffffff8111156114d1576114d161383a565b60405190808252806020026020018201604052801561157057816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816114ef5790505b50905060008267ffffffffffffffff81111561158e5761158e61383a565b6040519080825280602002602001820160405280156115b7578160200160208202803683370190505b50905060005b838110156119d65760008a82815181106115d9576115d96137cd565b6020908102919091018101518051600090815260329092526040909120805491925090611632576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8c81600101541461166f576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015473ffffffffffffffffffffffffffffffffffffffff8c81169116146116c5576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015474010000000000000000000000000000000000000000900460ff1661171b576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002810154700100000000000000000000000000000000900467ffffffffffffffff1615611775576040517f905e710700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b426002820180547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff811670010000000000000000000000000000000067ffffffffffffffff948516810291821793849055604080516101408101825287548152600188015460208201529386169286169290921791830191909152680100000000000000008304841660608301529091049091166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff161515610100820152600682018054839161012084019161188190613fde565b80601f01602080910402602001604051908101604052809291908181526020018280546118ad90613fde565b80156118fa5780601f106118cf576101008083540402835291602001916118fa565b820191906000526020600020905b8154815290600101906020018083116118dd57829003601f168201915b505050505081525050858481518110611915576119156137cd565b60200260200101819052508160200151848481518110611937576119376137cd565b6020026020010181815250508c8b73ffffffffffffffffffffffffffffffffffffffff1686858151811061196d5761196d6137cd565b602002602001015160c0015173ffffffffffffffffffffffffffffffffffffffff167ff930a6e2523c9cc298691873087a740550b8fc85a0680830414c148ed927f61585600001516040516119c491815260200190565b60405180910390a450506001016115bd565b506119e684838360018b8b6129d2565b9a9950505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152603460209081526040808320858452918290529091205467ffffffffffffffff1615611a68576040517fec9d6eeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526020829052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915590519091859173ffffffffffffffffffffffffffffffffffffffff8816917f92a1f7a41a7c585a8b09e25b195e225b1d43248daca46b0faf9e0792777a222991a450505050565b604080516020808252818301909252606091600091906020820181803683370190505090506000805b6020811015611bbe576000858260208110611b3957611b396137cd565b1a60f81b90507fff000000000000000000000000000000000000000000000000000000000000008116600003611b6f5750611bbe565b80848481518110611b8257611b826137cd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505060019182019101611b1c565b5060008167ffffffffffffffff811115611bda57611bda61383a565b6040519080825280601f01601f191660200182016040528015611c04576020820181803683370190505b50905060005b82811015611c7857838181518110611c2457611c246137cd565b602001015160f81c60f81b828281518110611c4157611c416137cd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611c0a565b50949350505050565b608081015167ffffffffffffffff1615801590611cb557504267ffffffffffffffff16816080015167ffffffffffffffff16105b15611cec576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015160408084015184518351848601518486015160608088015160808901518051908b012060a08a0151928c015173ffffffffffffffffffffffffffffffffffffffff1660009081529a8b9052978a208054999a97999798611313987ff83bb2b0ede93a840239f7e701a54d9bc35f03701f51ae153d601c6947ff3d3f989796959491928b611d7e83614099565b909155506080808f015160408051602081019c909c528b019990995273ffffffffffffffffffffffffffffffffffffffff90971660608a015267ffffffffffffffff9586169689019690965292151560a088015260c087019190915260e086015261010085015261012084019190915216610140820152610160016112f8565b60408051808201909152600081526060602082015284516040805180820190915260008152606060208201528167ffffffffffffffff811115611e4357611e4361383a565b604051908082528060200260200182016040528015611e6c578160200160208202803683370190505b5060208201526040517fa2ea7c6e000000000000000000000000000000000000000000000000000000008152600481018990526000907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611ede573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611f2491908101906140d1565b8051909150611f5f576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008367ffffffffffffffff811115611f7a57611f7a61383a565b60405190808252806020026020018201604052801561201957816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611f985790505b50905060008467ffffffffffffffff8111156120375761203761383a565b604051908082528060200260200182016040528015612060578160200160208202803683370190505b50905060005b858110156124ef5760008b8281518110612082576120826137cd565b60200260200101519050600067ffffffffffffffff16816020015167ffffffffffffffff16141580156120cd57504267ffffffffffffffff16816020015167ffffffffffffffff1611155b15612104576040517f08e8b93700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460400151158015612117575080604001515b1561214e576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006040518061014001604052806000801b81526020018f81526020016121724290565b67ffffffffffffffff168152602001836020015167ffffffffffffffff168152602001600067ffffffffffffffff16815260200183606001518152602001836000015173ffffffffffffffffffffffffffffffffffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff16815260200183604001511515815260200183608001518152509050600080600090505b6122148382612dc3565b600081815260326020526040902054909250156122335760010161220a565b81835260008281526032602090815260409182902085518155908501516001820155908401516002820180546060870151608088015167ffffffffffffffff908116700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff92821668010000000000000000027fffffffffffffffffffffffffffffffff000000000000000000000000000000009094169190951617919091171691909117905560a0840151600382015560c084015160048201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617905560e0850151600583018054610100880151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff000000000000000000000000000000000000000000909116929093169190911791909117905561012084015184919060068201906123b390826141f7565b50505060608401511561240a57606084015160009081526032602052604090205461240a576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8287868151811061241d5761241d6137cd565b60200260200101819052508360a0015186868151811061243f5761243f6137cd565b6020026020010181815250508189602001518681518110612462576124626137cd565b6020026020010181815250508f8e73ffffffffffffffffffffffffffffffffffffffff16856000015173ffffffffffffffffffffffffffffffffffffffff167f8bf46bf4cfd674fa735a3d63ec1c9ad4153f033c290341f3a588b75685141b35856040516124d291815260200190565b60405180910390a4505050506124e88160010190565b9050612066565b506124ff83838360008c8c6129d2565b845250919998505050505050505050565b606060008267ffffffffffffffff81111561252d5761252d61383a565b604051908082528060200260200182016040528015612556578160200160208202803683370190505b508451909150600090815b818110156125ef57600087828151811061257d5761257d6137cd565b6020026020010151905060008151905060005b818110156125db578281815181106125aa576125aa6137cd565b60200260200101518787815181106125c4576125c46137cd565b602090810291909101015260019586019501612590565b5050506125e88160010190565b9050612561565b509195945050505050565b60008281526033602052604090205467ffffffffffffffff161561264a576040517f2e26794600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526033602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051909184917f5aafceeb1c7ad58e4a84898bdee37c02c0fc46e7d24e6b60e8209449f183459f9190a35050565b60003073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561272257507f000000000000000000000000000000000000000000000000000000000000000046145b1561274c57507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b600061072a6127fd6126bc565b83612e22565b60008060006128128585612e64565b9092509050600081600481111561282b5761282b614311565b14801561286357508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b15612873576001925050506129cb565b6000808773ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b88886040516024016128a8929190614340565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516129319190614361565b600060405180830381855afa9150503d806000811461296c576040519150601f19603f3d011682016040523d82523d6000602084013e612971565b606091505b5091509150818015612984575080516020145b80156129c4575080517f1626ba7e00000000000000000000000000000000000000000000000000000000906129c29083016020908101908401614373565b145b9450505050505b9392505050565b84516000906001819003612a2a57612a2288886000815181106129f7576129f76137cd565b602002602001015188600081518110612a1257612a126137cd565b6020026020010151888888612ea9565b915050612db9565b602088015173ffffffffffffffffffffffffffffffffffffffff8116612acb5760005b82811015612ab057878181518110612a6757612a676137cd565b6020026020010151600014612aa8576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101612a4d565b508315612ac057612ac0856131c8565b600092505050612db9565b6000808273ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b3d919061438c565b905060005b84811015612bfa5760008a8281518110612b5e57612b5e6137cd565b6020026020010151905080600003612b765750612bf2565b82612bad576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88811115612be7576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b978890039792909201915b600101612b42565b508715612cd5576040517f88e5b2d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416906388e5b2d9908490612c57908e908e906004016143a9565b60206040518083038185885af1158015612c75573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612c9a919061438c565b612cd0576040517fbf2f3a8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612da4565b6040517f91db0b7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416906391db0b7e908490612d2b908e908e906004016143a9565b60206040518083038185885af1158015612d49573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612d6e919061438c565b612da4576040517fe8bee83900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8515612db357612db3876131c8565b50925050505b9695505050505050565b60208083015160c084015160e0850151604080870151606088015161010089015160a08a01516101208b01519451600099612e0499989796918c9101614462565b60405160208183030381529060405280519060200120905092915050565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526022810183905260428101829052600090606201612e04565b6000808251604103612e9a5760208301516040840151606085015160001a612e8e878285856131db565b94509450505050612ea2565b506000905060025b9250929050565b602086015160009073ffffffffffffffffffffffffffffffffffffffff8116612f1d578515612f04576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215612f1357612f13846131c8565b6000915050612db9565b8515613008578073ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f92919061438c565b612fc8576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83861115613002576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85840393505b84156130e0576040517fe49617e100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e49617e1908890613062908b90600401613740565b60206040518083038185885af1158015613080573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906130a5919061438c565b6130db576040517fccf3bb2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6131ad565b6040517fe60c350500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e60c3505908890613134908b90600401613740565b60206040518083038185885af1158015613152573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190613177919061438c565b6131ad576040517fbd8ba84d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82156131bc576131bc846131c8565b50939695505050505050565b80156131d8576131d833826132f3565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561321257506000905060036132ea565b8460ff16601b1415801561322a57508460ff16601c14155b1561323b57506000905060046132ea565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561328f573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166132e3576000600192509250506132ea565b9150600090505b94509492505050565b80471015613362576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064015b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146133bc576040519150601f19603f3d011682016040523d82523d6000602084013e6133c1565b606091505b5050905080610a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401613359565b60008083601f84011261346457600080fd5b50813567ffffffffffffffff81111561347c57600080fd5b6020830191508360208260051b8501011115612ea257600080fd5b600080602083850312156134aa57600080fd5b823567ffffffffffffffff8111156134c157600080fd5b6134cd85828601613452565b90969095509350505050565b60005b838110156134f45781810151838201526020016134dc565b50506000910152565b600081518084526135158160208601602086016134d9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129cb60208301846134fd565b73ffffffffffffffffffffffffffffffffffffffff811681146131d857600080fd5b80356135878161355a565b919050565b60006020828403121561359e57600080fd5b81356129cb8161355a565b6000602082840312156135bb57600080fd5b813567ffffffffffffffff8111156135d257600080fd5b820160e081850312156129cb57600080fd5b6020808252825182820181905260009190848201906040850190845b8181101561361c57835183529284019291840191600101613600565b50909695505050505050565b60006060828403121561363a57600080fd5b50919050565b60006020828403121561365257600080fd5b5035919050565b600061014082518452602083015160208501526040830151613687604086018267ffffffffffffffff169052565b5060608301516136a3606086018267ffffffffffffffff169052565b5060808301516136bf608086018267ffffffffffffffff169052565b5060a083015160a085015260c08301516136f160c086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060e083015161371960e086018273ffffffffffffffffffffffffffffffffffffffff169052565b506101008381015115159085015261012080840151818601839052612db9838701826134fd565b6020815260006129cb6020830184613659565b6000610100828403121561363a57600080fd5b6000806040838503121561377957600080fd5b82356137848161355a565b946020939093013593505050565b6000602082840312156137a457600080fd5b813567ffffffffffffffff8111156137bb57600080fd5b8201604081850312156129cb57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261383057600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561388c5761388c61383a565b60405290565b60405160c0810167ffffffffffffffff8111828210171561388c5761388c61383a565b6040516080810167ffffffffffffffff8111828210171561388c5761388c61383a565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561391f5761391f61383a565b604052919050565b600067ffffffffffffffff8211156139415761394161383a565b5060051b60200190565b60006040828403121561395d57600080fd5b6040516040810181811067ffffffffffffffff821117156139805761398061383a565b604052823581526020928301359281019290925250919050565b6000606082840312156139ac57600080fd5b6040516060810181811067ffffffffffffffff821117156139cf576139cf61383a565b604052905080823560ff811681146139e657600080fd5b8082525060208301356020820152604083013560408201525092915050565b600082601f830112613a1657600080fd5b81356020613a2b613a2683613927565b6138d8565b82815260609283028501820192828201919087851115613a4a57600080fd5b8387015b85811015613a6d57613a60898261399a565b8452928401928101613a4e565b5090979650505050505050565b803567ffffffffffffffff8116811461358757600080fd5b600060a08236031215613aa457600080fd5b613aac613869565b8235815260208084013567ffffffffffffffff80821115613acc57600080fd5b9085019036601f830112613adf57600080fd5b8135613aed613a2682613927565b81815260069190911b83018401908481019036831115613b0c57600080fd5b938501935b82851015613b3557613b23368661394b565b82528582019150604085019450613b11565b80868801525050506040860135925080831115613b5157600080fd5b5050613b5f36828601613a05565b604083015250613b716060840161357c565b6060820152613b8260808401613a7a565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561072a5761072a613b8d565b80151581146131d857600080fd5b600067ffffffffffffffff821115613bf757613bf761383a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600060c08284031215613c3557600080fd5b613c3d613892565b90508135613c4a8161355a565b81526020613c59838201613a7a565b818301526040830135613c6b81613bcf565b604083015260608381013590830152608083013567ffffffffffffffff811115613c9457600080fd5b8301601f81018513613ca557600080fd5b8035613cb3613a2682613bdd565b8181528684838501011115613cc757600080fd5b818484018583013760008483830101528060808601525050505060a082013560a082015292915050565b600060e08236031215613d0357600080fd5b613d0b613869565b82358152602083013567ffffffffffffffff811115613d2957600080fd5b613d3536828601613c23565b602083015250613d48366040850161399a565b604082015260a0830135613d5b8161355a565b6060820152613b8260c08401613a7a565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4183360301811261383057600080fd5b600061072a3683613c23565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261383057600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613e1557600080fd5b83018035915067ffffffffffffffff821115613e3057600080fd5b6020019150600581901b3603821315612ea257600080fd5b6000613e56613a2684613927565b80848252602080830192508560051b850136811115613e7457600080fd5b855b81811015613eb057803567ffffffffffffffff811115613e965760008081fd5b613ea236828a01613c23565b865250938201938201613e76565b50919695505050505050565b600060408284031215613ece57600080fd5b6129cb838361394b565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f0d57600080fd5b83018035915067ffffffffffffffff821115613f2857600080fd5b6020019150600681901b3603821315612ea257600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f7557600080fd5b83018035915067ffffffffffffffff821115613f9057600080fd5b6020019150606081023603821315612ea257600080fd5b600060608284031215613fb957600080fd5b6129cb838361399a565b600060208284031215613fd557600080fd5b6129cb82613a7a565b600181811c90821680613ff257607f821691505b60208210810361363a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000610100828403121561403e57600080fd5b614046613869565b82358152614057846020850161394b565b6020820152614069846060850161399a565b604082015260c083013561407c8161355a565b606082015261408d60e08401613a7a565b60808201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036140ca576140ca613b8d565b5060010190565b600060208083850312156140e457600080fd5b825167ffffffffffffffff808211156140fc57600080fd5b908401906080828703121561411057600080fd5b6141186138b5565b82518152838301516141298161355a565b81850152604083015161413b81613bcf565b604082015260608301518281111561415257600080fd5b80840193505086601f84011261416757600080fd5b82519150614177613a2683613bdd565b828152878584860101111561418b57600080fd5b61419a838683018787016134d9565b60608201529695505050505050565b601f821115610a6357600081815260208120601f850160051c810160208610156141d05750805b601f850160051c820191505b818110156141ef578281556001016141dc565b505050505050565b815167ffffffffffffffff8111156142115761421161383a565b6142258161421f8454613fde565b846141a9565b602080601f83116001811461427857600084156142425750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556141ef565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156142c5578886015182559484019460019091019084016142a6565b508582101561430157878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b82815260406020820152600061435960408301846134fd565b949350505050565b600082516138308184602087016134d9565b60006020828403121561438557600080fd5b5051919050565b60006020828403121561439e57600080fd5b81516129cb81613bcf565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b8381101561441e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261440c868351613659565b955093820193908201906001016143d2565b50508584038187015286518085528782019482019350915060005b8281101561445557845184529381019392810192600101614439565b5091979650505050505050565b89815260007fffffffffffffffffffffffffffffffffffffffff000000000000000000000000808b60601b166020840152808a60601b166034840152507fffffffffffffffff000000000000000000000000000000000000000000000000808960c01b166048840152808860c01b1660508401525085151560f81b605883015284605983015283516144fb8160798501602088016134d9565b80830190507fffffffff000000000000000000000000000000000000000000000000000000008460e01b166079820152607d81019150509a995050505050505050505056fea164736f6c6343000813000a",
Bin: "0x61016060405234801561001157600080fd5b50604080518082018252600381526245415360e81b60208083019182528351808501855260058152640312e332e360dc1b908201529151812060e08190527f6a08c3e203132c561752255a4d52ffae85bb9c5d33cb3291520dea1b843563896101008190524660a081815286517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818801819052818901959095526060810193909352608080840192909252308382018190528751808503909201825260c093840190975280519501949094209093529290915261012091909152516101405260805160a05160c05160e05161010051610120516101405161457e61014b600039600061073701526000612784015260006127d3015260006127ae01526000612707015260006127310152600061275b015261457e6000f3fe60806040526004361061018b5760003560e01c806395411525116100d6578063d45c44351161007f578063ed24911d11610059578063ed24911d146104fd578063f10b5cc814610512578063f17325e71461054157600080fd5b8063d45c443514610467578063e30bb5631461049e578063e71ff365146104dd57600080fd5b8063b469318d116100b0578063b469318d146103ba578063b83010d314610414578063cf190f341461044757600080fd5b80639541152514610367578063a3112a641461037a578063a6d4dbc7146103a757600080fd5b806344adc90e116101385780634d003070116101125780634d003070146102de57806354fd4d50146102fe57806379f7573a1461034757600080fd5b806344adc90e1461029857806346926267146102b85780634cb7e9e5146102cb57600080fd5b806317d7de7c1161016957806317d7de7c146102205780632d0335ab146102425780633c0427151461028557600080fd5b80630eabf6601461019057806312b11a17146101a557806313893f61146101e7575b600080fd5b6101a361019e3660046134c8565b610554565b005b3480156101b157600080fd5b507ffeb2925a02bae3dae48d424a0437a2b6ac939aa9230ddc55a1a76f065d9880765b6040519081526020015b60405180910390f35b3480156101f357600080fd5b506102076102023660046134c8565b6106eb565b60405167ffffffffffffffff90911681526020016101de565b34801561022c57600080fd5b50610235610730565b6040516101de9190613578565b34801561024e57600080fd5b506101d461025d3660046135bd565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101d46102933660046135da565b610760565b6102ab6102a63660046134c8565b610863565b6040516101de9190613615565b6101a36102c6366004613659565b6109e4565b6101a36102d93660046134c8565b610a68565b3480156102ea57600080fd5b506102076102f9366004613671565b610b4b565b34801561030a57600080fd5b506102356040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b34801561035357600080fd5b506101a3610362366004613671565b610b58565b6102ab6103753660046134c8565b610bef565b34801561038657600080fd5b5061039a610395366004613671565b610e62565b6040516101de9190613771565b6101a36103b5366004613784565b611025565b3480156103c657600080fd5b506102076103d5366004613797565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152603460209081526040808320938352929052205467ffffffffffffffff1690565b34801561042057600080fd5b507fb5d556f07587ec0f08cf386545cc4362c702a001650c2058002615ee5c9d1e756101d4565b34801561045357600080fd5b50610207610462366004613671565b6110ca565b34801561047357600080fd5b50610207610482366004613671565b60009081526033602052604090205467ffffffffffffffff1690565b3480156104aa57600080fd5b506104cd6104b9366004613671565b600090815260326020526040902054151590565b60405190151581526020016101de565b3480156104e957600080fd5b506102076104f83660046134c8565b6110d8565b34801561050957600080fd5b506101d4611110565b34801561051e57600080fd5b5060405173420000000000000000000000000000000000002081526020016101de565b6101d461054f3660046137c3565b61111a565b348160005b818110156106e4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82018114600086868481811061059a5761059a6137fe565b90506020028101906105ac919061382d565b6105b590613ac3565b60208101518051919250908015806105d257508260400151518114155b15610609576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156106ad576106a56040518060a001604052808660000151815260200185848151811061063e5761063e6137fe565b6020026020010151815260200186604001518481518110610661576106616137fe565b60200260200101518152602001866060015173ffffffffffffffffffffffffffffffffffffffff168152602001866080015167ffffffffffffffff168152506111d8565b60010161060c565b506106c383600001518385606001518a886113e9565b6106cd9088613bed565b9650505050506106dd8160010190565b9050610559565b5050505050565b60004282825b818110156107245761071c3387878481811061070f5761070f6137fe565b9050602002013585611a18565b6001016106f1565b50909150505b92915050565b606061075b7f0000000000000000000000000000000000000000000000000000000000000000611b17565b905090565b600061077361076e83613d22565b611ca5565b604080516001808252818301909252600091816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161078a5790505090506107f86020840184613d9d565b61080190613dd1565b81600081518110610814576108146137fe565b602090810291909101015261083d83358261083560c0870160a088016135bd565b346001611e2f565b60200151600081518110610853576108536137fe565b6020026020010151915050919050565b60608160008167ffffffffffffffff8111156108815761088161386b565b6040519080825280602002602001820160405280156108b457816020015b606081526020019060019003908161089f5790505b509050600034815b848110156109ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85018114368989848181106108fc576108fc6137fe565b905060200281019061090e9190613ddd565b905061091d6020820182613e11565b9050600003610958576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061097d823561096c6020850185613e11565b61097591613e79565b338887611e2f565b805190915061098c9086613bed565b945080602001518785815181106109a5576109a56137fe565b6020026020010181905250806020015151860195505050506109c78160010190565b90506108bc565b506109d98383612541565b979650505050505050565b604080516001808252818301909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816109fb579050509050610a3636839003830160208401613eed565b81600081518110610a4957610a496137fe565b6020908102919091010152610a63823582333460016113e9565b505050565b348160005b818110156106e4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201811436868684818110610aad57610aad6137fe565b9050602002810190610abf9190613ddd565b9050610b2c8135610ad36020840184613f09565b808060200260200160405190810160405280939291908181526020016000905b82821015610b1f57610b1060408302860136819003810190613eed565b81526020019060010190610af3565b50505050503388866113e9565b610b369086613bed565b94505050610b448160010190565b9050610a6d565b60004261072a838261262b565b33600090815260208190526040902054808211610ba1576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152602081815260409182902084905581518381529081018490527f57b09af877df9068fd60a69d7b21f5576b8b38955812d6ae4ac52942f1e38fb7910160405180910390a15050565b60608160008167ffffffffffffffff811115610c0d57610c0d61386b565b604051908082528060200260200182016040528015610c4057816020015b6060815260200190600190039081610c2b5790505b509050600034815b848110156109ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8501811436898984818110610c8857610c886137fe565b9050602002810190610c9a919061382d565b9050366000610cac6020840184613e11565b909250905080801580610ccd5750610cc76040850185613f71565b90508114155b15610d04576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610de557610ddd6040518060a0016040528087600001358152602001868685818110610d3957610d396137fe565b9050602002810190610d4b9190613d9d565b610d5490613dd1565b8152602001610d666040890189613f71565b85818110610d7657610d766137fe565b905060600201803603810190610d8c9190613fd8565b8152602001610da16080890160608a016135bd565b73ffffffffffffffffffffffffffffffffffffffff168152602001610dcc60a0890160808a01613ff4565b67ffffffffffffffff169052611ca5565b600101610d07565b506000610e0e8535610df78587613e79565b610e076080890160608a016135bd565b8b8a611e2f565b8051909150610e1d9089613bed565b975080602001518a8881518110610e3657610e366137fe565b602002602001018190525080602001515189019850505050505050610e5b8160010190565b9050610c48565b604080516101408101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e0820183905261010082019290925261012081019190915260008281526032602090815260409182902082516101408101845281548152600182015492810192909252600281015467ffffffffffffffff808216948401949094526801000000000000000081048416606084015270010000000000000000000000000000000090049092166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff16151561010082015260068201805491929161012084019190610f9c9061400f565b80601f0160208091040260200160405190810160405280929190818152602001828054610fc89061400f565b80156110155780601f10610fea57610100808354040283529160200191611015565b820191906000526020600020905b815481529060010190602001808311610ff857829003601f168201915b5050505050815250509050919050565b61103c6110373683900383018361405c565b6111d8565b604080516001808252818301909252600091816020015b604080518082019091526000808252602082015281526020019060019003908161105357905050905061108e36839003830160208401613eed565b816000815181106110a1576110a16137fe565b6020908102919091010152610a638235826110c260e0860160c087016135bd565b3460016113e9565b60004261072a338483611a18565b60004282825b81811015610724576111088686838181106110fb576110fb6137fe565b905060200201358461262b565b6001016110de565b600061075b6126ed565b604080516001808252818301909252600091829190816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816111345790505090506111a26020840184613d9d565b6111ab90613dd1565b816000815181106111be576111be6137fe565b602090810291909101015261083d83358233346001611e2f565b608081015167ffffffffffffffff161580159061120c57504267ffffffffffffffff16816080015167ffffffffffffffff16105b15611243576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201516040808401516060850151855184518587015173ffffffffffffffffffffffffffffffffffffffff84166000908152978890529487208054969794969495611337957fb5d556f07587ec0f08cf386545cc4362c702a001650c2058002615ee5c9d1e7595949392886112ba836140ca565b909155506080808c015160408051602081019990995273ffffffffffffffffffffffffffffffffffffffff9097169688019690965260608701949094529285019190915260a084015260c083015267ffffffffffffffff1660e0820152610100015b60405160208183030381529060405280519060200120612821565b90506113ad84606001518284602001518560400151866000015160405160200161139993929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b604051602081830303815290604052612834565b6113e3576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6040517fa2ea7c6e0000000000000000000000000000000000000000000000000000000081526004810186905260009081907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261149d9190810190614102565b80519091506114d8576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b855160008167ffffffffffffffff8111156114f5576114f561386b565b60405190808252806020026020018201604052801561159457816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816115135790505b50905060008267ffffffffffffffff8111156115b2576115b261386b565b6040519080825280602002602001820160405280156115db578160200160208202803683370190505b50905060005b838110156119fa5760008a82815181106115fd576115fd6137fe565b6020908102919091018101518051600090815260329092526040909120805491925090611656576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8c816001015414611693576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015473ffffffffffffffffffffffffffffffffffffffff8c81169116146116e9576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015474010000000000000000000000000000000000000000900460ff1661173f576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002810154700100000000000000000000000000000000900467ffffffffffffffff1615611799576040517f905e710700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b426002820180547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff811670010000000000000000000000000000000067ffffffffffffffff948516810291821793849055604080516101408101825287548152600188015460208201529386169286169290921791830191909152680100000000000000008304841660608301529091049091166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff16151561010082015260068201805483916101208401916118a59061400f565b80601f01602080910402602001604051908101604052809291908181526020018280546118d19061400f565b801561191e5780601f106118f35761010080835404028352916020019161191e565b820191906000526020600020905b81548152906001019060200180831161190157829003601f168201915b505050505081525050858481518110611939576119396137fe565b6020026020010181905250816020015184848151811061195b5761195b6137fe565b6020026020010181815250508c8b73ffffffffffffffffffffffffffffffffffffffff16868581518110611991576119916137fe565b602002602001015160c0015173ffffffffffffffffffffffffffffffffffffffff167ff930a6e2523c9cc298691873087a740550b8fc85a0680830414c148ed927f61585600001516040516119e891815260200190565b60405180910390a450506001016115e1565b50611a0a84838360018b8b612a03565b9a9950505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152603460209081526040808320858452918290529091205467ffffffffffffffff1615611a8c576040517fec9d6eeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526020829052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915590519091859173ffffffffffffffffffffffffffffffffffffffff8816917f92a1f7a41a7c585a8b09e25b195e225b1d43248daca46b0faf9e0792777a222991a450505050565b604080516020808252818301909252606091600091906020820181803683370190505090506000805b6020811015611be2576000858260208110611b5d57611b5d6137fe565b1a60f81b90507fff000000000000000000000000000000000000000000000000000000000000008116600003611b935750611be2565b80848481518110611ba657611ba66137fe565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505060019182019101611b40565b5060008167ffffffffffffffff811115611bfe57611bfe61386b565b6040519080825280601f01601f191660200182016040528015611c28576020820181803683370190505b50905060005b82811015611c9c57838181518110611c4857611c486137fe565b602001015160f81c60f81b828281518110611c6557611c656137fe565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611c2e565b50949350505050565b608081015167ffffffffffffffff1615801590611cd957504267ffffffffffffffff16816080015167ffffffffffffffff16105b15611d10576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201516040808401516060808601518651855186880151868801519488015160808901518051908b012060a08a015173ffffffffffffffffffffffffffffffffffffffff871660009081529b8c9052988b2080549a9b989a9899611337997ffeb2925a02bae3dae48d424a0437a2b6ac939aa9230ddc55a1a76f065d988076999493928c611da0836140ca565b919050558e6080015160405160200161131c9b9a999897969594939291909a8b5273ffffffffffffffffffffffffffffffffffffffff998a1660208c015260408b019890985295909716606089015267ffffffffffffffff938416608089015291151560a088015260c087015260e0860152610100850193909352610120840152166101408201526101600190565b60408051808201909152600081526060602082015284516040805180820190915260008152606060208201528167ffffffffffffffff811115611e7457611e7461386b565b604051908082528060200260200182016040528015611e9d578160200160208202803683370190505b5060208201526040517fa2ea7c6e000000000000000000000000000000000000000000000000000000008152600481018990526000907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611f0f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611f559190810190614102565b8051909150611f90576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008367ffffffffffffffff811115611fab57611fab61386b565b60405190808252806020026020018201604052801561204a57816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611fc95790505b50905060008467ffffffffffffffff8111156120685761206861386b565b604051908082528060200260200182016040528015612091578160200160208202803683370190505b50905060005b858110156125205760008b82815181106120b3576120b36137fe565b60200260200101519050600067ffffffffffffffff16816020015167ffffffffffffffff16141580156120fe57504267ffffffffffffffff16816020015167ffffffffffffffff1611155b15612135576040517f08e8b93700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460400151158015612148575080604001515b1561217f576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006040518061014001604052806000801b81526020018f81526020016121a34290565b67ffffffffffffffff168152602001836020015167ffffffffffffffff168152602001600067ffffffffffffffff16815260200183606001518152602001836000015173ffffffffffffffffffffffffffffffffffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff16815260200183604001511515815260200183608001518152509050600080600090505b6122458382612df4565b600081815260326020526040902054909250156122645760010161223b565b81835260008281526032602090815260409182902085518155908501516001820155908401516002820180546060870151608088015167ffffffffffffffff908116700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff92821668010000000000000000027fffffffffffffffffffffffffffffffff000000000000000000000000000000009094169190951617919091171691909117905560a0840151600382015560c084015160048201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617905560e0850151600583018054610100880151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff000000000000000000000000000000000000000000909116929093169190911791909117905561012084015184919060068201906123e49082614228565b50505060608401511561243b57606084015160009081526032602052604090205461243b576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8287868151811061244e5761244e6137fe565b60200260200101819052508360a00151868681518110612470576124706137fe565b6020026020010181815250508189602001518681518110612493576124936137fe565b6020026020010181815250508f8e73ffffffffffffffffffffffffffffffffffffffff16856000015173ffffffffffffffffffffffffffffffffffffffff167f8bf46bf4cfd674fa735a3d63ec1c9ad4153f033c290341f3a588b75685141b358560405161250391815260200190565b60405180910390a4505050506125198160010190565b9050612097565b5061253083838360008c8c612a03565b845250919998505050505050505050565b606060008267ffffffffffffffff81111561255e5761255e61386b565b604051908082528060200260200182016040528015612587578160200160208202803683370190505b508451909150600090815b818110156126205760008782815181106125ae576125ae6137fe565b6020026020010151905060008151905060005b8181101561260c578281815181106125db576125db6137fe565b60200260200101518787815181106125f5576125f56137fe565b6020908102919091010152600195860195016125c1565b5050506126198160010190565b9050612592565b509195945050505050565b60008281526033602052604090205467ffffffffffffffff161561267b576040517f2e26794600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526033602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051909184917f5aafceeb1c7ad58e4a84898bdee37c02c0fc46e7d24e6b60e8209449f183459f9190a35050565b60003073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561275357507f000000000000000000000000000000000000000000000000000000000000000046145b1561277d57507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b600061072a61282e6126ed565b83612e53565b60008060006128438585612e95565b9092509050600081600481111561285c5761285c614342565b14801561289457508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b156128a4576001925050506129fc565b6000808773ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b88886040516024016128d9929190614371565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516129629190614392565b600060405180830381855afa9150503d806000811461299d576040519150601f19603f3d011682016040523d82523d6000602084013e6129a2565b606091505b50915091508180156129b5575080516020145b80156129f5575080517f1626ba7e00000000000000000000000000000000000000000000000000000000906129f390830160209081019084016143a4565b145b9450505050505b9392505050565b84516000906001819003612a5b57612a538888600081518110612a2857612a286137fe565b602002602001015188600081518110612a4357612a436137fe565b6020026020010151888888612eda565b915050612dea565b602088015173ffffffffffffffffffffffffffffffffffffffff8116612afc5760005b82811015612ae157878181518110612a9857612a986137fe565b6020026020010151600014612ad9576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101612a7e565b508315612af157612af1856131f9565b600092505050612dea565b6000808273ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b6e91906143bd565b905060005b84811015612c2b5760008a8281518110612b8f57612b8f6137fe565b6020026020010151905080600003612ba75750612c23565b82612bde576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88811115612c18576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b978890039792909201915b600101612b73565b508715612d06576040517f88e5b2d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416906388e5b2d9908490612c88908e908e906004016143da565b60206040518083038185885af1158015612ca6573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612ccb91906143bd565b612d01576040517fbf2f3a8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612dd5565b6040517f91db0b7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416906391db0b7e908490612d5c908e908e906004016143da565b60206040518083038185885af1158015612d7a573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612d9f91906143bd565b612dd5576040517fe8bee83900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8515612de457612de4876131f9565b50925050505b9695505050505050565b60208083015160c084015160e0850151604080870151606088015161010089015160a08a01516101208b01519451600099612e3599989796918c9101614493565b60405160208183030381529060405280519060200120905092915050565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526022810183905260428101829052600090606201612e35565b6000808251604103612ecb5760208301516040840151606085015160001a612ebf8782858561320c565b94509450505050612ed3565b506000905060025b9250929050565b602086015160009073ffffffffffffffffffffffffffffffffffffffff8116612f4e578515612f35576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215612f4457612f44846131f9565b6000915050612dea565b8515613039578073ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fc391906143bd565b612ff9576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83861115613033576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85840393505b8415613111576040517fe49617e100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e49617e1908890613093908b90600401613771565b60206040518083038185885af11580156130b1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906130d691906143bd565b61310c576040517fccf3bb2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6131de565b6040517fe60c350500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e60c3505908890613165908b90600401613771565b60206040518083038185885af1158015613183573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906131a891906143bd565b6131de576040517fbd8ba84d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82156131ed576131ed846131f9565b50939695505050505050565b8015613209576132093382613324565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613243575060009050600361331b565b8460ff16601b1415801561325b57508460ff16601c14155b1561326c575060009050600461331b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156132c0573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166133145760006001925092505061331b565b9150600090505b94509492505050565b80471015613393576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064015b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146133ed576040519150601f19603f3d011682016040523d82523d6000602084013e6133f2565b606091505b5050905080610a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d61792068617665207265766572746564000000000000606482015260840161338a565b60008083601f84011261349557600080fd5b50813567ffffffffffffffff8111156134ad57600080fd5b6020830191508360208260051b8501011115612ed357600080fd5b600080602083850312156134db57600080fd5b823567ffffffffffffffff8111156134f257600080fd5b6134fe85828601613483565b90969095509350505050565b60005b8381101561352557818101518382015260200161350d565b50506000910152565b6000815180845261354681602086016020860161350a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129fc602083018461352e565b73ffffffffffffffffffffffffffffffffffffffff8116811461320957600080fd5b80356135b88161358b565b919050565b6000602082840312156135cf57600080fd5b81356129fc8161358b565b6000602082840312156135ec57600080fd5b813567ffffffffffffffff81111561360357600080fd5b820160e081850312156129fc57600080fd5b6020808252825182820181905260009190848201906040850190845b8181101561364d57835183529284019291840191600101613631565b50909695505050505050565b60006060828403121561366b57600080fd5b50919050565b60006020828403121561368357600080fd5b5035919050565b6000610140825184526020830151602085015260408301516136b8604086018267ffffffffffffffff169052565b5060608301516136d4606086018267ffffffffffffffff169052565b5060808301516136f0608086018267ffffffffffffffff169052565b5060a083015160a085015260c083015161372260c086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060e083015161374a60e086018273ffffffffffffffffffffffffffffffffffffffff169052565b506101008381015115159085015261012080840151818601839052612dea8387018261352e565b6020815260006129fc602083018461368a565b6000610100828403121561366b57600080fd5b600080604083850312156137aa57600080fd5b82356137b58161358b565b946020939093013593505050565b6000602082840312156137d557600080fd5b813567ffffffffffffffff8111156137ec57600080fd5b8201604081850312156129fc57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261386157600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff811182821017156138bd576138bd61386b565b60405290565b60405160c0810167ffffffffffffffff811182821017156138bd576138bd61386b565b6040516080810167ffffffffffffffff811182821017156138bd576138bd61386b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156139505761395061386b565b604052919050565b600067ffffffffffffffff8211156139725761397261386b565b5060051b60200190565b60006040828403121561398e57600080fd5b6040516040810181811067ffffffffffffffff821117156139b1576139b161386b565b604052823581526020928301359281019290925250919050565b6000606082840312156139dd57600080fd5b6040516060810181811067ffffffffffffffff82111715613a0057613a0061386b565b604052905080823560ff81168114613a1757600080fd5b8082525060208301356020820152604083013560408201525092915050565b600082601f830112613a4757600080fd5b81356020613a5c613a5783613958565b613909565b82815260609283028501820192828201919087851115613a7b57600080fd5b8387015b85811015613a9e57613a9189826139cb565b8452928401928101613a7f565b5090979650505050505050565b803567ffffffffffffffff811681146135b857600080fd5b600060a08236031215613ad557600080fd5b613add61389a565b8235815260208084013567ffffffffffffffff80821115613afd57600080fd5b9085019036601f830112613b1057600080fd5b8135613b1e613a5782613958565b81815260069190911b83018401908481019036831115613b3d57600080fd5b938501935b82851015613b6657613b54368661397c565b82528582019150604085019450613b42565b80868801525050506040860135925080831115613b8257600080fd5b5050613b9036828601613a36565b604083015250613ba2606084016135ad565b6060820152613bb360808401613aab565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561072a5761072a613bbe565b801515811461320957600080fd5b600067ffffffffffffffff821115613c2857613c2861386b565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600060c08284031215613c6657600080fd5b613c6e6138c3565b90508135613c7b8161358b565b81526020613c8a838201613aab565b818301526040830135613c9c81613c00565b604083015260608381013590830152608083013567ffffffffffffffff811115613cc557600080fd5b8301601f81018513613cd657600080fd5b8035613ce4613a5782613c0e565b8181528684838501011115613cf857600080fd5b818484018583013760008483830101528060808601525050505060a082013560a082015292915050565b600060e08236031215613d3457600080fd5b613d3c61389a565b82358152602083013567ffffffffffffffff811115613d5a57600080fd5b613d6636828601613c54565b602083015250613d7936604085016139cb565b604082015260a0830135613d8c8161358b565b6060820152613bb360c08401613aab565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4183360301811261386157600080fd5b600061072a3683613c54565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261386157600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613e4657600080fd5b83018035915067ffffffffffffffff821115613e6157600080fd5b6020019150600581901b3603821315612ed357600080fd5b6000613e87613a5784613958565b80848252602080830192508560051b850136811115613ea557600080fd5b855b81811015613ee157803567ffffffffffffffff811115613ec75760008081fd5b613ed336828a01613c54565b865250938201938201613ea7565b50919695505050505050565b600060408284031215613eff57600080fd5b6129fc838361397c565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f3e57600080fd5b83018035915067ffffffffffffffff821115613f5957600080fd5b6020019150600681901b3603821315612ed357600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613fa657600080fd5b83018035915067ffffffffffffffff821115613fc157600080fd5b6020019150606081023603821315612ed357600080fd5b600060608284031215613fea57600080fd5b6129fc83836139cb565b60006020828403121561400657600080fd5b6129fc82613aab565b600181811c9082168061402357607f821691505b60208210810361366b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000610100828403121561406f57600080fd5b61407761389a565b82358152614088846020850161397c565b602082015261409a84606085016139cb565b604082015260c08301356140ad8161358b565b60608201526140be60e08401613aab565b60808201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036140fb576140fb613bbe565b5060010190565b6000602080838503121561411557600080fd5b825167ffffffffffffffff8082111561412d57600080fd5b908401906080828703121561414157600080fd5b6141496138e6565b825181528383015161415a8161358b565b81850152604083015161416c81613c00565b604082015260608301518281111561418357600080fd5b80840193505086601f84011261419857600080fd5b825191506141a8613a5783613c0e565b82815287858486010111156141bc57600080fd5b6141cb8386830187870161350a565b60608201529695505050505050565b601f821115610a6357600081815260208120601f850160051c810160208610156142015750805b601f850160051c820191505b818110156142205782815560010161420d565b505050505050565b815167ffffffffffffffff8111156142425761424261386b565b61425681614250845461400f565b846141da565b602080601f8311600181146142a957600084156142735750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555614220565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156142f6578886015182559484019460019091019084016142d7565b508582101561433257878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b82815260406020820152600061438a604083018461352e565b949350505050565b6000825161386181846020870161350a565b6000602082840312156143b657600080fd5b5051919050565b6000602082840312156143cf57600080fd5b81516129fc81613c00565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b8381101561444f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261443d86835161368a565b95509382019390820190600101614403565b50508584038187015286518085528782019482019350915060005b828110156144865784518452938101939281019260010161446a565b5091979650505050505050565b89815260007fffffffffffffffffffffffffffffffffffffffff000000000000000000000000808b60601b166020840152808a60601b166034840152507fffffffffffffffff000000000000000000000000000000000000000000000000808960c01b166048840152808860c01b1660508401525085151560f81b6058830152846059830152835161452c81607985016020880161350a565b80830190507fffffffff000000000000000000000000000000000000000000000000000000008460e01b166079820152607d81019150509a995050505050505050505056fea164736f6c6343000813000a",
}
// EASABI is the input ABI used to generate the binding from.
......
......@@ -13,7 +13,7 @@ const EASStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/E
var EASStorageLayout = new(solc.StorageLayout)
var EASDeployedBin = "0x60806040526004361061018b5760003560e01c806395411525116100d6578063d45c44351161007f578063ed24911d11610059578063ed24911d146104fd578063f10b5cc814610512578063f17325e71461054157600080fd5b8063d45c443514610467578063e30bb5631461049e578063e71ff365146104dd57600080fd5b8063b469318d116100b0578063b469318d146103ba578063b83010d314610414578063cf190f341461044757600080fd5b80639541152514610367578063a3112a641461037a578063a6d4dbc7146103a757600080fd5b806344adc90e116101385780634d003070116101125780634d003070146102de57806354fd4d50146102fe57806379f7573a1461034757600080fd5b806344adc90e1461029857806346926267146102b85780634cb7e9e5146102cb57600080fd5b806317d7de7c1161016957806317d7de7c146102205780632d0335ab146102425780633c0427151461028557600080fd5b80630eabf6601461019057806312b11a17146101a557806313893f61146101e7575b600080fd5b6101a361019e366004613497565b610554565b005b3480156101b157600080fd5b507ff83bb2b0ede93a840239f7e701a54d9bc35f03701f51ae153d601c6947ff3d3f5b6040519081526020015b60405180910390f35b3480156101f357600080fd5b50610207610202366004613497565b6106eb565b60405167ffffffffffffffff90911681526020016101de565b34801561022c57600080fd5b50610235610730565b6040516101de9190613547565b34801561024e57600080fd5b506101d461025d36600461358c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101d46102933660046135a9565b610760565b6102ab6102a6366004613497565b610863565b6040516101de91906135e4565b6101a36102c6366004613628565b6109e4565b6101a36102d9366004613497565b610a68565b3480156102ea57600080fd5b506102076102f9366004613640565b610b4b565b34801561030a57600080fd5b506102356040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b34801561035357600080fd5b506101a3610362366004613640565b610b58565b6102ab610375366004613497565b610bef565b34801561038657600080fd5b5061039a610395366004613640565b610e62565b6040516101de9190613740565b6101a36103b5366004613753565b611025565b3480156103c657600080fd5b506102076103d5366004613766565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152603460209081526040808320938352929052205467ffffffffffffffff1690565b34801561042057600080fd5b507f2d4116d8c9824e4c316453e5c2843a1885580374159ce8768603c49085ef424c6101d4565b34801561045357600080fd5b50610207610462366004613640565b6110ca565b34801561047357600080fd5b50610207610482366004613640565b60009081526033602052604090205467ffffffffffffffff1690565b3480156104aa57600080fd5b506104cd6104b9366004613640565b600090815260326020526040902054151590565b60405190151581526020016101de565b3480156104e957600080fd5b506102076104f8366004613497565b6110d8565b34801561050957600080fd5b506101d4611110565b34801561051e57600080fd5b5060405173420000000000000000000000000000000000002081526020016101de565b6101d461054f366004613792565b61111a565b348160005b818110156106e4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82018114600086868481811061059a5761059a6137cd565b90506020028101906105ac91906137fc565b6105b590613a92565b60208101518051919250908015806105d257508260400151518114155b15610609576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156106ad576106a56040518060a001604052808660000151815260200185848151811061063e5761063e6137cd565b6020026020010151815260200186604001518481518110610661576106616137cd565b60200260200101518152602001866060015173ffffffffffffffffffffffffffffffffffffffff168152602001866080015167ffffffffffffffff168152506111d8565b60010161060c565b506106c383600001518385606001518a886113c5565b6106cd9088613bbc565b9650505050506106dd8160010190565b9050610559565b5050505050565b60004282825b818110156107245761071c3387878481811061070f5761070f6137cd565b90506020020135856119f4565b6001016106f1565b50909150505b92915050565b606061075b7f0000000000000000000000000000000000000000000000000000000000000000611af3565b905090565b600061077361076e83613cf1565b611c81565b604080516001808252818301909252600091816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161078a5790505090506107f86020840184613d6c565b61080190613da0565b81600081518110610814576108146137cd565b602090810291909101015261083d83358261083560c0870160a0880161358c565b346001611dfe565b60200151600081518110610853576108536137cd565b6020026020010151915050919050565b60608160008167ffffffffffffffff8111156108815761088161383a565b6040519080825280602002602001820160405280156108b457816020015b606081526020019060019003908161089f5790505b509050600034815b848110156109ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85018114368989848181106108fc576108fc6137cd565b905060200281019061090e9190613dac565b905061091d6020820182613de0565b9050600003610958576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061097d823561096c6020850185613de0565b61097591613e48565b338887611dfe565b805190915061098c9086613bbc565b945080602001518785815181106109a5576109a56137cd565b6020026020010181905250806020015151860195505050506109c78160010190565b90506108bc565b506109d98383612510565b979650505050505050565b604080516001808252818301909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816109fb579050509050610a3636839003830160208401613ebc565b81600081518110610a4957610a496137cd565b6020908102919091010152610a63823582333460016113c5565b505050565b348160005b818110156106e4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201811436868684818110610aad57610aad6137cd565b9050602002810190610abf9190613dac565b9050610b2c8135610ad36020840184613ed8565b808060200260200160405190810160405280939291908181526020016000905b82821015610b1f57610b1060408302860136819003810190613ebc565b81526020019060010190610af3565b50505050503388866113c5565b610b369086613bbc565b94505050610b448160010190565b9050610a6d565b60004261072a83826125fa565b33600090815260208190526040902054808211610ba1576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152602081815260409182902084905581518381529081018490527f57b09af877df9068fd60a69d7b21f5576b8b38955812d6ae4ac52942f1e38fb7910160405180910390a15050565b60608160008167ffffffffffffffff811115610c0d57610c0d61383a565b604051908082528060200260200182016040528015610c4057816020015b6060815260200190600190039081610c2b5790505b509050600034815b848110156109ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8501811436898984818110610c8857610c886137cd565b9050602002810190610c9a91906137fc565b9050366000610cac6020840184613de0565b909250905080801580610ccd5750610cc76040850185613f40565b90508114155b15610d04576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610de557610ddd6040518060a0016040528087600001358152602001868685818110610d3957610d396137cd565b9050602002810190610d4b9190613d6c565b610d5490613da0565b8152602001610d666040890189613f40565b85818110610d7657610d766137cd565b905060600201803603810190610d8c9190613fa7565b8152602001610da16080890160608a0161358c565b73ffffffffffffffffffffffffffffffffffffffff168152602001610dcc60a0890160808a01613fc3565b67ffffffffffffffff169052611c81565b600101610d07565b506000610e0e8535610df78587613e48565b610e076080890160608a0161358c565b8b8a611dfe565b8051909150610e1d9089613bbc565b975080602001518a8881518110610e3657610e366137cd565b602002602001018190525080602001515189019850505050505050610e5b8160010190565b9050610c48565b604080516101408101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e0820183905261010082019290925261012081019190915260008281526032602090815260409182902082516101408101845281548152600182015492810192909252600281015467ffffffffffffffff808216948401949094526801000000000000000081048416606084015270010000000000000000000000000000000090049092166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff16151561010082015260068201805491929161012084019190610f9c90613fde565b80601f0160208091040260200160405190810160405280929190818152602001828054610fc890613fde565b80156110155780601f10610fea57610100808354040283529160200191611015565b820191906000526020600020905b815481529060010190602001808311610ff857829003601f168201915b5050505050815250509050919050565b61103c6110373683900383018361402b565b6111d8565b604080516001808252818301909252600091816020015b604080518082019091526000808252602082015281526020019060019003908161105357905050905061108e36839003830160208401613ebc565b816000815181106110a1576110a16137cd565b6020908102919091010152610a638235826110c260e0860160c0870161358c565b3460016113c5565b60004261072a3384836119f4565b60004282825b81811015610724576111088686838181106110fb576110fb6137cd565b90506020020135846125fa565b6001016110de565b600061075b6126bc565b604080516001808252818301909252600091829190816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816111345790505090506111a26020840184613d6c565b6111ab90613da0565b816000815181106111be576111be6137cd565b602090810291909101015261083d83358233346001611dfe565b608081015167ffffffffffffffff161580159061120c57504267ffffffffffffffff16816080015167ffffffffffffffff16105b15611243576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201516040808401518451835184860151606088015173ffffffffffffffffffffffffffffffffffffffff166000908152968790529386208054959693959394611313947f2d4116d8c9824e4c316453e5c2843a1885580374159ce8768603c49085ef424c949392876112b883614099565b909155506080808b015160408051602081019890985287019590955260608601939093529184015260a083015267ffffffffffffffff1660c082015260e0015b604051602081830303815290604052805190602001206127f0565b905061138984606001518284602001518560400151866000015160405160200161137593929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b604051602081830303815290604052612803565b6113bf576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6040517fa2ea7c6e0000000000000000000000000000000000000000000000000000000081526004810186905260009081907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611433573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261147991908101906140d1565b80519091506114b4576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b855160008167ffffffffffffffff8111156114d1576114d161383a565b60405190808252806020026020018201604052801561157057816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816114ef5790505b50905060008267ffffffffffffffff81111561158e5761158e61383a565b6040519080825280602002602001820160405280156115b7578160200160208202803683370190505b50905060005b838110156119d65760008a82815181106115d9576115d96137cd565b6020908102919091018101518051600090815260329092526040909120805491925090611632576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8c81600101541461166f576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015473ffffffffffffffffffffffffffffffffffffffff8c81169116146116c5576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015474010000000000000000000000000000000000000000900460ff1661171b576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002810154700100000000000000000000000000000000900467ffffffffffffffff1615611775576040517f905e710700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b426002820180547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff811670010000000000000000000000000000000067ffffffffffffffff948516810291821793849055604080516101408101825287548152600188015460208201529386169286169290921791830191909152680100000000000000008304841660608301529091049091166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff161515610100820152600682018054839161012084019161188190613fde565b80601f01602080910402602001604051908101604052809291908181526020018280546118ad90613fde565b80156118fa5780601f106118cf576101008083540402835291602001916118fa565b820191906000526020600020905b8154815290600101906020018083116118dd57829003601f168201915b505050505081525050858481518110611915576119156137cd565b60200260200101819052508160200151848481518110611937576119376137cd565b6020026020010181815250508c8b73ffffffffffffffffffffffffffffffffffffffff1686858151811061196d5761196d6137cd565b602002602001015160c0015173ffffffffffffffffffffffffffffffffffffffff167ff930a6e2523c9cc298691873087a740550b8fc85a0680830414c148ed927f61585600001516040516119c491815260200190565b60405180910390a450506001016115bd565b506119e684838360018b8b6129d2565b9a9950505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152603460209081526040808320858452918290529091205467ffffffffffffffff1615611a68576040517fec9d6eeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526020829052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915590519091859173ffffffffffffffffffffffffffffffffffffffff8816917f92a1f7a41a7c585a8b09e25b195e225b1d43248daca46b0faf9e0792777a222991a450505050565b604080516020808252818301909252606091600091906020820181803683370190505090506000805b6020811015611bbe576000858260208110611b3957611b396137cd565b1a60f81b90507fff000000000000000000000000000000000000000000000000000000000000008116600003611b6f5750611bbe565b80848481518110611b8257611b826137cd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505060019182019101611b1c565b5060008167ffffffffffffffff811115611bda57611bda61383a565b6040519080825280601f01601f191660200182016040528015611c04576020820181803683370190505b50905060005b82811015611c7857838181518110611c2457611c246137cd565b602001015160f81c60f81b828281518110611c4157611c416137cd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611c0a565b50949350505050565b608081015167ffffffffffffffff1615801590611cb557504267ffffffffffffffff16816080015167ffffffffffffffff16105b15611cec576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015160408084015184518351848601518486015160608088015160808901518051908b012060a08a0151928c015173ffffffffffffffffffffffffffffffffffffffff1660009081529a8b9052978a208054999a97999798611313987ff83bb2b0ede93a840239f7e701a54d9bc35f03701f51ae153d601c6947ff3d3f989796959491928b611d7e83614099565b909155506080808f015160408051602081019c909c528b019990995273ffffffffffffffffffffffffffffffffffffffff90971660608a015267ffffffffffffffff9586169689019690965292151560a088015260c087019190915260e086015261010085015261012084019190915216610140820152610160016112f8565b60408051808201909152600081526060602082015284516040805180820190915260008152606060208201528167ffffffffffffffff811115611e4357611e4361383a565b604051908082528060200260200182016040528015611e6c578160200160208202803683370190505b5060208201526040517fa2ea7c6e000000000000000000000000000000000000000000000000000000008152600481018990526000907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611ede573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611f2491908101906140d1565b8051909150611f5f576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008367ffffffffffffffff811115611f7a57611f7a61383a565b60405190808252806020026020018201604052801561201957816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611f985790505b50905060008467ffffffffffffffff8111156120375761203761383a565b604051908082528060200260200182016040528015612060578160200160208202803683370190505b50905060005b858110156124ef5760008b8281518110612082576120826137cd565b60200260200101519050600067ffffffffffffffff16816020015167ffffffffffffffff16141580156120cd57504267ffffffffffffffff16816020015167ffffffffffffffff1611155b15612104576040517f08e8b93700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460400151158015612117575080604001515b1561214e576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006040518061014001604052806000801b81526020018f81526020016121724290565b67ffffffffffffffff168152602001836020015167ffffffffffffffff168152602001600067ffffffffffffffff16815260200183606001518152602001836000015173ffffffffffffffffffffffffffffffffffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff16815260200183604001511515815260200183608001518152509050600080600090505b6122148382612dc3565b600081815260326020526040902054909250156122335760010161220a565b81835260008281526032602090815260409182902085518155908501516001820155908401516002820180546060870151608088015167ffffffffffffffff908116700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff92821668010000000000000000027fffffffffffffffffffffffffffffffff000000000000000000000000000000009094169190951617919091171691909117905560a0840151600382015560c084015160048201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617905560e0850151600583018054610100880151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff000000000000000000000000000000000000000000909116929093169190911791909117905561012084015184919060068201906123b390826141f7565b50505060608401511561240a57606084015160009081526032602052604090205461240a576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8287868151811061241d5761241d6137cd565b60200260200101819052508360a0015186868151811061243f5761243f6137cd565b6020026020010181815250508189602001518681518110612462576124626137cd565b6020026020010181815250508f8e73ffffffffffffffffffffffffffffffffffffffff16856000015173ffffffffffffffffffffffffffffffffffffffff167f8bf46bf4cfd674fa735a3d63ec1c9ad4153f033c290341f3a588b75685141b35856040516124d291815260200190565b60405180910390a4505050506124e88160010190565b9050612066565b506124ff83838360008c8c6129d2565b845250919998505050505050505050565b606060008267ffffffffffffffff81111561252d5761252d61383a565b604051908082528060200260200182016040528015612556578160200160208202803683370190505b508451909150600090815b818110156125ef57600087828151811061257d5761257d6137cd565b6020026020010151905060008151905060005b818110156125db578281815181106125aa576125aa6137cd565b60200260200101518787815181106125c4576125c46137cd565b602090810291909101015260019586019501612590565b5050506125e88160010190565b9050612561565b509195945050505050565b60008281526033602052604090205467ffffffffffffffff161561264a576040517f2e26794600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526033602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051909184917f5aafceeb1c7ad58e4a84898bdee37c02c0fc46e7d24e6b60e8209449f183459f9190a35050565b60003073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561272257507f000000000000000000000000000000000000000000000000000000000000000046145b1561274c57507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b600061072a6127fd6126bc565b83612e22565b60008060006128128585612e64565b9092509050600081600481111561282b5761282b614311565b14801561286357508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b15612873576001925050506129cb565b6000808773ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b88886040516024016128a8929190614340565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516129319190614361565b600060405180830381855afa9150503d806000811461296c576040519150601f19603f3d011682016040523d82523d6000602084013e612971565b606091505b5091509150818015612984575080516020145b80156129c4575080517f1626ba7e00000000000000000000000000000000000000000000000000000000906129c29083016020908101908401614373565b145b9450505050505b9392505050565b84516000906001819003612a2a57612a2288886000815181106129f7576129f76137cd565b602002602001015188600081518110612a1257612a126137cd565b6020026020010151888888612ea9565b915050612db9565b602088015173ffffffffffffffffffffffffffffffffffffffff8116612acb5760005b82811015612ab057878181518110612a6757612a676137cd565b6020026020010151600014612aa8576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101612a4d565b508315612ac057612ac0856131c8565b600092505050612db9565b6000808273ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b3d919061438c565b905060005b84811015612bfa5760008a8281518110612b5e57612b5e6137cd565b6020026020010151905080600003612b765750612bf2565b82612bad576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88811115612be7576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b978890039792909201915b600101612b42565b508715612cd5576040517f88e5b2d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416906388e5b2d9908490612c57908e908e906004016143a9565b60206040518083038185885af1158015612c75573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612c9a919061438c565b612cd0576040517fbf2f3a8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612da4565b6040517f91db0b7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416906391db0b7e908490612d2b908e908e906004016143a9565b60206040518083038185885af1158015612d49573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612d6e919061438c565b612da4576040517fe8bee83900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8515612db357612db3876131c8565b50925050505b9695505050505050565b60208083015160c084015160e0850151604080870151606088015161010089015160a08a01516101208b01519451600099612e0499989796918c9101614462565b60405160208183030381529060405280519060200120905092915050565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526022810183905260428101829052600090606201612e04565b6000808251604103612e9a5760208301516040840151606085015160001a612e8e878285856131db565b94509450505050612ea2565b506000905060025b9250929050565b602086015160009073ffffffffffffffffffffffffffffffffffffffff8116612f1d578515612f04576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215612f1357612f13846131c8565b6000915050612db9565b8515613008578073ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f92919061438c565b612fc8576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83861115613002576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85840393505b84156130e0576040517fe49617e100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e49617e1908890613062908b90600401613740565b60206040518083038185885af1158015613080573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906130a5919061438c565b6130db576040517fccf3bb2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6131ad565b6040517fe60c350500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e60c3505908890613134908b90600401613740565b60206040518083038185885af1158015613152573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190613177919061438c565b6131ad576040517fbd8ba84d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82156131bc576131bc846131c8565b50939695505050505050565b80156131d8576131d833826132f3565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561321257506000905060036132ea565b8460ff16601b1415801561322a57508460ff16601c14155b1561323b57506000905060046132ea565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561328f573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166132e3576000600192509250506132ea565b9150600090505b94509492505050565b80471015613362576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064015b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146133bc576040519150601f19603f3d011682016040523d82523d6000602084013e6133c1565b606091505b5050905080610a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401613359565b60008083601f84011261346457600080fd5b50813567ffffffffffffffff81111561347c57600080fd5b6020830191508360208260051b8501011115612ea257600080fd5b600080602083850312156134aa57600080fd5b823567ffffffffffffffff8111156134c157600080fd5b6134cd85828601613452565b90969095509350505050565b60005b838110156134f45781810151838201526020016134dc565b50506000910152565b600081518084526135158160208601602086016134d9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129cb60208301846134fd565b73ffffffffffffffffffffffffffffffffffffffff811681146131d857600080fd5b80356135878161355a565b919050565b60006020828403121561359e57600080fd5b81356129cb8161355a565b6000602082840312156135bb57600080fd5b813567ffffffffffffffff8111156135d257600080fd5b820160e081850312156129cb57600080fd5b6020808252825182820181905260009190848201906040850190845b8181101561361c57835183529284019291840191600101613600565b50909695505050505050565b60006060828403121561363a57600080fd5b50919050565b60006020828403121561365257600080fd5b5035919050565b600061014082518452602083015160208501526040830151613687604086018267ffffffffffffffff169052565b5060608301516136a3606086018267ffffffffffffffff169052565b5060808301516136bf608086018267ffffffffffffffff169052565b5060a083015160a085015260c08301516136f160c086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060e083015161371960e086018273ffffffffffffffffffffffffffffffffffffffff169052565b506101008381015115159085015261012080840151818601839052612db9838701826134fd565b6020815260006129cb6020830184613659565b6000610100828403121561363a57600080fd5b6000806040838503121561377957600080fd5b82356137848161355a565b946020939093013593505050565b6000602082840312156137a457600080fd5b813567ffffffffffffffff8111156137bb57600080fd5b8201604081850312156129cb57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261383057600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561388c5761388c61383a565b60405290565b60405160c0810167ffffffffffffffff8111828210171561388c5761388c61383a565b6040516080810167ffffffffffffffff8111828210171561388c5761388c61383a565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561391f5761391f61383a565b604052919050565b600067ffffffffffffffff8211156139415761394161383a565b5060051b60200190565b60006040828403121561395d57600080fd5b6040516040810181811067ffffffffffffffff821117156139805761398061383a565b604052823581526020928301359281019290925250919050565b6000606082840312156139ac57600080fd5b6040516060810181811067ffffffffffffffff821117156139cf576139cf61383a565b604052905080823560ff811681146139e657600080fd5b8082525060208301356020820152604083013560408201525092915050565b600082601f830112613a1657600080fd5b81356020613a2b613a2683613927565b6138d8565b82815260609283028501820192828201919087851115613a4a57600080fd5b8387015b85811015613a6d57613a60898261399a565b8452928401928101613a4e565b5090979650505050505050565b803567ffffffffffffffff8116811461358757600080fd5b600060a08236031215613aa457600080fd5b613aac613869565b8235815260208084013567ffffffffffffffff80821115613acc57600080fd5b9085019036601f830112613adf57600080fd5b8135613aed613a2682613927565b81815260069190911b83018401908481019036831115613b0c57600080fd5b938501935b82851015613b3557613b23368661394b565b82528582019150604085019450613b11565b80868801525050506040860135925080831115613b5157600080fd5b5050613b5f36828601613a05565b604083015250613b716060840161357c565b6060820152613b8260808401613a7a565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561072a5761072a613b8d565b80151581146131d857600080fd5b600067ffffffffffffffff821115613bf757613bf761383a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600060c08284031215613c3557600080fd5b613c3d613892565b90508135613c4a8161355a565b81526020613c59838201613a7a565b818301526040830135613c6b81613bcf565b604083015260608381013590830152608083013567ffffffffffffffff811115613c9457600080fd5b8301601f81018513613ca557600080fd5b8035613cb3613a2682613bdd565b8181528684838501011115613cc757600080fd5b818484018583013760008483830101528060808601525050505060a082013560a082015292915050565b600060e08236031215613d0357600080fd5b613d0b613869565b82358152602083013567ffffffffffffffff811115613d2957600080fd5b613d3536828601613c23565b602083015250613d48366040850161399a565b604082015260a0830135613d5b8161355a565b6060820152613b8260c08401613a7a565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4183360301811261383057600080fd5b600061072a3683613c23565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261383057600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613e1557600080fd5b83018035915067ffffffffffffffff821115613e3057600080fd5b6020019150600581901b3603821315612ea257600080fd5b6000613e56613a2684613927565b80848252602080830192508560051b850136811115613e7457600080fd5b855b81811015613eb057803567ffffffffffffffff811115613e965760008081fd5b613ea236828a01613c23565b865250938201938201613e76565b50919695505050505050565b600060408284031215613ece57600080fd5b6129cb838361394b565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f0d57600080fd5b83018035915067ffffffffffffffff821115613f2857600080fd5b6020019150600681901b3603821315612ea257600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f7557600080fd5b83018035915067ffffffffffffffff821115613f9057600080fd5b6020019150606081023603821315612ea257600080fd5b600060608284031215613fb957600080fd5b6129cb838361399a565b600060208284031215613fd557600080fd5b6129cb82613a7a565b600181811c90821680613ff257607f821691505b60208210810361363a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000610100828403121561403e57600080fd5b614046613869565b82358152614057846020850161394b565b6020820152614069846060850161399a565b604082015260c083013561407c8161355a565b606082015261408d60e08401613a7a565b60808201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036140ca576140ca613b8d565b5060010190565b600060208083850312156140e457600080fd5b825167ffffffffffffffff808211156140fc57600080fd5b908401906080828703121561411057600080fd5b6141186138b5565b82518152838301516141298161355a565b81850152604083015161413b81613bcf565b604082015260608301518281111561415257600080fd5b80840193505086601f84011261416757600080fd5b82519150614177613a2683613bdd565b828152878584860101111561418b57600080fd5b61419a838683018787016134d9565b60608201529695505050505050565b601f821115610a6357600081815260208120601f850160051c810160208610156141d05750805b601f850160051c820191505b818110156141ef578281556001016141dc565b505050505050565b815167ffffffffffffffff8111156142115761421161383a565b6142258161421f8454613fde565b846141a9565b602080601f83116001811461427857600084156142425750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556141ef565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156142c5578886015182559484019460019091019084016142a6565b508582101561430157878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b82815260406020820152600061435960408301846134fd565b949350505050565b600082516138308184602087016134d9565b60006020828403121561438557600080fd5b5051919050565b60006020828403121561439e57600080fd5b81516129cb81613bcf565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b8381101561441e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261440c868351613659565b955093820193908201906001016143d2565b50508584038187015286518085528782019482019350915060005b8281101561445557845184529381019392810192600101614439565b5091979650505050505050565b89815260007fffffffffffffffffffffffffffffffffffffffff000000000000000000000000808b60601b166020840152808a60601b166034840152507fffffffffffffffff000000000000000000000000000000000000000000000000808960c01b166048840152808860c01b1660508401525085151560f81b605883015284605983015283516144fb8160798501602088016134d9565b80830190507fffffffff000000000000000000000000000000000000000000000000000000008460e01b166079820152607d81019150509a995050505050505050505056fea164736f6c6343000813000a"
var EASDeployedBin = "0x60806040526004361061018b5760003560e01c806395411525116100d6578063d45c44351161007f578063ed24911d11610059578063ed24911d146104fd578063f10b5cc814610512578063f17325e71461054157600080fd5b8063d45c443514610467578063e30bb5631461049e578063e71ff365146104dd57600080fd5b8063b469318d116100b0578063b469318d146103ba578063b83010d314610414578063cf190f341461044757600080fd5b80639541152514610367578063a3112a641461037a578063a6d4dbc7146103a757600080fd5b806344adc90e116101385780634d003070116101125780634d003070146102de57806354fd4d50146102fe57806379f7573a1461034757600080fd5b806344adc90e1461029857806346926267146102b85780634cb7e9e5146102cb57600080fd5b806317d7de7c1161016957806317d7de7c146102205780632d0335ab146102425780633c0427151461028557600080fd5b80630eabf6601461019057806312b11a17146101a557806313893f61146101e7575b600080fd5b6101a361019e3660046134c8565b610554565b005b3480156101b157600080fd5b507ffeb2925a02bae3dae48d424a0437a2b6ac939aa9230ddc55a1a76f065d9880765b6040519081526020015b60405180910390f35b3480156101f357600080fd5b506102076102023660046134c8565b6106eb565b60405167ffffffffffffffff90911681526020016101de565b34801561022c57600080fd5b50610235610730565b6040516101de9190613578565b34801561024e57600080fd5b506101d461025d3660046135bd565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101d46102933660046135da565b610760565b6102ab6102a63660046134c8565b610863565b6040516101de9190613615565b6101a36102c6366004613659565b6109e4565b6101a36102d93660046134c8565b610a68565b3480156102ea57600080fd5b506102076102f9366004613671565b610b4b565b34801561030a57600080fd5b506102356040518060400160405280600581526020017f312e342e3000000000000000000000000000000000000000000000000000000081525081565b34801561035357600080fd5b506101a3610362366004613671565b610b58565b6102ab6103753660046134c8565b610bef565b34801561038657600080fd5b5061039a610395366004613671565b610e62565b6040516101de9190613771565b6101a36103b5366004613784565b611025565b3480156103c657600080fd5b506102076103d5366004613797565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152603460209081526040808320938352929052205467ffffffffffffffff1690565b34801561042057600080fd5b507fb5d556f07587ec0f08cf386545cc4362c702a001650c2058002615ee5c9d1e756101d4565b34801561045357600080fd5b50610207610462366004613671565b6110ca565b34801561047357600080fd5b50610207610482366004613671565b60009081526033602052604090205467ffffffffffffffff1690565b3480156104aa57600080fd5b506104cd6104b9366004613671565b600090815260326020526040902054151590565b60405190151581526020016101de565b3480156104e957600080fd5b506102076104f83660046134c8565b6110d8565b34801561050957600080fd5b506101d4611110565b34801561051e57600080fd5b5060405173420000000000000000000000000000000000002081526020016101de565b6101d461054f3660046137c3565b61111a565b348160005b818110156106e4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82018114600086868481811061059a5761059a6137fe565b90506020028101906105ac919061382d565b6105b590613ac3565b60208101518051919250908015806105d257508260400151518114155b15610609576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156106ad576106a56040518060a001604052808660000151815260200185848151811061063e5761063e6137fe565b6020026020010151815260200186604001518481518110610661576106616137fe565b60200260200101518152602001866060015173ffffffffffffffffffffffffffffffffffffffff168152602001866080015167ffffffffffffffff168152506111d8565b60010161060c565b506106c383600001518385606001518a886113e9565b6106cd9088613bed565b9650505050506106dd8160010190565b9050610559565b5050505050565b60004282825b818110156107245761071c3387878481811061070f5761070f6137fe565b9050602002013585611a18565b6001016106f1565b50909150505b92915050565b606061075b7f0000000000000000000000000000000000000000000000000000000000000000611b17565b905090565b600061077361076e83613d22565b611ca5565b604080516001808252818301909252600091816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161078a5790505090506107f86020840184613d9d565b61080190613dd1565b81600081518110610814576108146137fe565b602090810291909101015261083d83358261083560c0870160a088016135bd565b346001611e2f565b60200151600081518110610853576108536137fe565b6020026020010151915050919050565b60608160008167ffffffffffffffff8111156108815761088161386b565b6040519080825280602002602001820160405280156108b457816020015b606081526020019060019003908161089f5790505b509050600034815b848110156109ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85018114368989848181106108fc576108fc6137fe565b905060200281019061090e9190613ddd565b905061091d6020820182613e11565b9050600003610958576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061097d823561096c6020850185613e11565b61097591613e79565b338887611e2f565b805190915061098c9086613bed565b945080602001518785815181106109a5576109a56137fe565b6020026020010181905250806020015151860195505050506109c78160010190565b90506108bc565b506109d98383612541565b979650505050505050565b604080516001808252818301909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816109fb579050509050610a3636839003830160208401613eed565b81600081518110610a4957610a496137fe565b6020908102919091010152610a63823582333460016113e9565b505050565b348160005b818110156106e4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201811436868684818110610aad57610aad6137fe565b9050602002810190610abf9190613ddd565b9050610b2c8135610ad36020840184613f09565b808060200260200160405190810160405280939291908181526020016000905b82821015610b1f57610b1060408302860136819003810190613eed565b81526020019060010190610af3565b50505050503388866113e9565b610b369086613bed565b94505050610b448160010190565b9050610a6d565b60004261072a838261262b565b33600090815260208190526040902054808211610ba1576040517f756688fe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152602081815260409182902084905581518381529081018490527f57b09af877df9068fd60a69d7b21f5576b8b38955812d6ae4ac52942f1e38fb7910160405180910390a15050565b60608160008167ffffffffffffffff811115610c0d57610c0d61386b565b604051908082528060200260200182016040528015610c4057816020015b6060815260200190600190039081610c2b5790505b509050600034815b848110156109ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8501811436898984818110610c8857610c886137fe565b9050602002810190610c9a919061382d565b9050366000610cac6020840184613e11565b909250905080801580610ccd5750610cc76040850185613f71565b90508114155b15610d04576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610de557610ddd6040518060a0016040528087600001358152602001868685818110610d3957610d396137fe565b9050602002810190610d4b9190613d9d565b610d5490613dd1565b8152602001610d666040890189613f71565b85818110610d7657610d766137fe565b905060600201803603810190610d8c9190613fd8565b8152602001610da16080890160608a016135bd565b73ffffffffffffffffffffffffffffffffffffffff168152602001610dcc60a0890160808a01613ff4565b67ffffffffffffffff169052611ca5565b600101610d07565b506000610e0e8535610df78587613e79565b610e076080890160608a016135bd565b8b8a611e2f565b8051909150610e1d9089613bed565b975080602001518a8881518110610e3657610e366137fe565b602002602001018190525080602001515189019850505050505050610e5b8160010190565b9050610c48565b604080516101408101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e0820183905261010082019290925261012081019190915260008281526032602090815260409182902082516101408101845281548152600182015492810192909252600281015467ffffffffffffffff808216948401949094526801000000000000000081048416606084015270010000000000000000000000000000000090049092166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff16151561010082015260068201805491929161012084019190610f9c9061400f565b80601f0160208091040260200160405190810160405280929190818152602001828054610fc89061400f565b80156110155780601f10610fea57610100808354040283529160200191611015565b820191906000526020600020905b815481529060010190602001808311610ff857829003601f168201915b5050505050815250509050919050565b61103c6110373683900383018361405c565b6111d8565b604080516001808252818301909252600091816020015b604080518082019091526000808252602082015281526020019060019003908161105357905050905061108e36839003830160208401613eed565b816000815181106110a1576110a16137fe565b6020908102919091010152610a638235826110c260e0860160c087016135bd565b3460016113e9565b60004261072a338483611a18565b60004282825b81811015610724576111088686838181106110fb576110fb6137fe565b905060200201358461262b565b6001016110de565b600061075b6126ed565b604080516001808252818301909252600091829190816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816111345790505090506111a26020840184613d9d565b6111ab90613dd1565b816000815181106111be576111be6137fe565b602090810291909101015261083d83358233346001611e2f565b608081015167ffffffffffffffff161580159061120c57504267ffffffffffffffff16816080015167ffffffffffffffff16105b15611243576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201516040808401516060850151855184518587015173ffffffffffffffffffffffffffffffffffffffff84166000908152978890529487208054969794969495611337957fb5d556f07587ec0f08cf386545cc4362c702a001650c2058002615ee5c9d1e7595949392886112ba836140ca565b909155506080808c015160408051602081019990995273ffffffffffffffffffffffffffffffffffffffff9097169688019690965260608701949094529285019190915260a084015260c083015267ffffffffffffffff1660e0820152610100015b60405160208183030381529060405280519060200120612821565b90506113ad84606001518284602001518560400151866000015160405160200161139993929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b604051602081830303815290604052612834565b6113e3576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6040517fa2ea7c6e0000000000000000000000000000000000000000000000000000000081526004810186905260009081907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261149d9190810190614102565b80519091506114d8576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b855160008167ffffffffffffffff8111156114f5576114f561386b565b60405190808252806020026020018201604052801561159457816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816115135790505b50905060008267ffffffffffffffff8111156115b2576115b261386b565b6040519080825280602002602001820160405280156115db578160200160208202803683370190505b50905060005b838110156119fa5760008a82815181106115fd576115fd6137fe565b6020908102919091018101518051600090815260329092526040909120805491925090611656576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8c816001015414611693576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015473ffffffffffffffffffffffffffffffffffffffff8c81169116146116e9576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600581015474010000000000000000000000000000000000000000900460ff1661173f576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002810154700100000000000000000000000000000000900467ffffffffffffffff1615611799576040517f905e710700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b426002820180547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff811670010000000000000000000000000000000067ffffffffffffffff948516810291821793849055604080516101408101825287548152600188015460208201529386169286169290921791830191909152680100000000000000008304841660608301529091049091166080820152600382015460a0820152600482015473ffffffffffffffffffffffffffffffffffffffff90811660c0830152600583015490811660e083015274010000000000000000000000000000000000000000900460ff16151561010082015260068201805483916101208401916118a59061400f565b80601f01602080910402602001604051908101604052809291908181526020018280546118d19061400f565b801561191e5780601f106118f35761010080835404028352916020019161191e565b820191906000526020600020905b81548152906001019060200180831161190157829003601f168201915b505050505081525050858481518110611939576119396137fe565b6020026020010181905250816020015184848151811061195b5761195b6137fe565b6020026020010181815250508c8b73ffffffffffffffffffffffffffffffffffffffff16868581518110611991576119916137fe565b602002602001015160c0015173ffffffffffffffffffffffffffffffffffffffff167ff930a6e2523c9cc298691873087a740550b8fc85a0680830414c148ed927f61585600001516040516119e891815260200190565b60405180910390a450506001016115e1565b50611a0a84838360018b8b612a03565b9a9950505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152603460209081526040808320858452918290529091205467ffffffffffffffff1615611a8c576040517fec9d6eeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526020829052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915590519091859173ffffffffffffffffffffffffffffffffffffffff8816917f92a1f7a41a7c585a8b09e25b195e225b1d43248daca46b0faf9e0792777a222991a450505050565b604080516020808252818301909252606091600091906020820181803683370190505090506000805b6020811015611be2576000858260208110611b5d57611b5d6137fe565b1a60f81b90507fff000000000000000000000000000000000000000000000000000000000000008116600003611b935750611be2565b80848481518110611ba657611ba66137fe565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505060019182019101611b40565b5060008167ffffffffffffffff811115611bfe57611bfe61386b565b6040519080825280601f01601f191660200182016040528015611c28576020820181803683370190505b50905060005b82811015611c9c57838181518110611c4857611c486137fe565b602001015160f81c60f81b828281518110611c6557611c656137fe565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611c2e565b50949350505050565b608081015167ffffffffffffffff1615801590611cd957504267ffffffffffffffff16816080015167ffffffffffffffff16105b15611d10576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201516040808401516060808601518651855186880151868801519488015160808901518051908b012060a08a015173ffffffffffffffffffffffffffffffffffffffff871660009081529b8c9052988b2080549a9b989a9899611337997ffeb2925a02bae3dae48d424a0437a2b6ac939aa9230ddc55a1a76f065d988076999493928c611da0836140ca565b919050558e6080015160405160200161131c9b9a999897969594939291909a8b5273ffffffffffffffffffffffffffffffffffffffff998a1660208c015260408b019890985295909716606089015267ffffffffffffffff938416608089015291151560a088015260c087015260e0860152610100850193909352610120840152166101408201526101600190565b60408051808201909152600081526060602082015284516040805180820190915260008152606060208201528167ffffffffffffffff811115611e7457611e7461386b565b604051908082528060200260200182016040528015611e9d578160200160208202803683370190505b5060208201526040517fa2ea7c6e000000000000000000000000000000000000000000000000000000008152600481018990526000907342000000000000000000000000000000000000209063a2ea7c6e90602401600060405180830381865afa158015611f0f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611f559190810190614102565b8051909150611f90576040517fbf37b20e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008367ffffffffffffffff811115611fab57611fab61386b565b60405190808252806020026020018201604052801561204a57816020015b60408051610140810182526000808252602080830182905292820181905260608083018290526080830182905260a0830182905260c0830182905260e0830182905261010083019190915261012082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181611fc95790505b50905060008467ffffffffffffffff8111156120685761206861386b565b604051908082528060200260200182016040528015612091578160200160208202803683370190505b50905060005b858110156125205760008b82815181106120b3576120b36137fe565b60200260200101519050600067ffffffffffffffff16816020015167ffffffffffffffff16141580156120fe57504267ffffffffffffffff16816020015167ffffffffffffffff1611155b15612135576040517f08e8b93700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460400151158015612148575080604001515b1561217f576040517f157bd4c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006040518061014001604052806000801b81526020018f81526020016121a34290565b67ffffffffffffffff168152602001836020015167ffffffffffffffff168152602001600067ffffffffffffffff16815260200183606001518152602001836000015173ffffffffffffffffffffffffffffffffffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff16815260200183604001511515815260200183608001518152509050600080600090505b6122458382612df4565b600081815260326020526040902054909250156122645760010161223b565b81835260008281526032602090815260409182902085518155908501516001820155908401516002820180546060870151608088015167ffffffffffffffff908116700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff92821668010000000000000000027fffffffffffffffffffffffffffffffff000000000000000000000000000000009094169190951617919091171691909117905560a0840151600382015560c084015160048201805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617905560e0850151600583018054610100880151151574010000000000000000000000000000000000000000027fffffffffffffffffffffff000000000000000000000000000000000000000000909116929093169190911791909117905561012084015184919060068201906123e49082614228565b50505060608401511561243b57606084015160009081526032602052604090205461243b576040517fc5723b5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8287868151811061244e5761244e6137fe565b60200260200101819052508360a00151868681518110612470576124706137fe565b6020026020010181815250508189602001518681518110612493576124936137fe565b6020026020010181815250508f8e73ffffffffffffffffffffffffffffffffffffffff16856000015173ffffffffffffffffffffffffffffffffffffffff167f8bf46bf4cfd674fa735a3d63ec1c9ad4153f033c290341f3a588b75685141b358560405161250391815260200190565b60405180910390a4505050506125198160010190565b9050612097565b5061253083838360008c8c612a03565b845250919998505050505050505050565b606060008267ffffffffffffffff81111561255e5761255e61386b565b604051908082528060200260200182016040528015612587578160200160208202803683370190505b508451909150600090815b818110156126205760008782815181106125ae576125ae6137fe565b6020026020010151905060008151905060005b8181101561260c578281815181106125db576125db6137fe565b60200260200101518787815181106125f5576125f56137fe565b6020908102919091010152600195860195016125c1565b5050506126198160010190565b9050612592565b509195945050505050565b60008281526033602052604090205467ffffffffffffffff161561267b576040517f2e26794600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526033602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051909184917f5aafceeb1c7ad58e4a84898bdee37c02c0fc46e7d24e6b60e8209449f183459f9190a35050565b60003073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561275357507f000000000000000000000000000000000000000000000000000000000000000046145b1561277d57507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b600061072a61282e6126ed565b83612e53565b60008060006128438585612e95565b9092509050600081600481111561285c5761285c614342565b14801561289457508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b156128a4576001925050506129fc565b6000808773ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b88886040516024016128d9929190614371565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516129629190614392565b600060405180830381855afa9150503d806000811461299d576040519150601f19603f3d011682016040523d82523d6000602084013e6129a2565b606091505b50915091508180156129b5575080516020145b80156129f5575080517f1626ba7e00000000000000000000000000000000000000000000000000000000906129f390830160209081019084016143a4565b145b9450505050505b9392505050565b84516000906001819003612a5b57612a538888600081518110612a2857612a286137fe565b602002602001015188600081518110612a4357612a436137fe565b6020026020010151888888612eda565b915050612dea565b602088015173ffffffffffffffffffffffffffffffffffffffff8116612afc5760005b82811015612ae157878181518110612a9857612a986137fe565b6020026020010151600014612ad9576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600101612a7e565b508315612af157612af1856131f9565b600092505050612dea565b6000808273ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b6e91906143bd565b905060005b84811015612c2b5760008a8281518110612b8f57612b8f6137fe565b6020026020010151905080600003612ba75750612c23565b82612bde576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88811115612c18576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b978890039792909201915b600101612b73565b508715612d06576040517f88e5b2d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416906388e5b2d9908490612c88908e908e906004016143da565b60206040518083038185885af1158015612ca6573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612ccb91906143bd565b612d01576040517fbf2f3a8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612dd5565b6040517f91db0b7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416906391db0b7e908490612d5c908e908e906004016143da565b60206040518083038185885af1158015612d7a573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612d9f91906143bd565b612dd5576040517fe8bee83900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8515612de457612de4876131f9565b50925050505b9695505050505050565b60208083015160c084015160e0850151604080870151606088015161010089015160a08a01516101208b01519451600099612e3599989796918c9101614493565b60405160208183030381529060405280519060200120905092915050565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526022810183905260428101829052600090606201612e35565b6000808251604103612ecb5760208301516040840151606085015160001a612ebf8782858561320c565b94509450505050612ed3565b506000905060025b9250929050565b602086015160009073ffffffffffffffffffffffffffffffffffffffff8116612f4e578515612f35576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215612f4457612f44846131f9565b6000915050612dea565b8515613039578073ffffffffffffffffffffffffffffffffffffffff1663ce46e0466040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fc391906143bd565b612ff9576040517f1574f9f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83861115613033576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85840393505b8415613111576040517fe49617e100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e49617e1908890613093908b90600401613771565b60206040518083038185885af11580156130b1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906130d691906143bd565b61310c576040517fccf3bb2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6131de565b6040517fe60c350500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e60c3505908890613165908b90600401613771565b60206040518083038185885af1158015613183573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906131a891906143bd565b6131de576040517fbd8ba84d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82156131ed576131ed846131f9565b50939695505050505050565b8015613209576132093382613324565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613243575060009050600361331b565b8460ff16601b1415801561325b57508460ff16601c14155b1561326c575060009050600461331b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156132c0573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166133145760006001925092505061331b565b9150600090505b94509492505050565b80471015613393576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064015b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146133ed576040519150601f19603f3d011682016040523d82523d6000602084013e6133f2565b606091505b5050905080610a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d61792068617665207265766572746564000000000000606482015260840161338a565b60008083601f84011261349557600080fd5b50813567ffffffffffffffff8111156134ad57600080fd5b6020830191508360208260051b8501011115612ed357600080fd5b600080602083850312156134db57600080fd5b823567ffffffffffffffff8111156134f257600080fd5b6134fe85828601613483565b90969095509350505050565b60005b8381101561352557818101518382015260200161350d565b50506000910152565b6000815180845261354681602086016020860161350a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006129fc602083018461352e565b73ffffffffffffffffffffffffffffffffffffffff8116811461320957600080fd5b80356135b88161358b565b919050565b6000602082840312156135cf57600080fd5b81356129fc8161358b565b6000602082840312156135ec57600080fd5b813567ffffffffffffffff81111561360357600080fd5b820160e081850312156129fc57600080fd5b6020808252825182820181905260009190848201906040850190845b8181101561364d57835183529284019291840191600101613631565b50909695505050505050565b60006060828403121561366b57600080fd5b50919050565b60006020828403121561368357600080fd5b5035919050565b6000610140825184526020830151602085015260408301516136b8604086018267ffffffffffffffff169052565b5060608301516136d4606086018267ffffffffffffffff169052565b5060808301516136f0608086018267ffffffffffffffff169052565b5060a083015160a085015260c083015161372260c086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060e083015161374a60e086018273ffffffffffffffffffffffffffffffffffffffff169052565b506101008381015115159085015261012080840151818601839052612dea8387018261352e565b6020815260006129fc602083018461368a565b6000610100828403121561366b57600080fd5b600080604083850312156137aa57600080fd5b82356137b58161358b565b946020939093013593505050565b6000602082840312156137d557600080fd5b813567ffffffffffffffff8111156137ec57600080fd5b8201604081850312156129fc57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261386157600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff811182821017156138bd576138bd61386b565b60405290565b60405160c0810167ffffffffffffffff811182821017156138bd576138bd61386b565b6040516080810167ffffffffffffffff811182821017156138bd576138bd61386b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156139505761395061386b565b604052919050565b600067ffffffffffffffff8211156139725761397261386b565b5060051b60200190565b60006040828403121561398e57600080fd5b6040516040810181811067ffffffffffffffff821117156139b1576139b161386b565b604052823581526020928301359281019290925250919050565b6000606082840312156139dd57600080fd5b6040516060810181811067ffffffffffffffff82111715613a0057613a0061386b565b604052905080823560ff81168114613a1757600080fd5b8082525060208301356020820152604083013560408201525092915050565b600082601f830112613a4757600080fd5b81356020613a5c613a5783613958565b613909565b82815260609283028501820192828201919087851115613a7b57600080fd5b8387015b85811015613a9e57613a9189826139cb565b8452928401928101613a7f565b5090979650505050505050565b803567ffffffffffffffff811681146135b857600080fd5b600060a08236031215613ad557600080fd5b613add61389a565b8235815260208084013567ffffffffffffffff80821115613afd57600080fd5b9085019036601f830112613b1057600080fd5b8135613b1e613a5782613958565b81815260069190911b83018401908481019036831115613b3d57600080fd5b938501935b82851015613b6657613b54368661397c565b82528582019150604085019450613b42565b80868801525050506040860135925080831115613b8257600080fd5b5050613b9036828601613a36565b604083015250613ba2606084016135ad565b6060820152613bb360808401613aab565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561072a5761072a613bbe565b801515811461320957600080fd5b600067ffffffffffffffff821115613c2857613c2861386b565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600060c08284031215613c6657600080fd5b613c6e6138c3565b90508135613c7b8161358b565b81526020613c8a838201613aab565b818301526040830135613c9c81613c00565b604083015260608381013590830152608083013567ffffffffffffffff811115613cc557600080fd5b8301601f81018513613cd657600080fd5b8035613ce4613a5782613c0e565b8181528684838501011115613cf857600080fd5b818484018583013760008483830101528060808601525050505060a082013560a082015292915050565b600060e08236031215613d3457600080fd5b613d3c61389a565b82358152602083013567ffffffffffffffff811115613d5a57600080fd5b613d6636828601613c54565b602083015250613d7936604085016139cb565b604082015260a0830135613d8c8161358b565b6060820152613bb360c08401613aab565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4183360301811261386157600080fd5b600061072a3683613c54565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261386157600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613e4657600080fd5b83018035915067ffffffffffffffff821115613e6157600080fd5b6020019150600581901b3603821315612ed357600080fd5b6000613e87613a5784613958565b80848252602080830192508560051b850136811115613ea557600080fd5b855b81811015613ee157803567ffffffffffffffff811115613ec75760008081fd5b613ed336828a01613c54565b865250938201938201613ea7565b50919695505050505050565b600060408284031215613eff57600080fd5b6129fc838361397c565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f3e57600080fd5b83018035915067ffffffffffffffff821115613f5957600080fd5b6020019150600681901b3603821315612ed357600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613fa657600080fd5b83018035915067ffffffffffffffff821115613fc157600080fd5b6020019150606081023603821315612ed357600080fd5b600060608284031215613fea57600080fd5b6129fc83836139cb565b60006020828403121561400657600080fd5b6129fc82613aab565b600181811c9082168061402357607f821691505b60208210810361366b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000610100828403121561406f57600080fd5b61407761389a565b82358152614088846020850161397c565b602082015261409a84606085016139cb565b604082015260c08301356140ad8161358b565b60608201526140be60e08401613aab565b60808201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036140fb576140fb613bbe565b5060010190565b6000602080838503121561411557600080fd5b825167ffffffffffffffff8082111561412d57600080fd5b908401906080828703121561414157600080fd5b6141496138e6565b825181528383015161415a8161358b565b81850152604083015161416c81613c00565b604082015260608301518281111561418357600080fd5b80840193505086601f84011261419857600080fd5b825191506141a8613a5783613c0e565b82815287858486010111156141bc57600080fd5b6141cb8386830187870161350a565b60608201529695505050505050565b601f821115610a6357600081815260208120601f850160051c810160208610156142015750805b601f850160051c820191505b818110156142205782815560010161420d565b505050505050565b815167ffffffffffffffff8111156142425761424261386b565b61425681614250845461400f565b846141da565b602080601f8311600181146142a957600084156142735750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555614220565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156142f6578886015182559484019460019091019084016142d7565b508582101561433257878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b82815260406020820152600061438a604083018461352e565b949350505050565b6000825161386181846020870161350a565b6000602082840312156143b657600080fd5b5051919050565b6000602082840312156143cf57600080fd5b81516129fc81613c00565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b8381101561444f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261443d86835161368a565b95509382019390820190600101614403565b50508584038187015286518085528782019482019350915060005b828110156144865784518452938101939281019260010161446a565b5091979650505050505050565b89815260007fffffffffffffffffffffffffffffffffffffffff000000000000000000000000808b60601b166020840152808a60601b166034840152507fffffffffffffffff000000000000000000000000000000000000000000000000808960c01b166048840152808860c01b1660508401525085151560f81b6058830152846059830152835161452c81607985016020880161350a565b80830190507fffffffff000000000000000000000000000000000000000000000000000000008460e01b166079820152607d81019150509a995050505050505050505056fea164736f6c6343000813000a"
func init() {
if err := json.Unmarshal([]byte(EASStorageLayoutJSON), EASStorageLayout); err != nil {
......
package main
import (
"bytes"
"context"
"errors"
"flag"
"fmt"
"math/big"
"os"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-service/client"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/sources"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/trie"
)
func CalcBaseFee(parent eth.BlockInfo, elasticity uint64, canyonActive bool) *big.Int {
denomUint := uint64(50)
if canyonActive {
denomUint = uint64(250)
}
parentGasTarget := parent.GasLimit() / elasticity
// If the parent gasUsed is the same as the target, the baseFee remains unchanged.
if parent.GasUsed() == parentGasTarget {
return new(big.Int).Set(parent.BaseFee())
}
var (
num = new(big.Int)
denom = new(big.Int)
)
if parent.GasUsed() > parentGasTarget {
// If the parent block used more gas than its target, the baseFee should increase.
// max(1, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator)
num.SetUint64(parent.GasUsed() - parentGasTarget)
num.Mul(num, parent.BaseFee())
num.Div(num, denom.SetUint64(parentGasTarget))
num.Div(num, denom.SetUint64(denomUint))
baseFeeDelta := math.BigMax(num, common.Big1)
return num.Add(parent.BaseFee(), baseFeeDelta)
} else {
// Otherwise if the parent block used less gas than its target, the baseFee should decrease.
// max(0, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator)
num.SetUint64(parentGasTarget - parent.GasUsed())
num.Mul(num, parent.BaseFee())
num.Div(num, denom.SetUint64(parentGasTarget))
num.Div(num, denom.SetUint64(denomUint))
baseFee := num.Sub(parent.BaseFee(), num)
return math.BigMax(baseFee, common.Big0)
}
}
func ManuallyEncodeReceipts(receipts types.Receipts, canyonActive bool) [][]byte {
v := uint64(1)
for _, receipt := range receipts {
if receipt.Type == types.DepositTxType {
if canyonActive {
receipt.DepositReceiptVersion = &v
} else {
receipt.DepositReceiptVersion = nil
}
}
}
var out [][]byte
for i := range receipts {
var buf bytes.Buffer
receipts.EncodeIndex(i, &buf)
out = append(out, buf.Bytes())
}
return out
}
type rawReceipts [][]byte
func (s rawReceipts) Len() int { return len(s) }
func (s rawReceipts) EncodeIndex(i int, w *bytes.Buffer) {
w.Write(s[i])
}
func HashList(list [][]byte) common.Hash {
hasher := trie.NewStackTrie(nil)
return types.DeriveSha(rawReceipts(list), hasher)
}
type L2Client interface {
BlockByNumber(context.Context, *big.Int) (*types.Block, error)
CodeAt(context.Context, common.Address, *big.Int) ([]byte, error)
InfoByNumber(context.Context, uint64) (eth.BlockInfo, error)
FetchReceipts(context.Context, common.Hash) (eth.BlockInfo, types.Receipts, error)
}
type Client struct {
*ethclient.Client
*sources.L1Client
}
type Args struct {
Number uint64
Elasticity uint64
Client L2Client
}
func ValidateReceipts(ctx Args, canyonActive bool) error {
block, err := ctx.Client.InfoByNumber(context.Background(), ctx.Number)
if err != nil {
return err
}
_, receipts, err := ctx.Client.FetchReceipts(context.Background(), block.Hash())
if err != nil {
return err
}
have := block.ReceiptHash()
want := HashList(ManuallyEncodeReceipts(receipts, canyonActive))
if have != want {
return fmt.Errorf("Receipts do not look correct. canyonActive: %v. have: %v, want: %v", canyonActive, have, want)
}
return nil
}
func Validate1559Params(ctx Args, canyonActive bool) error {
block, err := ctx.Client.InfoByNumber(context.Background(), ctx.Number)
if err != nil {
return err
}
parent, err := ctx.Client.InfoByNumber(context.Background(), ctx.Number-1)
if err != nil {
return err
}
want := CalcBaseFee(parent, ctx.Elasticity, canyonActive)
have := block.BaseFee()
if have.Cmp(want) != 0 {
return fmt.Errorf("BaseFee does not match. canyonActive: %v. have: %v, want: %v", canyonActive, have, want)
}
return nil
}
func ValidateWithdrawals(ctx Args, canyonActive bool) error {
block, err := ctx.Client.BlockByNumber(context.Background(), new(big.Int).SetUint64(ctx.Number))
if err != nil {
return err
}
if canyonActive && block.Withdrawals() == nil {
return errors.New("No nonwithdrawals in a canyon block")
} else if canyonActive && len(block.Withdrawals()) > 0 {
return errors.New("Withdrawals length is not zero in a canyon block")
} else if !canyonActive && block.Withdrawals() != nil {
return errors.New("Withdrawals in a pre-canyon block")
}
return nil
}
func ValidateCreate2Deployer(ctx Args, canyonActive bool) error {
addr := common.HexToAddress("0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2")
code, err := ctx.Client.CodeAt(context.Background(), addr, new(big.Int).SetUint64(ctx.Number))
if err != nil {
return err
}
codeHash := crypto.Keccak256Hash(code)
expectedCodeHash := common.HexToHash("0xb0550b5b431e30d38000efb7107aaa0ade03d48a7198a140edda9d27134468b2")
if canyonActive && codeHash != expectedCodeHash {
return fmt.Errorf("Canyon active but code hash does not match. have: %v, want: %v", codeHash, expectedCodeHash)
} else if !canyonActive && codeHash == expectedCodeHash {
return fmt.Errorf("Canyon not active but code hashes do match. codeHash: %v", codeHash)
}
return nil
}
// CheckActivation takes a function f which determines in a specific block follows the rules of a fork.
func CheckActivation(f func(Args, bool) error, ctx Args, forkActivated bool, valid *bool) {
if err := f(ctx, forkActivated); err != nil {
log.Error("Block did not follow fork rules", "err", err)
*valid = false
}
}
// CheckInactivation takes a function f which determines in a specific block follows the rules of a fork.
// It passes the oppose value of forkActivated & asserts that an error is returned.
func CheckInactivation(f func(Args, bool) error, ctx Args, forkActivated bool, valid *bool) {
if err := f(ctx, !forkActivated); err == nil {
log.Error("Block followed the wrong side of the fork rules")
*valid = false
}
}
func main() {
logger := log.New()
// Define the flag variables
var (
canyonActive bool
number uint64
elasticity uint64
rpcURL string
)
valid := true
// Define and parse the command-line flags
flag.BoolVar(&canyonActive, "canyon", false, "Set this flag to assert canyon behavior")
flag.Uint64Var(&number, "number", 31, "Block number to check")
flag.Uint64Var(&elasticity, "elasticity", 6, "Specify the EIP-1559 elasticity. 6 on mainnet/sepolia. 10 on goerli")
flag.StringVar(&rpcURL, "rpc-url", "http://localhost:8545", "Specify the L2 ETH RPC URL")
// Parse the command-line arguments
flag.Parse()
l2RPC, err := client.NewRPC(context.Background(), logger, rpcURL, client.WithDialBackoff(10))
if err != nil {
log.Crit("Error creating RPC", "err", err)
}
c := &rollup.Config{SeqWindowSize: 10}
l2Cfg := sources.L1ClientDefaultConfig(c, true, sources.RPCKindBasic)
sourceClient, err := sources.NewL1Client(l2RPC, logger, nil, l2Cfg)
if err != nil {
log.Crit("Error creating RPC", "err", err)
}
ethClient, err := ethclient.Dial(rpcURL)
if err != nil {
log.Crit("Error creating RPC", "err", err)
}
client := Client{ethClient, sourceClient}
ctx := Args{
Number: number,
Elasticity: elasticity,
Client: client,
}
CheckActivation(ValidateReceipts, ctx, canyonActive, &valid)
CheckInactivation(ValidateReceipts, ctx, canyonActive, &valid)
CheckActivation(Validate1559Params, ctx, canyonActive, &valid)
// Don't check in-activation for 1559 b/c at low basefees the two cannot be differentiated
CheckActivation(ValidateWithdrawals, ctx, canyonActive, &valid)
CheckInactivation(ValidateWithdrawals, ctx, canyonActive, &valid)
CheckActivation(ValidateCreate2Deployer, ctx, canyonActive, &valid)
CheckInactivation(ValidateCreate2Deployer, ctx, canyonActive, &valid)
if !valid {
os.Exit(1)
} else if canyonActive {
log.Info(fmt.Sprintf("Successfully validated block %v as a Canyon block", number))
} else {
log.Info(fmt.Sprintf("Successfully validated block %v as a Pre-Canyon block", number))
}
}
......@@ -39,7 +39,7 @@ type Agent struct {
log log.Logger
}
func NewAgent(m metrics.Metricer, loader ClaimLoader, maxDepth int, trace types.TraceProvider, responder Responder, updater types.OracleUpdater, agreeWithProposedOutput bool, log log.Logger) *Agent {
func NewAgent(m metrics.Metricer, loader ClaimLoader, maxDepth int, trace types.TraceAccessor, responder Responder, updater types.OracleUpdater, agreeWithProposedOutput bool, log log.Logger) *Agent {
return &Agent{
metrics: m,
solver: solver.NewGameSolver(maxDepth, trace),
......
......@@ -5,6 +5,7 @@ import (
"errors"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace"
"github.com/stretchr/testify/require"
"github.com/ethereum/go-ethereum/log"
......@@ -112,10 +113,10 @@ func setupTestAgent(t *testing.T, agreeWithProposedOutput bool) (*Agent, *stubCl
logger := testlog.Logger(t, log.LvlInfo)
claimLoader := &stubClaimLoader{}
depth := 4
trace := alphabet.NewTraceProvider("abcd", uint64(depth))
provider := alphabet.NewTraceProvider("abcd", uint64(depth))
responder := &stubResponder{}
updater := &stubUpdater{}
agent := NewAgent(metrics.NoopMetrics, claimLoader, depth, trace, responder, updater, agreeWithProposedOutput, logger)
agent := NewAgent(metrics.NoopMetrics, claimLoader, depth, trace.NewSimpleTraceAccessor(provider), responder, updater, agreeWithProposedOutput, logger)
return agent, claimLoader, responder
}
......
......@@ -19,6 +19,8 @@ const (
methodStatus = "status"
methodClaimCount = "claimDataLen"
methodClaim = "claimData"
methodL1Head = "l1Head"
methodProposals = "proposals"
)
type FaultDisputeGameContract struct {
......@@ -26,6 +28,12 @@ type FaultDisputeGameContract struct {
contract *batching.BoundContract
}
type Proposal struct {
Index *big.Int
L2BlockNumber *big.Int
OutputRoot common.Hash
}
func NewFaultDisputeGameContract(addr common.Address, caller *batching.MultiCaller) (*FaultDisputeGameContract, error) {
fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi()
if err != nil {
......@@ -62,6 +70,27 @@ func (f *FaultDisputeGameContract) GetAbsolutePrestateHash(ctx context.Context)
return result.GetHash(0), nil
}
func (f *FaultDisputeGameContract) GetL1Head(ctx context.Context) (common.Hash, error) {
result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodL1Head))
if err != nil {
return common.Hash{}, fmt.Errorf("failed to fetch L1 head: %w", err)
}
return result.GetHash(0), nil
}
// GetProposals returns the agreed and disputed proposals
func (f *FaultDisputeGameContract) GetProposals(ctx context.Context) (Proposal, Proposal, error) {
result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodProposals))
if err != nil {
return Proposal{}, Proposal{}, fmt.Errorf("failed to fetch proposals: %w", err)
}
var agreed, disputed Proposal
result.GetStruct(0, &agreed)
result.GetStruct(1, &disputed)
return agreed, disputed, nil
}
func (f *FaultDisputeGameContract) GetStatus(ctx context.Context) (gameTypes.GameStatus, error) {
result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodStatus))
if err != nil {
......
......@@ -60,6 +60,13 @@ func TestSimpleGetters(t *testing.T) {
return game.GetClaimCount(context.Background())
},
},
{
method: methodL1Head,
result: common.Hash{0xdd, 0xbb},
call: func(game *FaultDisputeGameContract) (any, error) {
return game.GetL1Head(context.Background())
},
},
}
for _, test := range tests {
test := test
......@@ -77,6 +84,33 @@ func TestSimpleGetters(t *testing.T) {
}
}
func TestGetProposals(t *testing.T) {
stubRpc, game := setup(t)
agreedIndex := big.NewInt(5)
agreedBlockNum := big.NewInt(6)
agreedRoot := common.Hash{0xaa}
disputedIndex := big.NewInt(7)
disputedBlockNum := big.NewInt(8)
disputedRoot := common.Hash{0xdd}
agreed := Proposal{
Index: agreedIndex,
L2BlockNumber: agreedBlockNum,
OutputRoot: agreedRoot,
}
disputed := Proposal{
Index: disputedIndex,
L2BlockNumber: disputedBlockNum,
OutputRoot: disputedRoot,
}
stubRpc.SetResponse(methodProposals, batching.BlockLatest, []interface{}{}, []interface{}{
agreed, disputed,
})
actualAgreed, actualDisputed, err := game.GetProposals(context.Background())
require.NoError(t, err)
require.Equal(t, agreed, actualAgreed)
require.Equal(t, disputed, actualDisputed)
}
func TestGetClaim(t *testing.T) {
stubRpc, game := setup(t)
idx := big.NewInt(2)
......
......@@ -8,6 +8,7 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/responder"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
......@@ -33,7 +34,7 @@ type GamePlayer struct {
status gameTypes.GameStatus
}
type resourceCreator func(addr common.Address, gameDepth uint64, dir string) (types.TraceProvider, types.OracleUpdater, error)
type resourceCreator func(addr common.Address, contract *contracts.FaultDisputeGameContract, gameDepth uint64, dir string) (types.TraceProvider, types.OracleUpdater, error)
func NewGamePlayer(
ctx context.Context,
......@@ -76,7 +77,7 @@ func NewGamePlayer(
return nil, fmt.Errorf("failed to fetch the game depth: %w", err)
}
provider, updater, err := creator(addr, gameDepth, dir)
provider, updater, err := creator(addr, loader, gameDepth, dir)
if err != nil {
return nil, fmt.Errorf("failed to create trace provider: %w", err)
}
......@@ -90,8 +91,10 @@ func NewGamePlayer(
return nil, fmt.Errorf("failed to create the responder: %w", err)
}
accessor := trace.NewSimpleTraceAccessor(provider)
agent := NewAgent(m, loader, int(gameDepth), accessor, responder, updater, cfg.AgreeWithProposedOutput, logger)
return &GamePlayer{
act: NewAgent(m, loader, int(gameDepth), provider, responder, updater, cfg.AgreeWithProposedOutput, logger).Act,
act: agent.Act,
agreeWithProposedOutput: cfg.AgreeWithProposedOutput,
loader: loader,
logger: logger,
......
......@@ -5,6 +5,7 @@ import (
"fmt"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon"
faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
......@@ -36,8 +37,8 @@ func RegisterGameTypes(
client *ethclient.Client,
) {
if cfg.TraceTypeEnabled(config.TraceTypeCannon) {
resourceCreator := func(addr common.Address, gameDepth uint64, dir string) (faultTypes.TraceProvider, faultTypes.OracleUpdater, error) {
provider, err := cannon.NewTraceProvider(ctx, logger, m, cfg, client, dir, addr, gameDepth)
resourceCreator := func(addr common.Address, contract *contracts.FaultDisputeGameContract, gameDepth uint64, dir string) (faultTypes.TraceProvider, faultTypes.OracleUpdater, error) {
provider, err := cannon.NewTraceProvider(ctx, logger, m, cfg, contract, dir, gameDepth)
if err != nil {
return nil, nil, fmt.Errorf("create cannon trace provider: %w", err)
}
......@@ -53,7 +54,7 @@ func RegisterGameTypes(
registry.RegisterGameType(cannonGameType, playerCreator)
}
if cfg.TraceTypeEnabled(config.TraceTypeAlphabet) {
resourceCreator := func(addr common.Address, gameDepth uint64, dir string) (faultTypes.TraceProvider, faultTypes.OracleUpdater, error) {
resourceCreator := func(addr common.Address, contract *contracts.FaultDisputeGameContract, gameDepth uint64, dir string) (faultTypes.TraceProvider, faultTypes.OracleUpdater, error) {
provider := alphabet.NewTraceProvider(cfg.AlphabetTrace, gameDepth)
updater := alphabet.NewOracleUpdater(logger)
return provider, updater, nil
......
......@@ -12,7 +12,7 @@ type GameSolver struct {
claimSolver *claimSolver
}
func NewGameSolver(gameDepth int, trace types.TraceProvider) *GameSolver {
func NewGameSolver(gameDepth int, trace types.TraceAccessor) *GameSolver {
return &GameSolver{
claimSolver: newClaimSolver(gameDepth, trace),
}
......
......@@ -6,6 +6,7 @@ import (
"testing"
faulttest "github.com/ethereum-optimism/optimism/op-challenger/game/fault/test"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
......@@ -113,7 +114,7 @@ func TestCalculateNextActions(t *testing.T) {
i, claim.Position.ToGIndex(), claim.Position.TraceIndex(maxDepth), claim.ParentContractIndex, claim.Countered, claim.Value)
}
solver := NewGameSolver(maxDepth, claimBuilder.CorrectTraceProvider())
solver := NewGameSolver(maxDepth, trace.NewSimpleTraceAccessor(claimBuilder.CorrectTraceProvider()))
actions, err := solver.CalculateNextActions(context.Background(), game)
require.NoError(t, err)
for i, action := range actions {
......
......@@ -7,7 +7,6 @@ import (
"fmt"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum/go-ethereum/common"
)
var (
......@@ -18,14 +17,14 @@ var (
// claimSolver uses a [TraceProvider] to determine the moves to make in a dispute game.
type claimSolver struct {
trace types.TraceProvider
trace types.TraceAccessor
gameDepth int
}
// newClaimSolver creates a new [claimSolver] using the provided [TraceProvider].
func newClaimSolver(gameDepth int, traceProvider types.TraceProvider) *claimSolver {
func newClaimSolver(gameDepth int, trace types.TraceAccessor) *claimSolver {
return &claimSolver{
traceProvider,
trace,
gameDepth,
}
}
......@@ -53,14 +52,14 @@ func (s *claimSolver) NextMove(ctx context.Context, claim types.Claim, game type
}
}
agree, err := s.agreeWithClaim(ctx, claim.ClaimData)
agree, err := s.agreeWithClaim(ctx, game, claim)
if err != nil {
return nil, err
}
if agree {
return s.defend(ctx, claim)
return s.defend(ctx, game, claim)
} else {
return s.attack(ctx, claim)
return s.attack(ctx, game, claim)
}
}
......@@ -93,28 +92,25 @@ func (s *claimSolver) AttemptStep(ctx context.Context, game types.Game, claim ty
return StepData{}, ErrStepIgnoreInvalidPath
}
claimCorrect, err := s.agreeWithClaim(ctx, claim.ClaimData)
claimCorrect, err := s.agreeWithClaim(ctx, game, claim)
if err != nil {
return StepData{}, err
}
var preState []byte
var proofData []byte
var oracleData *types.PreimageOracleData
var position types.Position
if !claimCorrect {
// Attack the claim by executing step index, so we need to get the pre-state of that index
preState, proofData, oracleData, err = s.trace.GetStepData(ctx, claim.Position)
if err != nil {
return StepData{}, err
}
position = claim.Position
} else {
// We agree with the claim so Defend and use this claim as the starting point to
// execute the step after. Thus we need the pre-state of the next step.
preState, proofData, oracleData, err = s.trace.GetStepData(ctx, claim.MoveRight())
// Defend and use this claim as the starting point to execute the step after.
// Thus, we need the pre-state of the next step.
position = claim.Position.MoveRight()
}
preState, proofData, oracleData, err := s.trace.GetStepData(ctx, game, claim, position)
if err != nil {
return StepData{}, err
}
}
return StepData{
LeafClaim: claim,
......@@ -126,9 +122,9 @@ func (s *claimSolver) AttemptStep(ctx context.Context, game types.Game, claim ty
}
// attack returns a response that attacks the claim.
func (s *claimSolver) attack(ctx context.Context, claim types.Claim) (*types.Claim, error) {
func (s *claimSolver) attack(ctx context.Context, game types.Game, claim types.Claim) (*types.Claim, error) {
position := claim.Attack()
value, err := s.traceAtPosition(ctx, position)
value, err := s.trace.Get(ctx, game, claim, position)
if err != nil {
return nil, fmt.Errorf("attack claim: %w", err)
}
......@@ -139,12 +135,12 @@ func (s *claimSolver) attack(ctx context.Context, claim types.Claim) (*types.Cla
}
// defend returns a response that defends the claim.
func (s *claimSolver) defend(ctx context.Context, claim types.Claim) (*types.Claim, error) {
func (s *claimSolver) defend(ctx context.Context, game types.Game, claim types.Claim) (*types.Claim, error) {
if claim.IsRoot() {
return nil, nil
}
position := claim.Defend()
value, err := s.traceAtPosition(ctx, position)
value, err := s.trace.Get(ctx, game, claim, position)
if err != nil {
return nil, fmt.Errorf("defend claim: %w", err)
}
......@@ -155,19 +151,14 @@ func (s *claimSolver) defend(ctx context.Context, claim types.Claim) (*types.Cla
}
// agreeWithClaim returns true if the claim is correct according to the internal [TraceProvider].
func (s *claimSolver) agreeWithClaim(ctx context.Context, claim types.ClaimData) (bool, error) {
ourValue, err := s.traceAtPosition(ctx, claim.Position)
func (s *claimSolver) agreeWithClaim(ctx context.Context, game types.Game, claim types.Claim) (bool, error) {
ourValue, err := s.trace.Get(ctx, game, claim, claim.Position)
return bytes.Equal(ourValue[:], claim.Value[:]), err
}
// traceAtPosition returns the [common.Hash] from internal [TraceProvider] at the given [Position].
func (s *claimSolver) traceAtPosition(ctx context.Context, p types.Position) (common.Hash, error) {
return s.trace.Get(ctx, p)
}
// agreeWithClaimPath returns true if the every other claim in the path to root is correct according to the internal [TraceProvider].
func (s *claimSolver) agreeWithClaimPath(ctx context.Context, game types.Game, claim types.Claim) (bool, error) {
agree, err := s.agreeWithClaim(ctx, claim.ClaimData)
agree, err := s.agreeWithClaim(ctx, game, claim)
if err != nil {
return false, err
}
......
......@@ -6,6 +6,7 @@ import (
"testing"
faulttest "github.com/ethereum-optimism/optimism/op-challenger/game/fault/test"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
......@@ -161,7 +162,7 @@ func TestAttemptStep(t *testing.T) {
t.Run(tableTest.name, func(t *testing.T) {
builder := claimBuilder.GameBuilder(tableTest.agreeWithOutputRoot, !tableTest.agreeWithOutputRoot)
tableTest.setupGame(builder)
alphabetSolver := newClaimSolver(maxDepth, claimBuilder.CorrectTraceProvider())
alphabetSolver := newClaimSolver(maxDepth, trace.NewSimpleTraceAccessor(claimBuilder.CorrectTraceProvider()))
game := builder.Game
claims := game.Claims()
lastClaim := claims[len(claims)-1]
......
package trace
import (
"context"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum/go-ethereum/common"
)
type ProviderCreator func(ctx context.Context, pre types.Claim, post types.Claim) (types.TraceProvider, error)
func NewSimpleTraceAccessor(trace types.TraceProvider) *Accessor {
selector := func(_ context.Context, _ types.Game, _ types.Claim, _ types.Position) (types.TraceProvider, error) {
return trace, nil
}
return &Accessor{selector}
}
type Accessor struct {
selector func(ctx context.Context, game types.Game, ref types.Claim, pos types.Position) (types.TraceProvider, error)
}
func (t *Accessor) Get(ctx context.Context, game types.Game, ref types.Claim, pos types.Position) (common.Hash, error) {
provider, err := t.selector(ctx, game, ref, pos)
if err != nil {
return common.Hash{}, err
}
return provider.Get(ctx, pos)
}
func (t *Accessor) GetStepData(ctx context.Context, game types.Game, ref types.Claim, pos types.Position) (prestate []byte, proofData []byte, preimageData *types.PreimageOracleData, err error) {
provider, err := t.selector(ctx, game, ref, pos)
if err != nil {
return nil, nil, nil, err
}
return provider.GetStepData(ctx, pos)
}
var _ types.TraceAccessor = (*Accessor)(nil)
package trace
import (
"context"
"fmt"
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/test"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/stretchr/testify/require"
)
func TestAccessor_UsesSelector(t *testing.T) {
ctx := context.Background()
depth := uint64(4)
provider1 := test.NewAlphabetWithProofProvider(t, int(depth), nil)
provider2 := alphabet.NewTraceProvider("qrstuv", depth)
claim := types.Claim{}
game := types.NewGameState(true, []types.Claim{claim}, depth)
pos1 := types.NewPositionFromGIndex(big.NewInt(4))
pos2 := types.NewPositionFromGIndex(big.NewInt(6))
accessor := &Accessor{
selector: func(ctx context.Context, actualGame types.Game, ref types.Claim, pos types.Position) (types.TraceProvider, error) {
require.Equal(t, game, actualGame)
require.Equal(t, claim, ref)
if pos == pos1 {
return provider1, nil
} else if pos == pos2 {
return provider2, nil
}
return nil, fmt.Errorf("incorrect position requested: %v", pos)
},
}
t.Run("Get", func(t *testing.T) {
actual, err := accessor.Get(ctx, game, claim, pos1)
require.NoError(t, err)
expected, err := provider1.Get(ctx, pos1)
require.NoError(t, err)
require.Equal(t, expected, actual)
actual, err = accessor.Get(ctx, game, claim, pos2)
require.NoError(t, err)
expected, err = provider2.Get(ctx, pos2)
require.NoError(t, err)
require.Equal(t, expected, actual)
})
t.Run("GetStepData", func(t *testing.T) {
actualPrestate, actualProofData, actualPreimageData, err := accessor.GetStepData(ctx, game, claim, pos1)
require.NoError(t, err)
expectedPrestate, expectedProofData, expectedPreimageData, err := provider1.GetStepData(ctx, pos1)
require.NoError(t, err)
require.Equal(t, expectedPrestate, actualPrestate)
require.Equal(t, expectedProofData, actualProofData)
require.Equal(t, expectedPreimageData, actualPreimageData)
actualPrestate, actualProofData, actualPreimageData, err = accessor.GetStepData(ctx, game, claim, pos2)
require.NoError(t, err)
expectedPrestate, expectedProofData, expectedPreimageData, err = provider2.GetStepData(ctx, pos2)
require.NoError(t, err)
require.Equal(t, expectedPrestate, actualPrestate)
require.Equal(t, expectedProofData, actualProofData)
require.Equal(t, expectedPreimageData, actualPreimageData)
})
}
......@@ -5,8 +5,7 @@ import (
"fmt"
"math/big"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
)
......@@ -25,26 +24,20 @@ type L2DataSource interface {
}
type GameInputsSource interface {
L1Head(opts *bind.CallOpts) ([32]byte, error)
Proposals(opts *bind.CallOpts) (struct {
Starting bindings.IFaultDisputeGameOutputProposal
Disputed bindings.IFaultDisputeGameOutputProposal
}, error)
GetL1Head(ctx context.Context) (common.Hash, error)
GetProposals(ctx context.Context) (agreed contracts.Proposal, disputed contracts.Proposal, err error)
}
func fetchLocalInputs(ctx context.Context, gameAddr common.Address, caller GameInputsSource, l2Client L2DataSource) (LocalGameInputs, error) {
opts := &bind.CallOpts{Context: ctx}
l1Head, err := caller.L1Head(opts)
func fetchLocalInputs(ctx context.Context, caller GameInputsSource, l2Client L2DataSource) (LocalGameInputs, error) {
l1Head, err := caller.GetL1Head(ctx)
if err != nil {
return LocalGameInputs{}, fmt.Errorf("fetch L1 head for game %v: %w", gameAddr, err)
return LocalGameInputs{}, fmt.Errorf("fetch L1 head: %w", err)
}
proposals, err := caller.Proposals(opts)
agreedOutput, claimedOutput, err := caller.GetProposals(ctx)
if err != nil {
return LocalGameInputs{}, fmt.Errorf("fetch proposals: %w", err)
}
claimedOutput := proposals.Disputed
agreedOutput := proposals.Starting
agreedHeader, err := l2Client.HeaderByNumber(ctx, agreedOutput.L2BlockNumber)
if err != nil {
return LocalGameInputs{}, fmt.Errorf("fetch L2 block header %v: %w", agreedOutput.L2BlockNumber, err)
......
......@@ -5,9 +5,8 @@ import (
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/require"
......@@ -15,15 +14,14 @@ import (
func TestFetchLocalInputs(t *testing.T) {
ctx := context.Background()
gameAddr := common.Address{0xab}
l1Client := &mockGameInputsSource{
contract := &mockGameInputsSource{
l1Head: common.Hash{0xcc},
starting: bindings.IFaultDisputeGameOutputProposal{
starting: contracts.Proposal{
Index: big.NewInt(6),
L2BlockNumber: big.NewInt(2222),
OutputRoot: common.Hash{0xdd},
},
disputed: bindings.IFaultDisputeGameOutputProposal{
disputed: contracts.Proposal{
Index: big.NewInt(7),
L2BlockNumber: big.NewInt(3333),
OutputRoot: common.Hash{0xee},
......@@ -32,41 +30,32 @@ func TestFetchLocalInputs(t *testing.T) {
l2Client := &mockL2DataSource{
chainID: big.NewInt(88422),
header: ethtypes.Header{
Number: l1Client.starting.L2BlockNumber,
Number: contract.starting.L2BlockNumber,
},
}
inputs, err := fetchLocalInputs(ctx, gameAddr, l1Client, l2Client)
inputs, err := fetchLocalInputs(ctx, contract, l2Client)
require.NoError(t, err)
require.Equal(t, l1Client.l1Head, inputs.L1Head)
require.Equal(t, contract.l1Head, inputs.L1Head)
require.Equal(t, l2Client.header.Hash(), inputs.L2Head)
require.EqualValues(t, l1Client.starting.OutputRoot, inputs.L2OutputRoot)
require.EqualValues(t, l1Client.disputed.OutputRoot, inputs.L2Claim)
require.Equal(t, l1Client.disputed.L2BlockNumber, inputs.L2BlockNumber)
require.EqualValues(t, contract.starting.OutputRoot, inputs.L2OutputRoot)
require.EqualValues(t, contract.disputed.OutputRoot, inputs.L2Claim)
require.Equal(t, contract.disputed.L2BlockNumber, inputs.L2BlockNumber)
}
type mockGameInputsSource struct {
l1Head common.Hash
starting bindings.IFaultDisputeGameOutputProposal
disputed bindings.IFaultDisputeGameOutputProposal
starting contracts.Proposal
disputed contracts.Proposal
}
func (s *mockGameInputsSource) L1Head(opts *bind.CallOpts) ([32]byte, error) {
func (s *mockGameInputsSource) GetL1Head(_ context.Context) (common.Hash, error) {
return s.l1Head, nil
}
func (s *mockGameInputsSource) Proposals(opts *bind.CallOpts) (struct {
Starting bindings.IFaultDisputeGameOutputProposal
Disputed bindings.IFaultDisputeGameOutputProposal
}, error) {
return struct {
Starting bindings.IFaultDisputeGameOutputProposal
Disputed bindings.IFaultDisputeGameOutputProposal
}{
Starting: s.starting,
Disputed: s.disputed,
}, nil
func (s *mockGameInputsSource) GetProposals(_ context.Context) (contracts.Proposal, contracts.Proposal, error) {
return s.starting, s.disputed, nil
}
type mockL2DataSource struct {
......
......@@ -8,11 +8,10 @@ import (
"os"
"path/filepath"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-service/ioutil"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/ethclient"
......@@ -56,17 +55,13 @@ type CannonTraceProvider struct {
lastStep uint64
}
func NewTraceProvider(ctx context.Context, logger log.Logger, m CannonMetricer, cfg *config.Config, l1Client bind.ContractCaller, dir string, gameAddr common.Address, gameDepth uint64) (*CannonTraceProvider, error) {
func NewTraceProvider(ctx context.Context, logger log.Logger, m CannonMetricer, cfg *config.Config, gameContract *contracts.FaultDisputeGameContract, dir string, gameDepth uint64) (*CannonTraceProvider, error) {
l2Client, err := ethclient.DialContext(ctx, cfg.CannonL2)
if err != nil {
return nil, fmt.Errorf("dial l2 client %v: %w", cfg.CannonL2, err)
}
defer l2Client.Close() // Not needed after fetching the inputs
gameCaller, err := bindings.NewFaultDisputeGameCaller(gameAddr, l1Client)
if err != nil {
return nil, fmt.Errorf("create caller for game %v: %w", gameAddr, err)
}
localInputs, err := fetchLocalInputs(ctx, gameAddr, gameCaller, l2Client)
localInputs, err := fetchLocalInputs(ctx, gameContract, l2Client)
if err != nil {
return nil, fmt.Errorf("fetch local game inputs: %w", err)
}
......
......@@ -57,6 +57,18 @@ type OracleUpdater interface {
UpdateOracle(ctx context.Context, data *PreimageOracleData) error
}
// TraceAccessor defines an interface to request data from a TraceProvider with additional context for the game position.
// This can be used to implement split games where lower layers of the game may have different values depending on claims
// at higher levels in the game.
type TraceAccessor interface {
// Get returns the claim value at the requested position, evaluated in the context of the specified claim (ref).
Get(ctx context.Context, game Game, ref Claim, pos Position) (common.Hash, error)
// GetStepData returns the data required to execute the step at the specified position,
// evaluated in the context of the specified claim (ref).
GetStepData(ctx context.Context, game Game, ref Claim, pos Position) (prestate []byte, proofData []byte, preimageData *PreimageOracleData, err error)
}
// TraceProvider is a generic way to get a claim value at a specific step in the trace.
type TraceProvider interface {
// Get returns the claim value at the requested index.
......
......@@ -23,10 +23,6 @@ test-http: pre-test
OP_E2E_USE_HTTP=true $(go_test) $(go_test_flags) ./...
.PHONY: test-http
test-span-batch: pre-test
OP_E2E_USE_SPAN_BATCH=true $(go_test) $(go_test_flags) ./...
.PHONY: test-span-batch
cannon-prestate:
make -C .. cannon-prestate
.PHONY: cannon-prestate
......
......@@ -6,20 +6,47 @@ import (
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"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/params"
"github.com/stretchr/testify/require"
)
// TestBatchInLastPossibleBlocks tests that the derivation pipeline
// TestBlockTimeBatchType run each blocktime-related test case in singular batch mode and span batch mode.
func TestBlockTimeBatchType(t *testing.T) {
tests := []struct {
name string
f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64)
}{
{"BatchInLastPossibleBlocks", BatchInLastPossibleBlocks},
{"LargeL1Gaps", LargeL1Gaps},
}
for _, test := range tests {
test := test
t.Run(test.name+"_SingularBatch", func(t *testing.T) {
test.f(t, nil)
})
}
spanBatchTimeOffset := hexutil.Uint64(0)
for _, test := range tests {
test := test
t.Run(test.name+"_SpanBatch", func(t *testing.T) {
test.f(t, &spanBatchTimeOffset)
})
}
}
// BatchInLastPossibleBlocks tests that the derivation pipeline
// accepts a batch that is included in the last possible L1 block
// where there are also no other batches included in the sequence
// window.
// This is a regression test against the bug fixed in PR #4566
func TestBatchInLastPossibleBlocks(gt *testing.T) {
func BatchInLastPossibleBlocks(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
dp.DeployConfig.SequencerWindowSize = 4
dp.DeployConfig.L2BlockTime = 2
......@@ -116,7 +143,7 @@ func TestBatchInLastPossibleBlocks(gt *testing.T) {
verifyChainStateOnSequencer(12, 23, 11, 17, 8)
}
// TestLargeL1Gaps tests the case that there is a gap between two L1 blocks which
// LargeL1Gaps tests the case that there is a gap between two L1 blocks which
// is larger than the sequencer drift.
// This test has the following parameters:
// L1 Block time: 4s. L2 Block time: 2s. Sequencer Drift: 32s
......@@ -127,13 +154,14 @@ func TestBatchInLastPossibleBlocks(gt *testing.T) {
// Then it generates 3 more L1 blocks.
// At this point it can verify that the batches where properly generated.
// Note: It batches submits when possible.
func TestLargeL1Gaps(gt *testing.T) {
func LargeL1Gaps(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L1BlockTime = 4
dp.DeployConfig.L2BlockTime = 2
dp.DeployConfig.SequencerWindowSize = 4
dp.DeployConfig.MaxSequencerDrift = 32
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug)
......
package actions
import (
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-service/testlog"
)
func TestDencunL1Fork(gt *testing.T) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
sd := e2eutils.Setup(t, dp, defaultAlloc)
activation := sd.L1Cfg.Timestamp + 24
sd.L1Cfg.Config.CancunTime = &activation
log := testlog.Logger(t, log.LvlDebug)
_, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log)
l1Head := miner.l1Chain.CurrentBlock()
require.False(t, sd.L1Cfg.Config.IsCancun(l1Head.Number, l1Head.Time), "Cancun not active yet")
// start op-nodes
sequencer.ActL2PipelineFull(t)
verifier.ActL2PipelineFull(t)
// build empty L1 blocks, crossing the fork boundary
miner.ActL1SetFeeRecipient(common.Address{'A', 0})
miner.ActEmptyBlock(t)
miner.ActEmptyBlock(t) // Cancun activates here
miner.ActEmptyBlock(t)
// verify Cancun is active
l1Head = miner.l1Chain.CurrentBlock()
require.True(t, sd.L1Cfg.Config.IsCancun(l1Head.Number, l1Head.Time), "Cancun active")
// build L2 chain up to and including L2 blocks referencing Cancun L1 blocks
sequencer.ActL1HeadSignal(t)
sequencer.ActBuildToL1Head(t)
miner.ActL1StartBlock(12)(t)
batcher.ActSubmitAll(t)
miner.ActL1IncludeTx(batcher.batcherAddr)(t)
miner.ActL1EndBlock(t)
// sync verifier
verifier.ActL1HeadSignal(t)
verifier.ActL2PipelineFull(t)
// verify verifier accepted Cancun L1 inputs
require.Equal(t, l1Head.Hash(), verifier.SyncStatus().SafeL2.L1Origin.Hash, "verifier synced L1 chain that includes Cancun headers")
require.Equal(t, sequencer.SyncStatus().UnsafeL2, verifier.SyncStatus().UnsafeL2, "verifier and sequencer agree")
}
......@@ -76,6 +76,13 @@ func (s *L1Miner) ActL1StartBlock(timeDelta uint64) Action {
if s.l1Cfg.Config.IsShanghai(header.Number, header.Time) {
header.WithdrawalsHash = &types.EmptyWithdrawalsHash
}
if s.l1Cfg.Config.IsCancun(header.Number, header.Time) {
var root common.Hash
var zero uint64
header.BlobGasUsed = &zero
header.ExcessBlobGas = &zero
header.ParentBeaconRoot = &root
}
s.l1Building = true
s.l1BuildingHeader = header
......
......@@ -7,6 +7,7 @@ import (
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
......@@ -20,7 +21,36 @@ import (
"github.com/ethereum-optimism/optimism/op-service/testlog"
)
func TestBatcher(gt *testing.T) {
// TestL2BatcherBatchType run each batcher-related test case in singular batch mode and span batch mode.
func TestL2BatcherBatchType(t *testing.T) {
tests := []struct {
name string
f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64)
}{
{"NormalBatcher", NormalBatcher},
{"L2Finalization", L2Finalization},
{"L2FinalizationWithSparseL1", L2FinalizationWithSparseL1},
{"GarbageBatch", GarbageBatch},
{"ExtendedTimeWithoutL1Batches", ExtendedTimeWithoutL1Batches},
{"BigL2Txs", BigL2Txs},
}
for _, test := range tests {
test := test
t.Run(test.name+"_SingularBatch", func(t *testing.T) {
test.f(t, nil)
})
}
spanBatchTimeOffset := hexutil.Uint64(0)
for _, test := range tests {
test := test
t.Run(test.name+"_SpanBatch", func(t *testing.T) {
test.f(t, &spanBatchTimeOffset)
})
}
}
func NormalBatcher(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
p := &e2eutils.TestParams{
MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12)
......@@ -29,6 +59,7 @@ func TestBatcher(gt *testing.T) {
L1BlockTime: 12,
}
dp := e2eutils.MakeDeployParams(t, p)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
......@@ -55,7 +86,7 @@ func TestBatcher(gt *testing.T) {
To: &dp.Addresses.Bob,
Value: e2eutils.Ether(2),
})
require.NoError(gt, cl.SendTransaction(t.Ctx(), tx))
require.NoError(t, cl.SendTransaction(t.Ctx(), tx))
sequencer.ActL2PipelineFull(t)
verifier.ActL2PipelineFull(t)
......@@ -97,9 +128,10 @@ func TestBatcher(gt *testing.T) {
require.NotNil(t, vTx)
}
func TestL2Finalization(gt *testing.T) {
func L2Finalization(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug)
miner, engine, sequencer := setupSequencerTest(t, sd, log)
......@@ -202,10 +234,11 @@ func TestL2Finalization(gt *testing.T) {
require.Equal(t, heightToSubmit, sequencer.SyncStatus().FinalizedL2.Number, "unknown/bad finalized L1 blocks are ignored")
}
// TestL2FinalizationWithSparseL1 tests that safe L2 blocks can be finalized even if we do not regularly get a L1 finalization signal
func TestL2FinalizationWithSparseL1(gt *testing.T) {
// L2FinalizationWithSparseL1 tests that safe L2 blocks can be finalized even if we do not regularly get a L1 finalization signal
func L2FinalizationWithSparseL1(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug)
miner, engine, sequencer := setupSequencerTest(t, sd, log)
......@@ -258,13 +291,14 @@ func TestL2FinalizationWithSparseL1(gt *testing.T) {
require.Equal(t, finalStatus.FinalizedL2.Number, finalStatus.UnsafeL2.Number, "sequencer submitted its L2 block and it finalized")
}
// TestGarbageBatch tests the behavior of an invalid/malformed output channel frame containing
// GarbageBatch tests the behavior of an invalid/malformed output channel frame containing
// valid batches being submitted to the batch inbox. These batches should always be rejected
// and the safe L2 head should remain unaltered.
func TestGarbageBatch(gt *testing.T) {
func GarbageBatch(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
p := defaultRollupTestParams
dp := e2eutils.MakeDeployParams(t, p)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
for _, garbageKind := range GarbageKinds {
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlError)
......@@ -340,7 +374,7 @@ func TestGarbageBatch(gt *testing.T) {
}
}
func TestExtendedTimeWithoutL1Batches(gt *testing.T) {
func ExtendedTimeWithoutL1Batches(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
p := &e2eutils.TestParams{
MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12)
......@@ -349,6 +383,7 @@ func TestExtendedTimeWithoutL1Batches(gt *testing.T) {
L1BlockTime: 12,
}
dp := e2eutils.MakeDeployParams(t, p)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlError)
miner, engine, sequencer := setupSequencerTest(t, sd, log)
......@@ -386,7 +421,7 @@ func TestExtendedTimeWithoutL1Batches(gt *testing.T) {
require.Equal(t, sequencer.L2Unsafe(), sequencer.L2Safe(), "same for sequencer")
}
// TestBigL2Txs tests a high-throughput case with constrained batcher:
// BigL2Txs tests a high-throughput case with constrained batcher:
// - Fill 40 L2 blocks to near max-capacity, with txs of 120 KB each
// - Buffer the L2 blocks into channels together as much as possible, submit data-txs only when necessary
// (just before crossing the max RLP channel size)
......@@ -398,7 +433,7 @@ func TestExtendedTimeWithoutL1Batches(gt *testing.T) {
// The goal of this test is to quickly run through an otherwise very slow process of submitting and including lots of data.
// This does not test the batcher code, but is really focused at testing the batcher utils
// and channel-decoding verifier code in the derive package.
func TestBigL2Txs(gt *testing.T) {
func BigL2Txs(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
p := &e2eutils.TestParams{
MaxSequencerDrift: 100,
......@@ -407,6 +442,7 @@ func TestBigL2Txs(gt *testing.T) {
L1BlockTime: 12,
}
dp := e2eutils.MakeDeployParams(t, p)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlInfo)
miner, engine, sequencer := setupSequencerTest(t, sd, log)
......@@ -464,7 +500,7 @@ func TestBigL2Txs(gt *testing.T) {
Value: big.NewInt(0),
Data: data,
})
require.NoError(gt, cl.SendTransaction(t.Ctx(), tx))
require.NoError(t, cl.SendTransaction(t.Ctx(), tx))
engine.ActL2IncludeTx(dp.Addresses.Alice)(t)
}
sequencer.ActL2EndBlock(t)
......
......@@ -4,6 +4,7 @@ import (
"testing"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require"
......@@ -14,9 +15,34 @@ import (
"github.com/ethereum-optimism/optimism/op-service/testlog"
)
func TestProposer(gt *testing.T) {
// TestProposerBatchType run each proposer-related test case in singular batch mode and span batch mode.
func TestProposerBatchType(t *testing.T) {
tests := []struct {
name string
f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64)
}{
{"RunProposerTest", RunProposerTest},
}
for _, test := range tests {
test := test
t.Run(test.name+"_SingularBatch", func(t *testing.T) {
test.f(t, nil)
})
}
spanBatchTimeOffset := hexutil.Uint64(0)
for _, test := range tests {
test := test
t.Run(test.name+"_SpanBatch", func(t *testing.T) {
test.f(t, &spanBatchTimeOffset)
})
}
}
func RunProposerTest(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
......
......@@ -7,6 +7,7 @@ import (
"testing"
"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/eth/ethconfig"
"github.com/ethereum/go-ethereum/log"
......@@ -21,8 +22,9 @@ import (
"github.com/ethereum-optimism/optimism/op-service/testlog"
)
func setupReorgTest(t Testing, config *e2eutils.TestParams) (*e2eutils.SetupData, *e2eutils.DeployParams, *L1Miner, *L2Sequencer, *L2Engine, *L2Verifier, *L2Engine, *L2Batcher) {
func setupReorgTest(t Testing, config *e2eutils.TestParams, spanBatchTimeOffset *hexutil.Uint64) (*e2eutils.SetupData, *e2eutils.DeployParams, *L1Miner, *L2Sequencer, *L2Engine, *L2Verifier, *L2Engine, *L2Batcher) {
dp := e2eutils.MakeDeployParams(t, config)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug)
......@@ -44,9 +46,38 @@ func setupReorgTestActors(t Testing, dp *e2eutils.DeployParams, sd *e2eutils.Set
return sd, dp, miner, sequencer, seqEngine, verifier, verifEngine, batcher
}
func TestReorgOrphanBlock(gt *testing.T) {
// TestReorgBatchType run each reorg-related test case in singular batch mode and span batch mode.
func TestReorgBatchType(t *testing.T) {
tests := []struct {
name string
f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64)
}{
{"ReorgOrphanBlock", ReorgOrphanBlock},
{"ReorgFlipFlop", ReorgFlipFlop},
{"DeepReorg", DeepReorg},
{"RestartOpGeth", RestartOpGeth},
{"ConflictingL2Blocks", ConflictingL2Blocks},
{"SyncAfterReorg", SyncAfterReorg},
}
for _, test := range tests {
test := test
t.Run(test.name+"_SingularBatch", func(t *testing.T) {
test.f(t, nil)
})
}
spanBatchTimeOffset := hexutil.Uint64(0)
for _, test := range tests {
test := test
t.Run(test.name+"_SpanBatch", func(t *testing.T) {
test.f(t, &spanBatchTimeOffset)
})
}
}
func ReorgOrphanBlock(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, defaultRollupTestParams)
sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, defaultRollupTestParams, spanBatchTimeOffset)
verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg)
sequencer.ActL2PipelineFull(t)
......@@ -112,9 +143,9 @@ func TestReorgOrphanBlock(gt *testing.T) {
require.Equal(t, verifier.L2Safe(), sequencer.L2Safe(), "verifier and sequencer see same safe L2 block, while only verifier dealt with the orphan and replay")
}
func TestReorgFlipFlop(gt *testing.T) {
func ReorgFlipFlop(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, defaultRollupTestParams)
sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, defaultRollupTestParams, spanBatchTimeOffset)
minerCl := miner.L1Client(t, sd.RollupCfg)
verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg)
checkVerifEngine := func() {
......@@ -333,7 +364,7 @@ func TestReorgFlipFlop(gt *testing.T) {
// Verifier
// - Unsafe head is 62
// - Safe head is 42
func TestDeepReorg(gt *testing.T) {
func DeepReorg(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
// Create actor and verification engine client
......@@ -342,7 +373,7 @@ func TestDeepReorg(gt *testing.T) {
SequencerWindowSize: 20,
ChannelTimeout: 120,
L1BlockTime: 4,
})
}, spanBatchTimeOffset)
minerCl := miner.L1Client(t, sd.RollupCfg)
l2Client := seqEngine.EthClient()
verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg)
......@@ -566,9 +597,9 @@ type rpcWrapper struct {
client.RPC
}
// TestRestartOpGeth tests that the sequencer can restart its execution engine without rollup-node restart,
// RestartOpGeth tests that the sequencer can restart its execution engine without rollup-node restart,
// including recovering the finalized/safe state of L2 chain without reorging.
func TestRestartOpGeth(gt *testing.T) {
func RestartOpGeth(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dbPath := path.Join(t.TempDir(), "testdb")
dbOption := func(_ *ethconfig.Config, nodeCfg *node.Config) error {
......@@ -576,6 +607,7 @@ func TestRestartOpGeth(gt *testing.T) {
return nil
}
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug)
jwtPath := e2eutils.WriteDefaultJWT(t)
......@@ -660,12 +692,13 @@ func TestRestartOpGeth(gt *testing.T) {
require.Equal(t, statusBeforeRestart.SafeL2, sequencer.L2Safe(), "expecting the safe block to catch up to what it was before shutdown after syncing from L1, and not be stuck at the finalized block")
}
// TestConflictingL2Blocks tests that a second copy of the sequencer stack cannot introduce an alternative
// ConflictingL2Blocks tests that a second copy of the sequencer stack cannot introduce an alternative
// L2 block (compared to something already secured by the first sequencer):
// the alt block is not synced by the verifier, in unsafe and safe sync modes.
func TestConflictingL2Blocks(gt *testing.T) {
func ConflictingL2Blocks(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug)
......@@ -772,7 +805,7 @@ func TestConflictingL2Blocks(gt *testing.T) {
require.Equal(t, sequencer.L2Unsafe(), altSequencer.L2Unsafe(), "and gets back in harmony with original sequencer")
}
func TestSyncAfterReorg(gt *testing.T) {
func SyncAfterReorg(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
testingParams := e2eutils.TestParams{
MaxSequencerDrift: 60,
......@@ -780,7 +813,7 @@ func TestSyncAfterReorg(gt *testing.T) {
ChannelTimeout: 2,
L1BlockTime: 12,
}
sd, dp, miner, sequencer, seqEngine, verifier, _, batcher := setupReorgTest(t, &testingParams)
sd, dp, miner, sequencer, seqEngine, verifier, _, batcher := setupReorgTest(t, &testingParams, spanBatchTimeOffset)
l2Client := seqEngine.EthClient()
log := testlog.Logger(t, log.LvlDebug)
addresses := e2eutils.CollectAddresses(sd, dp)
......
......@@ -23,9 +23,35 @@ import (
"github.com/stretchr/testify/require"
)
func TestDerivationWithFlakyL1RPC(gt *testing.T) {
// TestSyncBatchType run each sync test case in singular batch mode and span batch mode.
func TestSyncBatchType(t *testing.T) {
tests := []struct {
name string
f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64)
}{
{"DerivationWithFlakyL1RPC", DerivationWithFlakyL1RPC},
{"FinalizeWhileSyncing", FinalizeWhileSyncing},
}
for _, test := range tests {
test := test
t.Run(test.name+"_SingularBatch", func(t *testing.T) {
test.f(t, nil)
})
}
spanBatchTimeOffset := hexutil.Uint64(0)
for _, test := range tests {
test := test
t.Run(test.name+"_SpanBatch", func(t *testing.T) {
test.f(t, &spanBatchTimeOffset)
})
}
}
func DerivationWithFlakyL1RPC(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlError) // mute all the temporary derivation errors that we forcefully create
_, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log)
......@@ -62,9 +88,10 @@ func TestDerivationWithFlakyL1RPC(gt *testing.T) {
require.Equal(t, sequencer.L2Unsafe(), verifier.L2Safe(), "verifier is synced")
}
func TestFinalizeWhileSyncing(gt *testing.T) {
func FinalizeWhileSyncing(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlError) // mute all the temporary derivation errors that we forcefully create
_, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log)
......
......@@ -7,6 +7,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"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/stretchr/testify/require"
......@@ -19,13 +20,40 @@ import (
"github.com/ethereum-optimism/optimism/op-service/testlog"
)
// TestBatcherKeyRotation tests that batcher A can operate, then be replaced with batcher B, then ignore old batcher A,
// TestSystemConfigBatchType run each system config-related test case in singular batch mode and span batch mode.
func TestSystemConfigBatchType(t *testing.T) {
tests := []struct {
name string
f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64)
}{
{"BatcherKeyRotation", BatcherKeyRotation},
{"GPOParamsChange", GPOParamsChange},
{"GasLimitChange", GasLimitChange},
}
for _, test := range tests {
test := test
t.Run(test.name+"_SingularBatch", func(t *testing.T) {
test.f(t, nil)
})
}
spanBatchTimeOffset := hexutil.Uint64(0)
for _, test := range tests {
test := test
t.Run(test.name+"_SpanBatch", func(t *testing.T) {
test.f(t, &spanBatchTimeOffset)
})
}
}
// BatcherKeyRotation tests that batcher A can operate, then be replaced with batcher B, then ignore old batcher A,
// and that the change to batcher B is reverted properly upon reorg of L1.
func TestBatcherKeyRotation(gt *testing.T) {
func BatcherKeyRotation(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2BlockTime = 2
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
......@@ -198,11 +226,12 @@ func TestBatcherKeyRotation(gt *testing.T) {
require.Equal(t, sequencer.L2Unsafe(), verifier.L2Unsafe(), "verifier synced")
}
// TestGPOParamsChange tests that the GPO params can be updated to adjust fees of L2 transactions,
// GPOParamsChange tests that the GPO params can be updated to adjust fees of L2 transactions,
// and that the L1 data fees to the L2 transaction are applied correctly before, during and after the GPO update in L2.
func TestGPOParamsChange(gt *testing.T) {
func GPOParamsChange(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
......@@ -326,12 +355,13 @@ func TestGPOParamsChange(gt *testing.T) {
require.Equal(t, "2.3", receipt.FeeScalar.String(), "2_300_000 divided by 6 decimals = float(2.3)")
}
// TestGasLimitChange tests that the gas limit can be configured to L1,
// GasLimitChange tests that the gas limit can be configured to L1,
// and that the L2 changes the gas limit instantly at the exact block that adopts the L1 origin with
// the gas limit change event. And checks if a verifier node can reproduce the same gas limit change.
func TestGasLimitChange(gt *testing.T) {
func GasLimitChange(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
......
......@@ -13,10 +13,12 @@ import (
"github.com/ethereum-optimism/optimism/op-service/testlog"
)
type regolithScheduledTest struct {
type hardforkScheduledTest struct {
name string
regolithTime *hexutil.Uint64
spanBatchTime *hexutil.Uint64
activateRegolith bool
activateSpanBatch bool
}
// TestCrossLayerUser tests that common actions of the CrossLayerUser actor work in various regolith configurations:
......@@ -31,11 +33,18 @@ func TestCrossLayerUser(t *testing.T) {
zeroTime := hexutil.Uint64(0)
futureTime := hexutil.Uint64(20)
farFutureTime := hexutil.Uint64(2000)
tests := []regolithScheduledTest{
{name: "NoRegolith", regolithTime: nil, activateRegolith: false},
{name: "NotYetRegolith", regolithTime: &farFutureTime, activateRegolith: false},
{name: "RegolithAtGenesis", regolithTime: &zeroTime, activateRegolith: true},
{name: "RegolithAfterGenesis", regolithTime: &futureTime, activateRegolith: true},
tests := []hardforkScheduledTest{
{name: "NoRegolith", regolithTime: nil, activateRegolith: false, spanBatchTime: nil, activateSpanBatch: false},
{name: "NotYetRegolith", regolithTime: &farFutureTime, activateRegolith: false, spanBatchTime: nil, activateSpanBatch: false},
{name: "RegolithAtGenesis", regolithTime: &zeroTime, activateRegolith: true, spanBatchTime: nil, activateSpanBatch: false},
{name: "RegolithAfterGenesis", regolithTime: &futureTime, activateRegolith: true, spanBatchTime: nil, activateSpanBatch: false},
{name: "NoSpanBatch", regolithTime: &zeroTime, activateRegolith: true, spanBatchTime: nil, activateSpanBatch: false},
{name: "NotYetSpanBatch", regolithTime: &zeroTime, activateRegolith: true,
spanBatchTime: &farFutureTime, activateSpanBatch: false},
{name: "SpanBatchAtGenesis", regolithTime: &zeroTime, activateRegolith: true,
spanBatchTime: &zeroTime, activateSpanBatch: true},
{name: "SpanBatchAfterGenesis", regolithTime: &zeroTime, activateRegolith: true,
spanBatchTime: &futureTime, activateSpanBatch: true},
}
for _, test := range tests {
test := test // Use a fixed reference as the tests run in parallel
......@@ -45,10 +54,11 @@ func TestCrossLayerUser(t *testing.T) {
}
}
func runCrossLayerUserTest(gt *testing.T, test regolithScheduledTest) {
func runCrossLayerUserTest(gt *testing.T, test hardforkScheduledTest) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisRegolithTimeOffset = test.regolithTime
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = test.spanBatchTime
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug)
......
......@@ -4,13 +4,15 @@ import (
"context"
"path/filepath"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-service/sources/batching"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
)
......@@ -32,7 +34,7 @@ func (g *CannonGameHelper) StartChallenger(ctx context.Context, rollupCfg *rollu
return c
}
func (g *CannonGameHelper) CreateHonestActor(ctx context.Context, rollupCfg *rollup.Config, l2Genesis *core.Genesis, l1Client bind.ContractCaller, l1Endpoint string, l2Endpoint string, options ...challenger.Option) *HonestHelper {
func (g *CannonGameHelper) CreateHonestActor(ctx context.Context, rollupCfg *rollup.Config, l2Genesis *core.Genesis, l1Client *ethclient.Client, l1Endpoint string, l2Endpoint string, options ...challenger.Option) *HonestHelper {
opts := []challenger.Option{
challenger.WithCannon(g.t, rollupCfg, l2Genesis, l2Endpoint),
challenger.WithFactoryAddress(g.factoryAddr),
......@@ -42,7 +44,9 @@ func (g *CannonGameHelper) CreateHonestActor(ctx context.Context, rollupCfg *rol
cfg := challenger.NewChallengerConfig(g.t, l1Endpoint, opts...)
logger := testlog.Logger(g.t, log.LvlInfo).New("role", "CorrectTrace")
maxDepth := g.MaxDepth(ctx)
provider, err := cannon.NewTraceProvider(ctx, logger, metrics.NoopMetrics, cfg, l1Client, filepath.Join(cfg.Datadir, "honest"), g.addr, uint64(maxDepth))
gameContract, err := contracts.NewFaultDisputeGameContract(g.addr, batching.NewMultiCaller(l1Client.Client(), batching.DefaultBatchSize))
g.require.NoError(err, "Create game contract bindings")
provider, err := cannon.NewTraceProvider(ctx, logger, metrics.NoopMetrics, cfg, gameContract, filepath.Join(cfg.Datadir, "honest"), uint64(maxDepth))
g.require.NoError(err, "create cannon trace provider")
return &HonestHelper{
......
......@@ -59,7 +59,6 @@ func MakeDeployParams(t require.TestingT, tp *TestParams) *DeployParams {
deployConfig.L1BlockTime = tp.L1BlockTime
deployConfig.L2GenesisRegolithTimeOffset = nil
deployConfig.L2GenesisCanyonTimeOffset = CanyonTimeOffset()
deployConfig.L2GenesisSpanBatchTimeOffset = SpanBatchTimeOffset()
require.NoError(t, deployConfig.Check())
require.Equal(t, addresses.Batcher, deployConfig.BatchSenderAddress)
......@@ -186,14 +185,6 @@ func SystemConfigFromDeployConfig(deployConfig *genesis.DeployConfig) eth.System
}
}
func SpanBatchTimeOffset() *hexutil.Uint64 {
if os.Getenv("OP_E2E_USE_SPAN_BATCH") == "true" {
offset := hexutil.Uint64(0)
return &offset
}
return nil
}
func CanyonTimeOffset() *hexutil.Uint64 {
if os.Getenv("OP_E2E_USE_CANYON") == "true" {
offset := hexutil.Uint64(0)
......
......@@ -88,7 +88,6 @@ func DefaultSystemConfig(t *testing.T) SystemConfig {
deployConfig := config.DeployConfig.Copy()
deployConfig.L1GenesisBlockTimestamp = hexutil.Uint64(time.Now().Unix())
deployConfig.L2GenesisCanyonTimeOffset = e2eutils.CanyonTimeOffset()
deployConfig.L2GenesisSpanBatchTimeOffset = e2eutils.SpanBatchTimeOffset()
require.NoError(t, deployConfig.Check(), "Deploy config is invalid, do you need to run make devnet-allocs?")
l1Deployments := config.L1Deployments.Copy()
require.NoError(t, l1Deployments.Check())
......@@ -684,7 +683,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste
}
var batchType uint = derive.SingularBatchType
if os.Getenv("OP_E2E_USE_SPAN_BATCH") == "true" {
if cfg.DeployConfig.L2GenesisSpanBatchTimeOffset != nil && *cfg.DeployConfig.L2GenesisSpanBatchTimeOffset == hexutil.Uint64(0) {
batchType = derive.SpanBatchType
}
batcherMaxL1TxSizeBytes := cfg.BatcherMaxL1TxSizeBytes
......
......@@ -15,25 +15,42 @@ import (
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc"
"github.com/stretchr/testify/require"
)
func TestVerifyL2OutputRoot(t *testing.T) {
testVerifyL2OutputRoot(t, false)
testVerifyL2OutputRoot(t, false, false)
}
func TestVerifyL2OutputRootSpanBatch(t *testing.T) {
testVerifyL2OutputRoot(t, false, true)
}
func TestVerifyL2OutputRootDetached(t *testing.T) {
testVerifyL2OutputRoot(t, true)
testVerifyL2OutputRoot(t, true, false)
}
func TestVerifyL2OutputRootDetachedSpanBatch(t *testing.T) {
testVerifyL2OutputRoot(t, true, true)
}
func TestVerifyL2OutputRootEmptyBlock(t *testing.T) {
testVerifyL2OutputRootEmptyBlock(t, false)
testVerifyL2OutputRootEmptyBlock(t, false, false)
}
func TestVerifyL2OutputRootEmptyBlockSpanBatch(t *testing.T) {
testVerifyL2OutputRootEmptyBlock(t, false, true)
}
func TestVerifyL2OutputRootEmptyBlockDetached(t *testing.T) {
testVerifyL2OutputRootEmptyBlock(t, true)
testVerifyL2OutputRootEmptyBlock(t, true, false)
}
func TestVerifyL2OutputRootEmptyBlockDetachedSpanBatch(t *testing.T) {
testVerifyL2OutputRootEmptyBlock(t, true, true)
}
// TestVerifyL2OutputRootEmptyBlock asserts that the program can verify the output root of an empty block
......@@ -46,7 +63,7 @@ func TestVerifyL2OutputRootEmptyBlockDetached(t *testing.T) {
// - reboot the batch submitter
// - update the state root via a tx
// - run program
func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool) {
func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool, spanBatchActivated bool) {
InitParallel(t)
ctx := context.Background()
......@@ -56,6 +73,13 @@ func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool) {
// Use a small sequencer window size to avoid test timeout while waiting for empty blocks
// But not too small to ensure that our claim and subsequent state change is published
cfg.DeployConfig.SequencerWindowSize = 16
if spanBatchActivated {
// Activate span batch hard fork
minTs := hexutil.Uint64(0)
cfg.DeployConfig.L2GenesisSpanBatchTimeOffset = &minTs
} else {
cfg.DeployConfig.L2GenesisSpanBatchTimeOffset = nil
}
sys, err := cfg.Start(t)
require.Nil(t, err, "Error starting up system")
......@@ -147,13 +171,20 @@ func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool) {
})
}
func testVerifyL2OutputRoot(t *testing.T, detached bool) {
func testVerifyL2OutputRoot(t *testing.T, detached bool, spanBatchActivated bool) {
InitParallel(t)
ctx := context.Background()
cfg := DefaultSystemConfig(t)
// We don't need a verifier - just the sequencer is enough
delete(cfg.Nodes, "verifier")
if spanBatchActivated {
// Activate span batch hard fork
minTs := hexutil.Uint64(0)
cfg.DeployConfig.L2GenesisSpanBatchTimeOffset = &minTs
} else {
cfg.DeployConfig.L2GenesisSpanBatchTimeOffset = nil
}
sys, err := cfg.Start(t)
require.Nil(t, err, "Error starting up system")
......
......@@ -45,6 +45,31 @@ import (
"github.com/ethereum-optimism/optimism/op-service/testlog"
)
// TestSystemBatchType run each system e2e test case in singular batch mode and span batch mode.
// If the test case tests batch submission and advancing safe head, it should be tested in both singular and span batch mode.
func TestSystemBatchType(t *testing.T) {
tests := []struct {
name string
f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64)
}{
{"StopStartBatcher", StopStartBatcher},
}
for _, test := range tests {
test := test
t.Run(test.name+"_SingularBatch", func(t *testing.T) {
test.f(t, nil)
})
}
spanBatchTimeOffset := hexutil.Uint64(0)
for _, test := range tests {
test := test
t.Run(test.name+"_SpanBatch", func(t *testing.T) {
test.f(t, &spanBatchTimeOffset)
})
}
}
func TestMain(m *testing.M) {
if config.ExternalL2Shim != "" {
fmt.Println("Running tests with external L2 process adapter at ", config.ExternalL2Shim)
......@@ -1222,10 +1247,11 @@ func TestFees(t *testing.T) {
require.Equal(t, balanceDiff, totalFee, "balances should add up")
}
func TestStopStartBatcher(t *testing.T) {
func StopStartBatcher(t *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
InitParallel(t)
cfg := DefaultSystemConfig(t)
cfg.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sys, err := cfg.Start(t)
require.Nil(t, err, "Error starting up system")
defer sys.Close()
......
bin
# config files
genesis.json
jwt.txt
rollup.json
......@@ -2,6 +2,7 @@ package cli
import (
"fmt"
"strings"
"github.com/ethereum/go-ethereum/crypto"
"github.com/urfave/cli/v2"
......@@ -19,7 +20,7 @@ func LoadSignerSetup(ctx *cli.Context) (p2p.SignerSetup, error) {
if key != "" {
// Mnemonics are bad because they leak *all* keys when they leak.
// Unencrypted keys from file are bad because they are easy to leak (and we are not checking file permissions).
priv, err := crypto.HexToECDSA(key)
priv, err := crypto.HexToECDSA(strings.TrimPrefix(key, "0x"))
if err != nil {
return nil, fmt.Errorf("failed to read batch submitter key: %w", err)
}
......
......@@ -326,6 +326,12 @@ func BuildBlocksValidator(log log.Logger, cfg *rollup.Config, runCfg GossipRunti
return pubsub.ValidationReject
}
// [REJECT] if a V2 Block has non-empty withdrawals
if blockVersion == eth.BlockV2 && len(*payload.Withdrawals) != 0 {
log.Warn("payload is on v2 topic, but has non-empty withdrawals", "bad_hash", payload.BlockHash.String(), "withdrawal_count", len(*payload.Withdrawals))
return pubsub.ValidationReject
}
seen, ok := blockHeightLRU.Get(uint64(payload.BlockNumber))
if !ok {
seen = new(seenBlocks)
......
package p2p
import (
"bytes"
"context"
"fmt"
"math/big"
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/golang/snappy"
// "github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/testutils"
"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/crypto"
"github.com/ethereum/go-ethereum/log"
pubsub "github.com/libp2p/go-libp2p-pubsub"
pubsub_pb "github.com/libp2p/go-libp2p-pubsub/pb"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/stretchr/testify/require"
......@@ -89,3 +99,65 @@ func TestVerifyBlockSignature(t *testing.T) {
require.Equal(t, pubsub.ValidationIgnore, result)
})
}
func createSignedP2Payload(payload *eth.ExecutionPayload, signer Signer, l2ChainID *big.Int) ([]byte, error) {
var buf bytes.Buffer
buf.Write(make([]byte, 65))
if _, err := payload.MarshalSSZ(&buf); err != nil {
return nil, fmt.Errorf("failed to encoded execution payload to publish: %w", err)
}
data := buf.Bytes()
payloadData := data[65:]
sig, err := signer.Sign(context.TODO(), SigningDomainBlocksV1, l2ChainID, payloadData)
if err != nil {
return nil, fmt.Errorf("failed to sign execution payload with signer: %w", err)
}
copy(data[:65], sig[:])
// compress the full message
// This also copies the data, freeing up the original buffer to go back into the pool
return snappy.Encode(nil, data), nil
}
// TestBlockValidator does some very basic tests of the p2p block validation logic
func TestBlockValidator(t *testing.T) {
// Params Set 1: Create the validation function
cfg := &rollup.Config{
L2ChainID: big.NewInt(100),
}
secrets, err := e2eutils.DefaultMnemonicConfig.Secrets()
require.NoError(t, err)
runCfg := &testutils.MockRuntimeConfig{P2PSeqAddress: crypto.PubkeyToAddress(secrets.SequencerP2P.PublicKey)}
signer := &PreparedSigner{Signer: NewLocalSigner(secrets.SequencerP2P)}
// valFnV1 := BuildBlocksValidator(testlog.Logger(t, log.LvlCrit), rollupCfg, runCfg, eth.BlockV1)
valFnV2 := BuildBlocksValidator(testlog.Logger(t, log.LvlCrit), cfg, runCfg, eth.BlockV2)
// Params Set 2: Call the validation function
peerID := peer.ID("foo")
// Valid Case
payload := eth.ExecutionPayload{
Timestamp: hexutil.Uint64(time.Now().Unix()),
Withdrawals: &types.Withdrawals{},
}
payload.BlockHash, _ = payload.CheckBlockHash() // hack to generate the block hash easily.
data, err := createSignedP2Payload(&payload, signer, cfg.L2ChainID)
require.NoError(t, err)
message := &pubsub.Message{Message: &pubsub_pb.Message{Data: data}}
res := valFnV2(context.TODO(), peerID, message)
require.Equal(t, res, pubsub.ValidationAccept)
// Invalid because non-empty withdrawals when Canyon is active
payload = eth.ExecutionPayload{
Timestamp: hexutil.Uint64(time.Now().Unix()),
Withdrawals: &types.Withdrawals{&types.Withdrawal{Index: 1, Validator: 1}},
}
payload.BlockHash, _ = payload.CheckBlockHash()
data, err = createSignedP2Payload(&payload, signer, cfg.L2ChainID)
require.NoError(t, err)
message = &pubsub.Message{Message: &pubsub_pb.Message{Data: data}}
res = valFnV2(context.TODO(), peerID, message)
require.Equal(t, res, pubsub.ValidationReject)
}
......@@ -110,5 +110,9 @@ func LoadOPStackRollupConfig(chainID uint64) (*Config, error) {
cfg.ChannelTimeout = 120
cfg.MaxSequencerDrift = 1200
}
if chainID == pgnSepolia {
cfg.MaxSequencerDrift = 1000
cfg.SeqWindowSize = 7200
}
return cfg, nil
}
......@@ -20,6 +20,7 @@ type BlockInfo interface {
BaseFee() *big.Int
ReceiptHash() common.Hash
GasUsed() uint64
GasLimit() uint64
// HeaderRLP returns the RLP of the block header as per consensus rules
// Returns an error if the header RLP could not be written
......@@ -100,6 +101,10 @@ func (h headerBlockInfo) GasUsed() uint64 {
return h.Header.GasUsed
}
func (h headerBlockInfo) GasLimit() uint64 {
return h.Header.GasLimit
}
func (h headerBlockInfo) HeaderRLP() ([]byte, error) {
return rlp.EncodeToBytes(h.Header)
}
......
......@@ -117,3 +117,7 @@ func (c *CallResult) GetAddress(i int) common.Address {
func (c *CallResult) GetBigInt(i int) *big.Int {
return *abi.ConvertType(c.out[i], new(*big.Int)).(**big.Int)
}
func (c *CallResult) GetStruct(i int, target interface{}) {
abi.ConvertType(c.out[i], target)
}
......@@ -139,6 +139,24 @@ func TestCallResult_GetValues(t *testing.T) {
},
expected: big.NewInt(2398423),
},
{
name: "GetStruct",
getter: func(result *CallResult, i int) interface{} {
out := struct {
a *big.Int
b common.Hash
}{}
result.GetStruct(i, &out)
return out
},
expected: struct {
a *big.Int
b common.Hash
}{
a: big.NewInt(6),
b: common.Hash{0xee},
},
},
}
for _, test := range tests {
......
......@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"math/big"
"math/rand"
"testing"
"time"
......@@ -17,6 +18,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/trie"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)
......@@ -338,3 +340,233 @@ func TestEthClient_FetchReceipts(t *testing.T) {
t.Run(tc.name, tc.Run)
}
}
func TestVerifyReceipts(t *testing.T) {
validData := func() (eth.BlockID, common.Hash, []common.Hash, []*types.Receipt) {
block := eth.BlockID{
Hash: common.HexToHash("0x40fb7cc5fbc1ec594230a60648a442412116d50ae43d517ea458d8ea4e60bd1b"),
Number: 9998910,
}
txHashes := []common.Hash{
common.HexToHash("0x61e4872004a80843fcbede236527bf24707f4e8f44a2704ed9c4fb91c87b0f29"),
common.HexToHash("0x0ae25ad9ff01fd74fa1b0c11f12fbb623a3f0553a0eed465a6dbf0962898c3b6"),
common.HexToHash("0x2de33b18143039dcdf88cb62c3f3dd8f3f5d9f29807edfd3b0507246c55f9cb8"),
common.HexToHash("0xb6a381d3c31df47da82ac807c3000ae4adf55e981715f56d13a27b220de20198"),
}
receipts := []*types.Receipt{
{
Type: 2,
Status: 0,
CumulativeGasUsed: 0x3035b,
Bloom: types.BytesToBloom(common.Hex2Bytes("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")),
Logs: nil,
TxHash: txHashes[0],
GasUsed: 0x3035b,
EffectiveGasPrice: big.NewInt(0x12a05f20a),
BlockHash: block.Hash,
BlockNumber: new(big.Int).SetUint64(block.Number),
TransactionIndex: 0,
},
{
Type: 2,
Status: 1,
CumulativeGasUsed: 0xa9ae4,
Bloom: types.BytesToBloom(common.Hex2Bytes("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")),
Logs: nil,
TxHash: txHashes[1],
GasUsed: 0x79789,
EffectiveGasPrice: big.NewInt(0xb2d05e0a),
BlockHash: block.Hash,
BlockNumber: new(big.Int).SetUint64(block.Number),
TransactionIndex: 1,
},
{
Type: 0,
Status: 1,
CumulativeGasUsed: 0x101f09,
Bloom: types.BytesToBloom(common.Hex2Bytes("0x00000000000000000000000000000200000400000000000000000000000000800000000000040000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002002000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000800000000000000000000000000000000000000000000000000000400000000000000020000000000000000000000000002000000000000000000000000000000000000000000")),
Logs: []*types.Log{
{
Address: common.HexToAddress("0x759c5e44a9e4be8b7e9bd25a790ceb662c924c45"),
Topics: []common.Hash{
common.HexToHash("0x33830f93f4b524630176cdcbc04070b30ada13c6ad27081289131b77f178ff89"),
common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000426a80"),
common.HexToHash("0x000000000000000000000000a6275ee214f80a532c3abee0a4cbbc2d1dc22a72"),
},
Data: common.Hex2Bytes("0x00000000000000000000000000000000000000000000000000000000000005dc"),
BlockNumber: block.Number,
TxHash: txHashes[2],
TxIndex: 2,
BlockHash: block.Hash,
Index: 0,
Removed: false,
},
},
TxHash: txHashes[2],
GasUsed: 0x58425,
EffectiveGasPrice: big.NewInt(0xb2d05e00),
BlockHash: block.Hash,
BlockNumber: new(big.Int).SetUint64(block.Number),
TransactionIndex: 2,
},
{
Type: 0,
Status: 1,
CumulativeGasUsed: 0x1227ab,
Bloom: types.BytesToBloom(common.Hex2Bytes("0x00000000000000000000000000000200000400000000000000000000000000800000000000040000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002002000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000800000000000000000000000000000000000000000000000000000400000000000000020000000000000000000000000002000000000000000000000000000000000000000000")),
Logs: []*types.Log{
{
Address: common.HexToAddress("0x759c5e44a9e4be8b7e9bd25a790ceb662c924c45"),
Topics: []common.Hash{
common.HexToHash("0x33830f93f4b524630176cdcbc04070b30ada13c6ad27081289131b77f178ff89"),
common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000426a80"),
common.HexToHash("0x000000000000000000000000a6275ee214f80a532c3abee0a4cbbc2d1dc22a72"),
},
Data: common.Hex2Bytes("0x00000000000000000000000000000000000000000000000000000000000005dc"),
BlockNumber: block.Number,
TxHash: txHashes[3],
TxIndex: 3,
BlockHash: block.Hash,
Index: 1,
Removed: false,
},
},
TxHash: txHashes[3],
GasUsed: 0x208a2,
EffectiveGasPrice: big.NewInt(0x59682f0a),
BlockHash: block.Hash,
BlockNumber: new(big.Int).SetUint64(block.Number),
TransactionIndex: 3,
},
}
receiptsHash := types.DeriveSha(types.Receipts(receipts), trie.NewStackTrie(nil))
return block, receiptsHash, txHashes, receipts
}
t.Run("Valid", func(t *testing.T) {
block, receiptHash, txHashes, receipts := validData()
err := validateReceipts(block, receiptHash, txHashes, receipts)
require.NoError(t, err)
})
t.Run("NotEnoughReceipts", func(t *testing.T) {
block, receiptHash, txHashes, receipts := validData()
err := validateReceipts(block, receiptHash, txHashes, receipts[1:])
require.ErrorContains(t, err, fmt.Sprintf("got %d receipts but expected %d", len(receipts)-1, len(receipts)))
})
t.Run("TooManyReceipts", func(t *testing.T) {
block, receiptHash, txHashes, receipts := validData()
err := validateReceipts(block, receiptHash, txHashes, append(receipts, receipts[0]))
require.ErrorContains(t, err, fmt.Sprintf("got %d receipts but expected %d", len(receipts)+1, len(receipts)))
})
t.Run("NoTxButNotEmptyTrieRoot", func(t *testing.T) {
block, receiptHash, _, _ := validData()
err := validateReceipts(block, receiptHash, nil, nil)
require.ErrorContains(t, err, "no transactions, but got non-empty receipt trie root")
})
t.Run("NoTxWithEmptyTrieRoot", func(t *testing.T) {
block, _, _, _ := validData()
err := validateReceipts(block, types.EmptyRootHash, nil, nil)
require.NoError(t, err)
})
t.Run("IncorrectReceiptRoot", func(t *testing.T) {
block, _, txHashes, receipts := validData()
err := validateReceipts(block, common.Hash{0x35}, txHashes, receipts)
require.ErrorContains(t, err, "failed to fetch list of receipts: expected receipt root")
})
t.Run("NilReceipt", func(t *testing.T) {
block, receiptHash, txHashes, receipts := validData()
receipts[0] = nil
err := validateReceipts(block, receiptHash, txHashes, receipts)
require.ErrorContains(t, err, "returns nil on retrieval")
})
t.Run("IncorrectTxIndex", func(t *testing.T) {
block, receiptHash, txHashes, receipts := validData()
receipts[0].TransactionIndex = 2
err := validateReceipts(block, receiptHash, txHashes, receipts)
require.ErrorContains(t, err, "has unexpected tx index")
})
t.Run("Missing block number", func(t *testing.T) {
block, receiptHash, txHashes, receipts := validData()
receipts[0].BlockNumber = nil
err := validateReceipts(block, receiptHash, txHashes, receipts)
require.ErrorContains(t, err, "has unexpected nil block number")
})
t.Run("IncorrectBlockNumber", func(t *testing.T) {
block, receiptHash, txHashes, receipts := validData()
receipts[0].BlockNumber = big.NewInt(1234)
err := validateReceipts(block, receiptHash, txHashes, receipts)
require.ErrorContains(t, err, "has unexpected block number")
})
t.Run("IncorrectBlockHash", func(t *testing.T) {
block, receiptHash, txHashes, receipts := validData()
receipts[0].BlockHash = common.Hash{0x48}
err := validateReceipts(block, receiptHash, txHashes, receipts)
require.ErrorContains(t, err, "has unexpected block hash")
})
t.Run("IncorrectCumulativeUsed", func(t *testing.T) {
block, receiptHash, txHashes, receipts := validData()
receipts[1].CumulativeGasUsed = receipts[0].CumulativeGasUsed
err := validateReceipts(block, receiptHash, txHashes, receipts)
require.ErrorContains(t, err, "has invalid gas used metadata")
})
t.Run("IncorrectLogIndex", func(t *testing.T) {
block, receiptHash, txHashes, receipts := validData()
receipts[2].Logs[0].Index = 4
err := validateReceipts(block, receiptHash, txHashes, receipts)
require.ErrorContains(t, err, "has unexpected log index")
})
t.Run("LogIndexNotBlockBased", func(t *testing.T) {
block, receiptHash, txHashes, receipts := validData()
receipts[3].Logs[0].Index = 0
err := validateReceipts(block, receiptHash, txHashes, receipts)
require.ErrorContains(t, err, "has unexpected log index")
})
t.Run("IncorrectLogTxIndex", func(t *testing.T) {
block, receiptHash, txHashes, receipts := validData()
receipts[2].Logs[0].TxIndex = 1
err := validateReceipts(block, receiptHash, txHashes, receipts)
require.ErrorContains(t, err, "has unexpected tx index")
})
t.Run("IncorrectLogBlockHash", func(t *testing.T) {
block, receiptHash, txHashes, receipts := validData()
receipts[2].Logs[0].BlockHash = common.Hash{0x64}
err := validateReceipts(block, receiptHash, txHashes, receipts)
require.ErrorContains(t, err, "has unexpected block hash")
})
t.Run("IncorrectLogBlockNumber", func(t *testing.T) {
block, receiptHash, txHashes, receipts := validData()
receipts[2].Logs[0].BlockNumber = 4727923
err := validateReceipts(block, receiptHash, txHashes, receipts)
require.ErrorContains(t, err, "has unexpected block number")
})
t.Run("IncorrectLogTxHash", func(t *testing.T) {
block, receiptHash, txHashes, receipts := validData()
receipts[2].Logs[0].TxHash = common.Hash{0x87}
err := validateReceipts(block, receiptHash, txHashes, receipts)
require.ErrorContains(t, err, "has unexpected tx hash")
})
t.Run("Removed", func(t *testing.T) {
block, receiptHash, txHashes, receipts := validData()
receipts[2].Logs[0].Removed = true
err := validateReceipts(block, receiptHash, txHashes, receipts)
require.ErrorContains(t, err, "must never be removed due to reorg")
})
}
......@@ -78,6 +78,10 @@ func (h headerInfo) GasUsed() uint64 {
return h.Header.GasUsed
}
func (h headerInfo) GasLimit() uint64 {
return h.Header.GasLimit
}
func (h headerInfo) HeaderRLP() ([]byte, error) {
return rlp.EncodeToBytes(h.Header)
}
......@@ -103,7 +107,16 @@ type rpcHeader struct {
BaseFee *hexutil.Big `json:"baseFeePerGas"`
// WithdrawalsRoot was added by EIP-4895 and is ignored in legacy headers.
WithdrawalsRoot *common.Hash `json:"withdrawalsRoot"`
WithdrawalsRoot *common.Hash `json:"withdrawalsRoot,omitempty"`
// BlobGasUsed was added by EIP-4844 and is ignored in legacy headers.
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed,omitempty"`
// ExcessBlobGas was added by EIP-4844 and is ignored in legacy headers.
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas,omitempty"`
// ParentBeaconRoot was added by EIP-4788 and is ignored in legacy headers.
ParentBeaconRoot *common.Hash `json:"parentBeaconBlockRoot,omitempty"`
// untrusted info included by RPC, may have to be checked
Hash common.Hash `json:"hash"`
......@@ -156,6 +169,10 @@ func (hdr *rpcHeader) createGethHeader() *types.Header {
Nonce: hdr.Nonce,
BaseFee: (*big.Int)(hdr.BaseFee),
WithdrawalsHash: hdr.WithdrawalsRoot,
// Cancun
BlobGasUsed: (*uint64)(hdr.BlobGasUsed),
ExcessBlobGas: (*uint64)(hdr.ExcessBlobGas),
ParentBeaconRoot: hdr.ParentBeaconRoot,
}
}
......@@ -185,7 +202,7 @@ func (block *rpcBlock) verify() error {
}
for i, tx := range block.Transactions {
if tx == nil {
return fmt.Errorf("block tx %d is null", i)
return fmt.Errorf("block tx %d is nil", i)
}
}
if computed := types.DeriveSha(types.Transactions(block.Transactions), trie.NewStackTrie(nil)); block.TxHash != computed {
......
......@@ -23,6 +23,7 @@ type MockBlockInfo struct {
InfoBaseFee *big.Int
InfoReceiptRoot common.Hash
InfoGasUsed uint64
InfoGasLimit uint64
InfoHeaderRLP []byte
}
......@@ -66,6 +67,10 @@ func (l *MockBlockInfo) GasUsed() uint64 {
return l.InfoGasUsed
}
func (l *MockBlockInfo) GasLimit() uint64 {
return l.InfoGasLimit
}
func (l *MockBlockInfo) ID() eth.BlockID {
return eth.BlockID{Hash: l.InfoHash, Number: l.InfoNum}
}
......
# RPC for the network to deploy to
export ETH_RPC_URL=
# Sets the deployer's key to match the first default hardhat account
export PRIVATE_KEY=ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
# Name of the deployed network
export DEPLOYMENT_CONTEXT=getting-started
# Optional Tenderly details for a simulation link during deployment
export TENDERLY_PROJECT=
export TENDERLY_USERNAME=
export ETHERSCAN_API_KEY=
# Optional create2 salt for deterministic deployment of
# contract implementations
export IMPL_SALT=$(openssl rand -hex 32)
AdminFaucetAuthModuleTest:test_adminProof_verify_succeeds() (gas: 57573)
AdminFaucetAuthModuleTest:test_adminProof_verify_succeeds() (gas: 57607)
AdminFaucetAuthModuleTest:test_nonAdminProof_verify_succeeds() (gas: 59050)
AdminFaucetAuthModuleTest:test_proofWithWrongId_verify_succeeds() (gas: 60673)
AssetReceiverTest:test_constructor_succeeds() (gas: 9696)
AssetReceiverTest:test_constructor_succeeds() (gas: 9693)
AssetReceiverTest:test_receive_succeeds() (gas: 20844)
AssetReceiverTest:test_withdrawERC20_succeeds() (gas: 183383)
AssetReceiverTest:test_withdrawERC20_unauthorized_reverts() (gas: 153517)
AssetReceiverTest:test_withdrawERC20withAmount_succeeds() (gas: 182567)
AssetReceiverTest:test_withdrawERC20withAmount_unauthorized_reverts() (gas: 153528)
AssetReceiverTest:test_withdrawERC20withAmount_unauthorized_reverts() (gas: 153564)
AssetReceiverTest:test_withdrawERC721_succeeds() (gas: 50755)
AssetReceiverTest:test_withdrawERC721_unauthorized_reverts() (gas: 51063)
AssetReceiverTest:test_withdrawETH_succeeds() (gas: 28344)
AssetReceiverTest:test_withdrawETH_unauthorized_reverts() (gas: 10680)
AssetReceiverTest:test_withdrawETHwithAmount_succeeds() (gas: 28241)
AssetReceiverTest:test_withdrawETHwithAmount_unauthorized_reverts() (gas: 10738)
AttestationStationTest:test_attest_bulk_succeeds() (gas: 544387)
AttestationStationTest:test_attest_bulk_succeeds() (gas: 544321)
AttestationStationTest:test_attest_individual_succeeds() (gas: 472850)
AttestationStationTest:test_attest_single_succeeds() (gas: 491962)
BlockOracle_Test:test_checkpointAndLoad_succeeds() (gas: 58396)
......@@ -24,71 +24,71 @@ Bytes_slice_Test:test_slice_fromNonZeroIdx_works() (gas: 17240)
Bytes_slice_Test:test_slice_fromZeroIdx_works() (gas: 20804)
Bytes_toNibbles_Test:test_toNibbles_expectedResult128Bytes_works() (gas: 78882)
Bytes_toNibbles_Test:test_toNibbles_expectedResult5Bytes_works() (gas: 3992)
Bytes_toNibbles_Test:test_toNibbles_zeroLengthInput_works() (gas: 823)
Bytes_toNibbles_Test:test_toNibbles_zeroLengthInput_works() (gas: 845)
Constants_Test:test_eip1967Constants_succeeds() (gas: 453)
CrossDomainMessenger_BaseGas_Test:test_baseGas_succeeds() (gas: 20481)
CrossDomainOwnable2_Test:test_onlyOwner_notMessenger_reverts() (gas: 8539)
CrossDomainOwnable2_Test:test_onlyOwner_notOwner2_reverts() (gas: 57515)
CrossDomainOwnable2_Test:test_onlyOwner_notOwner2_reverts() (gas: 57518)
CrossDomainOwnable2_Test:test_onlyOwner_notOwner_reverts() (gas: 16655)
CrossDomainOwnable2_Test:test_onlyOwner_succeeds() (gas: 73600)
CrossDomainOwnable3_Test:test_constructor_succeeds() (gas: 10605)
CrossDomainOwnable2_Test:test_onlyOwner_succeeds() (gas: 73619)
CrossDomainOwnable3_Test:test_constructor_succeeds() (gas: 10627)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notMessenger_reverts() (gas: 28363)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner2_reverts() (gas: 74040)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner_reverts() (gas: 32096)
CrossDomainOwnable3_Test:test_crossDomainTransferOwnership_succeeds() (gas: 91581)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner2_reverts() (gas: 74002)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner_reverts() (gas: 32118)
CrossDomainOwnable3_Test:test_crossDomainTransferOwnership_succeeds() (gas: 91600)
CrossDomainOwnable3_Test:test_localOnlyOwner_notOwner_reverts() (gas: 13260)
CrossDomainOwnable3_Test:test_localOnlyOwner_succeeds() (gas: 35271)
CrossDomainOwnable3_Test:test_localTransferOwnership_succeeds() (gas: 52164)
CrossDomainOwnable3_Test:test_transferOwnershipNoLocal_succeeds() (gas: 48712)
CrossDomainOwnable3_Test:test_localTransferOwnership_succeeds() (gas: 52158)
CrossDomainOwnable3_Test:test_transferOwnershipNoLocal_succeeds() (gas: 48662)
CrossDomainOwnable3_Test:test_transferOwnership_noLocalZeroAddress_reverts() (gas: 12090)
CrossDomainOwnable3_Test:test_transferOwnership_notOwner_reverts() (gas: 13460)
CrossDomainOwnable3_Test:test_transferOwnership_zeroAddress_reverts() (gas: 12155)
CrossDomainOwnableThroughPortal_Test:test_depositTransaction_crossDomainOwner_succeeds() (gas: 81556)
CrossDomainOwnable3_Test:test_transferOwnership_zeroAddress_reverts() (gas: 12177)
CrossDomainOwnableThroughPortal_Test:test_depositTransaction_crossDomainOwner_succeeds() (gas: 81574)
CrossDomainOwnable_Test:test_onlyOwner_notOwner_reverts() (gas: 10597)
CrossDomainOwnable_Test:test_onlyOwner_succeeds() (gas: 34883)
CrossDomainOwnable_Test:test_onlyOwner_succeeds() (gas: 34905)
DelayedVetoable_Getters_Test:test_getters() (gas: 24620)
DelayedVetoable_Getters_TestFail:test_getters_notZeroAddress_reverts() (gas: 36289)
DelayedVetoable_HandleCall_TestFail:test_handleCall_unauthorizedInitiation_reverts() (gas: 15165)
DeployerWhitelist_Test:test_owner_succeeds() (gas: 7582)
DeployerWhitelist_Test:test_storageSlots_succeeds() (gas: 33395)
DeployerWhitelist_Test:test_storageSlots_succeeds() (gas: 33417)
DisputeGameFactory_Owner_Test:test_owner_succeeds() (gas: 12611)
DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_reverts() (gas: 16143)
DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44346)
DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_reverts() (gas: 16078)
DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44323)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15974)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18738)
Drippie_Test:test_create_calledTwice_reverts() (gas: 168953)
Drippie_Test:test_create_calledTwice_reverts() (gas: 168887)
Drippie_Test:test_create_succeeds() (gas: 183401)
Drippie_Test:test_drip_amount_succeeds() (gas: 285353)
Drippie_Test:test_drip_amount_succeeds() (gas: 285375)
Drippie_Test:test_drip_notExist_reverts() (gas: 14920)
Drippie_Test:test_drip_reentrant_reverts() (gas: 18875)
Drippie_Test:test_name_notExist_reverts() (gas: 16056)
Drippie_Test:test_notReentrant_zeroInterval_reverts() (gas: 18867)
Drippie_Test:test_not_active_reverts() (gas: 171162)
Drippie_Test:test_reentrant_succeeds() (gas: 180158)
Drippie_Test:test_set_statusNone_reverts() (gas: 168809)
Drippie_Test:test_set_statusSame_reverts() (gas: 169195)
Drippie_Test:test_set_status_succeeds() (gas: 198603)
Drippie_Test:test_notReentrant_zeroInterval_reverts() (gas: 18889)
Drippie_Test:test_not_active_reverts() (gas: 171184)
Drippie_Test:test_reentrant_succeeds() (gas: 180180)
Drippie_Test:test_set_statusNone_reverts() (gas: 168743)
Drippie_Test:test_set_statusSame_reverts() (gas: 169240)
Drippie_Test:test_set_status_succeeds() (gas: 198536)
Drippie_Test:test_shouldArchive_ifPaused_succeeds() (gas: 177348)
Drippie_Test:test_shouldNotAllowActive_ifArchived_reverts() (gas: 174669)
Drippie_Test:test_shouldNotAllowPaused_ifArchived_reverts() (gas: 174692)
Drippie_Test:test_shouldNotArchive_ifActive_reverts() (gas: 175732)
Drippie_Test:test_status_unauthorized_reverts() (gas: 167388)
Drippie_Test:test_trigger_oneFunction_succeeds() (gas: 338226)
Drippie_Test:test_trigger_twoFunctions_succeeds() (gas: 491907)
Drippie_Test:test_twice_inOneInterval_reverts() (gas: 303933)
FaucetTest:test_authAdmin_drip_succeeds() (gas: 366107)
FaucetTest:test_drip_afterTimeout_succeeds() (gas: 447891)
FaucetTest:test_drip_beforeTimeout_reverts() (gas: 378884)
FaucetTest:test_drip_disabledModule_reverts() (gas: 352401)
FaucetTest:test_drip_emitsEvent_succeeds() (gas: 369161)
FaucetTest:test_drip_githubSendsCorrectAmount_succeeds() (gas: 366607)
FaucetTest:test_drip_optimistNftSendsCorrectAmount_succeeds() (gas: 366551)
FaucetTest:test_drip_preventsReplayAttacks_succeeds() (gas: 369214)
FaucetTest:test_initialize_succeeds() (gas: 7626)
Drippie_Test:test_shouldNotAllowActive_ifArchived_reverts() (gas: 174691)
Drippie_Test:test_shouldNotAllowPaused_ifArchived_reverts() (gas: 174714)
Drippie_Test:test_shouldNotArchive_ifActive_reverts() (gas: 175754)
Drippie_Test:test_status_unauthorized_reverts() (gas: 167410)
Drippie_Test:test_trigger_oneFunction_succeeds() (gas: 338248)
Drippie_Test:test_trigger_twoFunctions_succeeds() (gas: 491929)
Drippie_Test:test_twice_inOneInterval_reverts() (gas: 303889)
FaucetTest:test_authAdmin_drip_succeeds() (gas: 366064)
FaucetTest:test_drip_afterTimeout_succeeds() (gas: 447913)
FaucetTest:test_drip_beforeTimeout_reverts() (gas: 378906)
FaucetTest:test_drip_disabledModule_reverts() (gas: 352423)
FaucetTest:test_drip_emitsEvent_succeeds() (gas: 369116)
FaucetTest:test_drip_githubSendsCorrectAmount_succeeds() (gas: 366562)
FaucetTest:test_drip_optimistNftSendsCorrectAmount_succeeds() (gas: 366573)
FaucetTest:test_drip_preventsReplayAttacks_succeeds() (gas: 369236)
FaucetTest:test_initialize_succeeds() (gas: 7648)
FaucetTest:test_nonAdmin_drip_fails() (gas: 262520)
FaucetTest:test_receive_succeeds() (gas: 17401)
FaucetTest:test_withdraw_nonAdmin_reverts() (gas: 13145)
FaucetTest:test_withdraw_succeeds() (gas: 78359)
FaucetTest:test_receive_succeeds() (gas: 17423)
FaucetTest:test_withdraw_nonAdmin_reverts() (gas: 13167)
FaucetTest:test_withdraw_succeeds() (gas: 78381)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot1:test_resolvesCorrectly_succeeds() (gas: 660030)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 666890)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 663593)
......@@ -99,125 +99,125 @@ FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeed
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 655638)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot4:test_resolvesCorrectly_succeeds() (gas: 656576)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot5:test_resolvesCorrectly_succeeds() (gas: 656027)
FaultDisputeGame_Test:test_addLocalData_static_succeeds() (gas: 642441)
FaultDisputeGame_Test:test_createdAt_succeeds() (gas: 10476)
FaultDisputeGame_Test:test_extraData_succeeds() (gas: 32422)
FaultDisputeGame_Test:test_addLocalData_static_succeeds() (gas: 642366)
FaultDisputeGame_Test:test_createdAt_succeeds() (gas: 10461)
FaultDisputeGame_Test:test_extraData_succeeds() (gas: 32407)
FaultDisputeGame_Test:test_gameData_succeeds() (gas: 32857)
FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8302)
FaultDisputeGame_Test:test_initialize_correctData_succeeds() (gas: 57779)
FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8287)
FaultDisputeGame_Test:test_initialize_correctData_succeeds() (gas: 57761)
FaultDisputeGame_Test:test_initialize_firstOutput_reverts() (gas: 213868)
FaultDisputeGame_Test:test_initialize_l1HeadTooOld_reverts() (gas: 228488)
FaultDisputeGame_Test:test_move_clockCorrectness_succeeds() (gas: 594294)
FaultDisputeGame_Test:test_move_clockTimeExceeded_reverts() (gas: 23200)
FaultDisputeGame_Test:test_move_defendRoot_reverts() (gas: 13325)
FaultDisputeGame_Test:test_move_duplicateClaim_reverts() (gas: 147396)
FaultDisputeGame_Test:test_move_duplicateClaimsDifferentSubgames_succeeds() (gas: 556844)
FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 585884)
FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 11019)
FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24674)
FaultDisputeGame_Test:test_move_simpleAttack_succeeds() (gas: 152017)
FaultDisputeGame_Test:test_resolve_challengeContested_succeeds() (gas: 269483)
FaultDisputeGame_Test:test_resolve_claimAlreadyResolved_reverts() (gas: 272368)
FaultDisputeGame_Test:test_resolve_claimAtMaxDepthAlreadyResolved_reverts() (gas: 586621)
FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9785)
FaultDisputeGame_Test:test_resolve_outOfOrderResolution_reverts() (gas: 309002)
FaultDisputeGame_Test:test_resolve_rootContested_succeeds() (gas: 139125)
FaultDisputeGame_Test:test_resolve_rootUncontestedButUnresolved_reverts() (gas: 15923)
FaultDisputeGame_Test:test_resolve_rootUncontestedClockNotExpired_succeeds() (gas: 18431)
FaultDisputeGame_Test:test_resolve_rootUncontested_succeeds() (gas: 51487)
FaultDisputeGame_Test:test_resolve_stepReached_succeeds() (gas: 498467)
FaultDisputeGame_Test:test_resolve_teamDeathmatch_succeeds() (gas: 443396)
FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8247)
FeeVault_Test:test_constructor_baseFeeVault_succeeds() (gas: 17428)
FeeVault_Test:test_constructor_l1FeeVault_succeeds() (gas: 17396)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 354511)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2952674)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 544927)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4057119)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 446161)
FaultDisputeGame_Test:test_initialize_l1HeadTooOld_reverts() (gas: 228482)
FaultDisputeGame_Test:test_move_clockCorrectness_succeeds() (gas: 594223)
FaultDisputeGame_Test:test_move_clockTimeExceeded_reverts() (gas: 23197)
FaultDisputeGame_Test:test_move_defendRoot_reverts() (gas: 13322)
FaultDisputeGame_Test:test_move_duplicateClaim_reverts() (gas: 147390)
FaultDisputeGame_Test:test_move_duplicateClaimsDifferentSubgames_succeeds() (gas: 556832)
FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 585875)
FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 11010)
FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24668)
FaultDisputeGame_Test:test_move_simpleAttack_succeeds() (gas: 152008)
FaultDisputeGame_Test:test_resolve_challengeContested_succeeds() (gas: 269473)
FaultDisputeGame_Test:test_resolve_claimAlreadyResolved_reverts() (gas: 272356)
FaultDisputeGame_Test:test_resolve_claimAtMaxDepthAlreadyResolved_reverts() (gas: 586606)
FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9776)
FaultDisputeGame_Test:test_resolve_outOfOrderResolution_reverts() (gas: 309015)
FaultDisputeGame_Test:test_resolve_rootContested_succeeds() (gas: 139119)
FaultDisputeGame_Test:test_resolve_rootUncontestedButUnresolved_reverts() (gas: 15935)
FaultDisputeGame_Test:test_resolve_rootUncontestedClockNotExpired_succeeds() (gas: 18428)
FaultDisputeGame_Test:test_resolve_rootUncontested_succeeds() (gas: 51484)
FaultDisputeGame_Test:test_resolve_stepReached_succeeds() (gas: 498448)
FaultDisputeGame_Test:test_resolve_teamDeathmatch_succeeds() (gas: 443399)
FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8232)
FeeVault_Test:test_constructor_baseFeeVault_succeeds() (gas: 17450)
FeeVault_Test:test_constructor_l1FeeVault_succeeds() (gas: 17418)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 354446)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2952696)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 544952)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4057122)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 446183)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3491910)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 45337)
GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 88797)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68320)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68973)
GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 143295)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68317)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68970)
GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 143303)
GasPriceOracle_Test:test_baseFee_succeeds() (gas: 8348)
GasPriceOracle_Test:test_decimals_succeeds() (gas: 6234)
GasPriceOracle_Test:test_gasPrice_succeeds() (gas: 8340)
GasPriceOracle_Test:test_l1BaseFee_succeeds() (gas: 10724)
GasPriceOracle_Test:test_overhead_succeeds() (gas: 10681)
GasPriceOracle_Test:test_scalar_succeeds() (gas: 10678)
GasPriceOracle_Test:test_setGasPrice_doesNotExist_reverts() (gas: 5934)
GasPriceOracle_Test:test_setL1BaseFee_doesNotExist_reverts() (gas: 5954)
GovernanceToken_Test:test_approve_succeeds() (gas: 138001)
GovernanceToken_Test:test_burnFrom_succeeds() (gas: 127560)
GasPriceOracle_Test:test_l1BaseFee_succeeds() (gas: 10680)
GasPriceOracle_Test:test_overhead_succeeds() (gas: 10637)
GasPriceOracle_Test:test_scalar_succeeds() (gas: 10700)
GasPriceOracle_Test:test_setGasPrice_doesNotExist_reverts() (gas: 5956)
GasPriceOracle_Test:test_setL1BaseFee_doesNotExist_reverts() (gas: 5976)
GovernanceToken_Test:test_approve_succeeds() (gas: 138023)
GovernanceToken_Test:test_burnFrom_succeeds() (gas: 127582)
GovernanceToken_Test:test_burn_succeeds() (gas: 119092)
GovernanceToken_Test:test_constructor_succeeds() (gas: 23757)
GovernanceToken_Test:test_constructor_succeeds() (gas: 23693)
GovernanceToken_Test:test_decreaseAllowance_succeeds() (gas: 141912)
GovernanceToken_Test:test_increaseAllowance_succeeds() (gas: 142066)
GovernanceToken_Test:test_mint_fromNotOwner_reverts() (gas: 21421)
GovernanceToken_Test:test_mint_fromOwner_succeeds() (gas: 110895)
GovernanceToken_Test:test_transferFrom_succeeds() (gas: 151318)
GovernanceToken_Test:test_transfer_succeeds() (gas: 142845)
GovernanceToken_Test:test_increaseAllowance_succeeds() (gas: 142022)
GovernanceToken_Test:test_mint_fromNotOwner_reverts() (gas: 21378)
GovernanceToken_Test:test_mint_fromOwner_succeeds() (gas: 110940)
GovernanceToken_Test:test_transferFrom_succeeds() (gas: 151340)
GovernanceToken_Test:test_transfer_succeeds() (gas: 142867)
Hashing_hashDepositSource_Test:test_hashDepositSource_succeeds() (gas: 700)
Initializer_Test:test_cannotReinitializeL1_succeeds() (gas: 101030)
L1BlockNumberTest:test_fallback_succeeds() (gas: 18655)
L1BlockNumberTest:test_getL1BlockNumber_succeeds() (gas: 10625)
Initializer_Test:test_cannotReinitializeL1_succeeds() (gas: 101024)
L1BlockNumberTest:test_fallback_succeeds() (gas: 18677)
L1BlockNumberTest:test_getL1BlockNumber_succeeds() (gas: 10647)
L1BlockNumberTest:test_receive_succeeds() (gas: 25384)
L1BlockTest:test_basefee_succeeds() (gas: 7599)
L1BlockTest:test_hash_succeeds() (gas: 7738)
L1BlockTest:test_basefee_succeeds() (gas: 7576)
L1BlockTest:test_hash_succeeds() (gas: 7694)
L1BlockTest:test_number_succeeds() (gas: 7674)
L1BlockTest:test_sequenceNumber_succeeds() (gas: 7676)
L1BlockTest:test_timestamp_succeeds() (gas: 7663)
L1BlockTest:test_updateValues_succeeds() (gas: 63327)
L1CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 24803)
L1CrossDomainMessenger_Test:test_relayMessage_legacyOldReplay_reverts() (gas: 49407)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() (gas: 239750)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailure_succeeds() (gas: 233442)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterSuccess_reverts() (gas: 126347)
L1CrossDomainMessenger_Test:test_relayMessage_legacy_succeeds() (gas: 79644)
L1CrossDomainMessenger_Test:test_relayMessage_retryAfterFailure_succeeds() (gas: 227503)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() (gas: 239747)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailure_succeeds() (gas: 233439)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterSuccess_reverts() (gas: 126344)
L1CrossDomainMessenger_Test:test_relayMessage_legacy_succeeds() (gas: 79600)
L1CrossDomainMessenger_Test:test_relayMessage_retryAfterFailure_succeeds() (gas: 227457)
L1CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 76636)
L1CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 60822)
L1CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 12388)
L1CrossDomainMessenger_Test:test_replayMessage_withValue_reverts() (gas: 33178)
L1CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 60802)
L1CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 12410)
L1CrossDomainMessenger_Test:test_replayMessage_withValue_reverts() (gas: 33134)
L1CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 392934)
L1CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 1669270)
L1CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 1669240)
L1CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 87957)
L1CrossDomainMessenger_Test:test_xDomainSender_notSet_reverts() (gas: 24282)
L1ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 62759)
L1ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 37376)
L1ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 455270)
L1ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 71000)
L1ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 35752)
L1ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 60589)
L1ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 35188)
L1ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 455010)
L1ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 70870)
L1ERC721Bridge_Test:test_constructor_succeeds() (gas: 18927)
L1ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 62744)
L1ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 37318)
L1ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 455255)
L1ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 71007)
L1ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 35737)
L1ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 60596)
L1ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 35173)
L1ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 454995)
L1ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 70855)
L1ERC721Bridge_Test:test_constructor_succeeds() (gas: 18883)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_notEscrowed_reverts() (gas: 29495)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 27239)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 27261)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 23305)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 25035)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 425309)
L1StandardBridge_BridgeETHTo_Test:test_bridgeETHTo_succeeds() (gas: 517214)
L1StandardBridge_BridgeETH_Test:test_bridgeETH_succeeds() (gas: 504458)
L1StandardBridge_DepositERC20To_Test:test_depositERC20To_succeeds() (gas: 723450)
L1StandardBridge_DepositERC20_Test:test_depositERC20_succeeds() (gas: 720986)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 425294)
L1StandardBridge_BridgeETHTo_Test:test_bridgeETHTo_succeeds() (gas: 517211)
L1StandardBridge_BridgeETH_Test:test_bridgeETH_succeeds() (gas: 504443)
L1StandardBridge_DepositERC20To_Test:test_depositERC20To_succeeds() (gas: 723456)
L1StandardBridge_DepositERC20_Test:test_depositERC20_succeeds() (gas: 721010)
L1StandardBridge_DepositERC20_TestFail:test_depositERC20_notEoa_reverts() (gas: 24955)
L1StandardBridge_DepositETHTo_Test:test_depositETHTo_succeeds() (gas: 517311)
L1StandardBridge_DepositETH_Test:test_depositETH_succeeds() (gas: 504597)
L1StandardBridge_DepositETHTo_Test:test_depositETHTo_succeeds() (gas: 517308)
L1StandardBridge_DepositETH_Test:test_depositETH_succeeds() (gas: 504582)
L1StandardBridge_DepositETH_TestFail:test_depositETH_notEoa_reverts() (gas: 43427)
L1StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 57849)
L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 40320)
L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 40461)
L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 40347)
L1StandardBridge_FinalizeERC20Withdrawal_Test:test_finalizeERC20Withdrawal_succeeds() (gas: 503457)
L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notMessenger_reverts() (gas: 37182)
L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notOtherBridge_reverts() (gas: 37849)
L1StandardBridge_FinalizeERC20Withdrawal_Test:test_finalizeERC20Withdrawal_succeeds() (gas: 478308)
L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notMessenger_reverts() (gas: 37188)
L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notOtherBridge_reverts() (gas: 37877)
L1StandardBridge_FinalizeETHWithdrawal_Test:test_finalizeETHWithdrawal_succeeds() (gas: 70062)
L1StandardBridge_Getter_Test:test_getters_succeeds() (gas: 32693)
L1StandardBridge_Initialize_Test:test_initialize_succeeds() (gas: 30416)
L1StandardBridge_Initialize_Test:test_initialize_succeeds() (gas: 30372)
L1StandardBridge_Receive_Test:test_receive_succeeds() (gas: 617691)
L2CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 8521)
L2CrossDomainMessenger_Test:test_relayMessage_retry_succeeds() (gas: 191101)
......@@ -225,70 +225,70 @@ L2CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 48936)
L2CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 31159)
L2CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 11756)
L2CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 124025)
L2CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 135887)
L2CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 135857)
L2CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 49311)
L2CrossDomainMessenger_Test:test_xDomainSender_senderNotSet_reverts() (gas: 10686)
L2ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 26498)
L2ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 21837)
L2ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 21814)
L2ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 152123)
L2ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 29472)
L2ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 22216)
L2ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 24332)
L2ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 19674)
L2ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 149764)
L2ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 29304)
L2ERC721Bridge_Test:test_constructor_succeeds() (gas: 14660)
L2ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 29494)
L2ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 22193)
L2ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 24354)
L2ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 19651)
L2ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 149786)
L2ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 29326)
L2ERC721Bridge_Test:test_constructor_succeeds() (gas: 14682)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_alreadyExists_reverts() (gas: 33650)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_interfaceNotCompliant_reverts() (gas: 241398)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 22193)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_interfaceNotCompliant_reverts() (gas: 241375)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 22215)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 18282)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 22113)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 174514)
L2OutputOracleUpgradeable_Test:test_initValuesOnImpl_succeeds() (gas: 32612)
L2OutputOracleUpgradeable_Test:test_initValuesOnImpl_succeeds() (gas: 32635)
L2OutputOracleUpgradeable_Test:test_initValuesOnProxy_succeeds() (gas: 56622)
L2OutputOracleUpgradeable_Test:test_initializeImpl_alreadyInitialized_reverts() (gas: 24782)
L2OutputOracleUpgradeable_Test:test_initializeProxy_alreadyInitialized_reverts() (gas: 26380)
L2OutputOracleUpgradeable_Test:test_upgrading_succeeds() (gas: 191207)
L2OutputOracle_constructor_Test:test_constructor_l2BlockTimeZero_reverts() (gas: 44322)
L2OutputOracle_constructor_Test:test_constructor_submissionInterval_reverts() (gas: 44354)
L2OutputOracle_constructor_Test:test_constructor_succeeds() (gas: 61377)
L2OutputOracle_constructor_Test:test_initialize_badTimestamp_reverts() (gas: 12388)
L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_afterLatest_reverts() (gas: 226825)
L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_finalized_reverts() (gas: 118642)
L2OutputOracle_constructor_Test:test_constructor_succeeds() (gas: 61399)
L2OutputOracle_constructor_Test:test_initialize_badTimestamp_reverts() (gas: 12433)
L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_afterLatest_reverts() (gas: 226802)
L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_finalized_reverts() (gas: 118576)
L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_ifNotChallenger_reverts() (gas: 21053)
L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_nonExistent_reverts() (gas: 117047)
L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_multipleOutputs_succeeds() (gas: 318242)
L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_singleOutput_succeeds() (gas: 193258)
L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_multipleOutputs_succeeds() (gas: 318177)
L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_singleOutput_succeeds() (gas: 193280)
L2OutputOracle_getter_Test:test_computeL2Timestamp_succeeds() (gas: 44553)
L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() (gas: 277477)
L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_noOutputsExis_reverts() (gas: 17960)
L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_previousBlock_succeeds() (gas: 103519)
L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_sameBlock_succeeds() (gas: 103427)
L2OutputOracle_getter_Test:test_getL2Output_succeeds() (gas: 109954)
L2OutputOracle_getter_Test:test_latestBlockNumber_succeeds() (gas: 104504)
L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() (gas: 277454)
L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_noOutputsExis_reverts() (gas: 17937)
L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_previousBlock_succeeds() (gas: 103541)
L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_sameBlock_succeeds() (gas: 103449)
L2OutputOracle_getter_Test:test_getL2Output_succeeds() (gas: 109931)
L2OutputOracle_getter_Test:test_latestBlockNumber_succeeds() (gas: 104526)
L2OutputOracle_getter_Test:test_nextBlockNumber_succeeds() (gas: 17492)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_emptyOutput_reverts() (gas: 34166)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_futureTimetamp_reverts() (gas: 34240)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_notProposer_reverts() (gas: 26076)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_proposeAnotherOutput_succeeds() (gas: 109323)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_emptyOutput_reverts() (gas: 34188)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_futureTimetamp_reverts() (gas: 34217)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_notProposer_reverts() (gas: 26098)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_proposeAnotherOutput_succeeds() (gas: 109345)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unexpectedBlockNumber_reverts() (gas: 33945)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unmatchedBlockhash_reverts() (gas: 34946)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unmatchedBlockhash_reverts() (gas: 34968)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_wrongFork_reverts() (gas: 34466)
L2OutputOracle_proposeL2Output_Test:test_proposeWithBlockhashAndHeight_succeeds() (gas: 100845)
L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 392327)
L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 392560)
L2StandardBridge_BridgeERC20_Test:test_bridgeERC20_succeeds() (gas: 387960)
L2StandardBridge_BridgeERC20_Test:test_bridgeLegacyERC20_succeeds() (gas: 396237)
L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 392336)
L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 392584)
L2StandardBridge_BridgeERC20_Test:test_bridgeERC20_succeeds() (gas: 387967)
L2StandardBridge_BridgeERC20_Test:test_bridgeLegacyERC20_succeeds() (gas: 396235)
L2StandardBridge_BridgeERC20_Test:test_withdrawLegacyERC20_succeeds() (gas: 396580)
L2StandardBridge_BridgeERC20_Test:test_withdraw_notEOA_reverts() (gas: 251901)
L2StandardBridge_BridgeERC20_Test:test_withdraw_withdrawingERC20_succeeds() (gas: 388241)
L2StandardBridge_BridgeERC20_Test:test_withdraw_notEOA_reverts() (gas: 251904)
L2StandardBridge_BridgeERC20_Test:test_withdraw_withdrawingERC20_succeeds() (gas: 388246)
L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 26200)
L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 26422)
L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 26227)
L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingERC20_succeeds() (gas: 96126)
L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingETH_succeeds() (gas: 95023)
L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingERC20_succeeds() (gas: 96147)
L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingETH_succeeds() (gas: 95044)
L2StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 45610)
L2StandardBridge_Test:test_initialize_succeeds() (gas: 28938)
L2StandardBridge_Test:test_initialize_succeeds() (gas: 28894)
L2StandardBridge_Test:test_receive_succeeds() (gas: 177147)
L2StandardBridge_Test:test_withdraw_ether_succeeds() (gas: 143411)
L2StandardBridge_Test:test_withdraw_insufficientValue_reverts() (gas: 16586)
......@@ -302,41 +302,41 @@ LegacyERC20ETH_Test:test_mint_doesNotExist_reverts() (gas: 10672)
LegacyERC20ETH_Test:test_transferFrom_doesNotExist_reverts() (gas: 13002)
LegacyERC20ETH_Test:test_transfer_doesNotExist_reverts() (gas: 10801)
LegacyMessagePasser_Test:test_passMessageToL1_succeeds() (gas: 34629)
LibPosition_Test:test_pos_correctness_succeeds() (gas: 38689)
LivenessGuard_CheckAfterExecution_TestFails:test_checkAfterExecution_callerIsNotSafe_revert() (gas: 8531)
LibPosition_Test:test_pos_correctness_succeeds() (gas: 38711)
LivenessGuard_CheckAfterExecution_TestFails:test_checkAfterExecution_callerIsNotSafe_revert() (gas: 8576)
LivenessGuard_CheckTx_Test:test_checkTransaction_succeeds() (gas: 233535)
LivenessGuard_CheckTx_TestFails:test_checkTransaction_callerIsNotSafe_revert() (gas: 10358)
LivenessGuard_Constructor_Test:test_constructor_works() (gas: 1198965)
LivenessGuard_Getters_Test:test_getters_works() (gas: 10662)
LivenessGuard_OwnerManagement_Test:test_addOwner_succeeds() (gas: 274366)
LivenessGuard_OwnerManagement_Test:test_removeOwner_succeeds() (gas: 243684)
LivenessGuard_OwnerManagement_Test:test_swapOwner_succeeds() (gas: 282299)
LivenessGuard_ShowLiveness_Test:test_showLiveness_succeeds() (gas: 28831)
LivenessGuard_OwnerManagement_Test:test_addOwner_succeeds() (gas: 274384)
LivenessGuard_OwnerManagement_Test:test_removeOwner_succeeds() (gas: 243663)
LivenessGuard_OwnerManagement_Test:test_swapOwner_succeeds() (gas: 282261)
LivenessGuard_ShowLiveness_Test:test_showLiveness_succeeds() (gas: 28850)
LivenessGuard_ShowLiveness_TestFail:test_showLiveness_callIsNotSafeOwner_reverts() (gas: 18770)
LivenessModule_CanRemove_Test:test_canRemove_works() (gas: 33026)
LivenessModule_CanRemove_TestFail:test_canRemove_notSafeOwner_reverts() (gas: 20489)
LivenessModule_CanRemove_Test:test_canRemove_works() (gas: 33071)
LivenessModule_CanRemove_TestFail:test_canRemove_notSafeOwner_reverts() (gas: 20534)
LivenessModule_Constructor_TestFail:test_constructor_minOwnersGreaterThanOwners_reverts() (gas: 83623)
LivenessModule_Constructor_TestFail:test_constructor_wrongThreshold_reverts() (gas: 92925)
LivenessModule_Get75PercentThreshold_Test:test_get75PercentThreshold_Works() (gas: 26339)
LivenessModule_Constructor_TestFail:test_constructor_wrongThreshold_reverts() (gas: 92903)
LivenessModule_Get75PercentThreshold_Test:test_get75PercentThreshold_Works() (gas: 26384)
LivenessModule_Getters_Test:test_getters_works() (gas: 14853)
LivenessModule_RemoveOwners_Test:test_removeOwners_allOwners_succeeds() (gas: 1316393)
LivenessModule_RemoveOwners_Test:test_removeOwners_allOwners_succeeds() (gas: 1316416)
LivenessModule_RemoveOwners_Test:test_removeOwners_oneOwner_succeeds() (gas: 130750)
LivenessModule_RemoveOwners_TestFail:test_removeOwners_belowEmptiedButNotShutDown_reverts() (gas: 1269598)
LivenessModule_RemoveOwners_TestFail:test_removeOwners_belowEmptiedButNotShutDown_reverts() (gas: 1269620)
LivenessModule_RemoveOwners_TestFail:test_removeOwners_belowMinButNotEmptied_reverts() (gas: 1273409)
LivenessModule_RemoveOwners_TestFail:test_removeOwners_differentArrayLengths_reverts() (gas: 10502)
LivenessModule_RemoveOwners_TestFail:test_removeOwners_guardChanged_reverts() (gas: 2836129)
LivenessModule_RemoveOwners_TestFail:test_removeOwners_invalidThreshold_reverts() (gas: 69358)
LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasShownLivenessRecently_reverts() (gas: 77749)
LivenessModule_RemoveOwners_TestFail:test_removeOwners_guardChanged_reverts() (gas: 2836151)
LivenessModule_RemoveOwners_TestFail:test_removeOwners_invalidThreshold_reverts() (gas: 69313)
LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasShownLivenessRecently_reverts() (gas: 77771)
LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasSignedRecently_reverts() (gas: 615047)
LivenessModule_RemoveOwners_TestFail:test_removeOwners_swapToFallbackOwner_reverts() (gas: 1278252)
LivenessModule_RemoveOwners_TestFail:test_removeOwners_wrongPreviousOwner_reverts() (gas: 73954)
MIPS_Test:test_add_succeeds() (gas: 123021)
MIPS_Test:test_addiSign_succeeds() (gas: 122946)
MIPS_Test:test_addi_succeeds() (gas: 123166)
MIPS_Test:test_addu_succeeds() (gas: 123041)
MIPS_Test:test_addu_succeeds() (gas: 122975)
MIPS_Test:test_addui_succeeds() (gas: 123162)
MIPS_Test:test_and_succeeds() (gas: 123017)
MIPS_Test:test_andi_succeeds() (gas: 122949)
MIPS_Test:test_andi_succeeds() (gas: 122994)
MIPS_Test:test_beq_succeeds() (gas: 203427)
MIPS_Test:test_bgez_succeeds() (gas: 122265)
MIPS_Test:test_bgtz_succeeds() (gas: 122205)
......@@ -351,15 +351,15 @@ MIPS_Test:test_clz_succeeds() (gas: 123177)
MIPS_Test:test_div_succeeds() (gas: 123134)
MIPS_Test:test_divu_succeeds() (gas: 123142)
MIPS_Test:test_exit_succeeds() (gas: 122657)
MIPS_Test:test_fcntl_succeeds() (gas: 204842)
MIPS_Test:test_fcntl_succeeds() (gas: 204864)
MIPS_Test:test_illegal_instruction_fails() (gas: 92045)
MIPS_Test:test_invalid_root_fails() (gas: 436216)
MIPS_Test:test_jal_nonzeroRegion_succeeds() (gas: 121273)
MIPS_Test:test_invalid_root_fails() (gas: 436238)
MIPS_Test:test_jal_nonzeroRegion_succeeds() (gas: 121250)
MIPS_Test:test_jal_succeeds() (gas: 121217)
MIPS_Test:test_jalr_succeeds() (gas: 122425)
MIPS_Test:test_jr_succeeds() (gas: 122096)
MIPS_Test:test_jump_inDelaySlot_fails() (gas: 85928)
MIPS_Test:test_jump_nonzeroRegion_succeeds() (gas: 120972)
MIPS_Test:test_jump_inDelaySlot_fails() (gas: 85884)
MIPS_Test:test_jump_nonzeroRegion_succeeds() (gas: 120994)
MIPS_Test:test_jump_succeeds() (gas: 120969)
MIPS_Test:test_lb_succeeds() (gas: 128187)
MIPS_Test:test_lbu_succeeds() (gas: 128085)
......@@ -374,10 +374,10 @@ MIPS_Test:test_mfhi_succeeds() (gas: 122634)
MIPS_Test:test_mflo_succeeds() (gas: 122718)
MIPS_Test:test_mmap_succeeds() (gas: 119637)
MIPS_Test:test_movn_succeeds() (gas: 204054)
MIPS_Test:test_movz_succeeds() (gas: 203923)
MIPS_Test:test_movz_succeeds() (gas: 203945)
MIPS_Test:test_mthi_succeeds() (gas: 122678)
MIPS_Test:test_mtlo_succeeds() (gas: 122741)
MIPS_Test:test_mul_succeeds() (gas: 122256)
MIPS_Test:test_mul_succeeds() (gas: 122278)
MIPS_Test:test_mult_succeeds() (gas: 122959)
MIPS_Test:test_multu_succeeds() (gas: 123018)
MIPS_Test:test_nor_succeeds() (gas: 123109)
......@@ -389,42 +389,42 @@ MIPS_Test:test_prestate_exited_succeeds() (gas: 113835)
MIPS_Test:test_sb_succeeds() (gas: 161547)
MIPS_Test:test_sc_succeeds() (gas: 161752)
MIPS_Test:test_sh_succeeds() (gas: 161606)
MIPS_Test:test_sll_succeeds() (gas: 122238)
MIPS_Test:test_sll_succeeds() (gas: 122260)
MIPS_Test:test_sllv_succeeds() (gas: 122402)
MIPS_Test:test_slt_succeeds() (gas: 205250)
MIPS_Test:test_sltu_succeeds() (gas: 123285)
MIPS_Test:test_sra_succeeds() (gas: 122468)
MIPS_Test:test_sra_succeeds() (gas: 122490)
MIPS_Test:test_srav_succeeds() (gas: 122758)
MIPS_Test:test_srl_succeeds() (gas: 122276)
MIPS_Test:test_srlv_succeeds() (gas: 122506)
MIPS_Test:test_step_abi_succeeds() (gas: 58532)
MIPS_Test:test_sub_succeeds() (gas: 123007)
MIPS_Test:test_subu_succeeds() (gas: 123070)
MIPS_Test:test_subu_succeeds() (gas: 123092)
MIPS_Test:test_sw_succeeds() (gas: 161604)
MIPS_Test:test_swl_succeeds() (gas: 161621)
MIPS_Test:test_swr_succeeds() (gas: 161696)
MIPS_Test:test_xor_succeeds() (gas: 123029)
MIPS_Test:test_xori_succeeds() (gas: 123147)
MerkleTrie_get_Test:test_get_corruptedProof_reverts() (gas: 5733)
MerkleTrie_get_Test:test_get_corruptedProof_reverts() (gas: 5710)
MerkleTrie_get_Test:test_get_extraProofElements_reverts() (gas: 58889)
MerkleTrie_get_Test:test_get_invalidDataRemainder_reverts() (gas: 35845)
MerkleTrie_get_Test:test_get_invalidInternalNodeHash_reverts() (gas: 49654)
MerkleTrie_get_Test:test_get_nonexistentKey1_reverts() (gas: 54770)
MerkleTrie_get_Test:test_get_invalidDataRemainder_reverts() (gas: 35867)
MerkleTrie_get_Test:test_get_invalidInternalNodeHash_reverts() (gas: 49676)
MerkleTrie_get_Test:test_get_nonexistentKey1_reverts() (gas: 54792)
MerkleTrie_get_Test:test_get_nonexistentKey2_reverts() (gas: 16699)
MerkleTrie_get_Test:test_get_smallerPathThanKey1_reverts() (gas: 51403)
MerkleTrie_get_Test:test_get_smallerPathThanKey2_reverts() (gas: 52884)
MerkleTrie_get_Test:test_get_smallerPathThanKey1_reverts() (gas: 51425)
MerkleTrie_get_Test:test_get_smallerPathThanKey2_reverts() (gas: 52840)
MerkleTrie_get_Test:test_get_validProof10_succeeds() (gas: 48845)
MerkleTrie_get_Test:test_get_validProof1_succeeds() (gas: 55970)
MerkleTrie_get_Test:test_get_validProof2_succeeds() (gas: 65861)
MerkleTrie_get_Test:test_get_validProof2_succeeds() (gas: 65883)
MerkleTrie_get_Test:test_get_validProof3_succeeds() (gas: 27309)
MerkleTrie_get_Test:test_get_validProof4_succeeds() (gas: 18105)
MerkleTrie_get_Test:test_get_validProof4_succeeds() (gas: 18127)
MerkleTrie_get_Test:test_get_validProof5_succeeds() (gas: 80701)
MerkleTrie_get_Test:test_get_validProof6_succeeds() (gas: 69460)
MerkleTrie_get_Test:test_get_validProof7_succeeds() (gas: 76158)
MerkleTrie_get_Test:test_get_validProof8_succeeds() (gas: 48802)
MerkleTrie_get_Test:test_get_validProof7_succeeds() (gas: 76115)
MerkleTrie_get_Test:test_get_validProof8_succeeds() (gas: 48824)
MerkleTrie_get_Test:test_get_validProof9_succeeds() (gas: 48802)
MerkleTrie_get_Test:test_get_wrongKeyProof_reverts() (gas: 50730)
MerkleTrie_get_Test:test_get_zeroBranchValueLength_reverts() (gas: 41684)
MerkleTrie_get_Test:test_get_wrongKeyProof_reverts() (gas: 50752)
MerkleTrie_get_Test:test_get_zeroBranchValueLength_reverts() (gas: 41706)
MerkleTrie_get_Test:test_get_zeroLengthKey_reverts() (gas: 3632)
MintManager_constructor_Test:test_constructor_succeeds() (gas: 10623)
MintManager_mint_Test:test_mint_afterPeriodElapsed_succeeds() (gas: 148184)
......@@ -436,101 +436,101 @@ MintManager_upgrade_Test:test_upgrade_fromNotOwner_reverts() (gas: 11041)
MintManager_upgrade_Test:test_upgrade_fromOwner_succeeds() (gas: 23509)
MintManager_upgrade_Test:test_upgrade_toZeroAddress_reverts() (gas: 11070)
Multichain:test_script_succeeds() (gas: 3078)
OptimismMintableERC20_Test:test_bridge_succeeds() (gas: 7695)
OptimismMintableERC20_Test:test_burn_notBridge_reverts() (gas: 11209)
OptimismMintableERC20_Test:test_burn_succeeds() (gas: 51050)
OptimismMintableERC20_Test:test_erc165_supportsInterface_succeeds() (gas: 7832)
OptimismMintableERC20_Test:test_l1Token_succeeds() (gas: 7717)
OptimismMintableERC20_Test:test_l2Bridge_succeeds() (gas: 7672)
OptimismMintableERC20_Test:test_legacy_succeeds() (gas: 14518)
OptimismMintableERC20_Test:test_mint_notBridge_reverts() (gas: 11187)
OptimismMintableERC20_Test:test_mint_succeeds() (gas: 63633)
OptimismMintableERC20_Test:test_remoteToken_succeeds() (gas: 7718)
OptimismMintableERC721Factory_Test:test_constructor_succeeds() (gas: 8402)
OptimismMintableERC20_Test:test_bridge_succeeds() (gas: 7732)
OptimismMintableERC20_Test:test_burn_notBridge_reverts() (gas: 11168)
OptimismMintableERC20_Test:test_burn_succeeds() (gas: 51057)
OptimismMintableERC20_Test:test_erc165_supportsInterface_succeeds() (gas: 7863)
OptimismMintableERC20_Test:test_l1Token_succeeds() (gas: 7732)
OptimismMintableERC20_Test:test_l2Bridge_succeeds() (gas: 7687)
OptimismMintableERC20_Test:test_legacy_succeeds() (gas: 14630)
OptimismMintableERC20_Test:test_mint_notBridge_reverts() (gas: 11212)
OptimismMintableERC20_Test:test_mint_succeeds() (gas: 63595)
OptimismMintableERC20_Test:test_remoteToken_succeeds() (gas: 7755)
OptimismMintableERC721Factory_Test:test_constructor_succeeds() (gas: 8424)
OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_sameTwice_reverts() (gas: 8937393460516800078)
OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_succeeds() (gas: 2316523)
OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_succeeds() (gas: 2316545)
OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_zeroRemoteToken_reverts() (gas: 9542)
OptimismMintableERC721_Test:test_burn_notBridge_reverts() (gas: 136967)
OptimismMintableERC721_Test:test_burn_succeeds() (gas: 118874)
OptimismMintableERC721_Test:test_constructor_succeeds() (gas: 24516)
OptimismMintableERC721_Test:test_safeMint_notBridge_reverts() (gas: 11209)
OptimismMintableERC721_Test:test_safeMint_succeeds() (gas: 140599)
OptimismMintableERC721_Test:test_supportsInterfaces_succeeds() (gas: 9028)
OptimismMintableERC721_Test:test_supportsInterfaces_succeeds() (gas: 9050)
OptimismMintableERC721_Test:test_tokenURI_succeeds() (gas: 163605)
OptimismMintableTokenFactory_Test:test_bridge_succeeds() (gas: 9856)
OptimismMintableTokenFactory_Test:test_createStandardL2TokenWithDecimals_succeeds() (gas: 1142627)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_remoteIsZero_reverts() (gas: 9621)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_sameTwice_reverts() (gas: 8937393460516764416)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_succeeds() (gas: 1142596)
OptimismPortalUpgradeable_Test:test_initialize_cannotInitImpl_reverts() (gas: 14593)
OptimismPortalUpgradeable_Test:test_initialize_cannotInitProxy_reverts() (gas: 16206)
OptimismPortalUpgradeable_Test:test_params_initValuesOnProxy_succeeds() (gas: 26711)
OptimismPortalUpgradeable_Test:test_upgradeToAndCall_upgrading_succeeds() (gas: 186086)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() (gas: 178734)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() (gas: 182285)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_succeeds() (gas: 1142619)
OptimismPortalUpgradeable_Test:test_initialize_cannotInitImpl_reverts() (gas: 14615)
OptimismPortalUpgradeable_Test:test_initialize_cannotInitProxy_reverts() (gas: 16222)
OptimismPortalUpgradeable_Test:test_params_initValuesOnProxy_succeeds() (gas: 26667)
OptimismPortalUpgradeable_Test:test_upgradeToAndCall_upgrading_succeeds() (gas: 186084)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() (gas: 178756)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() (gas: 182307)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() (gas: 41781)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() (gas: 174020)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 181245)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() (gas: 154785)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReentrancy_reverts() (gas: 219305)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReplay_reverts() (gas: 220962)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_paused_reverts() (gas: 38751)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() (gas: 209658)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails_fails() (gas: 8797746687696162678)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() (gas: 171369)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() (gas: 85806)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() (gas: 111361)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onSelfCall_reverts() (gas: 52996)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_paused_reverts() (gas: 58892)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() (gas: 297539)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() (gas: 227641)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProve_reverts() (gas: 166744)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() (gas: 154475)
OptimismPortal_Test:test_constructor_succeeds() (gas: 33454)
OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14300)
OptimismPortal_Test:test_depositTransaction_largeData_reverts() (gas: 512218)
OptimismPortal_Test:test_depositTransaction_smallGasLimit_reverts() (gas: 14556)
OptimismPortal_Test:test_isOutputFinalized_succeeds() (gas: 127617)
OptimismPortal_Test:test_minimumGasLimit_succeeds() (gas: 17639)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() (gas: 154807)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReentrancy_reverts() (gas: 219301)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReplay_reverts() (gas: 220984)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_paused_reverts() (gas: 38773)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() (gas: 209680)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails_fails() (gas: 8797746687696162679)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() (gas: 171324)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() (gas: 85828)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() (gas: 111318)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onSelfCall_reverts() (gas: 52993)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_paused_reverts() (gas: 58914)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() (gas: 297495)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() (gas: 227597)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProve_reverts() (gas: 166699)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() (gas: 154431)
OptimismPortal_Test:test_constructor_succeeds() (gas: 33476)
OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14294)
OptimismPortal_Test:test_depositTransaction_largeData_reverts() (gas: 512224)
OptimismPortal_Test:test_depositTransaction_smallGasLimit_reverts() (gas: 14550)
OptimismPortal_Test:test_isOutputFinalized_succeeds() (gas: 127639)
OptimismPortal_Test:test_minimumGasLimit_succeeds() (gas: 17643)
OptimismPortal_Test:test_pause_onlyGuardian_reverts() (gas: 24487)
OptimismPortal_Test:test_pause_succeeds() (gas: 27329)
OptimismPortal_Test:test_simple_isOutputFinalized_succeeds() (gas: 40883)
OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 31580)
OptimismPortal_Test:test_unpause_succeeds() (gas: 27349)
OptimistAllowlistTest:test_constructor_succeeds() (gas: 16407)
OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestorWithFalsyValue_fails() (gas: 49650)
OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestor_succeeds() (gas: 49254)
OptimistAllowlistTest:test_isAllowedToMint_fromCoinbaseQuestAttestorWithFalsyValue_fails() (gas: 49352)
OptimistAllowlistTest:test_isAllowedToMint_fromCoinbaseQuestAttestor_succeeds() (gas: 53433)
OptimistAllowlistTest:test_isAllowedToMint_fromInvite_succeeds() (gas: 235292)
OptimistAllowlistTest:test_isAllowedToMint_fromWrongAllowlistAttestor_fails() (gas: 58122)
OptimistAllowlistTest:test_isAllowedToMint_fromWrongCoinbaseQuestAttestor_fails() (gas: 58079)
OptimistAllowlistTest:test_isAllowedToMint_fromWrongOptimistInviter_fails() (gas: 57412)
OptimistAllowlistTest:test_isAllowedToMint_withMultipleAttestations_succeeds() (gas: 324720)
OptimistAllowlistTest:test_constructor_succeeds() (gas: 16362)
OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestorWithFalsyValue_fails() (gas: 49652)
OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestor_succeeds() (gas: 49276)
OptimistAllowlistTest:test_isAllowedToMint_fromCoinbaseQuestAttestorWithFalsyValue_fails() (gas: 49347)
OptimistAllowlistTest:test_isAllowedToMint_fromCoinbaseQuestAttestor_succeeds() (gas: 53455)
OptimistAllowlistTest:test_isAllowedToMint_fromInvite_succeeds() (gas: 235314)
OptimistAllowlistTest:test_isAllowedToMint_fromWrongAllowlistAttestor_fails() (gas: 58119)
OptimistAllowlistTest:test_isAllowedToMint_fromWrongCoinbaseQuestAttestor_fails() (gas: 58098)
OptimistAllowlistTest:test_isAllowedToMint_fromWrongOptimistInviter_fails() (gas: 57409)
OptimistAllowlistTest:test_isAllowedToMint_withMultipleAttestations_succeeds() (gas: 324717)
OptimistAllowlistTest:test_isAllowedToMint_withoutAnyAttestations_fails() (gas: 23046)
OptimistInviterTest:test_claimInvite_claimBeforeMinCommitmentPeriod_reverts() (gas: 142794)
OptimistInviterTest:test_claimInvite_claimForSomeoneElse_succeeds() (gas: 245313)
OptimistInviterTest:test_claimInvite_claimForSomeoneElse_succeeds() (gas: 245304)
OptimistInviterTest:test_claimInvite_replayingUsedNonce_reverts() (gas: 288334)
OptimistInviterTest:test_claimInvite_succeeds() (gas: 241271)
OptimistInviterTest:test_claimInvite_usingERC1271Wallet_succeeds() (gas: 245678)
OptimistInviterTest:test_claimInvite_usingSignatureIssuedForDifferentChain_reverts() (gas: 156562)
OptimistInviterTest:test_claimInvite_usingSignatureIssuedForDifferentContract_reverts() (gas: 156453)
OptimistInviterTest:test_claimInvite_usingSignatureIssuedForDifferentContract_reverts() (gas: 156475)
OptimistInviterTest:test_claimInvite_usingSignatureIssuedForDifferentVersion_reverts() (gas: 155077)
OptimistInviterTest:test_claimInvite_whenIssuerHasNoInvitesLeft_reverts() (gas: 561851)
OptimistInviterTest:test_claimInvite_whenIssuerNeverReceivedInvites_reverts() (gas: 110711)
OptimistInviterTest:test_claimInvite_withIncorrectSignature_reverts() (gas: 253045)
OptimistInviterTest:test_claimInvite_withoutCommittingHash_reverts() (gas: 119185)
OptimistInviterTest:test_commitInvite_committingForSomeoneElse_succeeds() (gas: 140559)
OptimistInviterTest:test_commitInvite_committingForYourself_succeeds() (gas: 138603)
OptimistInviterTest:test_commitInvite_committingForYourself_succeeds() (gas: 138625)
OptimistInviterTest:test_commitInvite_committingSameHashTwice_reverts() (gas: 142031)
OptimistInviterTest:test_grantInvites_adminAddingInvites_succeeds() (gas: 190682)
OptimistInviterTest:test_grantInvites_nonAdminAddingInvites_reverts() (gas: 14026)
OptimistInviterTest:test_initialize_succeeds() (gas: 10573)
OptimistInviterTest:test_grantInvites_adminAddingInvites_succeeds() (gas: 190670)
OptimistInviterTest:test_grantInvites_nonAdminAddingInvites_reverts() (gas: 14048)
OptimistInviterTest:test_initialize_succeeds() (gas: 10507)
OptimistTest:test_approve_soulbound_reverts() (gas: 70487)
OptimistTest:test_baseURI_returnsCorrectBaseURI_succeeds() (gas: 124566)
OptimistTest:test_burn_byNonOwner_reverts() (gas: 73197)
OptimistTest:test_burn_byOwner_succeeds() (gas: 54487)
OptimistTest:test_initialize_succeeds() (gas: 20840)
OptimistTest:test_initialize_succeeds() (gas: 20862)
OptimistTest:test_mint_afterAllowlistAttestation_succeeds() (gas: 121365)
OptimistTest:test_mint_afterCoinbaseQuestAttestation_succeeds() (gas: 130109)
OptimistTest:test_mint_afterInviteClaimed_succeeds() (gas: 310811)
......@@ -538,94 +538,94 @@ OptimistTest:test_mint_afterMultipleAttestations_succeeds() (gas: 377472)
OptimistTest:test_mint_forAlreadyMintedClaimer_reverts() (gas: 117923)
OptimistTest:test_mint_forNonAllowlistedClaimer_reverts() (gas: 29722)
OptimistTest:test_mint_secondaryMinter_succeeds() (gas: 72711)
OptimistTest:test_multicall_batchingClaimAndMint_succeeds() (gas: 308008)
OptimistTest:test_multicall_batchingClaimAndMint_succeeds() (gas: 307999)
OptimistTest:test_setApprovalForAll_soulbound_reverts() (gas: 74239)
OptimistTest:test_supportsInterface_returnsCorrectInterfaceForERC721_succeeds() (gas: 5805)
OptimistTest:test_tokenIdOfAddress_returnsOwnerID_succeeds() (gas: 63730)
OptimistTest:test_tokenURI_returnsCorrectTokenURI_succeeds() (gas: 195905)
OptimistTest:test_transferFrom_soulbound_reverts() (gas: 75512)
PreimageOracle_Test:test_keccak256PreimageKey_succeeds() (gas: 319)
PreimageOracle_Test:test_keccak256PreimageKey_succeeds() (gas: 342)
PreimageOracle_Test:test_loadKeccak256PreimagePart_outOfBoundsOffset_reverts() (gas: 8971)
PreimageOracle_Test:test_loadKeccak256PreimagePart_succeeds() (gas: 76076)
PreimageOracle_Test:test_loadLocalData_multipleContexts_succeeds() (gas: 147718)
PreimageOracle_Test:test_loadLocalData_onePart_succeeds() (gas: 75905)
PreimageOracle_Test:test_loadLocalData_outOfBoundsOffset_reverts() (gas: 8882)
ProtocolVersions_Initialize_Test:test_initialize_events_succeeds() (gas: 41623)
ProtocolVersions_Initialize_Test:test_initialize_values_succeeds() (gas: 45024)
ProtocolVersions_Setters_TestFail:test_setRecommended_notOwner_reverts() (gas: 15531)
ProtocolVersions_Initialize_Test:test_initialize_values_succeeds() (gas: 45046)
ProtocolVersions_Setters_TestFail:test_setRecommended_notOwner_reverts() (gas: 15553)
ProtocolVersions_Setters_TestFail:test_setRequired_notOwner_reverts() (gas: 15587)
ProxyAdmin_Test:test_chugsplashChangeProxyAdmin_succeeds() (gas: 36440)
ProxyAdmin_Test:test_chugsplashGetProxyAdmin_succeeds() (gas: 15675)
ProxyAdmin_Test:test_chugsplashGetProxyImplementation_succeeds() (gas: 51084)
ProxyAdmin_Test:test_chugsplashUpgradeAndCall_succeeds() (gas: 82311)
ProxyAdmin_Test:test_chugsplashUpgrade_succeeds() (gas: 48988)
ProxyAdmin_Test:test_chugsplashGetProxyAdmin_succeeds() (gas: 15610)
ProxyAdmin_Test:test_chugsplashGetProxyImplementation_succeeds() (gas: 51040)
ProxyAdmin_Test:test_chugsplashUpgradeAndCall_succeeds() (gas: 82239)
ProxyAdmin_Test:test_chugsplashUpgrade_succeeds() (gas: 48965)
ProxyAdmin_Test:test_delegateResolvedChangeProxyAdmin_succeeds() (gas: 33936)
ProxyAdmin_Test:test_delegateResolvedGetProxyAdmin_succeeds() (gas: 17691)
ProxyAdmin_Test:test_delegateResolvedGetProxyAdmin_succeeds() (gas: 17647)
ProxyAdmin_Test:test_delegateResolvedGetProxyImplementation_succeeds() (gas: 62028)
ProxyAdmin_Test:test_delegateResolvedUpgradeAndCall_succeeds() (gas: 98039)
ProxyAdmin_Test:test_delegateResolvedUpgradeAndCall_succeeds() (gas: 98033)
ProxyAdmin_Test:test_delegateResolvedUpgrade_succeeds() (gas: 58482)
ProxyAdmin_Test:test_erc1967ChangeProxyAdmin_succeeds() (gas: 34674)
ProxyAdmin_Test:test_erc1967ChangeProxyAdmin_succeeds() (gas: 34696)
ProxyAdmin_Test:test_erc1967GetProxyAdmin_succeeds() (gas: 15616)
ProxyAdmin_Test:test_erc1967GetProxyImplementation_succeeds() (gas: 52073)
ProxyAdmin_Test:test_erc1967UpgradeAndCall_succeeds() (gas: 78971)
ProxyAdmin_Test:test_erc1967UpgradeAndCall_succeeds() (gas: 78987)
ProxyAdmin_Test:test_erc1967Upgrade_succeeds() (gas: 50080)
ProxyAdmin_Test:test_isUpgrading_succeeds() (gas: 19442)
ProxyAdmin_Test:test_isUpgrading_succeeds() (gas: 19497)
ProxyAdmin_Test:test_onlyOwner_notOwner_reverts() (gas: 22767)
ProxyAdmin_Test:test_owner_succeeds() (gas: 9738)
ProxyAdmin_Test:test_proxyType_succeeds() (gas: 20533)
ProxyAdmin_Test:test_setAddressManager_notOwner_reverts() (gas: 10578)
ProxyAdmin_Test:test_setImplementationName_notOwner_reverts() (gas: 11111)
ProxyAdmin_Test:test_setImplementationName_succeeds() (gas: 38945)
ProxyAdmin_Test:test_setAddressManager_notOwner_reverts() (gas: 10600)
ProxyAdmin_Test:test_setImplementationName_notOwner_reverts() (gas: 11156)
ProxyAdmin_Test:test_setImplementationName_succeeds() (gas: 38967)
ProxyAdmin_Test:test_setProxyType_notOwner_reverts() (gas: 10814)
Proxy_Test:test_delegatesToImpl_succeeds() (gas: 45207)
Proxy_Test:test_implementationKey_succeeds() (gas: 20911)
Proxy_Test:test_implementation_isZeroAddress_reverts() (gas: 47628)
Proxy_Test:test_implementationKey_succeeds() (gas: 20933)
Proxy_Test:test_implementation_isZeroAddress_reverts() (gas: 47650)
Proxy_Test:test_implementation_zeroAddressCaller_succeeds() (gas: 14752)
Proxy_Test:test_ownerKey_succeeds() (gas: 19067)
Proxy_Test:test_ownerProxyCall_notAdmin_succeeds() (gas: 35477)
Proxy_Test:test_ownerProxyCall_notAdmin_succeeds() (gas: 35499)
Proxy_Test:test_proxyCallToImp_notAdmin_succeeds() (gas: 30010)
Proxy_Test:test_upgradeToAndCall_functionDoesNotExist_reverts() (gas: 107980)
Proxy_Test:test_upgradeToAndCall_functionDoesNotExist_reverts() (gas: 107935)
Proxy_Test:test_upgradeToAndCall_isPayable_succeeds() (gas: 53744)
Proxy_Test:test_upgradeToAndCall_succeeds() (gas: 125192)
Proxy_Test:test_upgradeToAndCall_succeeds() (gas: 125214)
Proxy_Test:test_upgradeTo_clashingFunctionSignatures_succeeds() (gas: 101363)
RLPReader_readBytes_Test:test_readBytes_bytestring00_succeeds() (gas: 1841)
RLPReader_readBytes_Test:test_readBytes_bytestring01_succeeds() (gas: 1818)
RLPReader_readBytes_Test:test_readBytes_bytestring00_succeeds() (gas: 1863)
RLPReader_readBytes_Test:test_readBytes_bytestring01_succeeds() (gas: 1840)
RLPReader_readBytes_Test:test_readBytes_bytestring7f_succeeds() (gas: 1861)
RLPReader_readBytes_Test:test_readBytes_invalidListLength_reverts() (gas: 3946)
RLPReader_readBytes_Test:test_readBytes_invalidListLength_reverts() (gas: 3903)
RLPReader_readBytes_Test:test_readBytes_invalidPrefix_reverts() (gas: 3961)
RLPReader_readBytes_Test:test_readBytes_invalidRemainder_reverts() (gas: 4155)
RLPReader_readBytes_Test:test_readBytes_invalidStringLength_reverts() (gas: 3857)
RLPReader_readBytes_Test:test_readBytes_revertListItem_reverts() (gas: 3998)
RLPReader_readList_Test:test_readList_dictTest1_succeeds() (gas: 23140)
RLPReader_readList_Test:test_readList_empty_succeeds() (gas: 4610)
RLPReader_readList_Test:test_readList_incorrectLengthInArray_reverts() (gas: 3954)
RLPReader_readList_Test:test_readList_incorrectLengthInArray_reverts() (gas: 3976)
RLPReader_readList_Test:test_readList_int32Overflow2_reverts() (gas: 4139)
RLPReader_readList_Test:test_readList_int32Overflow_reverts() (gas: 4116)
RLPReader_readList_Test:test_readList_int32Overflow_reverts() (gas: 4138)
RLPReader_readList_Test:test_readList_invalidRemainder_reverts() (gas: 4114)
RLPReader_readList_Test:test_readList_invalidShortList_reverts() (gas: 3967)
RLPReader_readList_Test:test_readList_invalidValue_reverts() (gas: 3878)
RLPReader_readList_Test:test_readList_leadingZerosInLongLengthArray1_reverts() (gas: 3982)
RLPReader_readList_Test:test_readList_leadingZerosInLongLengthArray2_reverts() (gas: 3968)
RLPReader_readList_Test:test_readList_leadingZerosInLongLengthArray2_reverts() (gas: 3945)
RLPReader_readList_Test:test_readList_leadingZerosInLongLengthList1_reverts() (gas: 3984)
RLPReader_readList_Test:test_readList_listLongerThan32Elements_reverts() (gas: 38590)
RLPReader_readList_Test:test_readList_listLongerThan32Elements_reverts() (gas: 38612)
RLPReader_readList_Test:test_readList_listOfLists2_succeeds() (gas: 12122)
RLPReader_readList_Test:test_readList_listOfLists_succeeds() (gas: 9450)
RLPReader_readList_Test:test_readList_longList1_succeeds() (gas: 28332)
RLPReader_readList_Test:test_readList_longList2_succeeds() (gas: 196395)
RLPReader_readList_Test:test_readList_longListLessThan56Bytes_reverts() (gas: 4046)
RLPReader_readList_Test:test_readList_longStringLength_reverts() (gas: 3924)
RLPReader_readList_Test:test_readList_listOfLists_succeeds() (gas: 9472)
RLPReader_readList_Test:test_readList_longList1_succeeds() (gas: 28354)
RLPReader_readList_Test:test_readList_longList2_succeeds() (gas: 196352)
RLPReader_readList_Test:test_readList_longListLessThan56Bytes_reverts() (gas: 4023)
RLPReader_readList_Test:test_readList_longStringLength_reverts() (gas: 3946)
RLPReader_readList_Test:test_readList_longStringLessThan56Bytes_reverts() (gas: 4009)
RLPReader_readList_Test:test_readList_multiList_succeeds() (gas: 11737)
RLPReader_readList_Test:test_readList_multiList_succeeds() (gas: 11695)
RLPReader_readList_Test:test_readList_nonOptimalLongLengthArray1_reverts() (gas: 3999)
RLPReader_readList_Test:test_readList_nonOptimalLongLengthArray2_reverts() (gas: 4022)
RLPReader_readList_Test:test_readList_nonOptimalLongLengthArray2_reverts() (gas: 4044)
RLPReader_readList_Test:test_readList_notEnoughContentForList1_reverts() (gas: 4115)
RLPReader_readList_Test:test_readList_notEnoughContentForList2_reverts() (gas: 4161)
RLPReader_readList_Test:test_readList_notEnoughContentForList2_reverts() (gas: 4117)
RLPReader_readList_Test:test_readList_notEnoughContentForString1_reverts() (gas: 4072)
RLPReader_readList_Test:test_readList_notEnoughContentForString2_reverts() (gas: 4138)
RLPReader_readList_Test:test_readList_notEnoughContentForString2_reverts() (gas: 4094)
RLPReader_readList_Test:test_readList_notLongEnough_reverts() (gas: 3955)
RLPReader_readList_Test:test_readList_shortListMax1_succeeds() (gas: 39580)
RLPReader_readList_Test:test_readList_shortListMax1_succeeds() (gas: 39602)
RLPWriter_writeList_Test:test_writeList_dictTest1_succeeds() (gas: 36979)
RLPWriter_writeList_Test:test_writeList_empty_succeeds() (gas: 1666)
RLPWriter_writeList_Test:test_writeList_empty_succeeds() (gas: 1689)
RLPWriter_writeList_Test:test_writeList_listoflists2_succeeds() (gas: 16566)
RLPWriter_writeList_Test:test_writeList_listoflists_succeeds() (gas: 10841)
RLPWriter_writeList_Test:test_writeList_longlist1_succeeds() (gas: 40383)
......@@ -634,23 +634,23 @@ RLPWriter_writeList_Test:test_writeList_multiList_succeeds() (gas: 22446)
RLPWriter_writeList_Test:test_writeList_shortListMax1_succeeds() (gas: 36793)
RLPWriter_writeList_Test:test_writeList_stringList_succeeds() (gas: 10697)
RLPWriter_writeString_Test:test_writeString_bytestring00_succeeds() (gas: 929)
RLPWriter_writeString_Test:test_writeString_bytestring01_succeeds() (gas: 906)
RLPWriter_writeString_Test:test_writeString_bytestring01_succeeds() (gas: 951)
RLPWriter_writeString_Test:test_writeString_bytestring7f_succeeds() (gas: 972)
RLPWriter_writeString_Test:test_writeString_empty_succeeds() (gas: 1611)
RLPWriter_writeString_Test:test_writeString_longstring2_succeeds() (gas: 258768)
RLPWriter_writeString_Test:test_writeString_longstring_succeeds() (gas: 16939)
RLPWriter_writeString_Test:test_writeString_longstring_succeeds() (gas: 16961)
RLPWriter_writeString_Test:test_writeString_shortstring2_succeeds() (gas: 15376)
RLPWriter_writeString_Test:test_writeString_shortstring_succeeds() (gas: 2470)
RLPWriter_writeUint_Test:test_writeUint_mediumint2_succeeds() (gas: 8699)
RLPWriter_writeUint_Test:test_writeUint_mediumint2_succeeds() (gas: 8721)
RLPWriter_writeUint_Test:test_writeUint_mediumint3_succeeds() (gas: 9098)
RLPWriter_writeUint_Test:test_writeUint_mediumint_succeeds() (gas: 8380)
RLPWriter_writeUint_Test:test_writeUint_mediumint_succeeds() (gas: 8357)
RLPWriter_writeUint_Test:test_writeUint_smallint2_succeeds() (gas: 7249)
RLPWriter_writeUint_Test:test_writeUint_smallint3_succeeds() (gas: 7271)
RLPWriter_writeUint_Test:test_writeUint_smallint4_succeeds() (gas: 7250)
RLPWriter_writeUint_Test:test_writeUint_smallint_succeeds() (gas: 7294)
RLPWriter_writeUint_Test:test_writeUint_zero_succeeds() (gas: 7777)
ResolvedDelegateProxy_Test:test_fallback_addressManagerNotSet_reverts() (gas: 605906)
ResolvedDelegateProxy_Test:test_fallback_delegateCallBar_reverts() (gas: 24783)
RLPWriter_writeUint_Test:test_writeUint_smallint4_succeeds() (gas: 7272)
RLPWriter_writeUint_Test:test_writeUint_smallint_succeeds() (gas: 7250)
RLPWriter_writeUint_Test:test_writeUint_zero_succeeds() (gas: 7734)
ResolvedDelegateProxy_Test:test_fallback_addressManagerNotSet_reverts() (gas: 605928)
ResolvedDelegateProxy_Test:test_fallback_delegateCallBar_reverts() (gas: 24805)
ResourceMetering_Test:test_meter_denominatorEq1_reverts() (gas: 20024064)
ResourceMetering_Test:test_meter_initialResourceParams_succeeds() (gas: 12423)
ResourceMetering_Test:test_meter_updateNoGasDelta_succeeds() (gas: 2011591)
......@@ -660,25 +660,25 @@ ResourceMetering_Test:test_meter_updateTenEmptyBlocks_succeeds() (gas: 23747)
ResourceMetering_Test:test_meter_updateTwoEmptyBlocks_succeeds() (gas: 23703)
ResourceMetering_Test:test_meter_useMax_succeeds() (gas: 20020816)
ResourceMetering_Test:test_meter_useMoreThanMax_reverts() (gas: 19549)
SafeCall_Test:test_callWithMinGas_noLeakageHigh_succeeds() (gas: 1021670598)
SafeCall_Test:test_callWithMinGas_noLeakageLow_succeeds() (gas: 1095190688)
SafeCall_Test:test_callWithMinGas_noLeakageHigh_succeeds() (gas: 1020805932)
SafeCall_Test:test_callWithMinGas_noLeakageLow_succeeds() (gas: 1094905711)
SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2_succeeds() (gas: 80640)
SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2recipientReverts_fails() (gas: 48926)
SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2recipientReverts_fails() (gas: 48948)
SequencerFeeVault_Test:test_constructor_succeeds() (gas: 7705)
SequencerFeeVault_Test:test_minWithdrawalAmount_succeeds() (gas: 12816)
SequencerFeeVault_Test:test_minWithdrawalAmount_succeeds() (gas: 12794)
SequencerFeeVault_Test:test_receive_succeeds() (gas: 17395)
SequencerFeeVault_Test:test_withdraw_notEnough_reverts() (gas: 9399)
SequencerFeeVault_Test:test_withdraw_toL1_succeeds() (gas: 618343)
SetPrevBaseFee_Test:test_setPrevBaseFee_succeeds() (gas: 11595)
StandardBridge_Stateless_Test:test_isCorrectTokenPair_succeeds() (gas: 50181)
StandardBridge_Stateless_Test:test_isCorrectTokenPair_succeeds() (gas: 50149)
StandardBridge_Stateless_Test:test_isOptimismMintableERC20_succeeds() (gas: 33142)
Storage_Roundtrip_Test:test_setGetAddress_succeeds(bytes32,address) (runs: 64, μ: 31510, ~: 31821)
Storage_Roundtrip_Test:test_setGetBytes32_succeeds(bytes32,bytes32) (runs: 64, μ: 31598, ~: 31598)
Storage_Roundtrip_Test:test_setGetAddress_succeeds(bytes32,address) (runs: 64, μ: 31532, ~: 31843)
Storage_Roundtrip_Test:test_setGetBytes32_succeeds(bytes32,bytes32) (runs: 64, μ: 31620, ~: 31620)
Storage_Roundtrip_Test:test_setGetUint_succeeds(bytes32,uint256) (runs: 64, μ: 30731, ~: 31664)
SystemConfig_Initialize_Test:test_initialize_events_succeeds() (gas: 88188)
SystemConfig_Initialize_Test:test_initialize_startBlockNoop_reverts() (gas: 77253)
SystemConfig_Initialize_Test:test_initialize_events_succeeds() (gas: 88186)
SystemConfig_Initialize_Test:test_initialize_startBlockNoop_reverts() (gas: 77216)
SystemConfig_Initialize_Test:test_initialize_startBlockOverride_succeeds() (gas: 81116)
SystemConfig_Initialize_Test:test_initialize_values_succeeds() (gas: 88501)
SystemConfig_Initialize_Test:test_initialize_values_succeeds() (gas: 88546)
SystemConfig_Initialize_TestFail:test_initialize_lowGasLimit_reverts() (gas: 59900)
SystemConfig_Setters_TestFail:test_setBatcherHash_notOwner_reverts() (gas: 15675)
SystemConfig_Setters_TestFail:test_setGasConfig_notOwner_reverts() (gas: 15644)
......@@ -689,10 +689,10 @@ SystemConfig_Setters_TestFail:test_setResourceConfig_lowGasLimit_reverts() (gas:
SystemConfig_Setters_TestFail:test_setResourceConfig_notOwner_reverts() (gas: 16867)
SystemConfig_Setters_TestFail:test_setResourceConfig_zeroDenominator_reverts() (gas: 18629)
SystemConfig_Setters_TestFail:test_setUnsafeBlockSigner_notOwner_reverts() (gas: 15658)
TransactorTest:test_call_succeeds() (gas: 26709)
TransactorTest:test_call_unauthorized_reverts() (gas: 18117)
TransactorTest:test_constructor_succeeds() (gas: 9739)
TransactorTest:test_delegateCall_succeeds() (gas: 20909)
TransactorTest:test_call_succeeds() (gas: 26754)
TransactorTest:test_call_unauthorized_reverts() (gas: 18139)
TransactorTest:test_constructor_succeeds() (gas: 9673)
TransactorTest:test_delegateCall_succeeds() (gas: 20931)
TransactorTest:test_delegateCall_unauthorized_reverts() (gas: 18124)
TransferOnionTest:test_constructor_succeeds() (gas: 564855)
TransferOnionTest:test_constructor_succeeds() (gas: 564789)
TransferOnionTest:test_unwrap_succeeds() (gas: 724955)
\ No newline at end of file
......@@ -26,3 +26,6 @@ deployments/1337
# Devnet config which changes with each 'make devnet-up'
deploy-config/devnetL1.json
# Getting Started guide deploy config
deploy-config/getting-started.json
# `SystemConfig` Invariants
## The gas limit of the `SystemConfig` contract can never be lower than the hard-coded lower bound.
**Test:** [`SystemConfig.t.sol#L80`](../test/invariants/SystemConfig.t.sol#L80)
**Test:** [`SystemConfig.t.sol#L70`](../test/invariants/SystemConfig.t.sol#L70)
Subproject commit e8a047e3f40f13fa37af6fe14e6e06283d9a060e
Subproject commit 37a37ab73364d6644bfe11edf88a07880f99bd56
......@@ -20,5 +20,22 @@
"faucetOnchainAuthModuleAmount": 1000000000000000000,
"faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOffchainAuthModuleTtl": 86400,
"faucetOffchainAuthModuleAmount": 50000000000000000
"faucetOffchainAuthModuleAmount": 50000000000000000,
"opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1",
"baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120",
"pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3",
"zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB",
"orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333",
"modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2",
"lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17",
"installOpChainFaucetsDrips": false,
"archivePreviousOpChainFaucetsDrips": false,
"dripVersion": 1,
"previousDripVersion": 0,
"smallOpChainFaucetDripValue": 2000000000000000000,
"smallOpChainFaucetDripInterval": 86400,
"largeOpChainFaucetDripValue": 34000000000000000000,
"largeOpChainFaucetDripInterval": 86400,
"opChainAdminWalletDripValue": 1000000000000000000,
"opChainAdminWalletDripInterval": 2592000
}
......@@ -20,5 +20,22 @@
"faucetOnchainAuthModuleAmount": 1000000000000000000,
"faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOffchainAuthModuleTtl": 86400,
"faucetOffchainAuthModuleAmount": 50000000000000000
"faucetOffchainAuthModuleAmount": 50000000000000000,
"opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1",
"baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120",
"pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3",
"zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB",
"orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333",
"modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2",
"lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17",
"installOpChainFaucetsDrips": false,
"archivePreviousOpChainFaucetsDrips": false,
"dripVersion": 1,
"previousDripVersion": 0,
"smallOpChainFaucetDripValue": 2000000000000000000,
"smallOpChainFaucetDripInterval": 86400,
"largeOpChainFaucetDripValue": 34000000000000000000,
"largeOpChainFaucetDripInterval": 86400,
"opChainAdminWalletDripValue": 1000000000000000000,
"opChainAdminWalletDripInterval": 2592000
}
......@@ -20,5 +20,22 @@
"faucetOnchainAuthModuleAmount": 1000000000000000000,
"faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOffchainAuthModuleTtl": 86400,
"faucetOffchainAuthModuleAmount": 50000000000000000
"faucetOffchainAuthModuleAmount": 50000000000000000,
"opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1",
"baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120",
"pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3",
"zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB",
"orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333",
"modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2",
"lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17",
"installOpChainFaucetsDrips": false,
"archivePreviousOpChainFaucetsDrips": false,
"dripVersion": 1,
"previousDripVersion": 0,
"smallOpChainFaucetDripValue": 2000000000000000000,
"smallOpChainFaucetDripInterval": 86400,
"largeOpChainFaucetDripValue": 34000000000000000000,
"largeOpChainFaucetDripInterval": 86400,
"opChainAdminWalletDripValue": 1000000000000000000,
"opChainAdminWalletDripInterval": 2592000
}
......@@ -20,5 +20,22 @@
"faucetOnchainAuthModuleAmount": 1000000000000000000,
"faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOffchainAuthModuleTtl": 86400,
"faucetOffchainAuthModuleAmount": 50000000000000000
"faucetOffchainAuthModuleAmount": 50000000000000000,
"opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1",
"baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120",
"pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3",
"zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB",
"orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333",
"modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2",
"lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17",
"installOpChainFaucetsDrips": false,
"archivePreviousOpChainFaucetsDrips": false,
"dripVersion": 1,
"previousDripVersion": 0,
"smallOpChainFaucetDripValue": 2000000000000000000,
"smallOpChainFaucetDripInterval": 86400,
"largeOpChainFaucetDripValue": 34000000000000000000,
"largeOpChainFaucetDripInterval": 86400,
"opChainAdminWalletDripValue": 1000000000000000000,
"opChainAdminWalletDripInterval": 2592000
}
......@@ -20,5 +20,22 @@
"faucetOnchainAuthModuleAmount": 1000000000000000000,
"faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOffchainAuthModuleTtl": 86400,
"faucetOffchainAuthModuleAmount": 50000000000000000
"faucetOffchainAuthModuleAmount": 50000000000000000,
"opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1",
"baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120",
"pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3",
"zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB",
"orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333",
"modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2",
"lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17",
"installOpChainFaucetsDrips": false,
"archivePreviousOpChainFaucetsDrips": false,
"dripVersion": 1,
"previousDripVersion": 0,
"smallOpChainFaucetDripValue": 2000000000000000000,
"smallOpChainFaucetDripInterval": 86400,
"largeOpChainFaucetDripValue": 34000000000000000000,
"largeOpChainFaucetDripInterval": 86400,
"opChainAdminWalletDripValue": 1000000000000000000,
"opChainAdminWalletDripInterval": 2592000
}
......@@ -20,5 +20,22 @@
"faucetOnchainAuthModuleAmount": 1000000000000000000,
"faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOffchainAuthModuleTtl": 86400,
"faucetOffchainAuthModuleAmount": 50000000000000000
"faucetOffchainAuthModuleAmount": 50000000000000000,
"opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1",
"baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120",
"pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3",
"zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB",
"orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333",
"modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2",
"lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17",
"installOpChainFaucetsDrips": false,
"archivePreviousOpChainFaucetsDrips": false,
"dripVersion": 1,
"previousDripVersion": 0,
"smallOpChainFaucetDripValue": 2000000000000000000,
"smallOpChainFaucetDripInterval": 86400,
"largeOpChainFaucetDripValue": 34000000000000000000,
"largeOpChainFaucetDripInterval": 86400,
"opChainAdminWalletDripValue": 1000000000000000000,
"opChainAdminWalletDripInterval": 2592000
}
......@@ -20,5 +20,22 @@
"faucetOnchainAuthModuleAmount": 1000000000000000000,
"faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOffchainAuthModuleTtl": 86400,
"faucetOffchainAuthModuleAmount": 50000000000000000
"faucetOffchainAuthModuleAmount": 50000000000000000,
"opL1BridgeAddress": "0x636Af16bf2f682dD3109e60102b8E1A089FedAa8",
"baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120",
"pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3",
"zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB",
"orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333",
"modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2",
"lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17",
"installOpChainFaucetsDrips": false,
"archivePreviousOpChainFaucetsDrips": false,
"dripVersion": 1,
"previousDripVersion": 0,
"smallOpChainFaucetDripValue": 2000000000000000000,
"smallOpChainFaucetDripInterval": 86400,
"largeOpChainFaucetDripValue": 34000000000000000000,
"largeOpChainFaucetDripInterval": 86400,
"opChainAdminWalletDripValue": 1000000000000000000,
"opChainAdminWalletDripInterval": 2592000
}
......@@ -20,5 +20,22 @@
"faucetOnchainAuthModuleAmount": 1000000000000000000,
"faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOffchainAuthModuleTtl": 86400,
"faucetOffchainAuthModuleAmount": 50000000000000000
"faucetOffchainAuthModuleAmount": 50000000000000000,
"opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1",
"baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120",
"pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3",
"zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB",
"orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333",
"modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2",
"lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17",
"installOpChainFaucetsDrips": false,
"archivePreviousOpChainFaucetsDrips": false,
"dripVersion": 1,
"previousDripVersion": 0,
"smallOpChainFaucetDripValue": 2000000000000000000,
"smallOpChainFaucetDripInterval": 86400,
"largeOpChainFaucetDripValue": 34000000000000000000,
"largeOpChainFaucetDripInterval": 86400,
"opChainAdminWalletDripValue": 1000000000000000000,
"opChainAdminWalletDripInterval": 2592000
}
{
"faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6",
"faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5",
"faucetDripV1Value": 20000000000000000000,
"faucetDripV1Interval": 3600,
"faucetDripV1Threshold": 100000000000000000000,
"faucetDripV2Interval": 604800,
"faucetDripV2Threshold": 20000000000000000000,
"faucetDripV2Value": 500000000000000000000,
"faucetAdminDripV1Interval": 86400,
"faucetAdminDripV1Threshold": 100000000000000000,
"faucetAdminDripV1Value": 1000000000000000000,
"faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f",
"faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF",
"faucetGelatoBalanceV1DripInterval": 86400,
"faucetGelatoBalanceV1Value": 1000000000000000000,
"faucetGelatoThreshold": 100000000000000000,
"faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOnchainAuthModuleTtl": 86400,
"faucetOnchainAuthModuleAmount": 1000000000000000000,
"faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOffchainAuthModuleTtl": 86400,
"faucetOffchainAuthModuleAmount": 50000000000000000,
"opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1",
"baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120",
"pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3",
"zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB",
"orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333",
"modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2",
"lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17",
"installOpChainFaucetsDrips": true,
"archivePreviousOpChainFaucetsDrips": false,
"dripVersion": 2,
"previousDripVersion": 1,
"smallOpChainFaucetDripValue": 2000000000000000000,
"smallOpChainFaucetDripInterval": 86400,
"largeOpChainFaucetDripValue": 34000000000000000000,
"largeOpChainFaucetDripInterval": 86400,
"opChainAdminWalletDripValue": 1000000000000000000,
"opChainAdminWalletDripInterval": 2592000
}
......@@ -46,6 +46,14 @@ contract DeployPeriphery is Deployer {
initializeFaucet();
installFaucetAuthModulesConfigs();
if (cfg.installOpChainFaucetsDrips()) {
installOpChainFaucetsDrippieConfigs();
}
if (cfg.archivePreviousOpChainFaucetsDrips()) {
archivePreviousOpChainFaucetsDrippieConfigs();
}
}
/// @notice Deploy all of the proxies
......@@ -243,6 +251,113 @@ contract DeployPeriphery is Deployer {
console.log("Faucet drip configs successfully installed");
}
/// @notice installs drip configs that deposit funds to all OP Chain faucets. This function
/// should only be called on an L1 testnet.
function installOpChainFaucetsDrippieConfigs() public {
uint256 drippieOwnerPrivateKey = vm.envUint("DRIPPIE_OWNER_PRIVATE_KEY");
vm.startBroadcast(drippieOwnerPrivateKey);
Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
console.log("Installing OP Chain faucet drips at %s", address(drippie));
installSmallOpChainFaucetsDrips();
installLargeOpChainFaucetsDrips();
installSmallOpChainAdminWalletDrips();
installLargeOpChainAdminWalletDrips();
vm.stopBroadcast();
console.log("OP chain faucet drip configs successfully installed");
}
/// @notice archives the previous OP Chain drip configs.
function archivePreviousOpChainFaucetsDrippieConfigs() public {
uint256 drippieOwnerPrivateKey = vm.envUint("DRIPPIE_OWNER_PRIVATE_KEY");
vm.startBroadcast(drippieOwnerPrivateKey);
Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
console.log("Archiving OP Chain faucet drips at %s", address(drippie));
archivePreviousSmallOpChainFaucetsDrips();
archivePreviousLargeOpChainFaucetsDrips();
vm.stopBroadcast();
console.log("OP chain faucet drip configs successfully installed");
}
/// @notice installs drips that send funds to small OP chain faucets on the scheduled interval.
function installSmallOpChainFaucetsDrips() public {
address faucetProxy = mustGetAddress("FaucetProxy");
uint256 arrayLength = cfg.getSmallFaucetsL1BridgeAddressesCount();
for (uint256 i = 0; i < arrayLength; i++) {
address l1BridgeAddress = cfg.smallFaucetsL1BridgeAddresses(i);
_installDepositEthToDrip(
faucetProxy,
l1BridgeAddress,
cfg.smallOpChainFaucetDripValue(),
cfg.smallOpChainFaucetDripInterval(),
_faucetDripName(l1BridgeAddress, cfg.dripVersion())
);
}
}
/// @notice installs drips that send funds to the admin wallets for small OP chain faucets
/// on the scheduled interval.
function installSmallOpChainAdminWalletDrips() public {
require(
cfg.faucetOnchainAuthModuleAdmin() == cfg.faucetOffchainAuthModuleAdmin(),
"installSmallOpChainAdminWalletDrips: Only handles identical admin wallet addresses"
);
address adminWallet = cfg.faucetOnchainAuthModuleAdmin();
uint256 arrayLength = cfg.getSmallFaucetsL1BridgeAddressesCount();
for (uint256 i = 0; i < arrayLength; i++) {
address l1BridgeAddress = cfg.smallFaucetsL1BridgeAddresses(i);
_installDepositEthToDrip(
adminWallet,
l1BridgeAddress,
cfg.opChainAdminWalletDripValue(),
cfg.opChainAdminWalletDripInterval(),
_adminWalletDripName(l1BridgeAddress, cfg.dripVersion())
);
}
}
/// @notice installs drips that send funds to the admin wallets for large OP chain faucets
/// on the scheduled interval.
function installLargeOpChainAdminWalletDrips() public {
require(
cfg.faucetOnchainAuthModuleAdmin() == cfg.faucetOffchainAuthModuleAdmin(),
"installLargeOpChainAdminWalletDrips: Only handles identical admin wallet addresses"
);
address adminWallet = cfg.faucetOnchainAuthModuleAdmin();
uint256 arrayLength = cfg.getLargeFaucetsL1BridgeAddressesCount();
for (uint256 i = 0; i < arrayLength; i++) {
address l1BridgeAddress = cfg.largeFaucetsL1BridgeAddresses(i);
_installDepositEthToDrip(
adminWallet,
l1BridgeAddress,
cfg.opChainAdminWalletDripValue(),
cfg.opChainAdminWalletDripInterval(),
_adminWalletDripName(l1BridgeAddress, cfg.dripVersion())
);
}
}
/// @notice installs drips that send funds to large OP chain faucets on the scheduled interval.
function installLargeOpChainFaucetsDrips() public {
address faucetProxy = mustGetAddress("FaucetProxy");
uint256 arrayLength = cfg.getLargeFaucetsL1BridgeAddressesCount();
for (uint256 i = 0; i < arrayLength; i++) {
address l1BridgeAddress = cfg.largeFaucetsL1BridgeAddresses(i);
_installDepositEthToDrip(
faucetProxy,
l1BridgeAddress,
cfg.largeOpChainFaucetDripValue(),
cfg.largeOpChainFaucetDripInterval(),
_faucetDripName(l1BridgeAddress, cfg.dripVersion())
);
}
}
/// @notice installs the FaucetDripV1 drip on the faucet drippie contract.
function installFaucetDripV1() public broadcast {
Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
......@@ -378,12 +493,75 @@ contract DeployPeriphery is Deployer {
_activateIfPausedDrip(drippie, dripName);
}
function archivePreviousSmallOpChainFaucetsDrips() public {
Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
uint256 arrayLength = cfg.getSmallFaucetsL1BridgeAddressesCount();
for (uint256 i = 0; i < arrayLength; i++) {
address l1BridgeAddress = cfg.smallFaucetsL1BridgeAddresses(i);
_pauseIfActivatedDrip(drippie, _faucetDripName(l1BridgeAddress, cfg.previousDripVersion()));
_pauseIfActivatedDrip(drippie, _adminWalletDripName(l1BridgeAddress, cfg.previousDripVersion()));
_archiveIfPausedDrip(drippie, _faucetDripName(l1BridgeAddress, cfg.previousDripVersion()));
_archiveIfPausedDrip(drippie, _adminWalletDripName(l1BridgeAddress, cfg.previousDripVersion()));
}
}
function archivePreviousLargeOpChainFaucetsDrips() public {
Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
uint256 arrayLength = cfg.getLargeFaucetsL1BridgeAddressesCount();
for (uint256 i = 0; i < arrayLength; i++) {
address l1BridgeAddress = cfg.largeFaucetsL1BridgeAddresses(i);
_pauseIfActivatedDrip(drippie, _faucetDripName(l1BridgeAddress, cfg.previousDripVersion()));
_pauseIfActivatedDrip(drippie, _adminWalletDripName(l1BridgeAddress, cfg.previousDripVersion()));
_archiveIfPausedDrip(drippie, _faucetDripName(l1BridgeAddress, cfg.previousDripVersion()));
_archiveIfPausedDrip(drippie, _adminWalletDripName(l1BridgeAddress, cfg.previousDripVersion()));
}
}
function _activateIfPausedDrip(Drippie drippie, string memory dripName) internal {
require(
drippie.getDripStatus(dripName) == Drippie.DripStatus.ACTIVE
|| drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED,
"attempting to activate a drip that is not currently paused or activated"
);
if (drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED) {
console.log("%s is paused, activating", dripName);
drippie.status(dripName, Drippie.DripStatus.ACTIVE);
console.log("%s activated", dripName);
require(drippie.getDripStatus(dripName) == Drippie.DripStatus.ACTIVE);
} else {
console.log("%s already activated", dripName);
}
}
function _pauseIfActivatedDrip(Drippie drippie, string memory dripName) internal {
require(
drippie.getDripStatus(dripName) == Drippie.DripStatus.ACTIVE
|| drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED,
"attempting to pause a drip that is not currently paused or activated"
);
if (drippie.getDripStatus(dripName) == Drippie.DripStatus.ACTIVE) {
console.log("%s is active, pausing", dripName);
drippie.status(dripName, Drippie.DripStatus.PAUSED);
console.log("%s paused", dripName);
require(drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED);
} else {
console.log("%s already paused", dripName);
}
}
function _archiveIfPausedDrip(Drippie drippie, string memory dripName) internal {
require(
drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED
|| drippie.getDripStatus(dripName) == Drippie.DripStatus.ARCHIVED,
"attempting to archive a drip that is not currently paused or archived"
);
if (drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED) {
console.log("%s is paused, archiving", dripName);
drippie.status(dripName, Drippie.DripStatus.ARCHIVED);
console.log("%s archived", dripName);
require(drippie.getDripStatus(dripName) == Drippie.DripStatus.ARCHIVED);
} else {
console.log("%s already archived", dripName);
}
}
......@@ -493,4 +671,52 @@ contract DeployPeriphery is Deployer {
console.log("Faucet Auth Module configs successfully installed");
}
function _faucetDripName(address _l1Bridge, uint256 version) internal pure returns (string memory) {
string memory dripNamePrefixWithBridgeAddress = string.concat("faucet-drip-", vm.toString(_l1Bridge));
string memory versionSuffix = string.concat("-", vm.toString(version));
return string.concat(dripNamePrefixWithBridgeAddress, versionSuffix);
}
function _adminWalletDripName(address _l1Bridge, uint256 version) internal pure returns (string memory) {
string memory dripNamePrefixWithBridgeAddress = string.concat("faucet-admin-drip-", vm.toString(_l1Bridge));
string memory versionSuffix = string.concat("-", vm.toString(version));
return string.concat(dripNamePrefixWithBridgeAddress, versionSuffix);
}
function _installDepositEthToDrip(
address _depositTo,
address _l1Bridge,
uint256 _dripValue,
uint256 _dripInterval,
string memory dripName
)
internal
{
Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
if (drippie.getDripStatus(dripName) == Drippie.DripStatus.NONE) {
console.log("installing %s", dripName);
Drippie.DripAction[] memory actions = new Drippie.DripAction[](1);
actions[0] = Drippie.DripAction({
target: payable(_l1Bridge),
data: abi.encodeWithSignature("depositETHTo(address,uint32,bytes)", _depositTo, 200000, ""),
value: _dripValue
});
drippie.create({
_name: dripName,
_config: Drippie.DripConfig({
reentrant: false,
interval: _dripInterval,
dripcheck: CheckTrue(mustGetAddress("CheckTrue")),
checkparams: abi.encode(""),
actions: actions
})
});
console.log("%s installed successfully", dripName);
} else {
console.log("%s already installed.", dripName);
}
_activateIfPausedDrip(drippie, dripName);
}
}
......@@ -88,7 +88,10 @@ abstract contract Deployer is Script {
string memory chainIdPath = string.concat(deploymentsDir, "/.chainId");
try vm.readFile(chainIdPath) returns (string memory localChainId) {
if (vm.envOr("STRICT_DEPLOYMENT", true)) {
require(vm.parseUint(localChainId) == chainId, "Misconfigured networks");
require(
vm.parseUint(localChainId) == chainId,
string.concat("Misconfigured networks: ", localChainId, " != ", vm.toString(chainId))
);
}
} catch {
vm.writeFile(chainIdPath, vm.toString(chainId));
......@@ -281,7 +284,7 @@ abstract contract Deployer is Script {
}
/// @notice Returns the contract name from a deploy transaction.
function _getContractNameFromDeployTransaction(string memory _deployTx) internal returns (string memory) {
function _getContractNameFromDeployTransaction(string memory _deployTx) internal pure returns (string memory) {
return stdJson.readString(_deployTx, ".contractName");
}
......
......@@ -34,6 +34,25 @@ contract PeripheryDeployConfig is Script {
address public faucetOffchainAuthModuleAdmin;
uint256 public faucetOffchainAuthModuleTtl;
uint256 public faucetOffchainAuthModuleAmount;
bool public installOpChainFaucetsDrips;
bool public archivePreviousOpChainFaucetsDrips;
uint256 public smallOpChainFaucetDripValue;
uint256 public smallOpChainFaucetDripInterval;
uint256 public largeOpChainFaucetDripValue;
uint256 public largeOpChainFaucetDripInterval;
uint256 public opChainAdminWalletDripValue;
uint256 public opChainAdminWalletDripInterval;
address public opL1BridgeAddress;
address public baseL1BridgeAddress;
address public zoraL1BridgeAddress;
address public pgnL1BridgeAddress;
address public orderlyL1BridgeAddress;
address public modeL1BridgeAddress;
address public lyraL1BridgeAddress;
address[5] public smallFaucetsL1BridgeAddresses;
address[2] public largeFaucetsL1BridgeAddresses;
uint256 public dripVersion;
uint256 public previousDripVersion;
constructor(string memory _path) {
console.log("PeripheryDeployConfig: reading file %s", _path);
......@@ -66,5 +85,37 @@ contract PeripheryDeployConfig is Script {
faucetOffchainAuthModuleAdmin = stdJson.readAddress(_json, "$.faucetOffchainAuthModuleAdmin");
faucetOffchainAuthModuleTtl = stdJson.readUint(_json, "$.faucetOffchainAuthModuleTtl");
faucetOffchainAuthModuleAmount = stdJson.readUint(_json, "$.faucetOffchainAuthModuleAmount");
installOpChainFaucetsDrips = stdJson.readBool(_json, "$.installOpChainFaucetsDrips");
archivePreviousOpChainFaucetsDrips = stdJson.readBool(_json, "$.archivePreviousOpChainFaucetsDrips");
opL1BridgeAddress = stdJson.readAddress(_json, "$.opL1BridgeAddress");
baseL1BridgeAddress = stdJson.readAddress(_json, "$.baseL1BridgeAddress");
zoraL1BridgeAddress = stdJson.readAddress(_json, "$.zoraL1BridgeAddress");
pgnL1BridgeAddress = stdJson.readAddress(_json, "$.pgnL1BridgeAddress");
orderlyL1BridgeAddress = stdJson.readAddress(_json, "$.orderlyL1BridgeAddress");
modeL1BridgeAddress = stdJson.readAddress(_json, "$.modeL1BridgeAddress");
lyraL1BridgeAddress = stdJson.readAddress(_json, "$.lyraL1BridgeAddress");
dripVersion = stdJson.readUint(_json, "$.dripVersion");
previousDripVersion = stdJson.readUint(_json, "$.previousDripVersion");
smallOpChainFaucetDripValue = stdJson.readUint(_json, "$.smallOpChainFaucetDripValue");
smallOpChainFaucetDripInterval = stdJson.readUint(_json, "$.smallOpChainFaucetDripInterval");
largeOpChainFaucetDripValue = stdJson.readUint(_json, "$.largeOpChainFaucetDripValue");
largeOpChainFaucetDripInterval = stdJson.readUint(_json, "$.largeOpChainFaucetDripInterval");
opChainAdminWalletDripValue = stdJson.readUint(_json, "$.opChainAdminWalletDripValue");
opChainAdminWalletDripInterval = stdJson.readUint(_json, "$.opChainAdminWalletDripInterval");
largeFaucetsL1BridgeAddresses[0] = opL1BridgeAddress;
largeFaucetsL1BridgeAddresses[1] = baseL1BridgeAddress;
smallFaucetsL1BridgeAddresses[0] = zoraL1BridgeAddress;
smallFaucetsL1BridgeAddresses[1] = pgnL1BridgeAddress;
smallFaucetsL1BridgeAddresses[2] = orderlyL1BridgeAddress;
smallFaucetsL1BridgeAddresses[3] = modeL1BridgeAddress;
smallFaucetsL1BridgeAddresses[4] = lyraL1BridgeAddress;
}
function getSmallFaucetsL1BridgeAddressesCount() public view returns (uint256 count) {
return smallFaucetsL1BridgeAddresses.length;
}
function getLargeFaucetsL1BridgeAddressesCount() public view returns (uint256 count) {
return largeFaucetsL1BridgeAddresses.length;
}
}
#!/usr/bin/env bash
# This script is used to generate the getting-started.json configuration file
# used in the Getting Started quickstart guide on the docs site. Avoids the
# need to have the getting-started.json committed to the repo since it's an
# invalid JSON file when not filled in, which is annoying.
reqenv() {
if [ -z "${!1}" ]; then
echo "Error: environment variable '$1' is undefined"
exit 1
fi
}
# Check required environment variables
reqenv "GS_ADMIN_ADDRESS"
reqenv "GS_BATCHER_ADDRESS"
reqenv "GS_PROPOSER_ADDRESS"
reqenv "GS_SEQUENCER_ADDRESS"
reqenv "L1_RPC_URL"
# Get the finalized block timestamp and hash
block=$(cast block finalized --rpc-url $L1_RPC_URL)
timestamp=$(echo "$block" | awk '/timestamp/ { print $2 }')
blockhash=$(echo "$block" | awk '/hash/ { print $2 }')
# Generate the config file
config=$(cat << EOL
{
"finalSystemOwner": "ADMIN",
"portalGuardian": "ADMIN",
"finalSystemOwner": "$GS_ADMIN_ADDRESS",
"portalGuardian": "$GS_ADMIN_ADDRESS",
"l1StartingBlockTag": "BLOCKHASH",
"l1StartingBlockTag": "$blockhash",
"l1ChainID": 5,
"l1ChainID": 11155111,
"l2ChainID": 42069,
"l2BlockTime": 2,
"l1BlockTime": 12,
......@@ -13,23 +41,23 @@
"sequencerWindowSize": 3600,
"channelTimeout": 300,
"p2pSequencerAddress": "SEQUENCER",
"p2pSequencerAddress": "$GS_SEQUENCER_ADDRESS",
"batchInboxAddress": "0xff00000000000000000000000000000000042069",
"batchSenderAddress": "BATCHER",
"batchSenderAddress": "$GS_BATCHER_ADDRESS",
"l2OutputOracleSubmissionInterval": 120,
"l2OutputOracleStartingBlockNumber": 0,
"l2OutputOracleStartingTimestamp": TIMESTAMP,
"l2OutputOracleStartingTimestamp": $timestamp,
"l2OutputOracleProposer": "PROPOSER",
"l2OutputOracleChallenger": "ADMIN",
"l2OutputOracleProposer": "$GS_PROPOSER_ADDRESS",
"l2OutputOracleChallenger": "$GS_ADMIN_ADDRESS",
"finalizationPeriodSeconds": 12,
"proxyAdminOwner": "ADMIN",
"baseFeeVaultRecipient": "ADMIN",
"l1FeeVaultRecipient": "ADMIN",
"sequencerFeeVaultRecipient": "ADMIN",
"proxyAdminOwner": "$GS_ADMIN_ADDRESS",
"baseFeeVaultRecipient": "$GS_ADMIN_ADDRESS",
"l1FeeVaultRecipient": "$GS_ADMIN_ADDRESS",
"sequencerFeeVaultRecipient": "$GS_ADMIN_ADDRESS",
"baseFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000",
"l1FeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000",
......@@ -44,7 +72,7 @@
"enableGovernance": true,
"governanceTokenSymbol": "OP",
"governanceTokenName": "Optimism",
"governanceTokenOwner": "ADMIN",
"governanceTokenOwner": "$GS_ADMIN_ADDRESS",
"l2GenesisBlockGasLimit": "0x1c9c380",
"l2GenesisBlockBaseFeePerGas": "0x3b9aca00",
......@@ -59,3 +87,8 @@
"requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000",
"recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
EOL
)
# Write the config file
echo "$config" > deploy-config/getting-started.json
#!/usr/bin/env bash
# This script prints out the versions of the various tools used in the Getting
# Started quickstart guide on the docs site. Simplifies things for users so
# they can easily see if they're using the right versions of everything.
version() {
local string=$1
local version_regex='([0-9]+(\.[0-9]+)+)'
if [[ $string =~ $version_regex ]]; then
echo "${BASH_REMATCH[1]}"
else
echo "No version found."
fi
}
# Grab versions
ver_git=$(version "$(git --version)")
ver_go=$(version "$(go version)")
ver_node=$(version "$(node --version)")
ver_pnpm=$(version "$(pnpm --version)")
ver_foundry=$(version "$(forge --version)")
ver_make=$(version "$(make --version)")
ver_jq=$(version "$(jq --version)")
ver_direnv=$(version "$(direnv --version)")
# Print versions
echo "Dependency | Minimum | Actual"
echo "git 2 $ver_git"
echo "go 1.21 $ver_go"
echo "node 20 $ver_node"
echo "pnpm 8 $ver_pnpm"
echo "foundry 0.2.0 $ver_foundry"
echo "make 3 $ver_make"
echo "jq 1.6 $ver_jq"
echo "direnv 2 $ver_direnv"
#!/usr/bin/env bash
# This script is used to generate the four wallets that are used in the Getting
# Started quickstart guide on the docs site. Simplifies things for users
# slightly while also avoiding the need for users to manually copy/paste a
# bunch of stuff over to the environment file.
# Generate wallets
wallet1=$(cast wallet new)
wallet2=$(cast wallet new)
wallet3=$(cast wallet new)
wallet4=$(cast wallet new)
# Grab wallet addresses
address1=$(echo "$wallet1" | awk '/Address/ { print $2 }')
address2=$(echo "$wallet2" | awk '/Address/ { print $2 }')
address3=$(echo "$wallet3" | awk '/Address/ { print $2 }')
address4=$(echo "$wallet4" | awk '/Address/ { print $2 }')
# Grab wallet private keys
key1=$(echo "$wallet1" | awk '/Private key/ { print $3 }')
key2=$(echo "$wallet2" | awk '/Private key/ { print $3 }')
key3=$(echo "$wallet3" | awk '/Private key/ { print $3 }')
key4=$(echo "$wallet4" | awk '/Private key/ { print $3 }')
# Print out the environment variables to copy
echo "Copy the following into your .envrc file:"
echo
echo "# Admin account"
echo "export GS_ADMIN_ADDRESS=$address1"
echo "export GS_ADMIN_PRIVATE_KEY=$key1"
echo
echo "# Batcher account"
echo "export GS_BATCHER_ADDRESS=$address2"
echo "export GS_BATCHER_PRIVATE_KEY=$key2"
echo
echo "# Proposer account"
echo "export GS_PROPOSER_ADDRESS=$address3"
echo "export GS_PROPOSER_PRIVATE_KEY=$key3"
echo
echo "# Sequencer account"
echo "export GS_SEQUENCER_ADDRESS=$address4"
echo "export GS_SEQUENCER_PRIVATE_KEY=$key4"
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { console } from "forge-std/console.sol";
import { SafeBuilder } from "../universal/SafeBuilder.sol";
import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol";
import { IGnosisSafe, Enum } from "../interfaces/IGnosisSafe.sol";
import { LibSort } from "../libraries/LibSort.sol";
import { ProxyAdmin } from "src/universal/ProxyAdmin.sol";
import { Constants } from "src/libraries/Constants.sol";
import { SystemConfig } from "src/L1/SystemConfig.sol";
import { ResourceMetering } from "src/L1/ResourceMetering.sol";
import { DeployConfig } from "scripts/DeployConfig.s.sol";
import { SystemConfig } from "src/L1/SystemConfig.sol";
import { L1StandardBridge } from "src/L1/L1StandardBridge.sol";
import { L2OutputOracle } from "src/L1/L2OutputOracle.sol";
import { OptimismPortal } from "src/L1/OptimismPortal.sol";
import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol";
import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol";
import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol";
import { Predeploys } from "src/libraries/Predeploys.sol";
/// @title Multichain
/// @notice Upgrade script for upgrading the L1 contracts after the multichain upgrade.
/// This upgrade involves all of the contracts having the same implementations.
/// The implementation addresses are known ahead of time.
/// Configure the network using the `NETWORK` env var, the options are:
/// `goerli-prod`, `chaosnet` and `devnet`.
contract Multichain is SafeBuilder {
/// @notice Address of the ProxyAdmin, passed in via constructor of `run`.
ProxyAdmin internal PROXY_ADMIN;
/// @notice An instance of the deployconfig contract, the NETWORK env var determines
/// which file is read from disk to populate this contract.
DeployConfig internal cfg;
/// @notice Represents a set of L1 contracts. Used to represent a set of proxies.
struct ContractSet {
address L1CrossDomainMessenger;
address L1StandardBridge;
address L2OutputOracle;
address OptimismMintableERC20Factory;
address OptimismPortal;
address SystemConfig;
address L1ERC721Bridge;
}
/// @notice Possible value of NETWORK env var, for goerli
string internal constant GOERLI_PROD = "goerli-prod";
/// @notice Possible value of NETWORK env var, for chaosnet
string internal constant CHAOSNET = "chaosnet";
/// @notice Possible value of NETWORK env var, for devnet
string internal constant DEVNET = "devnet";
/// @notice Digest of goerli-prod for comparison purposes
bytes32 internal goerli = keccak256(bytes(GOERLI_PROD));
/// @notice Digest of chaosnet for comparison purposes
bytes32 internal chaosnet = keccak256(bytes(CHAOSNET));
/// @notice Digest of devnet for comparison purposes
bytes32 internal devnet = keccak256(bytes(DEVNET));
/// @notice L1CrossDomainMessenger implementation to upgrade to
address internal constant L1CrossDomainMessengerImplementation = 0xb5df97bB67f5AA7254d40E1B7034bBFF7F183a38;
/// @notice L1StandardBridge implementation to upgrade to
address internal constant L1StandardBridgeImplementation = 0xd9aA10f75a2a93Bfc73AaDD41ae777e900CEdBc9;
/// @notice L2OutputOracle implementation to upgrade to
address internal constant L2OutputOracleImplementation = 0xaBd96C062c6B640d5670455E9d1cD98383Dd23CA;
/// @notice OptimismMintableERC20Factory to upgrade to
address internal constant OptimismMintableERC20FactoryImplementation = 0xdfe97868233d1aa22e815a266982f2cf17685a27;
/// @notice OptimismPortal implementation to upgrade to
address internal constant OptimismPortalImplementation = 0x345D27c7B6C90fef5beA9631037C36119f4bF93e;
/// @notice SystemConfig implementation to upgrade to
address internal constant SystemConfigImplementation = 0x543bA4AADBAb8f9025686Bd03993043599c6fB04;
/// @notice L1ERC721Bridge implementation to upgrade to
address internal constant L1ERC721BridgeImplementation = 0x53C115eD8D9902f4999fDBd8B93Ea79BF37cb588;
/// @notice A mapping of deployment name to ContractSet of proxy addresses.
ContractSet internal proxies;
/// @notice The expected versions for the contracts to be upgraded to.
string internal constant L1CrossDomainMessengerVersion = "1.5.1";
string internal constant L1StandardBridgeVersion = "1.2.1";
string internal constant L2OutputOracleVersion = "1.4.1";
string internal constant OptimismMintableERC20FactoryVersion = "1.3.0";
string internal constant OptimismPortalVersion = "1.8.1";
string internal constant SystemConfigVersion = "1.6.0";
string internal constant L1ERC721BridgeVersion = "1.2.1";
/// @notice The value of the NETWORK env var
string internal NETWORK;
// @notice Cache a non view function call to the SystemConfig contract
uint256 internal l2OutputOracleStartingTimestamp;
/// @notice Place the contract addresses in storage so they can be used when building calldata.
function setUp() external {
// Set the network in storage
NETWORK = vm.envOr("NETWORK", GOERLI_PROD);
// TODO: hack
PROXY_ADMIN = ProxyAdmin(vm.envOr("PROXY_ADMIN", 0x01d3670863c3F4b24D7b107900f0b75d4BbC6e0d));
// For simple comparisons of dynamic types
bytes32 network = keccak256(bytes(NETWORK));
string memory deployConfigPath;
if (network == goerli) {
console.log("Using goerli-prod");
deployConfigPath = string.concat(vm.projectRoot(), "/deploy-config/goerli.json");
proxies = ContractSet({
L1CrossDomainMessenger: 0x5086d1eEF304eb5284A0f6720f79403b4e9bE294,
L1StandardBridge: 0x636Af16bf2f682dD3109e60102b8E1A089FedAa8,
L2OutputOracle: 0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0,
OptimismMintableERC20Factory: 0x883dcF8B05364083D849D8bD226bC8Cb4c42F9C5,
OptimismPortal: 0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383,
SystemConfig: 0xAe851f927Ee40dE99aaBb7461C00f9622ab91d60,
L1ERC721Bridge: 0x8DD330DdE8D9898d43b4dc840Da27A07dF91b3c9
});
} else if (network == chaosnet) {
console.log("Using chaosnet");
deployConfigPath = string.concat(vm.projectRoot(), "/deploy-config/chaosnet.json");
proxies = ContractSet({
L1CrossDomainMessenger: 0xfc428D28D197fFf99A5EbAc6be8B761FEd8718Da,
L1StandardBridge: 0x60859421Ed85C0B11071230cf61dcEeEf54630Ff,
L2OutputOracle: 0x7D00A03f180d8C07B88d8c1384a15326c38FF9Ff,
OptimismMintableERC20Factory: 0x526920419b61153c1F80fD306B5Ab52b69110A6C,
OptimismPortal: 0x1566c8Eea4A255C07Ef58edF91431c8A73ae0B62,
SystemConfig: 0xf2Fa3621cAa534a2AE9Eb36667da57890E5C9E6a,
L1ERC721Bridge: 0x058BBf091232afE99BC2481F809254cD15e64Df5
});
} else if (network == devnet) {
console.log("Using devnet");
deployConfigPath = string.concat(vm.projectRoot(), "/deploy-config/internal-devnet.json");
proxies = ContractSet({
L1CrossDomainMessenger: 0x71A046D793C71af209960DCb8bD5388d2c5D2a78,
L1StandardBridge: 0x791590936abB3531c9d54CD10CEC4B14415B0Ba7,
L2OutputOracle: 0xA57B9f15AA204b9D68DF58849b02Df16c80C0999,
OptimismMintableERC20Factory: 0x2998dDaF6AaA00Fa8A7104214688d29Bc749B78F,
OptimismPortal: 0x83a242F8481D4F8a605Aa82BA9D42BA574054258,
SystemConfig: 0x9673B370b773D9FFc4C282B3aF315ab05f17E20C,
L1ERC721Bridge: 0x60e0f047FfA2Fad2AF197c9CDb404bDF47277Ed4
});
} else {
revert("Invalid network");
}
cfg = new DeployConfig(deployConfigPath);
// cache the starting timestamp here as to not break the view functions below
l2OutputOracleStartingTimestamp = cfg.l2OutputOracleStartingTimestamp();
}
/// @notice Follow up assertions to ensure that the script ran to completion.
function _postCheck() internal view override {
ContractSet memory prox = getProxies();
require(
_versionHash(prox.L1CrossDomainMessenger) == keccak256(bytes(L1CrossDomainMessengerVersion)),
"L1CrossDomainMessenger"
);
require(_versionHash(prox.L1StandardBridge) == keccak256(bytes(L1StandardBridgeVersion)), "L1StandardBridge");
require(_versionHash(prox.L2OutputOracle) == keccak256(bytes(L2OutputOracleVersion)), "L2OutputOracle");
require(
_versionHash(prox.OptimismMintableERC20Factory) == keccak256(bytes(OptimismMintableERC20FactoryVersion)),
"OptimismMintableERC20Factory"
);
require(_versionHash(prox.OptimismPortal) == keccak256(bytes(OptimismPortalVersion)), "OptimismPortal");
require(_versionHash(prox.SystemConfig) == keccak256(bytes(SystemConfigVersion)), "SystemConfig");
require(_versionHash(prox.L1ERC721Bridge) == keccak256(bytes(L1ERC721BridgeVersion)), "L1ERC721Bridge");
ResourceMetering.ResourceConfig memory rcfg = SystemConfig(prox.SystemConfig).resourceConfig();
ResourceMetering.ResourceConfig memory dflt = Constants.DEFAULT_RESOURCE_CONFIG();
require(keccak256(abi.encode(rcfg)) == keccak256(abi.encode(dflt)));
// Check that the codehashes of all implementations match the proxies set implementations.
require(
PROXY_ADMIN.getProxyImplementation(prox.L1CrossDomainMessenger).codehash
== L1CrossDomainMessengerImplementation.codehash,
"L1CrossDomainMessenger codehash"
);
require(
PROXY_ADMIN.getProxyImplementation(prox.L1StandardBridge).codehash
== L1StandardBridgeImplementation.codehash,
"L1StandardBridge codehash"
);
require(
PROXY_ADMIN.getProxyImplementation(prox.L2OutputOracle).codehash == L2OutputOracleImplementation.codehash,
"L2OutputOracle codehash"
);
require(
PROXY_ADMIN.getProxyImplementation(prox.OptimismMintableERC20Factory).codehash
== OptimismMintableERC20FactoryImplementation.codehash,
"OptimismMintableERC20Factory codehash"
);
require(
PROXY_ADMIN.getProxyImplementation(prox.OptimismPortal).codehash == OptimismPortalImplementation.codehash,
"OptimismPortal codehash"
);
require(
PROXY_ADMIN.getProxyImplementation(prox.SystemConfig).codehash == SystemConfigImplementation.codehash,
"SystemConfig codehash"
);
require(
PROXY_ADMIN.getProxyImplementation(prox.L1ERC721Bridge).codehash == L1ERC721BridgeImplementation.codehash,
"L1ERC721Bridge codehash"
);
_postCheckSystemConfig();
_postCheckL1CrossDomainMessenger();
_postCheckL1StandardBridge();
_postCheckL2OutputOracle();
_postCheckOptimismMintableERC20Factory();
_postCheckL1ERC721Bridge();
_postCheckOptimismPortal();
}
/// @notice Post check hook for the system config
function _postCheckSystemConfig() internal view {
SystemConfig config = SystemConfig(proxies.SystemConfig);
require(config.owner() == cfg.finalSystemOwner());
require(config.overhead() == cfg.gasPriceOracleOverhead());
require(config.scalar() == cfg.gasPriceOracleScalar());
require(config.unsafeBlockSigner() == cfg.p2pSequencerAddress());
require(config.batcherHash() == bytes32(uint256(uint160(cfg.batchSenderAddress()))));
ResourceMetering.ResourceConfig memory rconfig = Constants.DEFAULT_RESOURCE_CONFIG();
ResourceMetering.ResourceConfig memory resourceConfig = config.resourceConfig();
require(resourceConfig.maxResourceLimit == rconfig.maxResourceLimit);
require(resourceConfig.elasticityMultiplier == rconfig.elasticityMultiplier);
require(resourceConfig.baseFeeMaxChangeDenominator == rconfig.baseFeeMaxChangeDenominator);
require(resourceConfig.systemTxMaxGas == rconfig.systemTxMaxGas);
require(resourceConfig.minimumBaseFee == rconfig.minimumBaseFee);
require(resourceConfig.maximumBaseFee == rconfig.maximumBaseFee);
require(config.l1ERC721Bridge() == proxies.L1ERC721Bridge);
require(config.l1StandardBridge() == proxies.L1StandardBridge);
require(config.l2OutputOracle() == proxies.L2OutputOracle);
require(config.optimismPortal() == proxies.OptimismPortal);
require(config.l1CrossDomainMessenger() == proxies.L1CrossDomainMessenger);
// A non zero start block is an override
uint256 startBlock = cfg.systemConfigStartBlock();
if (startBlock != 0) {
require(config.startBlock() == startBlock);
} else {
require(config.startBlock() == block.number);
}
}
/// @notice Post check hook for the L1CrossDomainMessenger
function _postCheckL1CrossDomainMessenger() internal view {
L1CrossDomainMessenger messenger = L1CrossDomainMessenger(proxies.L1CrossDomainMessenger);
require(address(messenger.portal()) == proxies.OptimismPortal);
}
/// @notice Post check hook for the L1StandardBridge
function _postCheckL1StandardBridge() internal view {
L1StandardBridge bridge = L1StandardBridge(payable(proxies.L1StandardBridge));
require(address(bridge.MESSENGER()) == proxies.L1CrossDomainMessenger);
require(address(bridge.messenger()) == proxies.L1CrossDomainMessenger);
require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_STANDARD_BRIDGE);
require(address(bridge.otherBridge()) == Predeploys.L2_STANDARD_BRIDGE);
// Ensures that the legacy slot is modified correctly. This will fail
// during predeployment simulation on OP Mainnet if there is a bug.
bytes32 slot0 = vm.load(address(bridge), bytes32(uint256(0)));
require(slot0 == bytes32(uint256(2)));
}
/// @notice Post check hook for the L2OutputOracle
function _postCheckL2OutputOracle() internal view {
L2OutputOracle oracle = L2OutputOracle(proxies.L2OutputOracle);
require(oracle.SUBMISSION_INTERVAL() == cfg.l2OutputOracleSubmissionInterval());
require(oracle.submissionInterval() == cfg.l2OutputOracleSubmissionInterval());
require(oracle.L2_BLOCK_TIME() == cfg.l2BlockTime());
require(oracle.l2BlockTime() == cfg.l2BlockTime());
require(oracle.PROPOSER() == cfg.l2OutputOracleProposer());
require(oracle.proposer() == cfg.l2OutputOracleProposer());
require(oracle.CHALLENGER() == cfg.l2OutputOracleChallenger());
require(oracle.challenger() == cfg.l2OutputOracleChallenger());
require(oracle.FINALIZATION_PERIOD_SECONDS() == cfg.finalizationPeriodSeconds());
require(oracle.finalizationPeriodSeconds() == cfg.finalizationPeriodSeconds());
require(oracle.startingBlockNumber() == cfg.l2OutputOracleStartingBlockNumber());
require(oracle.startingTimestamp() == l2OutputOracleStartingTimestamp);
}
/// @notice Post check hook for the OptimismMintableERC20Factory
function _postCheckOptimismMintableERC20Factory() internal view {
OptimismMintableERC20Factory factory = OptimismMintableERC20Factory(proxies.OptimismMintableERC20Factory);
require(factory.BRIDGE() == proxies.L1StandardBridge);
}
/// @notice Post check hook for the L1ERC721Bridge
function _postCheckL1ERC721Bridge() internal view {
L1ERC721Bridge bridge = L1ERC721Bridge(proxies.L1ERC721Bridge);
require(address(bridge.MESSENGER()) == proxies.L1CrossDomainMessenger);
require(bridge.OTHER_BRIDGE() == Predeploys.L2_ERC721_BRIDGE);
}
/// @notice Post check hook for the OptimismPortal
function _postCheckOptimismPortal() internal view {
OptimismPortal portal = OptimismPortal(payable(proxies.OptimismPortal));
require(address(portal.L2_ORACLE()) == proxies.L2OutputOracle);
require(portal.GUARDIAN() == cfg.portalGuardian());
require(address(portal.SYSTEM_CONFIG()) == proxies.SystemConfig);
require(portal.paused() == false);
}
/// @notice Test coverage of the logic. Should only run on goerli but other chains
/// could be added.
function test_script_succeeds() external skipWhenNotForking {
address _safe;
address _proxyAdmin;
if (block.chainid == GOERLI) {
_safe = 0xBc1233d0C3e6B5d53Ab455cF65A6623F6dCd7e4f;
_proxyAdmin = 0x01d3670863c3F4b24D7b107900f0b75d4BbC6e0d;
// Set the proxy admin for the `_postCheck` function
PROXY_ADMIN = ProxyAdmin(_proxyAdmin);
}
require(_safe != address(0) && _proxyAdmin != address(0));
address[] memory owners = IGnosisSafe(payable(_safe)).getOwners();
for (uint256 i; i < owners.length; i++) {
address owner = owners[i];
vm.startBroadcast(owner);
bool success = _run(_safe, _proxyAdmin);
vm.stopBroadcast();
if (success) {
console.log("tx success");
break;
}
}
_postCheck();
}
/// @notice Builds the calldata that the multisig needs to make for the upgrade to happen.
/// A total of 8 calls are made, 7 upgrade implementations and 1 sets the resource
/// config to the default value in the SystemConfig contract.
function buildCalldata(address _proxyAdmin) internal view override returns (bytes memory) {
IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](7);
ContractSet memory prox = getProxies();
// Upgrade the L1CrossDomainMessenger
calls[0] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgradeAndCall,
(
payable(prox.L1CrossDomainMessenger), // proxy
L1CrossDomainMessengerImplementation, // implementation
abi.encodeCall( // data
L1CrossDomainMessenger.initialize, (OptimismPortal(payable(prox.OptimismPortal))))
)
)
});
// Upgrade the L1StandardBridge
calls[1] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgradeAndCall,
(
payable(prox.L1StandardBridge), // proxy
L1StandardBridgeImplementation, // implementation
abi.encodeCall(L1StandardBridge.initialize, (L1CrossDomainMessenger(prox.L1CrossDomainMessenger))) // data
)
)
});
// Upgrade the L2OutputOracle
calls[2] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgradeAndCall,
(
payable(prox.L2OutputOracle), // proxy
L2OutputOracleImplementation, // implementation
abi.encodeCall( // data
L2OutputOracle.initialize,
(
cfg.l2OutputOracleStartingBlockNumber(),
l2OutputOracleStartingTimestamp,
cfg.l2OutputOracleProposer(),
cfg.l2OutputOracleChallenger()
)
)
)
)
});
// Upgrade the OptimismMintableERC20Factory. No initialize function.
calls[3] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgradeAndCall,
(
payable(prox.OptimismMintableERC20Factory), // proxy
OptimismMintableERC20FactoryImplementation, // implementation
abi.encodeCall( // data
OptimismMintableERC20Factory.initialize, (prox.L1StandardBridge))
)
)
});
// Upgrade the OptimismPortal
calls[4] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgradeAndCall,
(
payable(prox.OptimismPortal), // proxy
OptimismPortalImplementation, // implementation
abi.encodeCall( // data
OptimismPortal.initialize,
(
L2OutputOracle(prox.L2OutputOracle),
cfg.portalGuardian(),
SystemConfig(prox.SystemConfig),
false
)
)
)
)
});
// Upgrade the SystemConfig
calls[5] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgradeAndCall,
(
payable(prox.SystemConfig), // proxy
SystemConfigImplementation, // implementation
abi.encodeCall( // data
SystemConfig.initialize,
(
cfg.finalSystemOwner(),
cfg.gasPriceOracleOverhead(),
cfg.gasPriceOracleScalar(),
bytes32(uint256(uint160(cfg.batchSenderAddress()))),
uint64(cfg.l2GenesisBlockGasLimit()),
cfg.p2pSequencerAddress(),
Constants.DEFAULT_RESOURCE_CONFIG(),
cfg.systemConfigStartBlock(),
cfg.batchInboxAddress(),
SystemConfig.Addresses({
l1CrossDomainMessenger: prox.L1CrossDomainMessenger,
l1ERC721Bridge: prox.L1ERC721Bridge,
l1StandardBridge: prox.L1StandardBridge,
l2OutputOracle: prox.L2OutputOracle,
optimismPortal: prox.OptimismPortal,
optimismMintableERC20Factory: prox.OptimismMintableERC20Factory
})
)
)
)
)
});
// Upgrade the L1ERC721Bridge
calls[6] = IMulticall3.Call3({
target: _proxyAdmin,
allowFailure: false,
callData: abi.encodeCall(
ProxyAdmin.upgradeAndCall,
(
payable(prox.L1ERC721Bridge),
L1ERC721BridgeImplementation,
abi.encodeCall(L1ERC721Bridge.initialize, (L1CrossDomainMessenger(prox.L1CrossDomainMessenger)))
)
)
});
return abi.encodeCall(IMulticall3.aggregate3, (calls));
}
/// @notice Returns the ContractSet that represents the proxies for a given network.
/// Configure the network with the NETWORK env var.
function getProxies() internal view returns (ContractSet memory) {
require(proxies.L1CrossDomainMessenger != address(0), "no proxies for this network");
return proxies;
}
}
{
"src/EAS/EAS.sol": "0xe5e9700b94a88a2e1baabe4bfa66d5c1c94e811bcc5d2c64526afc649df59118",
"src/EAS/EAS.sol": "0x850a0eb089d5a01f489c7239f5b9a1b09120afb1bc80239268215c2dfe1de26c",
"src/EAS/SchemaRegistry.sol": "0x5ee1a0c3b2bf1eb5edb53fb0967cf13856be546f0f16fe7acdc3e4f286db6831",
"src/L1/DelayedVetoable.sol": "0x276c6276292095e6aa37a70008cf4e0d1cbcc020dbc9107459bbc72ab5ed744f",
"src/L1/L1CrossDomainMessenger.sol": "0x2aa4e06827bc48484212eb2bdc30fd604ffd23b37e401b78ef428c12fa9b8385",
......
......@@ -80,11 +80,11 @@ contract EAS is IEAS, ISemver, EIP1271Verifier {
uint256[MAX_GAP - 3] private __gap;
/// @notice Semantic version.
/// @custom:semver 1.3.0
string public constant version = "1.3.0";
/// @custom:semver 1.4.0
string public constant version = "1.4.0";
/// @dev Creates a new EAS instance.
constructor() EIP1271Verifier("EAS", "1.2.0") { }
constructor() EIP1271Verifier("EAS", "1.3.0") { }
/// @inheritdoc IEAS
function getSchemaRegistry() external pure returns (ISchemaRegistry) {
......
......@@ -30,13 +30,13 @@ abstract contract EIP1271Verifier is EIP712 {
error InvalidNonce();
// The hash of the data type used to relay calls to the attest function. It's the value of
// keccak256("Attest(bytes32 schema,address recipient,uint64 expirationTime,bool revocable,bytes32 refUID,bytes
// data,uint256 value,uint256 nonce,uint64 deadline)").
bytes32 private constant ATTEST_TYPEHASH = 0xf83bb2b0ede93a840239f7e701a54d9bc35f03701f51ae153d601c6947ff3d3f;
// keccak256("Attest(address attester,bytes32 schema,address recipient,uint64 expirationTime,bool revocable,bytes32
// refUID,bytes data,uint256 value,uint256 nonce,uint64 deadline)").
bytes32 private constant ATTEST_TYPEHASH = 0xfeb2925a02bae3dae48d424a0437a2b6ac939aa9230ddc55a1a76f065d988076;
// The hash of the data type used to relay calls to the revoke function. It's the value of
// keccak256("Revoke(bytes32 schema,bytes32 uid,uint256 value,uint256 nonce,uint64 deadline)").
bytes32 private constant REVOKE_TYPEHASH = 0x2d4116d8c9824e4c316453e5c2843a1885580374159ce8768603c49085ef424c;
// keccak256("Revoke(address revoker,bytes32 schema,bytes32 uid,uint256 value,uint256 nonce,uint64 deadline)").
bytes32 private constant REVOKE_TYPEHASH = 0xb5d556f07587ec0f08cf386545cc4362c702a001650c2058002615ee5c9d1e75;
// The user readable name of the signing domain.
bytes32 private immutable _name;
......@@ -116,6 +116,7 @@ abstract contract EIP1271Verifier is EIP712 {
keccak256(
abi.encode(
ATTEST_TYPEHASH,
request.attester,
request.schema,
data.recipient,
data.expirationTime,
......@@ -150,7 +151,13 @@ abstract contract EIP1271Verifier is EIP712 {
bytes32 hash = _hashTypedDataV4(
keccak256(
abi.encode(
REVOKE_TYPEHASH, request.schema, data.uid, data.value, _nonces[request.revoker]++, request.deadline
REVOKE_TYPEHASH,
request.revoker,
request.schema,
data.uid,
data.value,
_nonces[request.revoker]++,
request.deadline
)
)
);
......
......@@ -13,7 +13,7 @@ contract SafeCall_Test is Test {
vm.assume(from.balance == 0);
vm.assume(to.balance == 0);
// no precompiles (mainnet)
assumeNoPrecompiles(to, 1);
assumeNotPrecompile(to);
// don't call the vm
vm.assume(to != address(vm));
vm.assume(from != address(vm));
......@@ -47,7 +47,7 @@ contract SafeCall_Test is Test {
vm.assume(from.balance == 0);
vm.assume(to.balance == 0);
// no precompiles (mainnet)
assumeNoPrecompiles(to, 1);
assumeNotPrecompile(to);
// don't call the vm
vm.assume(to != address(vm));
vm.assume(from != address(vm));
......@@ -89,7 +89,7 @@ contract SafeCall_Test is Test {
vm.assume(from.balance == 0);
vm.assume(to.balance == 0);
// no precompiles (mainnet)
assumeNoPrecompiles(to, 1);
assumeNotPrecompile(to);
// don't call the vm
vm.assume(to != address(vm));
vm.assume(from != address(vm));
......
......@@ -8,11 +8,6 @@ import { ResourceMetering } from "src/L1/ResourceMetering.sol";
import { Constants } from "src/libraries/Constants.sol";
contract SystemConfig_GasLimitLowerBound_Invariant is Test {
struct FuzzInterface {
address target;
string[] artifacts;
}
SystemConfig public config;
function setUp() external {
......@@ -59,19 +54,14 @@ contract SystemConfig_GasLimitLowerBound_Invariant is Test {
selectors[0] = config.setGasLimit.selector;
FuzzSelector memory selector = FuzzSelector({ addr: address(config), selectors: selectors });
targetSelector(selector);
}
/// @dev Allows the SystemConfig contract to be the target of the invariant test
/// Allows the SystemConfig contract to be the target of the invariant test
/// when it is behind a proxy. Foundry calls this function under the hood to
/// know the ABI to use when calling the target contract.
function targetInterfaces() public view returns (FuzzInterface[] memory) {
require(address(config) != address(0), "SystemConfig not initialized");
FuzzInterface[] memory targets = new FuzzInterface[](1);
string[] memory artifacts = new string[](1);
artifacts[0] = "SystemConfig";
targets[0] = FuzzInterface(address(config), artifacts);
return targets;
FuzzInterface memory target = FuzzInterface(address(config), artifacts);
targetInterface(target);
}
/// @custom:invariant The gas limit of the `SystemConfig` contract can never be lower
......
......@@ -82,6 +82,6 @@
"change-case": "4.1.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"viem": "^1.18.4"
"viem": "^1.18.6"
}
}
......@@ -44,7 +44,7 @@
"jsdom": "^22.1.0",
"tsup": "^7.2.0",
"typescript": "^5.2.2",
"viem": "^1.18.4",
"viem": "^1.18.6",
"vite": "^4.5.0",
"vitest": "^0.34.2"
},
......
......@@ -56,7 +56,7 @@
"ts-node": "^10.9.1",
"typedoc": "^0.25.3",
"typescript": "^5.2.2",
"viem": "^1.18.4",
"viem": "^1.18.6",
"vitest": "^0.34.2",
"zod": "^3.22.4"
},
......
......@@ -37,7 +37,7 @@
"@vitest/coverage-istanbul": "^0.34.6",
"tsup": "^7.2.0",
"typescript": "^5.2.2",
"viem": "^1.18.4",
"viem": "^1.18.6",
"vite": "^4.5.0",
"vitest": "^0.34.1",
"zod": "^3.22.4"
......
......@@ -17,7 +17,7 @@ importers:
devDependencies:
'@babel/eslint-parser':
specifier: ^7.18.2
version: 7.22.15(@babel/core@7.22.10)(eslint@8.52.0)
version: 7.22.15(@babel/core@7.22.10)(eslint@8.53.0)
'@changesets/changelog-github':
specifier: ^0.4.8
version: 0.4.8
......@@ -35,10 +35,10 @@ importers:
version: 20.8.9
'@typescript-eslint/eslint-plugin':
specifier: ^6.9.1
version: 6.9.1(@typescript-eslint/parser@6.9.1)(eslint@8.52.0)(typescript@5.2.2)
version: 6.9.1(@typescript-eslint/parser@6.9.1)(eslint@8.53.0)(typescript@5.2.2)
'@typescript-eslint/parser':
specifier: ^6.9.1
version: 6.9.1(eslint@8.52.0)(typescript@5.2.2)
version: 6.9.1(eslint@8.53.0)(typescript@5.2.2)
chai:
specifier: ^4.3.10
version: 4.3.10
......@@ -49,38 +49,38 @@ importers:
specifier: ^2.2.0
version: 2.2.1
eslint:
specifier: ^8.52.0
version: 8.52.0
specifier: ^8.53.0
version: 8.53.0
eslint-config-prettier:
specifier: ^8.3.0
version: 8.3.0(eslint@8.52.0)
version: 8.3.0(eslint@8.53.0)
eslint-config-standard:
specifier: ^16.0.3
version: 16.0.3(eslint-plugin-import@2.29.0)(eslint-plugin-node@11.1.0)(eslint-plugin-promise@5.2.0)(eslint@8.52.0)
version: 16.0.3(eslint-plugin-import@2.29.0)(eslint-plugin-node@11.1.0)(eslint-plugin-promise@5.2.0)(eslint@8.53.0)
eslint-plugin-import:
specifier: ^2.29.0
version: 2.29.0(@typescript-eslint/parser@6.9.1)(eslint@8.52.0)
version: 2.29.0(@typescript-eslint/parser@6.9.1)(eslint@8.53.0)
eslint-plugin-jsdoc:
specifier: ^35.1.2
version: 35.5.1(eslint@8.52.0)
version: 35.5.1(eslint@8.53.0)
eslint-plugin-node:
specifier: ^11.1.0
version: 11.1.0(eslint@8.52.0)
version: 11.1.0(eslint@8.53.0)
eslint-plugin-prefer-arrow:
specifier: ^1.2.3
version: 1.2.3(eslint@8.52.0)
version: 1.2.3(eslint@8.53.0)
eslint-plugin-prettier:
specifier: ^4.0.0
version: 4.2.1(eslint-config-prettier@8.3.0)(eslint@8.52.0)(prettier@2.8.8)
version: 4.2.1(eslint-config-prettier@8.3.0)(eslint@8.53.0)(prettier@2.8.8)
eslint-plugin-promise:
specifier: ^5.1.0
version: 5.2.0(eslint@8.52.0)
version: 5.2.0(eslint@8.53.0)
eslint-plugin-react:
specifier: ^7.24.0
version: 7.33.2(eslint@8.52.0)
version: 7.33.2(eslint@8.53.0)
eslint-plugin-unicorn:
specifier: ^49.0.0
version: 49.0.0(eslint@8.52.0)
version: 49.0.0(eslint@8.53.0)
husky:
specifier: ^8.0.3
version: 8.0.3
......@@ -97,8 +97,8 @@ importers:
specifier: ^10.2.0
version: 10.2.0
nx:
specifier: 17.0.2
version: 17.0.2
specifier: 17.0.3
version: 17.0.3
nx-cloud:
specifier: latest
version: 16.5.2
......@@ -298,11 +298,11 @@ importers:
specifier: ^18.2.0
version: 18.2.0(react@18.2.0)
viem:
specifier: ^1.18.4
version: 1.18.4(typescript@5.2.2)(zod@3.22.4)
specifier: ^1.18.6
version: 1.18.6(typescript@5.2.2)(zod@3.22.4)
wagmi:
specifier: '>1.0.0'
version: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.4)
version: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.6)
devDependencies:
'@eth-optimism/contracts-bedrock':
specifier: workspace:*
......@@ -324,7 +324,7 @@ importers:
version: 1.5.2(@wagmi/core@1.4.5)(typescript@5.2.2)(wagmi@1.0.1)
'@wagmi/core':
specifier: ^1.4.5
version: 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.4)
version: 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.6)
abitype:
specifier: ^0.10.2
version: 0.10.2(typescript@5.2.2)
......@@ -438,8 +438,8 @@ importers:
specifier: ^5.2.2
version: 5.2.2
viem:
specifier: ^1.18.4
version: 1.18.4(typescript@5.2.2)(zod@3.22.4)
specifier: ^1.18.6
version: 1.18.6(typescript@5.2.2)(zod@3.22.4)
vite:
specifier: ^4.5.0
version: 4.5.0(@types/node@20.8.9)
......@@ -529,8 +529,8 @@ importers:
specifier: ^5.2.2
version: 5.2.2
viem:
specifier: ^1.18.4
version: 1.18.4(typescript@5.2.2)(zod@3.22.4)
specifier: ^1.18.6
version: 1.18.6(typescript@5.2.2)(zod@3.22.4)
vitest:
specifier: ^0.34.2
version: 0.34.2
......@@ -569,8 +569,8 @@ importers:
specifier: ^5.2.2
version: 5.2.2
viem:
specifier: ^1.18.4
version: 1.18.4(typescript@5.2.2)(zod@3.22.4)
specifier: ^1.18.6
version: 1.18.6(typescript@5.2.2)(zod@3.22.4)
vite:
specifier: ^4.5.0
version: 4.5.0(@types/node@20.8.9)
......@@ -638,7 +638,7 @@ packages:
- supports-color
dev: true
/@babel/eslint-parser@7.22.15(@babel/core@7.22.10)(eslint@8.52.0):
/@babel/eslint-parser@7.22.15(@babel/core@7.22.10)(eslint@8.53.0):
resolution: {integrity: sha512-yc8OOBIQk1EcRrpizuARSQS0TWAcOMpEJ1aafhNznaeYkeL+OhqnDObGFylB8ka8VFF/sZc+S4RzHyO+3LjQxg==}
engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0}
peerDependencies:
......@@ -647,7 +647,7 @@ packages:
dependencies:
'@babel/core': 7.22.10
'@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1
eslint: 8.52.0
eslint: 8.53.0
eslint-visitor-keys: 2.1.0
semver: 6.3.1
dev: true
......@@ -1811,6 +1811,16 @@ packages:
eslint-visitor-keys: 3.4.3
dev: true
/@eslint-community/eslint-utils@4.4.0(eslint@8.53.0):
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
dependencies:
eslint: 8.53.0
eslint-visitor-keys: 3.4.3
dev: true
/@eslint-community/regexpp@4.6.2:
resolution: {integrity: sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==}
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
......@@ -1833,11 +1843,33 @@ packages:
- supports-color
dev: true
/@eslint/eslintrc@2.1.3:
resolution: {integrity: sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
ajv: 6.12.6
debug: 4.3.4(supports-color@8.1.1)
espree: 9.6.1
globals: 13.21.0
ignore: 5.2.4
import-fresh: 3.3.0
js-yaml: 4.1.0
minimatch: 3.1.2
strip-json-comments: 3.1.1
transitivePeerDependencies:
- supports-color
dev: true
/@eslint/js@8.52.0:
resolution: {integrity: sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
/@eslint/js@8.53.0:
resolution: {integrity: sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
/@eth-optimism/contracts-periphery@1.0.8:
resolution: {integrity: sha512-n8a9rmlMxl1lWSiC1zHUlr5Qk6qy85nhsmSgpU12El1WY75MOIPknSTQKj+yJhEmrTtI0PViWlKfgviY09pwUg==}
dev: false
......@@ -2997,11 +3029,11 @@ packages:
- debug
dev: true
/@nrwl/tao@17.0.2:
resolution: {integrity: sha512-H+htIRzQR6Ibael34rhQkpNkpFFFmaSTsIzdqkBqL4j5+FzSpZh67NJnWSY8vsYQGQL8Ncc+MHvpQC+7pyfgGw==}
/@nrwl/tao@17.0.3:
resolution: {integrity: sha512-X6zcwf6c3z7TuztRJWM/OCfzm7+LI4Uw4coc9+PWr44ohHkgId2wEJTzXrDT3+lvv8DgwPpgWPwqntw+YcgRYg==}
hasBin: true
dependencies:
nx: 17.0.2
nx: 17.0.3
tslib: 2.6.2
transitivePeerDependencies:
- '@swc-node/register'
......@@ -3009,8 +3041,8 @@ packages:
- debug
dev: true
/@nx/nx-darwin-arm64@17.0.2:
resolution: {integrity: sha512-OSZLRfV8VplYPEqMcIg3mbAsJXlXEHKrdlJ0KUTk8Hih2+wl7cxuSEwG7X7qfBUOz+ognxaqicL+hueNrgwjlQ==}
/@nx/nx-darwin-arm64@17.0.3:
resolution: {integrity: sha512-KA75JC/hgkt9qwK4dnN1tlaTXWdYItkNMjji6YjkyAYabbLKQKVcQoPocYP/RB/Gng+vNslXwuug2atgxDf43g==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
......@@ -3018,8 +3050,8 @@ packages:
dev: true
optional: true
/@nx/nx-darwin-x64@17.0.2:
resolution: {integrity: sha512-olGt5R2dWYwdl1+I2RfJ8LdZO1elqhr9yDPnMIx//ZuN6T6wJA+Wdp2P3qpM1bY0F1lI/6AgjqzRyrTLUZ9cDA==}
/@nx/nx-darwin-x64@17.0.3:
resolution: {integrity: sha512-YVWk9jNibD7fzn8oNBl/UNu8NEfcVwFo5wiNyfOql495yP0tyGdZNHD4i/7aS2Y654G1JYDRf7TutJ7wWFU8bg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
......@@ -3027,8 +3059,8 @@ packages:
dev: true
optional: true
/@nx/nx-freebsd-x64@17.0.2:
resolution: {integrity: sha512-+mta0J2G2byd+rfZ275oZs0aYXC/s92nI9ySBFQFQZnKJ6bsAagdZHe+uETsnE4xdhFXD8kvNMJU1WTGlyFyjg==}
/@nx/nx-freebsd-x64@17.0.3:
resolution: {integrity: sha512-yiYkfY+3IrlBrlaXN6SO4Fnb0a+Ti+FPwAqRPpH6q3uTCh0NmNgE99ydtT31ZbgCF1ZwRK8NdCbuNO3w9uznwA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [freebsd]
......@@ -3036,8 +3068,8 @@ packages:
dev: true
optional: true
/@nx/nx-linux-arm-gnueabihf@17.0.2:
resolution: {integrity: sha512-m80CmxHHyNAJ8j/0rkjc0hg/eGQlf6V2sLsV+gEJkz2sTEEdgSOK4DvnWcZRWO/SWBnqigxoHX4Kf5TH1nmoHA==}
/@nx/nx-linux-arm-gnueabihf@17.0.3:
resolution: {integrity: sha512-x4h6QJlESJZ0bigUlxNEVyi7F/VWQQx+1IBptofXhK5eTOPjJ5qgINdM38AZg+kBJDz5XOVMDejg6RzHlhs0Tg==}
engines: {node: '>= 10'}
cpu: [arm]
os: [linux]
......@@ -3045,8 +3077,8 @@ packages:
dev: true
optional: true
/@nx/nx-linux-arm64-gnu@17.0.2:
resolution: {integrity: sha512-AsD1H6wt68MK1u6vkmtNaFaxDMcyuk6dpo5kq1YT9cfUd614ys3qMUjVp3P2CXxzXh+0UDZeGrc6qotNKOkpJw==}
/@nx/nx-linux-arm64-gnu@17.0.3:
resolution: {integrity: sha512-1lysnsZv9FS+9fciK0qh5PhsQ8U+vyFoR/jiJl+3vqYNUwEmNLD0VEAZzpZL2SJXQqD5E0bjuQpYxiD7YRXImQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
......@@ -3054,8 +3086,8 @@ packages:
dev: true
optional: true
/@nx/nx-linux-arm64-musl@17.0.2:
resolution: {integrity: sha512-f8pUFoZHBFQtHnopHgTEuwIiu0Rzem0dD7iK8SyyBy/lRAADtHCAHxaPAG+iatHAJ9h4DFIB50k9ybYxDtH2mg==}
/@nx/nx-linux-arm64-musl@17.0.3:
resolution: {integrity: sha512-0/bvSpbc4vOy9E24fu0ajDGe3SO8lmLtlxjXwGRcnzlt/MWM8sazoO0lX163/X2wF6tuL6+HXHOr6AeqsdeRXQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
......@@ -3063,8 +3095,8 @@ packages:
dev: true
optional: true
/@nx/nx-linux-x64-gnu@17.0.2:
resolution: {integrity: sha512-PISrHjLTxv5w8bz50vPZH6puYos88xu28o4IbVyYWrUrhoFsAx9Zbn1D6gWDPMSaKJU32v1l+5bTciQjQJU8fQ==}
/@nx/nx-linux-x64-gnu@17.0.3:
resolution: {integrity: sha512-tKO6MYUxpUsHMuZrYy8hG20RIOdBY3kyEK8wxH8JZZaXKeYUK+5vv5DavWpY5wuu2jffNIJNsbUzcrqOlcbDOg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
......@@ -3072,8 +3104,8 @@ packages:
dev: true
optional: true
/@nx/nx-linux-x64-musl@17.0.2:
resolution: {integrity: sha512-2wsqyBRjsxmAjxW+0lnGFtJLTk+AxgW7gjMv8NgLK8P1bc/sJYQB+g0o5op2z+szXRG3Noi0RZ9C0fG39EPFZw==}
/@nx/nx-linux-x64-musl@17.0.3:
resolution: {integrity: sha512-H88yBLrI51m6NGoCkpBYhacRyTBfDuf7x00SnxSfD1yLlxCazPUG7CGkMedpzXo10YHxCFvg7B/Fa23DRRleUg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
......@@ -3081,8 +3113,8 @@ packages:
dev: true
optional: true
/@nx/nx-win32-arm64-msvc@17.0.2:
resolution: {integrity: sha512-Sc3sQUcS5xdk05PABe/knG6orG5rmHZdSUj6SMRpvYfN2tM3ziNn6/wCF/LJoW6n70OxrOEXXwLSRK/5WigXbA==}
/@nx/nx-win32-arm64-msvc@17.0.3:
resolution: {integrity: sha512-bKzmzjvgLB4IzLWTySqXgBgXawfw0ZSjUkscFQ3ZHrK9loMba1Ue8Ugy2DktlkUrCyPmGSot+YZViTzWP75C3w==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
......@@ -3090,8 +3122,8 @@ packages:
dev: true
optional: true
/@nx/nx-win32-x64-msvc@17.0.2:
resolution: {integrity: sha512-XhET0BDk6fbvTBCs7m5gZii8+2WhLpiC1sZchJw4LAJN2VJBiy3I3xnvpQYGFOAWaCb/iUGpuN/qP/NlQ+LNgA==}
/@nx/nx-win32-x64-msvc@17.0.3:
resolution: {integrity: sha512-SJssAOyUM1IW9t84/Uzau9JHo14hnG5mxvcrborNGlLq+WnP0jzISVs7gvV2xWZ9j1JemxA5KLbkMuIkJyR6qQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
......@@ -3197,7 +3229,7 @@ packages:
resolution: {integrity: sha512-gYw0ki/EAuV1oSyMxpqandHjnthZjYYy+YWpTAzf8BqfXM3ItcZLpjxfg+3+mXW8HIO+3jw6T9iiqEXsqHaMMw==}
dependencies:
'@safe-global/safe-gateway-typescript-sdk': 3.7.3
viem: 1.18.4(typescript@5.2.2)(zod@3.22.4)
viem: 1.18.6(typescript@5.2.2)(zod@3.22.4)
transitivePeerDependencies:
- bufferutil
- encoding
......@@ -4230,6 +4262,35 @@ packages:
- supports-color
dev: true
/@typescript-eslint/eslint-plugin@6.9.1(@typescript-eslint/parser@6.9.1)(eslint@8.53.0)(typescript@5.2.2):
resolution: {integrity: sha512-w0tiiRc9I4S5XSXXrMHOWgHgxbrBn1Ro+PmiYhSg2ZVdxrAJtQgzU5o2m1BfP6UOn7Vxcc6152vFjQfmZR4xEg==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
'@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha
eslint: ^7.0.0 || ^8.0.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@eslint-community/regexpp': 4.6.2
'@typescript-eslint/parser': 6.9.1(eslint@8.53.0)(typescript@5.2.2)
'@typescript-eslint/scope-manager': 6.9.1
'@typescript-eslint/type-utils': 6.9.1(eslint@8.53.0)(typescript@5.2.2)
'@typescript-eslint/utils': 6.9.1(eslint@8.53.0)(typescript@5.2.2)
'@typescript-eslint/visitor-keys': 6.9.1
debug: 4.3.4(supports-color@8.1.1)
eslint: 8.53.0
graphemer: 1.4.0
ignore: 5.2.4
natural-compare: 1.4.0
semver: 7.5.4
ts-api-utils: 1.0.1(typescript@5.2.2)
typescript: 5.2.2
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/parser@6.9.1(eslint@8.52.0)(typescript@5.2.2):
resolution: {integrity: sha512-C7AK2wn43GSaCUZ9do6Ksgi2g3mwFkMO3Cis96kzmgudoVaKyt62yNzJOktP0HDLb/iO2O0n2lBOzJgr6Q/cyg==}
engines: {node: ^16.0.0 || >=18.0.0}
......@@ -4251,6 +4312,27 @@ packages:
- supports-color
dev: true
/@typescript-eslint/parser@6.9.1(eslint@8.53.0)(typescript@5.2.2):
resolution: {integrity: sha512-C7AK2wn43GSaCUZ9do6Ksgi2g3mwFkMO3Cis96kzmgudoVaKyt62yNzJOktP0HDLb/iO2O0n2lBOzJgr6Q/cyg==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@typescript-eslint/scope-manager': 6.9.1
'@typescript-eslint/types': 6.9.1
'@typescript-eslint/typescript-estree': 6.9.1(typescript@5.2.2)
'@typescript-eslint/visitor-keys': 6.9.1
debug: 4.3.4(supports-color@8.1.1)
eslint: 8.53.0
typescript: 5.2.2
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/scope-manager@6.9.1:
resolution: {integrity: sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==}
engines: {node: ^16.0.0 || >=18.0.0}
......@@ -4279,6 +4361,26 @@ packages:
- supports-color
dev: true
/@typescript-eslint/type-utils@6.9.1(eslint@8.53.0)(typescript@5.2.2):
resolution: {integrity: sha512-eh2oHaUKCK58qIeYp19F5V5TbpM52680sB4zNSz29VBQPTWIlE/hCj5P5B1AChxECe/fmZlspAWFuRniep1Skg==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@typescript-eslint/typescript-estree': 6.9.1(typescript@5.2.2)
'@typescript-eslint/utils': 6.9.1(eslint@8.53.0)(typescript@5.2.2)
debug: 4.3.4(supports-color@8.1.1)
eslint: 8.53.0
ts-api-utils: 1.0.1(typescript@5.2.2)
typescript: 5.2.2
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/types@6.9.1:
resolution: {integrity: sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==}
engines: {node: ^16.0.0 || >=18.0.0}
......@@ -4324,6 +4426,25 @@ packages:
- typescript
dev: true
/@typescript-eslint/utils@6.9.1(eslint@8.53.0)(typescript@5.2.2):
resolution: {integrity: sha512-L1T0A5nFdQrMVunpZgzqPL6y2wVreSyHhKGZryS6jrEN7bD9NplVAyMryUhXsQ4TWLnZmxc2ekar/lSGIlprCA==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0)
'@types/json-schema': 7.0.12
'@types/semver': 7.5.0
'@typescript-eslint/scope-manager': 6.9.1
'@typescript-eslint/types': 6.9.1
'@typescript-eslint/typescript-estree': 6.9.1(typescript@5.2.2)
eslint: 8.53.0
semver: 7.5.4
transitivePeerDependencies:
- supports-color
- typescript
dev: true
/@typescript-eslint/visitor-keys@6.9.1:
resolution: {integrity: sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==}
engines: {node: ^16.0.0 || >=18.0.0}
......@@ -4562,7 +4683,7 @@ packages:
wagmi:
optional: true
dependencies:
'@wagmi/core': 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.4)
'@wagmi/core': 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.6)
abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3)
abort-controller: 3.0.0
bundle-require: 3.1.2(esbuild@0.16.17)
......@@ -4584,15 +4705,15 @@ packages:
picocolors: 1.0.0
prettier: 2.8.8
typescript: 5.2.2
viem: 1.18.4(typescript@5.2.2)(zod@3.22.3)
wagmi: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.4)
viem: 1.18.6(typescript@5.2.2)(zod@3.22.3)
wagmi: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.6)
zod: 3.22.3
transitivePeerDependencies:
- bufferutil
- utf-8-validate
dev: true
/@wagmi/connectors@1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.4):
/@wagmi/connectors@1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.6):
resolution: {integrity: sha512-fl01vym19DE1uoE+MlASw5zo3Orr/YXlJRjOKLaKYtV+Q7jOLY4TwHgq7sEMs+JYOvFICFBEAlWNNxidr51AqQ==}
peerDependencies:
'@wagmi/chains': '>=0.2.0'
......@@ -4615,7 +4736,7 @@ packages:
abitype: 0.8.1(typescript@5.2.2)
eventemitter3: 4.0.7
typescript: 5.2.2
viem: 1.18.4(typescript@5.2.2)(zod@3.22.4)
viem: 1.18.6(typescript@5.2.2)(zod@3.22.4)
transitivePeerDependencies:
- '@react-native-async-storage/async-storage'
- bufferutil
......@@ -4627,7 +4748,7 @@ packages:
- utf-8-validate
- zod
/@wagmi/connectors@3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.4):
/@wagmi/connectors@3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.6):
resolution: {integrity: sha512-UgwsQKQDFObJVJMf9pDfFoXTv710o4zrTHyhIWKBTMMkLpCMsMxN5+ZaDhBYt/BgoRinfRYQo8uwuwLhxE6Log==}
peerDependencies:
typescript: '>=5.0.4'
......@@ -4647,7 +4768,7 @@ packages:
abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3)
eventemitter3: 4.0.7
typescript: 5.2.2
viem: 1.18.4(typescript@5.2.2)(zod@3.22.4)
viem: 1.18.6(typescript@5.2.2)(zod@3.22.4)
transitivePeerDependencies:
- '@react-native-async-storage/async-storage'
- '@types/react'
......@@ -4660,7 +4781,7 @@ packages:
- zod
dev: true
/@wagmi/core@1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.4):
/@wagmi/core@1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.6):
resolution: {integrity: sha512-Zzg4Ob92QMF9NsC+z5/8JZjMn3NCCnwVWGJlv79qRX9mp5Ku40OzJNvqDnjcSGjshe6H0L/KtFZAqTlmu8lT7w==}
peerDependencies:
typescript: '>=4.9.4'
......@@ -4670,11 +4791,11 @@ packages:
optional: true
dependencies:
'@wagmi/chains': 0.2.22(typescript@5.2.2)
'@wagmi/connectors': 1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.4)
'@wagmi/connectors': 1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.6)
abitype: 0.8.1(typescript@5.2.2)
eventemitter3: 4.0.7
typescript: 5.2.2
viem: 1.18.4(typescript@5.2.2)(zod@3.22.4)
viem: 1.18.6(typescript@5.2.2)(zod@3.22.4)
zustand: 4.3.9(react@18.2.0)
transitivePeerDependencies:
- '@react-native-async-storage/async-storage'
......@@ -4688,7 +4809,7 @@ packages:
- utf-8-validate
- zod
/@wagmi/core@1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.4):
/@wagmi/core@1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.6):
resolution: {integrity: sha512-N9luRb1Uk4tBN9kaYcQSWKE9AsRt/rvZaFt5IZech4JPzNN2sQlfhKd9GEjOXYRDqEPHdDvos7qyBKiDNTz4GA==}
peerDependencies:
typescript: '>=5.0.4'
......@@ -4697,11 +4818,11 @@ packages:
typescript:
optional: true
dependencies:
'@wagmi/connectors': 3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.4)
'@wagmi/connectors': 3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.6)
abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3)
eventemitter3: 4.0.7
typescript: 5.2.2
viem: 1.18.4(typescript@5.2.2)(zod@3.22.4)
viem: 1.18.6(typescript@5.2.2)(zod@3.22.4)
zustand: 4.3.9(react@18.2.0)
transitivePeerDependencies:
- '@react-native-async-storage/async-storage'
......@@ -7457,16 +7578,16 @@ packages:
engines: {node: '>=10'}
dev: true
/eslint-config-prettier@8.3.0(eslint@8.52.0):
/eslint-config-prettier@8.3.0(eslint@8.53.0):
resolution: {integrity: sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==}
hasBin: true
peerDependencies:
eslint: '>=7.0.0'
dependencies:
eslint: 8.52.0
eslint: 8.53.0
dev: true
/eslint-config-standard@16.0.3(eslint-plugin-import@2.29.0)(eslint-plugin-node@11.1.0)(eslint-plugin-promise@5.2.0)(eslint@8.52.0):
/eslint-config-standard@16.0.3(eslint-plugin-import@2.29.0)(eslint-plugin-node@11.1.0)(eslint-plugin-promise@5.2.0)(eslint@8.53.0):
resolution: {integrity: sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==}
peerDependencies:
eslint: ^7.12.1
......@@ -7474,10 +7595,10 @@ packages:
eslint-plugin-node: ^11.1.0
eslint-plugin-promise: ^4.2.1 || ^5.0.0
dependencies:
eslint: 8.52.0
eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.9.1)(eslint@8.52.0)
eslint-plugin-node: 11.1.0(eslint@8.52.0)
eslint-plugin-promise: 5.2.0(eslint@8.52.0)
eslint: 8.53.0
eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.9.1)(eslint@8.53.0)
eslint-plugin-node: 11.1.0(eslint@8.53.0)
eslint-plugin-promise: 5.2.0(eslint@8.53.0)
dev: true
/eslint-import-resolver-node@0.3.9:
......@@ -7490,7 +7611,7 @@ packages:
- supports-color
dev: true
/eslint-module-utils@2.8.0(@typescript-eslint/parser@6.9.1)(eslint-import-resolver-node@0.3.9)(eslint@8.52.0):
/eslint-module-utils@2.8.0(@typescript-eslint/parser@6.9.1)(eslint-import-resolver-node@0.3.9)(eslint@8.53.0):
resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
engines: {node: '>=4'}
peerDependencies:
......@@ -7511,26 +7632,26 @@ packages:
eslint-import-resolver-webpack:
optional: true
dependencies:
'@typescript-eslint/parser': 6.9.1(eslint@8.52.0)(typescript@5.2.2)
'@typescript-eslint/parser': 6.9.1(eslint@8.53.0)(typescript@5.2.2)
debug: 3.2.7
eslint: 8.52.0
eslint: 8.53.0
eslint-import-resolver-node: 0.3.9
transitivePeerDependencies:
- supports-color
dev: true
/eslint-plugin-es@3.0.1(eslint@8.52.0):
/eslint-plugin-es@3.0.1(eslint@8.53.0):
resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==}
engines: {node: '>=8.10.0'}
peerDependencies:
eslint: '>=4.19.1'
dependencies:
eslint: 8.52.0
eslint: 8.53.0
eslint-utils: 2.1.0
regexpp: 3.2.0
dev: true
/eslint-plugin-import@2.29.0(@typescript-eslint/parser@6.9.1)(eslint@8.52.0):
/eslint-plugin-import@2.29.0(@typescript-eslint/parser@6.9.1)(eslint@8.53.0):
resolution: {integrity: sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==}
engines: {node: '>=4'}
peerDependencies:
......@@ -7540,16 +7661,16 @@ packages:
'@typescript-eslint/parser':
optional: true
dependencies:
'@typescript-eslint/parser': 6.9.1(eslint@8.52.0)(typescript@5.2.2)
'@typescript-eslint/parser': 6.9.1(eslint@8.53.0)(typescript@5.2.2)
array-includes: 3.1.7
array.prototype.findlastindex: 1.2.3
array.prototype.flat: 1.3.2
array.prototype.flatmap: 1.3.2
debug: 3.2.7
doctrine: 2.1.0
eslint: 8.52.0
eslint: 8.53.0
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.9.1)(eslint-import-resolver-node@0.3.9)(eslint@8.52.0)
eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.9.1)(eslint-import-resolver-node@0.3.9)(eslint@8.53.0)
hasown: 2.0.0
is-core-module: 2.13.1
is-glob: 4.0.3
......@@ -7565,7 +7686,7 @@ packages:
- supports-color
dev: true
/eslint-plugin-jsdoc@35.5.1(eslint@8.52.0):
/eslint-plugin-jsdoc@35.5.1(eslint@8.53.0):
resolution: {integrity: sha512-pPYPWtsykwVEue1tYEyoppBj4dgF7XicF67tLLLraY6RQYBq7qMKjUHji19+hfiTtYKKBD0YfeK8hgjPAE5viw==}
engines: {node: '>=12'}
peerDependencies:
......@@ -7574,7 +7695,7 @@ packages:
'@es-joy/jsdoccomment': 0.9.0-alpha.1
comment-parser: 1.1.6-beta.0
debug: 4.3.4(supports-color@8.1.1)
eslint: 8.52.0
eslint: 8.53.0
esquery: 1.4.0
jsdoc-type-pratt-parser: 1.1.1
lodash: 4.17.21
......@@ -7585,14 +7706,14 @@ packages:
- supports-color
dev: true
/eslint-plugin-node@11.1.0(eslint@8.52.0):
/eslint-plugin-node@11.1.0(eslint@8.53.0):
resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==}
engines: {node: '>=8.10.0'}
peerDependencies:
eslint: '>=5.16.0'
dependencies:
eslint: 8.52.0
eslint-plugin-es: 3.0.1(eslint@8.52.0)
eslint: 8.53.0
eslint-plugin-es: 3.0.1(eslint@8.53.0)
eslint-utils: 2.1.0
ignore: 5.2.4
minimatch: 3.1.2
......@@ -7600,15 +7721,15 @@ packages:
semver: 6.3.1
dev: true
/eslint-plugin-prefer-arrow@1.2.3(eslint@8.52.0):
/eslint-plugin-prefer-arrow@1.2.3(eslint@8.53.0):
resolution: {integrity: sha512-J9I5PKCOJretVuiZRGvPQxCbllxGAV/viI20JO3LYblAodofBxyMnZAJ+WGeClHgANnSJberTNoFWWjrWKBuXQ==}
peerDependencies:
eslint: '>=2.0.0'
dependencies:
eslint: 8.52.0
eslint: 8.53.0
dev: true
/eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.3.0)(eslint@8.52.0)(prettier@2.8.8):
/eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.3.0)(eslint@8.53.0)(prettier@2.8.8):
resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==}
engines: {node: '>=12.0.0'}
peerDependencies:
......@@ -7619,22 +7740,22 @@ packages:
eslint-config-prettier:
optional: true
dependencies:
eslint: 8.52.0
eslint-config-prettier: 8.3.0(eslint@8.52.0)
eslint: 8.53.0
eslint-config-prettier: 8.3.0(eslint@8.53.0)
prettier: 2.8.8
prettier-linter-helpers: 1.0.0
dev: true
/eslint-plugin-promise@5.2.0(eslint@8.52.0):
/eslint-plugin-promise@5.2.0(eslint@8.53.0):
resolution: {integrity: sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==}
engines: {node: ^10.12.0 || >=12.0.0}
peerDependencies:
eslint: ^7.0.0
dependencies:
eslint: 8.52.0
eslint: 8.53.0
dev: true
/eslint-plugin-react@7.33.2(eslint@8.52.0):
/eslint-plugin-react@7.33.2(eslint@8.53.0):
resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==}
engines: {node: '>=4'}
peerDependencies:
......@@ -7645,7 +7766,7 @@ packages:
array.prototype.tosorted: 1.1.1
doctrine: 2.1.0
es-iterator-helpers: 1.0.13
eslint: 8.52.0
eslint: 8.53.0
estraverse: 5.3.0
jsx-ast-utils: 3.2.0
minimatch: 3.1.2
......@@ -7659,17 +7780,17 @@ packages:
string.prototype.matchall: 4.0.8
dev: true
/eslint-plugin-unicorn@49.0.0(eslint@8.52.0):
/eslint-plugin-unicorn@49.0.0(eslint@8.53.0):
resolution: {integrity: sha512-0fHEa/8Pih5cmzFW5L7xMEfUTvI9WKeQtjmKpTUmY+BiFCDxkxrTdnURJOHKykhtwIeyYsxnecbGvDCml++z4Q==}
engines: {node: '>=16'}
peerDependencies:
eslint: '>=8.52.0'
dependencies:
'@babel/helper-validator-identifier': 7.22.20
'@eslint-community/eslint-utils': 4.4.0(eslint@8.52.0)
'@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0)
ci-info: 3.8.0
clean-regexp: 1.0.0
eslint: 8.52.0
eslint: 8.53.0
esquery: 1.5.0
indent-string: 4.0.0
is-builtin-module: 3.2.1
......@@ -7767,6 +7888,53 @@ packages:
- supports-color
dev: true
/eslint@8.53.0:
resolution: {integrity: sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
hasBin: true
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0)
'@eslint-community/regexpp': 4.6.2
'@eslint/eslintrc': 2.1.3
'@eslint/js': 8.53.0
'@humanwhocodes/config-array': 0.11.13
'@humanwhocodes/module-importer': 1.0.1
'@nodelib/fs.walk': 1.2.8
'@ungap/structured-clone': 1.2.0
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.3
debug: 4.3.4(supports-color@8.1.1)
doctrine: 3.0.0
escape-string-regexp: 4.0.0
eslint-scope: 7.2.2
eslint-visitor-keys: 3.4.3
espree: 9.6.1
esquery: 1.5.0
esutils: 2.0.3
fast-deep-equal: 3.1.3
file-entry-cache: 6.0.1
find-up: 5.0.0
glob-parent: 6.0.2
globals: 13.21.0
graphemer: 1.4.0
ignore: 5.2.4
imurmurhash: 0.1.4
is-glob: 4.0.3
is-path-inside: 3.0.3
js-yaml: 4.1.0
json-stable-stringify-without-jsonify: 1.0.1
levn: 0.4.1
lodash.merge: 4.6.2
minimatch: 3.1.2
natural-compare: 1.4.0
optionator: 0.9.3
strip-ansi: 6.0.1
text-table: 0.2.0
transitivePeerDependencies:
- supports-color
dev: true
/espree@9.6.1:
resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
......@@ -11274,8 +11442,8 @@ packages:
- debug
dev: true
/nx@17.0.2:
resolution: {integrity: sha512-utk9ufxLlRd210nEV6cKjMLVK0gup2ZMlNT41lLgUX/gp3Q59G1NkyLo3o29DxBh3AhNJ9q5MKgybmzDNdpudA==}
/nx@17.0.3:
resolution: {integrity: sha512-VShJISKCYt3iVJoMUPZiv67+0tiItxWMnfVmTmPZPio2Fu+wGc9U4ijjPxcmp2RJmLRaxkB9cn5rlrAvkIrNMA==}
hasBin: true
requiresBuild: true
peerDependencies:
......@@ -11287,7 +11455,7 @@ packages:
'@swc/core':
optional: true
dependencies:
'@nrwl/tao': 17.0.2
'@nrwl/tao': 17.0.3
'@yarnpkg/lockfile': 1.1.0
'@yarnpkg/parsers': 3.0.0-rc.46
'@zkochan/js-yaml': 0.0.6
......@@ -11323,16 +11491,16 @@ packages:
yargs: 17.7.2
yargs-parser: 21.1.1
optionalDependencies:
'@nx/nx-darwin-arm64': 17.0.2
'@nx/nx-darwin-x64': 17.0.2
'@nx/nx-freebsd-x64': 17.0.2
'@nx/nx-linux-arm-gnueabihf': 17.0.2
'@nx/nx-linux-arm64-gnu': 17.0.2
'@nx/nx-linux-arm64-musl': 17.0.2
'@nx/nx-linux-x64-gnu': 17.0.2
'@nx/nx-linux-x64-musl': 17.0.2
'@nx/nx-win32-arm64-msvc': 17.0.2
'@nx/nx-win32-x64-msvc': 17.0.2
'@nx/nx-darwin-arm64': 17.0.3
'@nx/nx-darwin-x64': 17.0.3
'@nx/nx-freebsd-x64': 17.0.3
'@nx/nx-linux-arm-gnueabihf': 17.0.3
'@nx/nx-linux-arm64-gnu': 17.0.3
'@nx/nx-linux-arm64-musl': 17.0.3
'@nx/nx-linux-x64-gnu': 17.0.3
'@nx/nx-linux-x64-musl': 17.0.3
'@nx/nx-win32-arm64-msvc': 17.0.3
'@nx/nx-win32-x64-msvc': 17.0.3
transitivePeerDependencies:
- debug
dev: true
......@@ -14292,8 +14460,8 @@ packages:
vfile-message: 2.0.4
dev: true
/viem@1.18.4(typescript@5.2.2)(zod@3.22.3):
resolution: {integrity: sha512-im+y30k+IGT6VtfD/q1V0RX5PaiHPsFTHkKqvTjTqV+ZT8RgJXzOGPXr5E0uPIm2cbJAJp6A9nR9BCHY7BKR2Q==}
/viem@1.18.6(typescript@5.2.2)(zod@3.22.3):
resolution: {integrity: sha512-oKkrxF2aqxjJ4pmm0ko7j+ZFRekP6VGIknSroV+6+dF+T31bscltPZwJ0fOJDxCOVhoVtxrKFRTkkasEVDblUA==}
peerDependencies:
typescript: '>=5.0.4'
peerDependenciesMeta:
......@@ -14315,8 +14483,8 @@ packages:
- zod
dev: true
/viem@1.18.4(typescript@5.2.2)(zod@3.22.4):
resolution: {integrity: sha512-im+y30k+IGT6VtfD/q1V0RX5PaiHPsFTHkKqvTjTqV+ZT8RgJXzOGPXr5E0uPIm2cbJAJp6A9nR9BCHY7BKR2Q==}
/viem@1.18.6(typescript@5.2.2)(zod@3.22.4):
resolution: {integrity: sha512-oKkrxF2aqxjJ4pmm0ko7j+ZFRekP6VGIknSroV+6+dF+T31bscltPZwJ0fOJDxCOVhoVtxrKFRTkkasEVDblUA==}
peerDependencies:
typescript: '>=5.0.4'
peerDependenciesMeta:
......@@ -14809,7 +14977,7 @@ packages:
xml-name-validator: 4.0.0
dev: true
/wagmi@1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.4):
/wagmi@1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.6):
resolution: {integrity: sha512-+2UkZG9eA3tKqXj1wvlvI8mL0Bcff7Tf5CKfUOyQsdKcY+J5rfwYYya25G+jja57umpHFtfxRaL7xDkNjehrRg==}
peerDependencies:
react: '>=17.0.0'
......@@ -14822,12 +14990,12 @@ packages:
'@tanstack/query-sync-storage-persister': 4.29.25
'@tanstack/react-query': 4.29.25(react-dom@18.2.0)(react@18.2.0)
'@tanstack/react-query-persist-client': 4.29.25(@tanstack/react-query@4.29.25)
'@wagmi/core': 1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.4)
'@wagmi/core': 1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.6)
abitype: 0.8.1(typescript@5.2.2)
react: 18.2.0
typescript: 5.2.2
use-sync-external-store: 1.2.0(react@18.2.0)
viem: 1.18.4(typescript@5.2.2)(zod@3.22.4)
viem: 1.18.6(typescript@5.2.2)(zod@3.22.4)
transitivePeerDependencies:
- '@react-native-async-storage/async-storage'
- bufferutil
......
......@@ -213,8 +213,9 @@ The RLP-encoded consensus-enforced fields are:
- `bloom` (standard): bloom filter of the transaction logs.
- `logs` (standard): log events emitted by the EVM processing.
- `depositNonce` (unique extension): Optional field. The deposit transaction persists the nonce used during execution.
- Before Regolith, this `depositNonce` field must always be omitted.
- With Regolith, this `depositNonce` field must always be included.
- `depositNonceVersion` (unique extension): Optional field. The value must be 1 if the field is present
- Before Canyon, these `depositNonce` & `depositNonceVersion` fields must always be omitted.
- With Canyon, these `depositNonce` & `depositNonceVersion` fields must always be included.
Starting with Regolith, the receipt API responses utilize the receipt changes for more accurate response data:
......
......@@ -694,9 +694,12 @@ equivalents. The `v2` methods are backwards compatible with `v1` payloads but su
[`engine_getPayloadV2`]: exec-engine.md#engine_getpayloadv2
[`engine_newPayloadV2`]: exec-engine.md#engine_newpayloadv2
The execution payload is an object of type [`ExecutionPayloadV1`][eth-payload].
The execution payload is an object of type [`ExecutionPayloadV2`][eth-payload].
[eth-payload]: https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#executionpayloadv1
[eth-payload]: https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#payloadattributesv2
With V2 of the execution payload, before Canyon the withdrawals field is required to be nil. After Canyon the
withdrawals field is required to be non-nil. The op-node should set the withdrawals field to be an empty list.
#### Forkchoice synchronization
......@@ -892,7 +895,7 @@ without dispute (fault proof challenge window), a name-collision with the proof-
[deriving-payload-attr]: #deriving-payload-attributes
For every L2 block derived from L1 data, we need to build [payload attributes][g-payload-attr],
represented by an [expanded version][expanded-payload] of the [`PayloadAttributesV1`][eth-payload] object,
represented by an [expanded version][expanded-payload] of the [`PayloadAttributesV2`][eth-payload] object,
which includes additional `transactions` and `noTxPool` fields.
This process happens during the payloads-attributes queue ran by a verifier node, as well as during block-production
......@@ -912,7 +915,7 @@ This block is part of a [sequencing epoch][g-sequencing-epoch],
whose number matches that of an L1 block (its *[L1 origin][g-l1-origin]*).
This L1 block is used to derive L1 attributes and (for the first L2 block in the epoch) user deposits.
Therefore, a [`PayloadAttributesV1`][expanded-payload] object must include the following transactions:
Therefore, a [`PayloadAttributesV2`][expanded-payload] object must include the following transactions:
- one or more [deposited transactions][g-deposited], of two kinds:
- a single *[L1 attributes deposited transaction][g-l1-attr-deposit]*, derived from the L1 origin.
......@@ -933,7 +936,7 @@ entries.
[payload attributes]: #building-individual-payload-attributes
After deriving the transactions list, the rollup node constructs a [`PayloadAttributesV1`][extended-attributes] as
After deriving the transactions list, the rollup node constructs a [`PayloadAttributesV2`][extended-attributes] as
follows:
- `timestamp` is set to the batch's timestamp.
......@@ -943,6 +946,7 @@ follows:
encoded with [EIP-2718].
- `noTxPool` is set to `true`, to use the exact above `transactions` list when constructing the block.
- `gasLimit` is set to the current `gasLimit` value in the [system configuration][g-system-config] of this payload.
- `withdrawals` is set to nil prior to Canyon and an empty array after Canyon
[extended-attributes]: exec-engine.md#extended-payloadattributesv1
[Fee Vaults]: exec-engine.md#fee-vaults
......@@ -4,6 +4,7 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [1559 Parameters](#1559-parameters)
- [Deposited transaction processing](#deposited-transaction-processing)
- [Deposited transaction boundaries](#deposited-transaction-boundaries)
- [Fees](#fees)
......@@ -13,7 +14,7 @@
- [L1-Cost fees (L1 Fee Vault)](#l1-cost-fees-l1-fee-vault)
- [Engine API](#engine-api)
- [`engine_forkchoiceUpdatedV2`](#engine_forkchoiceupdatedv2)
- [Extended PayloadAttributesV1](#extended-payloadattributesv1)
- [Extended PayloadAttributesV2](#extended-payloadattributesv2)
- [`engine_newPayloadV2`](#engine_newpayloadv2)
- [`engine_getPayloadV2`](#engine_getpayloadv2)
- [`engine_signalSuperchainV1`](#engine_signalsuperchainv1)
......@@ -26,6 +27,14 @@
This document outlines the modifications, configuration and usage of a L1 execution engine for L2.
## 1559 Parameters
The execution engine must be able to take a per chain configuration which specifies the EIP-1559 Denominator
and EIP-1559 elasticity. After Canyon it should also take a new value `EIP1559DenominatorCanyon` and use that as
the denominator in the 1559 formula rather than the prior denominator.
The formula for EIP-1559 is not otherwise modified.
## Deposited transaction processing
The Engine interfaces abstract away transaction types with [EIP-2718][eip-2718].
......@@ -140,17 +149,18 @@ Within the rollup, the types of forkchoice updates translate as:
- `finalizedBlockHash`: irreversible block hash, matches lower boundary of the dispute period.
To support rollup functionality, one backwards-compatible change is introduced
to [`engine_forkchoiceUpdatedV2`][engine_forkchoiceUpdatedV2]: the extended `PayloadAttributesV1`
to [`engine_forkchoiceUpdatedV2`][engine_forkchoiceUpdatedV2]: the extended `PayloadAttributesV2`
#### Extended PayloadAttributesV1
#### Extended PayloadAttributesV2
[`PayloadAttributesV1`][PayloadAttributesV1] is extended to:
[`PayloadAttributesV2`][PayloadAttributesV2] is extended to:
```js
PayloadAttributesV1: {
PayloadAttributesV2: {
timestamp: QUANTITY
random: DATA (32 bytes)
suggestedFeeRecipient: DATA (20 bytes)
withdrawals: array of WithdrawalV1
transactions: array of DATA
noTxPool: bool
gasLimit: QUANTITY or null
......@@ -163,7 +173,7 @@ to a JSON array.
Each item of the `transactions` array is a byte list encoding a transaction: `TransactionType ||
TransactionPayload` or `LegacyTransaction`, as defined in [EIP-2718][eip-2718].
This is equivalent to the `transactions` field in [`ExecutionPayloadV1`][ExecutionPayloadV1]
This is equivalent to the `transactions` field in [`ExecutionPayloadV2`][ExecutionPayloadV2]
The `transactions` field is optional:
......@@ -301,7 +311,7 @@ the operation within the engine is the exact same as with L1 (although with an E
[eip-2718-transactions]: https://eips.ethereum.org/EIPS/eip-2718#transactions
[exec-api-data]: https://github.com/ethereum/execution-apis/blob/769c53c94c4e487337ad0edea9ee0dce49c79bfa/src/engine/specification.md#structures
[l1-api-spec]: https://github.com/ethereum/execution-apis/blob/769c53c94c4e487337ad0edea9ee0dce49c79bfa/src/engine/specification.md
[PayloadAttributesV1]: https://github.com/ethereum/execution-apis/blob/769c53c94c4e487337ad0edea9ee0dce49c79bfa/src/engine/specification.md#PayloadAttributesV1
[PayloadAttributesV2]: https://github.com/ethereum/execution-apis/blob/584905270d8ad665718058060267061ecfd79ca5/src/engine/shanghai.md#PayloadAttributesV2
[ExecutionPayloadV1]: https://github.com/ethereum/execution-apis/blob/769c53c94c4e487337ad0edea9ee0dce49c79bfa/src/engine/specification.md#ExecutionPayloadV1
[engine_forkchoiceUpdatedV2]: https://github.com/ethereum/execution-apis/blob/584905270d8ad665718058060267061ecfd79ca5/src/engine/shanghai.md#engine_forkchoiceupdatedv2
[engine_newPayloadV2]: https://github.com/ethereum/execution-apis/blob/584905270d8ad665718058060267061ecfd79ca5/src/engine/shanghai.md#engine_newpayloadv2
......
......@@ -797,7 +797,7 @@ In these specifications, "execution engine" always refer to the L2 execution eng
[Solidity events]: https://docs.soliditylang.org/en/latest/contracts.html?highlight=events#events
[nano-header]: https://github.com/norswap/nanoeth/blob/cc5d94a349c90627024f3cd629a2d830008fec72/src/com/norswap/nanoeth/blocks/BlockHeader.java#L22-L156
[yellow]: https://ethereum.github.io/yellowpaper/paper.pdf
[engine-api]: https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#PayloadAttributesV1
[engine-api]: https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#PayloadAttributesV2
[merge]: https://ethereum.org/en/eth2/merge/
[mempool]: https://www.quicknode.com/guides/defi/how-to-access-ethereum-mempool
[L1 consensus layer]: https://github.com/ethereum/consensus-specs/#readme
......
......@@ -23,6 +23,7 @@
- [L1FeeVault](#l1feevault)
- [SchemaRegistry](#schemaregistry)
- [EAS](#eas)
- [create2Deployer](#create2deployer)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
......@@ -45,7 +46,7 @@ and there is no proxy deployed at that account.
The following table includes each of the predeploys. The system version
indicates when the predeploy was introduced. The possible values are `Legacy`
or `Bedrock`. Deprecated contracts should not be used.
or `Bedrock` or `Canyon`. Deprecated contracts should not be used.
| Name | Address | Introduced | Deprecated | Proxied |
| ----------------------------- | ------------------------------------------ | ---------- | ---------- |---------|
......@@ -69,6 +70,7 @@ or `Bedrock`. Deprecated contracts should not be used.
| L1FeeVault | 0x420000000000000000000000000000000000001a | Bedrock | No | Yes |
| SchemaRegistry | 0x4200000000000000000000000000000000000020 | Bedrock | No | Yes |
| EAS | 0x4200000000000000000000000000000000000021 | Bedrock | No | Yes |
| create2Deployer | 0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2 | Canyon | No | No |
## LegacyMessagePasser
......@@ -332,3 +334,54 @@ protocol.
Address: `0x4200000000000000000000000000000000000021`
The `EAS` predeploy implements the `Ethereum Attestation Service` protocol.
## create2Deployer
[Implementation](https://github.com/mdehoog/create2deployer/blob/69b9a8e112b15f9257ce8c62b70a09914e7be29c/contracts/Create2Deployer.sol)
The create2Deployer is a nice Solidity wrapper around the CREATE2 opcode. It provides the following ABI.
```solidity
/**
* @dev Deploys a contract using `CREATE2`. The address where the
* contract will be deployed can be known in advance via {computeAddress}.
*
* The bytecode for a contract can be obtained from Solidity with
* `type(contractName).creationCode`.
*
* Requirements:
* - `bytecode` must not be empty.
* - `salt` must have not been used for `bytecode` already.
* - the factory must have a balance of at least `value`.
* - if `value` is non-zero, `bytecode` must have a `payable` constructor.
*/
function deploy(uint256 value, bytes32 salt, bytes memory code) public
/**
* @dev Deployment of the {ERC1820Implementer}.
* Further information: https://eips.ethereum.org/EIPS/eip-1820
*/
function deployERC1820Implementer(uint256 value, bytes32 salt)
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy}.
* Any change in the `bytecodeHash` or `salt` will result in a new destination address.
*/
function computeAddress(bytes32 salt, bytes32 codeHash) public view returns (address)
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy} from a
* contract located at `deployer`. If `deployer` is this contract's address, returns the
* same value as {computeAddress}.
*/
function computeAddressWithDeployer(
bytes32 salt,
bytes32 codeHash,
address deployer
) public pure returns (address)
```
Address: `0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2`
When Canyon activates, the contract code at `0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2` is set to
`0x6080604052600436106100435760003560e01c8063076c37b21461004f578063481286e61461007157806356299481146100ba57806366cfa057146100da57600080fd5b3661004a57005b600080fd5b34801561005b57600080fd5b5061006f61006a366004610327565b6100fa565b005b34801561007d57600080fd5b5061009161008c366004610327565b61014a565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100c657600080fd5b506100916100d5366004610349565b61015d565b3480156100e657600080fd5b5061006f6100f53660046103ca565b610172565b61014582826040518060200161010f9061031a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052610183565b505050565b600061015683836102e7565b9392505050565b600061016a8484846102f0565b949350505050565b61017d838383610183565b50505050565b6000834710156101f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e636500000060448201526064015b60405180910390fd5b815160000361025f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f60448201526064016101eb565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff8116610156576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f790000000000000060448201526064016101eb565b60006101568383305b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b61014e806104ad83390190565b6000806040838503121561033a57600080fd5b50508035926020909101359150565b60008060006060848603121561035e57600080fd5b8335925060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156103df57600080fd5b8335925060208401359150604084013567ffffffffffffffff8082111561040557600080fd5b818601915086601f83011261041957600080fd5b81358181111561042b5761042b61039b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156104715761047161039b565b8160405282815289602084870101111561048a57600080fd5b826020860160208301376000602084830101528095505050505050925092509256fe608060405234801561001057600080fd5b5061012e806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063249cb3fa14602d575b600080fd5b603c603836600460b1565b604e565b60405190815260200160405180910390f35b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff16608857600060aa565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b45b9392505050565b6000806040838503121560c357600080fd5b82359150602083013573ffffffffffffffffffffffffffffffffffffffff8116811460ed57600080fd5b80915050925092905056fea26469706673582212205ffd4e6cede7d06a5daf93d48d0541fc68189eeb16608c1999a82063b666eb1164736f6c63430008130033a2646970667358221220fdc4a0fe96e3b21c108ca155438d37c9143fb01278a3c1d274948bad89c564ba64736f6c63430008130033`.
......@@ -291,6 +291,7 @@ An [extended-validator] checks the incoming messages as follows, in order of ope
- `[REJECT]` if the `block_hash` in the `payload` is not valid
- `[REJECT]` if the block is on the V1 topic and has withdrawals
- `[REJECT]` if the block is on the V2 topic and does not have withdrawals
- `[REJECT]` if the block is on the V2 topic and has a non-zero amount of withdrawals
- `[REJECT]` if more than 5 different blocks have been seen with the same block height
- `[IGNORE]` if the block has already been seen
- `[REJECT]` if the signature by the sequencer is not valid
......
......@@ -64,6 +64,8 @@ Span-batches address these inefficiencies, with a new batch format version.
## Span batch format
[span-batch-format]: #span-batch-format
Note that span-batches, unlike previous singular batches,
encode *a range of consecutive* L2 blocks at the same time.
......@@ -268,7 +270,13 @@ Span-batches share the same queue with v0 batches: batches are processed in L1 i
A set of modified validation rules apply to the span-batches.
Rules are enforced with the [contextual definitions](./derivation.md#batch-queue) as v0-batch validation:
`batch`, `epoch`, `inclusion_block_number`, `next_timestamp`, `next_epoch`, `batch_origin`
`epoch`, `inclusion_block_number`, `next_timestamp`
Definitions:
- `batch` as defined in the [Span batch format section][span-batch-format].
- `prev_l2_block` is the L2 block from the current safe chain,
whose timestamp is at `span_start.timestamp - l2_block_time`
Span-batch rules, in validation order:
......@@ -279,10 +287,12 @@ Span-batch rules, in validation order:
- If known, then define `batch_origin` as `next_epoch`
- `batch_origin.timestamp < span_batch_upgrade_timestamp` -> `drop`:
i.e. enforce the [span batch upgrade activation rule](#span-batch-activation-rule).
- `batch.start_timestamp > next_timestamp` -> `future`: i.e. the batch must be ready to process.
- `batch.start_timestamp < next_timestamp` -> `drop`: i.e. the batch must not be too old.
- `batch.parent_check != safe_l2_head.hash[:20]` -> `drop`: i.e. the checked part of the parent hash must be equal
to the L2 safe head block hash.
- `span_start.timestamp > next_timestamp` -> `future`: i.e. the batch must be ready to process,
but does not have to start exactly at the `next_timestamp`, since it can overlap with previously processed blocks,
- `span_end.timestamp < next_timestamp` -> `drop`: i.e. the batch must have at least one new block to process.
- If there's no `prev_l2_block` in the current safe chain -> `drop`: i.e. the timestamp must be aligned.
- `batch.parent_check != prev_l2_block.hash[:20]` -> `drop`:
i.e. the checked part of the parent hash must be equal to the same part of the corresponding L2 block hash.
- Sequencing-window checks:
- Note: The sequencing window is enforced for the *batch as a whole*:
if the batch was partially invalid instead, it would drop the oldest L2 blocks,
......@@ -294,7 +304,7 @@ Span-batch rules, in validation order:
- Rules:
- `start_epoch_num + sequence_window_size < inclusion_block_number` -> `drop`:
i.e. the batch must be included timely.
- `start_epoch_num > epoch.number + 1` -> `drop`:
- `start_epoch_num > prev_l2_block.l1_origin.number + 1` -> `drop`:
i.e. the L1 origin cannot change by more than one L1 block per L2 block.
- If `batch.l1_origin_check` does not match the canonical L1 chain at `end_epoch_num` -> `drop`:
verify the batch is intended for this L1 chain.
......@@ -302,9 +312,8 @@ Span-batch rules, in validation order:
is past `inclusion_block_number` because of the following invariant.
- Invariant: the epoch-num in the batch is always less than the inclusion block number,
if and only if the L1 epoch hash is correct.
- `start_epoch_num < epoch.number` -> `drop`: must have been duplicate batch,
we may be past this L1 block in the safe L2 chain. If a span-batch overlaps with older information,
it is dropped, since partially valid span-batches are not accepted.
- `start_epoch_num < prev_l2_block.l1_origin.number` -> `drop`:
epoch number cannot be older than the origin of parent block
- Max Sequencer time-drift checks:
- Note: The max time-drift is enforced for the *batch as a whole*, to keep the possible output variants small.
- Variables:
......@@ -313,7 +322,7 @@ Span-batch rules, in validation order:
- `next_epoch`: `block_input.origin`'s next L1 block.
It may reach to the next origin outside the L1 origins of the span.
- Rules:
- For each `block_input` that can be read from the span-batch:
- For each `block_input` whose timestamp is greater than `safe_head.timestamp`:
- `block_input.timestamp < block_input.origin.time` -> `drop`: enforce the min L2 timestamp rule.
- `block_input.timestamp > block_input.origin.time + max_sequencer_drift`: enforce the L2 timestamp drift rule,
but with exceptions to preserve above min L2 timestamp invariant:
......@@ -332,6 +341,16 @@ Span-batch rules, in validation order:
that is invalid or derived by other means exclusively:
- any transaction that is empty (zero length `tx_data`)
- any [deposited transactions][g-deposit-tx-type] (identified by the transaction type prefix byte in `tx_data`)
- Overlapped blocks checks:
- Note: If the span batch overlaps the current L2 safe chain, we must validate all overlapped blocks.
- Variables:
- `block_input`: an L2 block derived from the span-batch.
- `safe_block`: an L2 block from the current L2 safe chain, at same timestamp as `block_input`
- Rules:
- For each `block_input`, whose timestamp is less than `next_timestamp`:
- `block_input.l1_origin.number != safe_block.l1_origin.number` -> `drop`
- `block_input.transactions != safe_block.transactions` -> `drop`
- compare excluding deposit transactions
Once validated, the batch-queue then emits a block-input for each of the blocks included in the span-batch.
The next derivation stage is thus only aware of individual block inputs, similar to the previous V0 batch,
......
......@@ -32,6 +32,7 @@ chains following the same Superchain Target upgrade synchronously.
- [OP-Stack Protocol versions](#op-stack-protocol-versions)
- [Post-Bedrock Network upgrades](#post-bedrock-network-upgrades)
- [Regolith](#regolith)
- [Canyon](#canyon)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
......@@ -245,6 +246,7 @@ but the matching L1-origin information may not be present at the time of activat
([announcement](https://optimism.mirror.xyz/gQWKlrDqHzdKPsB1iUnI-cVN3v0NvsWnazK7ajlt1fI)).
- `v3.0.0-1`: 2023 Jan 13th - Bedrock pre-release, deployed on OP-Goerli, and later Base-Goerli.
- `v3.0.0`: 2023 Jun 6th - Bedrock, including the Regolith hardfork improvements, first deployed on OP-Mainnet.
- `v4.0.0`: TBD - Canyon
## Post-Bedrock Network upgrades
......@@ -273,3 +275,24 @@ The [execution engine specification](./exec-engine.md) specifies the L1 cost fun
The Regolith upgrade uses a *L2 block-timestamp* activation-rule, and is specified in both the
rollup-node (`regolith_time`) and execution engine (`config.regolithTime`).
## Canyon
The Canyon upgrade contains the Shapella upgrade from L1 and some minor protocol fixes.
- Shapella Upgrade
- [EIP-3651: Warm COINBASE](https://eips.ethereum.org/EIPS/eip-3651)
- [EIP-3855: PUSH0 instruction](https://eips.ethereum.org/EIPS/eip-3855)
- [EIP-3860: Limit and meter initcode](https://eips.ethereum.org/EIPS/eip-3860)
- [EIP-4895: Beacon chain push withdrawals as operations](https://eips.ethereum.org/EIPS/eip-4895)
- [Withdrawlas are prohibited in P2P Blocks](./rollup-node-p2p.md#block-validation)
- [Withdrawals should be set to the empty array with Canyon](./derivation.md#building-individual-payload-attributes)
- [EIP-6049: Deprecate SELFDESTRUCT](https://eips.ethereum.org/EIPS/eip-6049)
- [Modifies the EIP-1559 Denominator](./exec-engine.md#1559-parameters)
- [Channel Ordering Fix](./derivation.md#reading)
- [Adds the deposit nonce & deposit nonce version to the deposit receipt hash](./deposits.md#deposit-receipt)
- [Deploys the create2Deployer to `0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2`](./predeploys.md#create2deployer)
The Canyon upgrade uses a *L2 block-timestamp* activation-rule, and is specified in both the
rollup-node (`canyon_time`) and execution engine (`config.canyonTime`). Shanghai time in the
execution engine should be set to the same time as the Canyon time.
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