diff --git a/.changeset/angry-cameras-arrive.md b/.changeset/angry-cameras-arrive.md
new file mode 100644
index 0000000000000..5f4c82ce5ca0b
--- /dev/null
+++ b/.changeset/angry-cameras-arrive.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/contracts-bedrock': patch
+---
+
+Fix slither script
diff --git a/.changeset/cool-items-smell.md b/.changeset/cool-items-smell.md
new file mode 100644
index 0000000000000..890752fe05589
--- /dev/null
+++ b/.changeset/cool-items-smell.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/contracts-bedrock': patch
+---
+
+Update genesis-l2 task to set immutables in the bytecode
diff --git a/.changeset/curly-spies-switch.md b/.changeset/curly-spies-switch.md
new file mode 100644
index 0000000000000..b5f83c27b8909
--- /dev/null
+++ b/.changeset/curly-spies-switch.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/contracts-bedrock': patch
+---
+
+Fix build for smaller package
diff --git a/.changeset/dry-bears-beg.md b/.changeset/dry-bears-beg.md
new file mode 100644
index 0000000000000..d413cd8d96bb7
--- /dev/null
+++ b/.changeset/dry-bears-beg.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/contracts-bedrock': patch
+---
+
+Use the same initializable across codebase
diff --git a/.changeset/early-keys-know.md b/.changeset/early-keys-know.md
new file mode 100644
index 0000000000000..bc667ddcefbd1
--- /dev/null
+++ b/.changeset/early-keys-know.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/contracts-bedrock': patch
+---
+
+Update @foundry-rs/hardhat-forge@0.1.16
diff --git a/.changeset/eight-ravens-prove.md b/.changeset/eight-ravens-prove.md
new file mode 100644
index 0000000000000..406ccb2970194
--- /dev/null
+++ b/.changeset/eight-ravens-prove.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/contracts-bedrock': patch
+---
+
+Fix build on latest foundry
diff --git a/.changeset/eighty-kings-approve.md b/.changeset/eighty-kings-approve.md
new file mode 100644
index 0000000000000..65b88fb56e83d
--- /dev/null
+++ b/.changeset/eighty-kings-approve.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/core-utils': patch
+---
+
+Implement basic OpNodeProvider
diff --git a/.changeset/fast-mangos-smoke.md b/.changeset/fast-mangos-smoke.md
new file mode 100644
index 0000000000000..3d930d04893aa
--- /dev/null
+++ b/.changeset/fast-mangos-smoke.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/hardhat-deploy-config': patch
+---
+
+Support JSON-formatted deploy configs
diff --git a/.changeset/giant-gifts-attend.md b/.changeset/giant-gifts-attend.md
new file mode 100644
index 0000000000000..7f730e0d9593c
--- /dev/null
+++ b/.changeset/giant-gifts-attend.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/proxyd': minor
+---
+
+Add frontend rate limiting
diff --git a/.changeset/hip-shrimps-cheat.md b/.changeset/hip-shrimps-cheat.md
new file mode 100644
index 0000000000000..ef6c68e18f63d
--- /dev/null
+++ b/.changeset/hip-shrimps-cheat.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/contracts-bedrock': patch
+---
+
+Emit an extra event when withdrawals are initiated to make chainops easier
diff --git a/.changeset/little-squids-invent.md b/.changeset/little-squids-invent.md
new file mode 100644
index 0000000000000..64d24bff35493
--- /dev/null
+++ b/.changeset/little-squids-invent.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/proxyd': patch
+---
+
+Unwrap single RPC batches
diff --git a/.changeset/many-wasps-notice.md b/.changeset/many-wasps-notice.md
new file mode 100644
index 0000000000000..03777b57c5018
--- /dev/null
+++ b/.changeset/many-wasps-notice.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/contracts-bedrock': patch
+---
+
+Fix portal deployment to have L2OutputOracle proxy address
diff --git a/.changeset/modern-candles-obey.md b/.changeset/modern-candles-obey.md
new file mode 100644
index 0000000000000..e0700cb98e740
--- /dev/null
+++ b/.changeset/modern-candles-obey.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/contracts-bedrock': patch
+---
+
+Add watch task
diff --git a/.changeset/pretty-boxes-thank.md b/.changeset/pretty-boxes-thank.md
new file mode 100644
index 0000000000000..2da334474c551
--- /dev/null
+++ b/.changeset/pretty-boxes-thank.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/contracts-bedrock': patch
+---
+
+Add harhdat forge contract verification support
diff --git a/.changeset/quiet-books-design.md b/.changeset/quiet-books-design.md
new file mode 100644
index 0000000000000..8c7c7cdc84a5d
--- /dev/null
+++ b/.changeset/quiet-books-design.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/proxyd': patch
+---
+
+Parameterize full RPC request logging
diff --git a/.changeset/rare-suits-turn.md b/.changeset/rare-suits-turn.md
new file mode 100644
index 0000000000000..e0560db46a977
--- /dev/null
+++ b/.changeset/rare-suits-turn.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/contracts-bedrock': patch
+---
+
+Update hardhat-forge dep, remove dead deps
diff --git a/.changeset/slimy-spoons-repair.md b/.changeset/slimy-spoons-repair.md
new file mode 100644
index 0000000000000..4c9eef2f635e4
--- /dev/null
+++ b/.changeset/slimy-spoons-repair.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/contracts-bedrock': patch
+---
+
+bedrock-goerli-96f44f79 deployment
diff --git a/.changeset/smart-pumpkins-jam.md b/.changeset/smart-pumpkins-jam.md
new file mode 100644
index 0000000000000..987ada119315b
--- /dev/null
+++ b/.changeset/smart-pumpkins-jam.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/foundry': patch
+---
+
+Update to 64fe4acc97e6d76551cea7598c201f05ecd65639
diff --git a/.changeset/spotty-cameras-guess.md b/.changeset/spotty-cameras-guess.md
new file mode 100644
index 0000000000000..1e1bf3e491524
--- /dev/null
+++ b/.changeset/spotty-cameras-guess.md
@@ -0,0 +1,6 @@
+---
+'@eth-optimism/contracts-bedrock': patch
+'@eth-optimism/core-utils': patch
+---
+
+Update deposit transaction type
diff --git a/.changeset/wet-doors-collect.md b/.changeset/wet-doors-collect.md
new file mode 100644
index 0000000000000..e1f54d4b0d3e0
--- /dev/null
+++ b/.changeset/wet-doors-collect.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/integration-tests': patch
+---
+
+Modularize the itests away from depending on api of messenger
diff --git a/.changeset/wet-suns-develop.md b/.changeset/wet-suns-develop.md
new file mode 100644
index 0000000000000..1044d9df16b15
--- /dev/null
+++ b/.changeset/wet-suns-develop.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/contracts-bedrock': patch
+---
+
+Fix typechain exports
diff --git a/.changeset/wicked-impalas-wonder.md b/.changeset/wicked-impalas-wonder.md
new file mode 100644
index 0000000000000..7628cfccc2eb1
--- /dev/null
+++ b/.changeset/wicked-impalas-wonder.md
@@ -0,0 +1,5 @@
+---
+'@eth-optimism/sdk': minor
+---
+
+Add wstETH to sdk
diff --git a/.changeset/wise-ads-try.md b/.changeset/wise-ads-try.md
new file mode 100644
index 0000000000000..53231cd7a9e13
--- /dev/null
+++ b/.changeset/wise-ads-try.md
@@ -0,0 +1,7 @@
+---
+'@eth-optimism/sdk': minor
+'@eth-optimism/contracts-bedrock': patch
+'@eth-optimism/core-utils': patch
+---
+
+Updates the SDK to be compatible with Bedrock (via the "bedrock: true" constructor param). Updates the build pipeline for contracts-bedrock to export a properly formatted dist folder that matches our other packages.
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 646e21711fe1f..4ee85f886cab7 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -15,7 +15,7 @@ jobs:
name: Check if we should run
command: |
shopt -s inherit_errexit
- CHANGED=$(check-changed "packages/")
+ CHANGED=$(check-changed "(op-bindings|packages/)")
if [[ "$CHANGED" = "FALSE" ]]; then
circleci step halt
fi
@@ -141,7 +141,7 @@ jobs:
name: gas snapshot
command: |
forge --version
- forge snapshot --check || exit 0
+ forge snapshot --check
environment:
FOUNDRY_PROFILE: ci
working_directory: packages/contracts-bedrock
@@ -277,14 +277,19 @@ jobs:
image: ubuntu-2004:202111-02
steps:
- checkout
+ - run:
+ name: yarn dev deps # todo: what's the best way to pull in the dependencies for linting? yarn install above is using production env without dev dependencies
+ command: yarn install --production=false
+ - run:
+ name: specs toc
+ command: yarn lint:specs:toc && git diff --exit-code
- run:
name: markdown lint
- command: |
- docker run -v `pwd`:/workdir davidanson/markdownlint-cli2:0.4.0 "op-node/README.md" "./specs/**/*.md" "#**/node_modules"
+ command: yarn lint:specs:check
- run:
name: link lint
command: |
- docker run --init -it -v `pwd`:/input lycheeverse/lychee --verbose --no-progress --exclude-loopback --exclude twitter.com --exclude-mail /input/README.md "/input/specs/**/*.md" "/input/meta/**/*.md" "/input/op-node/**/*.md" || exit 0
+ docker run --init -it -v `pwd`:/input lycheeverse/lychee --verbose --no-progress --exclude-loopback --exclude twitter.com --exclude-mail /input/README.md "/input/specs/**/*.md"
fuzz-op-node:
docker:
@@ -449,17 +454,25 @@ jobs:
make devnet-up
- run:
name: Do a deposit
- no_output_timeout: 5m
command: |
- npx hardhat compile
- npx hardhat deposit \
+ timeout 5m npx hardhat deposit \
--to 0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244 \
--amount-eth 1 \
--private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
--network devnetL1
- working_directory: packages/contracts-bedrock/contracts-bedrock
+ working_directory: packages/contracts-bedrock
+ - run:
+ name: Deposit ERC20 through the bridge
+ command: timeout 5m npx hardhat deposit --network devnetL1
+ working_directory: packages/sdk
+ - run:
+ name: Check the status
+ command: npx hardhat check-op-node
+ working_directory: packages/contracts-bedrock
- run:
- command: echo "Deposit complete."
+ name: Check L2 Config
+ command: npx hardhat check-l2-config
+ working_directory: packages/contracts-bedrock
integration-tests:
machine:
@@ -691,20 +704,6 @@ workflows:
docker_context: ops/docker/hardhat
context:
- optimism
- - docker-publish:
- name: go-builder-release
- docker_file: ops/docker/go-builder/Dockerfile
- docker_tags: ethereumoptimism/go-builder:nightly
- docker_context: .
- context:
- - optimism
- - docker-publish:
- name: js-builder-release
- docker_file: ops/docker/js-builder/Dockerfile
- docker_tags: ethereumoptimism/js-builder:nightly
- docker_context: .
- context:
- - optimism
- docker-publish:
name: proxyd-release
docker_file: proxyd/Dockerfile
diff --git a/Makefile b/Makefile
index 8fccde6284ab2..02da5bd806dea 100644
--- a/Makefile
+++ b/Makefile
@@ -93,3 +93,7 @@ semgrep:
$(eval DEV_REF := $(shell git rev-parse develop))
SEMGREP_REPO_NAME=ethereum-optimism/optimism semgrep ci --baseline-commit=$(DEV_REF)
.PHONY: semgrep
+
+clean-node-modules:
+ rm -rf node_modules
+ rm -rf packages/**/node_modules
diff --git a/README.md b/README.md
index 7d13ea6717b45..9e70313a29161 100644
--- a/README.md
+++ b/README.md
@@ -58,7 +58,7 @@ root
├── teleportr: Bridge for teleporting ETH between L1 and L2 at low cost
~~ BEDROCK upgrade - Not production-ready yet, part of next major upgrade ~~
-├── contracts-bedrock: Bedrock smart contracts. To be merged with ./packages/contracts.
+├── packages/contracts-bedrock: Bedrock smart contracts. To be merged with ./packages/contracts.
├── op-bindings: Go bindings for Bedrock smart contracts.
├── op-batcher: L2-Batch Submitter, submits bundles of batches to L1
├── op-e2e: End-to-End testing of all bedrock components in Go
diff --git a/cloudbuild.yaml b/cloudbuild.yaml
new file mode 100644
index 0000000000000..ef7ef83c00846
--- /dev/null
+++ b/cloudbuild.yaml
@@ -0,0 +1,36 @@
+steps:
+ - name: 'gcr.io/kaniko-project/executor:latest'
+ args:
+ - --destination=us-central1-docker.pkg.dev/$PROJECT_ID/images/op-node:$_TAG
+ - --destination=us-central1-docker.pkg.dev/$PROJECT_ID/images/op-node:$COMMIT_SHA
+ - --dockerfile=op-node/Dockerfile
+ - --cache=true
+ - --cache-ttl=48h
+ waitFor: ['-']
+ - name: 'gcr.io/kaniko-project/executor:latest'
+ args:
+ - --destination=us-central1-docker.pkg.dev/$PROJECT_ID/images/op-batcher:$_TAG
+ - --destination=us-central1-docker.pkg.dev/$PROJECT_ID/images/op-batcher:$COMMIT_SHA
+ - --dockerfile=./op-batcher/Dockerfile
+ - --cache=true
+ - --cache-ttl=48h
+ waitFor: ['-']
+ - name: 'gcr.io/kaniko-project/executor:latest'
+ args:
+ - --destination=us-central1-docker.pkg.dev/$PROJECT_ID/images/op-proposer:$_TAG
+ - --destination=us-central1-docker.pkg.dev/$PROJECT_ID/images/op-proposer:$COMMIT_SHA
+ - --dockerfile=./op-proposer/Dockerfile
+ - --cache=true
+ - --cache-ttl=48h
+ waitFor: ['-']
+ - name: 'gcr.io/kaniko-project/executor:latest'
+ args:
+ - --destination=us-central1-docker.pkg.dev/$PROJECT_ID/images/deployer-bedrock:$_TAG
+ - --destination=us-central1-docker.pkg.dev/$PROJECT_ID/images/deployer-bedrock:$COMMIT_SHA
+ - --dockerfile=./ops/docker/Dockerfile.packages
+ - --target=deployer-bedrock
+ - --cache=true
+ - --cache-ttl=48h
+ waitFor: ['-']
+options:
+ machineType: N1_HIGHCPU_32
\ No newline at end of file
diff --git a/go.work b/go.work
index 78f6d67bbe717..221b53f13bfb2 100644
--- a/go.work
+++ b/go.work
@@ -18,7 +18,7 @@ use (
./state-surgery
)
-replace github.com/ethereum/go-ethereum v1.10.20 => github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220715235548-70b02481016d
+replace github.com/ethereum/go-ethereum v1.10.21 => github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220803173305-1c9d4cc76a6e
// For local debugging:
-//replace github.com/ethereum/go-ethereum v1.10.20 => ../go-ethereum
+//replace github.com/ethereum/go-ethereum v1.10.21 => ../go-ethereum
diff --git a/go.work.sum b/go.work.sum
index 427fc6ffe9913..6e378420bb0cb 100644
--- a/go.work.sum
+++ b/go.work.sum
@@ -15,6 +15,7 @@ cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJW
cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
+github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
diff --git a/integration-tests/test/queue-ingestion.spec.ts b/integration-tests/test/queue-ingestion.spec.ts
index 8011558c45d67..c3170dc7d6431 100644
--- a/integration-tests/test/queue-ingestion.spec.ts
+++ b/integration-tests/test/queue-ingestion.spec.ts
@@ -2,6 +2,7 @@
import { providers } from 'ethers'
import { applyL1ToL2Alias } from '@eth-optimism/core-utils'
import { asL2Provider } from '@eth-optimism/sdk'
+import { getContractInterface } from '@eth-optimism/contracts'
/* Imports: External */
import { expect } from './shared/setup'
@@ -47,11 +48,9 @@ describe('Queue Ingestion', () => {
receipt.remoteTx.hash
)) as any
- const params =
- env.messenger.contracts.l2.L2CrossDomainMessenger.interface.decodeFunctionData(
- 'relayMessage',
- l2Tx.data
- )
+ const params = getContractInterface(
+ 'L2CrossDomainMessenger'
+ ).decodeFunctionData('relayMessage', l2Tx.data)
expect(params._sender.toLowerCase()).to.equal(
env.l1Wallet.address.toLowerCase()
diff --git a/op-batcher/batch_submitter.go b/op-batcher/batch_submitter.go
index 9d3d7086c93c8..8aff5c61196f6 100644
--- a/op-batcher/batch_submitter.go
+++ b/op-batcher/batch_submitter.go
@@ -3,11 +3,17 @@ package op_batcher
import (
"bytes"
"context"
+ "crypto/ecdsa"
+ "errors"
"fmt"
"io"
"math/big"
+ "net"
+ "net/http"
+ _ "net/http/pprof"
"os"
"os/signal"
+ "strings"
"sync"
"syscall"
"time"
@@ -76,6 +82,26 @@ func Main(version string) func(ctx *cli.Context) error {
defer batchSubmitter.Stop()
l.Info("Batch Submitter started")
+ if cfg.PprofEnabled {
+ var srv http.Server
+ srv.Addr = net.JoinHostPort(cfg.PprofAddr, cfg.PprofPort)
+ // Start pprof server + register it's shutdown
+ go func() {
+ l.Info("pprof server started", "addr", srv.Addr)
+ if err := srv.ListenAndServe(); err != http.ErrServerClosed {
+ l.Error("error in pprof server", "err", err)
+ } else {
+ l.Info("pprof server shutting down")
+ }
+
+ }()
+ defer func() {
+ shutCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ err := srv.Shutdown(shutCtx)
+ l.Info("pprof server shut down", "err", err)
+ }()
+ }
interruptChannel := make(chan os.Signal, 1)
signal.Notify(interruptChannel, []os.Signal{
@@ -112,26 +138,43 @@ type BatchSubmitter struct {
func NewBatchSubmitter(cfg Config, l log.Logger) (*BatchSubmitter, error) {
ctx := context.Background()
- // Parse wallet private key that will be used to submit L2 txs to the batch
- // inbox address.
- wallet, err := hdwallet.NewFromMnemonic(cfg.Mnemonic)
- if err != nil {
- return nil, err
- }
+ var err error
+ var sequencerPrivKey *ecdsa.PrivateKey
+ var addr common.Address
- acc := accounts.Account{
- URL: accounts.URL{
- Path: cfg.SequencerHDPath,
- },
- }
- addr, err := wallet.Address(acc)
- if err != nil {
- return nil, err
+ if cfg.PrivateKey != "" && cfg.Mnemonic != "" {
+ return nil, errors.New("cannot specify both a private key and a mnemonic")
}
- sequencerPrivKey, err := wallet.PrivateKey(acc)
- if err != nil {
- return nil, err
+ if cfg.PrivateKey == "" {
+ // Parse wallet private key that will be used to submit L2 txs to the batch
+ // inbox address.
+ wallet, err := hdwallet.NewFromMnemonic(cfg.Mnemonic)
+ if err != nil {
+ return nil, err
+ }
+
+ acc := accounts.Account{
+ URL: accounts.URL{
+ Path: cfg.SequencerHDPath,
+ },
+ }
+ addr, err = wallet.Address(acc)
+ if err != nil {
+ return nil, err
+ }
+
+ sequencerPrivKey, err = wallet.PrivateKey(acc)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ sequencerPrivKey, err = crypto.HexToECDSA(strings.TrimPrefix(cfg.PrivateKey, "0x"))
+ if err != nil {
+ return nil, err
+ }
+
+ addr = crypto.PubkeyToAddress(sequencerPrivKey.PublicKey)
}
batchInboxAddress, err := parseAddress(cfg.SequencerBatchInboxAddress)
diff --git a/op-batcher/config.go b/op-batcher/config.go
index cba453408263f..078584355d29f 100644
--- a/op-batcher/config.go
+++ b/op-batcher/config.go
@@ -56,6 +56,9 @@ type Config struct {
// batched submission of sequencer transactions.
SequencerHDPath string
+ // PrivateKey is the private key used to submit sequencer transactions.
+ PrivateKey string
+
// SequencerBatchInboxAddress is the address in which to send batch
// transactions.
SequencerBatchInboxAddress string
@@ -68,6 +71,11 @@ type Config struct {
// LogTerminal if true, will log to stdout in terminal format. Otherwise the
// output will be in JSON format.
LogTerminal bool
+
+ // Flags for the pprof server
+ PprofEnabled bool
+ PprofAddr string
+ PprofPort string
}
// NewConfig parses the Config from the provided flags or environment variables.
@@ -86,9 +94,13 @@ func NewConfig(ctx *cli.Context) Config {
ResubmissionTimeout: ctx.GlobalDuration(flags.ResubmissionTimeoutFlag.Name),
Mnemonic: ctx.GlobalString(flags.MnemonicFlag.Name),
SequencerHDPath: ctx.GlobalString(flags.SequencerHDPathFlag.Name),
+ PrivateKey: ctx.GlobalString(flags.PrivateKeyFlag.Name),
SequencerBatchInboxAddress: ctx.GlobalString(flags.SequencerBatchInboxAddressFlag.Name),
/* Optional Flags */
- LogLevel: ctx.GlobalString(flags.LogLevelFlag.Name),
- LogTerminal: ctx.GlobalBool(flags.LogTerminalFlag.Name),
+ LogLevel: ctx.GlobalString(flags.LogLevelFlag.Name),
+ LogTerminal: ctx.GlobalBool(flags.LogTerminalFlag.Name),
+ PprofEnabled: ctx.GlobalBool(flags.PprofEnabledFlag.Name),
+ PprofAddr: ctx.GlobalString(flags.PprofAddrFlag.Name),
+ PprofPort: ctx.GlobalString(flags.PprofPortFlag.Name),
}
}
diff --git a/op-batcher/flags/flags.go b/op-batcher/flags/flags.go
index b5a34fd1178de..c09f67aeb6634 100644
--- a/op-batcher/flags/flags.go
+++ b/op-batcher/flags/flags.go
@@ -82,15 +82,18 @@ var (
Name: "mnemonic",
Usage: "The mnemonic used to derive the wallets for either the " +
"sequencer or the l2output",
- Required: true,
- EnvVar: prefixEnvVar("MNEMONIC"),
+ EnvVar: prefixEnvVar("MNEMONIC"),
}
SequencerHDPathFlag = cli.StringFlag{
Name: "sequencer-hd-path",
Usage: "The HD path used to derive the sequencer wallet from the " +
"mnemonic. The mnemonic flag must also be set.",
- Required: true,
- EnvVar: prefixEnvVar("SEQUENCER_HD_PATH"),
+ EnvVar: prefixEnvVar("SEQUENCER_HD_PATH"),
+ }
+ PrivateKeyFlag = cli.StringFlag{
+ Name: "private-key",
+ Usage: "The private key to use with the l2output wallet. Must not be used with mnemonic.",
+ EnvVar: prefixEnvVar("PRIVATE_KEY"),
}
SequencerBatchInboxAddressFlag = cli.StringFlag{
Name: "sequencer-batch-inbox-address",
@@ -113,6 +116,23 @@ var (
"in JSON format.",
EnvVar: prefixEnvVar("LOG_TERMINAL"),
}
+ PprofEnabledFlag = cli.BoolFlag{
+ Name: "pprof.enabled",
+ Usage: "Enable the pprof server",
+ EnvVar: prefixEnvVar("PPROF_ENABLED"),
+ }
+ PprofAddrFlag = cli.StringFlag{
+ Name: "pprof.addr",
+ Usage: "pprof listening address",
+ Value: "0.0.0.0",
+ EnvVar: prefixEnvVar("PPROF_ADDR"),
+ }
+ PprofPortFlag = cli.IntFlag{
+ Name: "pprof.port",
+ Usage: "pprof listening port",
+ Value: 6060,
+ EnvVar: prefixEnvVar("PPROF_PORT"),
+ }
)
var requiredFlags = []cli.Flag{
@@ -126,14 +146,18 @@ var requiredFlags = []cli.Flag{
NumConfirmationsFlag,
SafeAbortNonceTooLowCountFlag,
ResubmissionTimeoutFlag,
- MnemonicFlag,
- SequencerHDPathFlag,
SequencerBatchInboxAddressFlag,
}
var optionalFlags = []cli.Flag{
+ MnemonicFlag,
+ SequencerHDPathFlag,
+ PrivateKeyFlag,
LogLevelFlag,
LogTerminalFlag,
+ PprofEnabledFlag,
+ PprofAddrFlag,
+ PprofPortFlag,
}
// Flags contains the list of configuration options available to the binary.
diff --git a/op-batcher/go.mod b/op-batcher/go.mod
index c981f7b169508..63e9b3cb5ca6e 100644
--- a/op-batcher/go.mod
+++ b/op-batcher/go.mod
@@ -5,7 +5,7 @@ go 1.18
require (
github.com/ethereum-optimism/optimism/op-node v0.3.0
github.com/ethereum-optimism/optimism/op-proposer v0.3.0
- github.com/ethereum/go-ethereum v1.10.20
+ github.com/ethereum/go-ethereum v1.10.21
github.com/miguelmota/go-ethereum-hdwallet v0.1.1
github.com/urfave/cli v1.22.5
)
@@ -54,4 +54,4 @@ require (
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
)
-replace github.com/ethereum/go-ethereum v1.10.20 => github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220715235548-70b02481016d
+replace github.com/ethereum/go-ethereum v1.10.21 => github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220803173305-1c9d4cc76a6e
diff --git a/op-batcher/go.sum b/op-batcher/go.sum
index 1f18a8b449970..31a7c988694dc 100644
--- a/op-batcher/go.sum
+++ b/op-batcher/go.sum
@@ -153,8 +153,8 @@ github.com/ethereum-optimism/optimism/op-node v0.3.0 h1:jep/cbIbP7fjBSAR48yk5NJV
github.com/ethereum-optimism/optimism/op-node v0.3.0/go.mod h1:iF9AhYjr8jNeoCDNP/Vs/ywQ2USZU5L66AxZbSAUi0E=
github.com/ethereum-optimism/optimism/op-proposer v0.3.0 h1:K1ipZt3TLD0BJi7tKOmx8tCLXj9i4f4baBIhbPmUxk4=
github.com/ethereum-optimism/optimism/op-proposer v0.3.0/go.mod h1:GcQ9VCWz2zEVexecq5IYo/2eadK/y7IBOEfx4YV1QJk=
-github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220715235548-70b02481016d h1:w0DBXhp0sv0bWRDOCA/Y6yHOALU7qLLLf5/kE3YfFr4=
-github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220715235548-70b02481016d/go.mod h1:m2m08SAQ8XB0VcVBoDg9n74Dw5PUMl3hzv1NXVBFPfg=
+github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220803173305-1c9d4cc76a6e h1:hz+iywXjnqz6xA3lTLvtNL9OZyX76pS5SER4kZBmQLs=
+github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220803173305-1c9d4cc76a6e/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg=
github.com/ethereum/go-ethereum v1.10.4/go.mod h1:nEE0TP5MtxGzOMd7egIrbPJMQBnhVU3ELNxhBglIzhg=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
diff --git a/op-bindings/Makefile b/op-bindings/Makefile
index a6b60951a917f..8908f7d7361cc 100644
--- a/op-bindings/Makefile
+++ b/op-bindings/Makefile
@@ -18,22 +18,22 @@ gas-price-oracle-deployed: gas-price-oracle-bindings
./gen_deployed_bytecode.sh GasPriceOracle bindings
l1block-bindings:
- ./gen_bindings.sh L1Block bindings
+ ./gen_bindings.sh contracts/L2/L1Block.sol:L1Block bindings
l2-to-l1-message-passer-bindings:
- ./gen_bindings.sh L2ToL1MessagePasser bindings
+ ./gen_bindings.sh contracts/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser bindings
optimism-portal-bindings:
- ./gen_bindings.sh OptimismPortal bindings
+ ./gen_bindings.sh contracts/L1/OptimismPortal.sol:OptimismPortal bindings
l2-output-oracle-bindings:
- ./gen_bindings.sh L2OutputOracle bindings
+ ./gen_bindings.sh contracts/L1/L2OutputOracle.sol:L2OutputOracle bindings
gas-price-oracle-bindings:
- ./gen_bindings.sh GasPriceOracle bindings
+ ./gen_bindings.sh contracts/L2/GasPriceOracle.sol:GasPriceOracle bindings
address-manager-bindings:
- ./gen_bindings.sh AddressManager bindings
+ ./gen_bindings.sh contracts/legacy/AddressManager.sol:AddressManager bindings
mkdir:
mkdir -p bin bindings
diff --git a/op-bindings/bindings/l2outputoracle.go b/op-bindings/bindings/l2outputoracle.go
index 74868f695b6ea..6ee9136fd7322 100644
--- a/op-bindings/bindings/l2outputoracle.go
+++ b/op-bindings/bindings/l2outputoracle.go
@@ -37,7 +37,7 @@ type TypesOutputProposal struct {
// L2OutputOracleMetaData contains all meta data concerning the L2OutputOracle contract.
var L2OutputOracleMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_submissionInterval\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_genesisL2Output\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_historicalTotalBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startingBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startingTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockTime\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_proposer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"l1Timestamp\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"OutputDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"l1Timestamp\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"OutputProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousProposer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newProposer\",\"type\":\"address\"}],\"name\":\"ProposerChanged\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"HISTORICAL_TOTAL_BLOCKS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_BLOCK_TIME\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"STARTING_BLOCK_NUMBER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"STARTING_TIMESTAMP\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SUBMISSION_INTERVAL\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newProposer\",\"type\":\"address\"}],\"name\":\"changeProposer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"computeL2Timestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"internalType\":\"structTypes.OutputProposal\",\"name\":\"_proposal\",\"type\":\"tuple\"}],\"name\":\"deleteL2Output\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"getL2Output\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"internalType\":\"structTypes.OutputProposal\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_genesisL2Output\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_startingBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_proposer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_l1Blockhash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l1BlockNumber\",\"type\":\"uint256\"}],\"name\":\"proposeL2Output\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proposer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
- Bin: "0x6101806040523480156200001257600080fd5b50604051620023d0380380620023d08339810160408190526200003591620005f4565b6000608081905260a052600160c052428310620000cd5760405162461bcd60e51b8152602060048201526044602482018190527f4c324f75747075744f7261636c653a20696e697469616c204c3220626c6f636b908201527f2074696d65206d757374206265206c657373207468616e2063757272656e742060648201526374696d6560e01b608482015260a4015b60405180910390fd5b60e0889052610100869052610120859052610140849052610160839052620000f88786848462000106565b505050505050505062000666565b6000620001146001620001cf565b905080156200012d576000805461ff0019166101001790555b604080518082018252868152426020808301918252600088815260679091529290922090518155905160019091015560668490556200016b620002e2565b62000176836200034a565b620001818262000514565b8015620001c8576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b60008054610100900460ff161562000264578160ff16600114801562000208575062000206306200056660201b620014181760201c565b155b6200025c5760405162461bcd60e51b815260206004820152602e60248201526000805160206200239083398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000c4565b506000919050565b60005460ff808416911610620002c35760405162461bcd60e51b815260206004820152602e60248201526000805160206200239083398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000c4565b506000805460ff191660ff92909216919091179055600190565b919050565b600054610100900460ff166200033e5760405162461bcd60e51b815260206004820152602b6024820152600080516020620023b083398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000c4565b6200034862000575565b565b6033546001600160a01b03163314620003a65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620000c4565b6001600160a01b038116620004245760405162461bcd60e51b815260206004820152603760248201527f4c324f75747075744f7261636c653a206e65772070726f706f7365722063616e60448201527f6e6f7420626520746865207a65726f20616464726573730000000000000000006064820152608401620000c4565b6033546001600160a01b03166001600160a01b0316816001600160a01b031603620004b85760405162461bcd60e51b815260206004820152603860248201527f4c324f75747075744f7261636c653a2070726f706f7365722063616e6e6f742060448201527f6265207468652073616d6520617320746865206f776e657200000000000000006064820152608401620000c4565b6065546040516001600160a01b038084169216907f3d7728dc2838bb794606bd89f5a37930830b32060f69ee929bbfc59b669024dd90600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03163b151590565b600054610100900460ff16620005d15760405162461bcd60e51b815260206004820152602b6024820152600080516020620023b083398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000c4565b620003483362000514565b80516001600160a01b0381168114620002dd57600080fd5b600080600080600080600080610100898b0312156200061257600080fd5b885197506020890151965060408901519550606089015194506080890151935060a089015192506200064760c08a01620005dc565b91506200065760e08a01620005dc565b90509295985092959890939650565b60805160a05160c05160e05161010051610120516101405161016051611c7e620007126000396000818161013f01526111370152600081816101a801526111900152600081816101f201528181610e2901528181610f2501528181611061015261115b0152600061034b0152600081816102260152818161068901528181610f0101528181610f6401526112b70152600061070e015260006106e5015260006106bc0152611c7e6000f3fe6080604052600436106101285760003560e01c80638da5cb5b116100a5578063a8e4fb9011610074578063d20b1a5111610059578063d20b1a51146103ba578063dcec3348146103da578063f2fde38b146103ef57600080fd5b8063a8e4fb901461036d578063d1de856c1461039a57600080fd5b80638da5cb5b1461029f5780639aaab648146102eb578063a25ae557146102fe578063a4771aad1461033957600080fd5b80634ab65d73116100fc57806354fd4d50116100e157806354fd4d5014610248578063715018a61461026a57806372d5fe211461027f57600080fd5b80634ab65d73146101e0578063529933df1461021457600080fd5b80622134cc1461012d578063093b3d901461017457806320e9fcd4146101965780634599c788146101ca575b600080fd5b34801561013957600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561018057600080fd5b5061019461018f3660046118d4565b61040f565b005b3480156101a257600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b3480156101d657600080fd5b5061016160665481565b3480156101ec57600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b34801561022057600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b34801561025457600080fd5b5061025d6106b5565b60405161016b919061197a565b34801561027657600080fd5b50610194610758565b34801561028b57600080fd5b5061019461029a3660046119ef565b6107e5565b3480156102ab57600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161016b565b6101946102f9366004611a11565b610a6a565b34801561030a57600080fd5b5061031e610319366004611a43565b610e13565b6040805182518152602092830151928101929092520161016b565b34801561034557600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b34801561037957600080fd5b506065546102c69073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a657600080fd5b506101616103b5366004611a43565b61105d565b3480156103c657600080fd5b506101946103d5366004611a5c565b6111ba565b3480156103e657600080fd5b506101616112b3565b3480156103fb57600080fd5b5061019461040a3660046119ef565b6112e8565b60335473ffffffffffffffffffffffffffffffffffffffff163314610495576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6066546000908152606760209081526040918290208251808401909352805480845260019091015491830191909152825114610579576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604f60248201527f4c324f75747075744f7261636c653a206f757470757420726f6f7420746f206460448201527f656c65746520646f6573206e6f74206d6174636820746865206c61746573742060648201527f6f75747075742070726f706f73616c0000000000000000000000000000000000608482015260a40161048c565b8060200151826020015114610636576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f4c324f75747075744f7261636c653a2074696d657374616d7020746f2064656c60448201527f65746520646f6573206e6f74206d6174636820746865206c6174657374206f7560648201527f747075742070726f706f73616c00000000000000000000000000000000000000608482015260a40161048c565b606654602082015182516040517f11e942315215fbc11bf574b22ca610d001e704d870a2307833c188d31600b5c690600090a460668054600090815260676020526040812081815560010155546106ae907f000000000000000000000000000000000000000000000000000000000000000090611ad1565b6066555050565b60606106e07f0000000000000000000000000000000000000000000000000000000000000000611434565b6107097f0000000000000000000000000000000000000000000000000000000000000000611434565b6107327f0000000000000000000000000000000000000000000000000000000000000000611434565b60405160200161074493929190611ae8565b604051602081830303815290604052905090565b60335473ffffffffffffffffffffffffffffffffffffffff1633146107d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161048c565b6107e36000611569565b565b60335473ffffffffffffffffffffffffffffffffffffffff163314610866576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161048c565b73ffffffffffffffffffffffffffffffffffffffff8116610909576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c324f75747075744f7261636c653a206e65772070726f706f7365722063616e60448201527f6e6f7420626520746865207a65726f2061646472657373000000000000000000606482015260840161048c565b60335473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036109dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c324f75747075744f7261636c653a2070726f706f7365722063616e6e6f742060448201527f6265207468652073616d6520617320746865206f776e65720000000000000000606482015260840161048c565b60655460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f3d7728dc2838bb794606bd89f5a37930830b32060f69ee929bbfc59b669024dd90600090a3606580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60655473ffffffffffffffffffffffffffffffffffffffff163314610b11576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c324f75747075744f7261636c653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642062792070726f706f736572000000000000000000606482015260840161048c565b610b196112b3565b8314610bcd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a40161048c565b42610bd78461105d565b10610c64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e207468652066757475726500000000000000000000606482015260840161048c565b83610cf1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161048c565b8115610dad5781814014610dad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b6861736820646f6573206e60448201527f6f74206d6174636820746865206861736820617420746865206578706563746560648201527f6420686569676874000000000000000000000000000000000000000000000000608482015260a40161048c565b6040805180820182528581524260208083018281526000888152606790925284822093518455516001909301929092556066869055915185929187917fc120f5e881491e6e212befa39e36b8f57d5eca31915f2e5d60a420f418caa6df9190a450505050565b60408051808201909152600080825260208201527f0000000000000000000000000000000000000000000000000000000000000000821015610efd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d6265722063616e60448201527f6e6f74206265206c657373207468616e20746865207374617274696e6720626c60648201527f6f636b206e756d6265722e000000000000000000000000000000000000000000608482015260a40161048c565b60007f0000000000000000000000000000000000000000000000000000000000000000610f4a7f000000000000000000000000000000000000000000000000000000000000000085611ad1565b610f549190611b8d565b905060008115610f9757610f88827f0000000000000000000000000000000000000000000000000000000000000000611ad1565b610f929085611ba1565b610f99565b835b600081815260676020908152604091829020825180840190935280548084526001909101549183019190915291925090611055576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a204e6f206f757470757420666f756e642060448201527f666f72207468617420626c6f636b206e756d6265722e00000000000000000000606482015260840161048c565b949350505050565b60007f0000000000000000000000000000000000000000000000000000000000000000821015611135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605360248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f742062652067726561746572207468616e206f7220657175616c20746f20737460648201527f617274696e6720626c6f636b206e756d62657200000000000000000000000000608482015260a40161048c565b7f00000000000000000000000000000000000000000000000000000000000000006111807f000000000000000000000000000000000000000000000000000000000000000084611ad1565b61118a9190611bb9565b6111b4907f0000000000000000000000000000000000000000000000000000000000000000611ba1565b92915050565b60006111c660016115e0565b905080156111fb57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6040805180820182528681524260208083019182526000888152606790915292909220905181559051600190910155606684905561123761176b565b611240836107e5565b61124982611569565b80156112ac57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006066546112e39190611ba1565b905090565b60335473ffffffffffffffffffffffffffffffffffffffff163314611369576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161048c565b73ffffffffffffffffffffffffffffffffffffffff811661140c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161048c565b61141581611569565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60608160000361147757505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156114a1578061148b81611bf6565b915061149a9050600a83611c2e565b915061147b565b60008167ffffffffffffffff8111156114bc576114bc6118a5565b6040519080825280601f01601f1916602001820160405280156114e6576020820181803683370190505b5090505b8415611055576114fb600183611ad1565b9150611508600a86611b8d565b611513906030611ba1565b60f81b81838151811061152857611528611c42565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611562600a86611c2e565b94506114ea565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008054610100900460ff1615611697578160ff1660011480156116035750303b155b61168f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161048c565b506000919050565b60005460ff80841691161061172e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161048c565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff16611802576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161048c565b6107e3600054610100900460ff1661189c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161048c565b6107e333611569565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000604082840312156118e657600080fd5b6040516040810181811067ffffffffffffffff82111715611930577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052823581526020928301359281019290925250919050565b60005b8381101561196557818101518382015260200161194d565b83811115611974576000848401525b50505050565b602081526000825180602084015261199981604085016020870161194a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461176657600080fd5b600060208284031215611a0157600080fd5b611a0a826119cb565b9392505050565b60008060008060808587031215611a2757600080fd5b5050823594602084013594506040840135936060013592509050565b600060208284031215611a5557600080fd5b5035919050565b60008060008060808587031215611a7257600080fd5b8435935060208501359250611a89604086016119cb565b9150611a97606086016119cb565b905092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611ae357611ae3611aa2565b500390565b60008451611afa81846020890161194a565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611b36816001850160208a0161194a565b60019201918201528351611b5181600284016020880161194a565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611b9c57611b9c611b5e565b500690565b60008219821115611bb457611bb4611aa2565b500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611bf157611bf1611aa2565b500290565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611c2757611c27611aa2565b5060010190565b600082611c3d57611c3d611b5e565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e747261637420697320616c726561496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069",
+ Bin: "0x6101806040523480156200001257600080fd5b5060405162002159380380620021598339810160408190526200003591620005a3565b6000608081905260a052600160c052428310620000cd5760405162461bcd60e51b8152602060048201526044602482018190527f4c324f75747075744f7261636c653a20696e697469616c204c3220626c6f636b908201527f2074696d65206d757374206265206c657373207468616e2063757272656e742060648201526374696d6560e01b608482015260a4015b60405180910390fd5b60e0889052610100869052610120859052610140849052610160839052620000f88786848462000106565b505050505050505062000615565b600054610100900460ff1615808015620001275750600054600160ff909116105b8062000157575062000144306200028260201b620013171760201c565b15801562000157575060005460ff166001145b620001bc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000c4565b6000805460ff191660011790558015620001e0576000805461ff0019166101001790555b604080518082018252868152426020808301918252600088815260679091529290922090518155905160019091015560668490556200021e62000291565b6200022983620002f9565b620002348262000471565b80156200027b576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b6001600160a01b03163b151590565b600054610100900460ff16620002ed5760405162461bcd60e51b815260206004820152602b60248201526000805160206200213983398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000c4565b620002f7620004c3565b565b620003036200052a565b6001600160a01b038116620003815760405162461bcd60e51b815260206004820152603760248201527f4c324f75747075744f7261636c653a206e65772070726f706f7365722063616e60448201527f6e6f7420626520746865207a65726f20616464726573730000000000000000006064820152608401620000c4565b6033546001600160a01b03166001600160a01b0316816001600160a01b031603620004155760405162461bcd60e51b815260206004820152603860248201527f4c324f75747075744f7261636c653a2070726f706f7365722063616e6e6f742060448201527f6265207468652073616d6520617320746865206f776e657200000000000000006064820152608401620000c4565b6065546040516001600160a01b038084169216907f3d7728dc2838bb794606bd89f5a37930830b32060f69ee929bbfc59b669024dd90600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166200051f5760405162461bcd60e51b815260206004820152602b60248201526000805160206200213983398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000c4565b620002f73362000471565b6033546001600160a01b03163314620002f75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620000c4565b80516001600160a01b03811681146200059e57600080fd5b919050565b600080600080600080600080610100898b031215620005c157600080fd5b885197506020890151965060408901519550606089015194506080890151935060a08901519250620005f660c08a0162000586565b91506200060660e08a0162000586565b90509295985092959890939650565b60805160a05160c05160e05161010051610120516101405161016051611a78620006c16000396000818161013f0152610fcc0152600081816101a801526110250152600081816101f201528181610cbe01528181610dba01528181610ef60152610ff00152600061034b0152600081816102260152818161061001528181610d9601528181610df9015261122f015260006106950152600061066c015260006106430152611a786000f3fe6080604052600436106101285760003560e01c80638da5cb5b116100a5578063a8e4fb9011610074578063d20b1a5111610059578063d20b1a51146103ba578063dcec3348146103da578063f2fde38b146103ef57600080fd5b8063a8e4fb901461036d578063d1de856c1461039a57600080fd5b80638da5cb5b1461029f5780639aaab648146102eb578063a25ae557146102fe578063a4771aad1461033957600080fd5b80634ab65d73116100fc57806354fd4d50116100e157806354fd4d5014610248578063715018a61461026a57806372d5fe211461027f57600080fd5b80634ab65d73146101e0578063529933df1461021457600080fd5b80622134cc1461012d578063093b3d901461017457806320e9fcd4146101965780634599c788146101ca575b600080fd5b34801561013957600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561018057600080fd5b5061019461018f3660046116c9565b61040f565b005b3480156101a257600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b3480156101d657600080fd5b5061016160665481565b3480156101ec57600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b34801561022057600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b34801561025457600080fd5b5061025d61063c565b60405161016b919061176f565b34801561027657600080fd5b506101946106df565b34801561028b57600080fd5b5061019461029a3660046117e9565b6106f3565b3480156102ab57600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161016b565b6101946102f936600461180b565b6108ff565b34801561030a57600080fd5b5061031e61031936600461183d565b610ca8565b6040805182518152602092830151928101929092520161016b565b34801561034557600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b34801561037957600080fd5b506065546102c69073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a657600080fd5b506101616103b536600461183d565b610ef2565b3480156103c657600080fd5b506101946103d5366004611856565b61104f565b3480156103e657600080fd5b5061016161122b565b3480156103fb57600080fd5b5061019461040a3660046117e9565b611260565b610417611333565b6066546000908152606760209081526040918290208251808401909352805480845260019091015491830191909152825114610500576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604f60248201527f4c324f75747075744f7261636c653a206f757470757420726f6f7420746f206460448201527f656c65746520646f6573206e6f74206d6174636820746865206c61746573742060648201527f6f75747075742070726f706f73616c0000000000000000000000000000000000608482015260a4015b60405180910390fd5b80602001518260200151146105bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f4c324f75747075744f7261636c653a2074696d657374616d7020746f2064656c60448201527f65746520646f6573206e6f74206d6174636820746865206c6174657374206f7560648201527f747075742070726f706f73616c00000000000000000000000000000000000000608482015260a4016104f7565b606654602082015182516040517f11e942315215fbc11bf574b22ca610d001e704d870a2307833c188d31600b5c690600090a46066805460009081526067602052604081208181556001015554610635907f0000000000000000000000000000000000000000000000000000000000000000906118cb565b6066555050565b60606106677f00000000000000000000000000000000000000000000000000000000000000006113b4565b6106907f00000000000000000000000000000000000000000000000000000000000000006113b4565b6106b97f00000000000000000000000000000000000000000000000000000000000000006113b4565b6040516020016106cb939291906118e2565b604051602081830303815290604052905090565b6106e7611333565b6106f160006114e9565b565b6106fb611333565b73ffffffffffffffffffffffffffffffffffffffff811661079e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c324f75747075744f7261636c653a206e65772070726f706f7365722063616e60448201527f6e6f7420626520746865207a65726f206164647265737300000000000000000060648201526084016104f7565b60335473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610871576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c324f75747075744f7261636c653a2070726f706f7365722063616e6e6f742060448201527f6265207468652073616d6520617320746865206f776e6572000000000000000060648201526084016104f7565b60655460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f3d7728dc2838bb794606bd89f5a37930830b32060f69ee929bbfc59b669024dd90600090a3606580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60655473ffffffffffffffffffffffffffffffffffffffff1633146109a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c324f75747075744f7261636c653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642062792070726f706f73657200000000000000000060648201526084016104f7565b6109ae61122b565b8314610a62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a4016104f7565b42610a6c84610ef2565b10610af9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e20746865206675747572650000000000000000000060648201526084016104f7565b83610b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f206861736800000000000060648201526084016104f7565b8115610c425781814014610c42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b6861736820646f6573206e60448201527f6f74206d6174636820746865206861736820617420746865206578706563746560648201527f6420686569676874000000000000000000000000000000000000000000000000608482015260a4016104f7565b6040805180820182528581524260208083018281526000888152606790925284822093518455516001909301929092556066869055915185929187917fc120f5e881491e6e212befa39e36b8f57d5eca31915f2e5d60a420f418caa6df9190a450505050565b60408051808201909152600080825260208201527f0000000000000000000000000000000000000000000000000000000000000000821015610d92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d6265722063616e60448201527f6e6f74206265206c657373207468616e20746865207374617274696e6720626c60648201527f6f636b206e756d6265722e000000000000000000000000000000000000000000608482015260a4016104f7565b60007f0000000000000000000000000000000000000000000000000000000000000000610ddf7f0000000000000000000000000000000000000000000000000000000000000000856118cb565b610de99190611987565b905060008115610e2c57610e1d827f00000000000000000000000000000000000000000000000000000000000000006118cb565b610e27908561199b565b610e2e565b835b600081815260676020908152604091829020825180840190935280548084526001909101549183019190915291925090610eea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a204e6f206f757470757420666f756e642060448201527f666f72207468617420626c6f636b206e756d6265722e0000000000000000000060648201526084016104f7565b949350505050565b60007f0000000000000000000000000000000000000000000000000000000000000000821015610fca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605360248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f742062652067726561746572207468616e206f7220657175616c20746f20737460648201527f617274696e6720626c6f636b206e756d62657200000000000000000000000000608482015260a4016104f7565b7f00000000000000000000000000000000000000000000000000000000000000006110157f0000000000000000000000000000000000000000000000000000000000000000846118cb565b61101f91906119b3565b611049907f000000000000000000000000000000000000000000000000000000000000000061199b565b92915050565b600054610100900460ff161580801561106f5750600054600160ff909116105b806110895750303b158015611089575060005460ff166001145b611115576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104f7565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561117357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b604080518082018252868152426020808301918252600088815260679091529290922090518155905160019091015560668490556111af611560565b6111b8836106f3565b6111c1826114e9565b801561122457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b60007f000000000000000000000000000000000000000000000000000000000000000060665461125b919061199b565b905090565b611268611333565b73ffffffffffffffffffffffffffffffffffffffff811661130b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104f7565b611314816114e9565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104f7565b6060816000036113f757505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611421578061140b816119f0565b915061141a9050600a83611a28565b91506113fb565b60008167ffffffffffffffff81111561143c5761143c61169a565b6040519080825280601f01601f191660200182016040528015611466576020820181803683370190505b5090505b8415610eea5761147b6001836118cb565b9150611488600a86611987565b61149390603061199b565b60f81b8183815181106114a8576114a8611a3c565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506114e2600a86611a28565b945061146a565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166115f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104f7565b6106f1600054610100900460ff16611691576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104f7565b6106f1336114e9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000604082840312156116db57600080fd5b6040516040810181811067ffffffffffffffff82111715611725577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052823581526020928301359281019290925250919050565b60005b8381101561175a578181015183820152602001611742565b83811115611769576000848401525b50505050565b602081526000825180602084015261178e81604085016020870161173f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146117e457600080fd5b919050565b6000602082840312156117fb57600080fd5b611804826117c0565b9392505050565b6000806000806080858703121561182157600080fd5b5050823594602084013594506040840135936060013592509050565b60006020828403121561184f57600080fd5b5035919050565b6000806000806080858703121561186c57600080fd5b8435935060208501359250611883604086016117c0565b9150611891606086016117c0565b905092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156118dd576118dd61189c565b500390565b600084516118f481846020890161173f565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611930816001850160208a0161173f565b6001920191820152835161194b81600284016020880161173f565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261199657611996611958565b500690565b600082198211156119ae576119ae61189c565b500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156119eb576119eb61189c565b500290565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611a2157611a2161189c565b5060010190565b600082611a3757611a37611958565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069",
}
// L2OutputOracleABI is the input ABI used to generate the binding from.
diff --git a/op-bindings/bindings/l2tol1messagepasser.go b/op-bindings/bindings/l2tol1messagepasser.go
index 190ebd1f12736..fcbd08d2ecd5d 100644
--- a/op-bindings/bindings/l2tol1messagepasser.go
+++ b/op-bindings/bindings/l2tol1messagepasser.go
@@ -30,8 +30,8 @@ var (
// L2ToL1MessagePasserMetaData contains all meta data concerning the L2ToL1MessagePasser contract.
var L2ToL1MessagePasserMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"WithdrawalInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawerBalanceBurnt\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"initiateWithdrawal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"sentMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
- Bin: "0x60e060405234801561001057600080fd5b506000608081905260a052600160c05260805160a05160c0516108e861004f60003960006102d3015260006102aa0152600061028101526108e86000f3fe60806040526004361061005e5760003560e01c806382e3702d1161004357806382e3702d146100c7578063affed0e014610107578063c2b3e5ac1461012b57600080fd5b806344df8e701461008757806354fd4d501461009c57600080fd5b366100825761008033620186a060405180602001604052806000815250610139565b005b600080fd5b34801561009357600080fd5b50610080610242565b3480156100a857600080fd5b506100b161027a565b6040516100be919061055c565b60405180910390f35b3480156100d357600080fd5b506100f76100e2366004610576565b60006020819052908152604090205460ff1681565b60405190151581526020016100be565b34801561011357600080fd5b5061011d60015481565b6040519081526020016100be565b6100806101393660046105be565b600061019e6040518060c0016040528060015481526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff1681526020013481526020018581526020018481525061031d565b6000818152602081905260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915554905191925073ffffffffffffffffffffffffffffffffffffffff8616913391907f87bf7b546c8de873abb0db5b579ec131f8d0cf5b14f39933551cf9ced23a61369061022c903490899089906106c2565b60405180910390a4505060018054810190555050565b4761024c8161036a565b60405181907f7967de617a5ac1cc7eba2d6f37570a0135afa950d8bb77cdd35f0d0b4e85a16f90600090a250565b60606102a57f0000000000000000000000000000000000000000000000000000000000000000610399565b6102ce7f0000000000000000000000000000000000000000000000000000000000000000610399565b6102f77f0000000000000000000000000000000000000000000000000000000000000000610399565b604051602001610309939291906106ea565b604051602081830303815290604052905090565b80516020808301516040808501516060860151608087015160a0880151935160009761034d979096959101610760565b604051602081830303815290604052805190602001209050919050565b80604051610377906104d6565b6040518091039082f0905080158015610394573d6000803e3d6000fd5b505050565b6060816000036103dc57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561040657806103f0816107e6565b91506103ff9050600a8361084d565b91506103e0565b60008167ffffffffffffffff8111156104215761042161058f565b6040519080825280601f01601f19166020018201604052801561044b576020820181803683370190505b5090505b84156104ce57610460600183610861565b915061046d600a86610878565b61047890603061088c565b60f81b81838151811061048d5761048d6108a4565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506104c7600a8661084d565b945061044f565b949350505050565b6008806108d483390190565b60005b838110156104fd5781810151838201526020016104e5565b8381111561050c576000848401525b50505050565b6000815180845261052a8160208601602086016104e2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061056f6020830184610512565b9392505050565b60006020828403121561058857600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156105d357600080fd5b833573ffffffffffffffffffffffffffffffffffffffff811681146105f757600080fd5b925060208401359150604084013567ffffffffffffffff8082111561061b57600080fd5b818601915086601f83011261062f57600080fd5b8135818111156106415761064161058f565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156106875761068761058f565b816040528281528960208487010111156106a057600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b8381528260208201526060604082015260006106e16060830184610512565b95945050505050565b600084516106fc8184602089016104e2565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610738816001850160208a016104e2565b600192019182015283516107538160028401602088016104e2565b0160020195945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526107ab60c0830184610512565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610817576108176107b7565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261085c5761085c61081e565b500490565b600082821015610873576108736107b7565b500390565b6000826108875761088761081e565b500690565b6000821982111561089f5761089f6107b7565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfe608060405230fffea164736f6c634300080f000a",
+ ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"WithdrawalInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"WithdrawalInitiatedExtension1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawerBalanceBurnt\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"initiateWithdrawal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"sentMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
+ Bin: "0x60e060405234801561001057600080fd5b506000608081905260a052600160c05260805160a05160c05161091361004f60003960006102fe015260006102d5015260006102ac01526109136000f3fe60806040526004361061005e5760003560e01c806382e3702d1161004357806382e3702d146100c7578063affed0e014610107578063c2b3e5ac1461012b57600080fd5b806344df8e701461008757806354fd4d501461009c57600080fd5b366100825761008033620186a060405180602001604052806000815250610139565b005b600080fd5b34801561009357600080fd5b5061008061026d565b3480156100a857600080fd5b506100b16102a5565b6040516100be9190610587565b60405180910390f35b3480156100d357600080fd5b506100f76100e23660046105a1565b60006020819052908152604090205460ff1681565b60405190151581526020016100be565b34801561011357600080fd5b5061011d60015481565b6040519081526020016100be565b6100806101393660046105e9565b600061019e6040518060c0016040528060015481526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff16815260200134815260200185815260200184815250610348565b6000818152602081905260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915554905191925073ffffffffffffffffffffffffffffffffffffffff8616913391907f87bf7b546c8de873abb0db5b579ec131f8d0cf5b14f39933551cf9ced23a61369061022c903490899089906106ed565b60405180910390a460405181907f2ef6ceb1668fdd882b1f89ddd53a666b0c1113d14cf90c0fbf97c7b1ad880fbb90600090a2505060018054810190555050565b4761027781610395565b60405181907f7967de617a5ac1cc7eba2d6f37570a0135afa950d8bb77cdd35f0d0b4e85a16f90600090a250565b60606102d07f00000000000000000000000000000000000000000000000000000000000000006103c4565b6102f97f00000000000000000000000000000000000000000000000000000000000000006103c4565b6103227f00000000000000000000000000000000000000000000000000000000000000006103c4565b60405160200161033493929190610715565b604051602081830303815290604052905090565b80516020808301516040808501516060860151608087015160a0880151935160009761037897909695910161078b565b604051602081830303815290604052805190602001209050919050565b806040516103a290610501565b6040518091039082f09050801580156103bf573d6000803e3d6000fd5b505050565b60608160000361040757505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610431578061041b81610811565b915061042a9050600a83610878565b915061040b565b60008167ffffffffffffffff81111561044c5761044c6105ba565b6040519080825280601f01601f191660200182016040528015610476576020820181803683370190505b5090505b84156104f95761048b60018361088c565b9150610498600a866108a3565b6104a39060306108b7565b60f81b8183815181106104b8576104b86108cf565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506104f2600a86610878565b945061047a565b949350505050565b6008806108ff83390190565b60005b83811015610528578181015183820152602001610510565b83811115610537576000848401525b50505050565b6000815180845261055581602086016020860161050d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061059a602083018461053d565b9392505050565b6000602082840312156105b357600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156105fe57600080fd5b833573ffffffffffffffffffffffffffffffffffffffff8116811461062257600080fd5b925060208401359150604084013567ffffffffffffffff8082111561064657600080fd5b818601915086601f83011261065a57600080fd5b81358181111561066c5761066c6105ba565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156106b2576106b26105ba565b816040528281528960208487010111156106cb57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b83815282602082015260606040820152600061070c606083018461053d565b95945050505050565b6000845161072781846020890161050d565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610763816001850160208a0161050d565b6001920191820152835161077e81600284016020880161050d565b0160020195945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526107d660c083018461053d565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610842576108426107e2565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261088757610887610849565b500490565b60008282101561089e5761089e6107e2565b500390565b6000826108b2576108b2610849565b500690565b600082198211156108ca576108ca6107e2565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfe608060405230fffea164736f6c634300080f000a",
}
// L2ToL1MessagePasserABI is the input ABI used to generate the binding from.
@@ -522,6 +522,150 @@ func (_L2ToL1MessagePasser *L2ToL1MessagePasserFilterer) ParseWithdrawalInitiate
return event, nil
}
+// L2ToL1MessagePasserWithdrawalInitiatedExtension1Iterator is returned from FilterWithdrawalInitiatedExtension1 and is used to iterate over the raw logs and unpacked data for WithdrawalInitiatedExtension1 events raised by the L2ToL1MessagePasser contract.
+type L2ToL1MessagePasserWithdrawalInitiatedExtension1Iterator struct {
+ Event *L2ToL1MessagePasserWithdrawalInitiatedExtension1 // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *L2ToL1MessagePasserWithdrawalInitiatedExtension1Iterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(L2ToL1MessagePasserWithdrawalInitiatedExtension1)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(L2ToL1MessagePasserWithdrawalInitiatedExtension1)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *L2ToL1MessagePasserWithdrawalInitiatedExtension1Iterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *L2ToL1MessagePasserWithdrawalInitiatedExtension1Iterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// L2ToL1MessagePasserWithdrawalInitiatedExtension1 represents a WithdrawalInitiatedExtension1 event raised by the L2ToL1MessagePasser contract.
+type L2ToL1MessagePasserWithdrawalInitiatedExtension1 struct {
+ Hash [32]byte
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterWithdrawalInitiatedExtension1 is a free log retrieval operation binding the contract event 0x2ef6ceb1668fdd882b1f89ddd53a666b0c1113d14cf90c0fbf97c7b1ad880fbb.
+//
+// Solidity: event WithdrawalInitiatedExtension1(bytes32 indexed hash)
+func (_L2ToL1MessagePasser *L2ToL1MessagePasserFilterer) FilterWithdrawalInitiatedExtension1(opts *bind.FilterOpts, hash [][32]byte) (*L2ToL1MessagePasserWithdrawalInitiatedExtension1Iterator, error) {
+
+ var hashRule []interface{}
+ for _, hashItem := range hash {
+ hashRule = append(hashRule, hashItem)
+ }
+
+ logs, sub, err := _L2ToL1MessagePasser.contract.FilterLogs(opts, "WithdrawalInitiatedExtension1", hashRule)
+ if err != nil {
+ return nil, err
+ }
+ return &L2ToL1MessagePasserWithdrawalInitiatedExtension1Iterator{contract: _L2ToL1MessagePasser.contract, event: "WithdrawalInitiatedExtension1", logs: logs, sub: sub}, nil
+}
+
+// WatchWithdrawalInitiatedExtension1 is a free log subscription operation binding the contract event 0x2ef6ceb1668fdd882b1f89ddd53a666b0c1113d14cf90c0fbf97c7b1ad880fbb.
+//
+// Solidity: event WithdrawalInitiatedExtension1(bytes32 indexed hash)
+func (_L2ToL1MessagePasser *L2ToL1MessagePasserFilterer) WatchWithdrawalInitiatedExtension1(opts *bind.WatchOpts, sink chan<- *L2ToL1MessagePasserWithdrawalInitiatedExtension1, hash [][32]byte) (event.Subscription, error) {
+
+ var hashRule []interface{}
+ for _, hashItem := range hash {
+ hashRule = append(hashRule, hashItem)
+ }
+
+ logs, sub, err := _L2ToL1MessagePasser.contract.WatchLogs(opts, "WithdrawalInitiatedExtension1", hashRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(L2ToL1MessagePasserWithdrawalInitiatedExtension1)
+ if err := _L2ToL1MessagePasser.contract.UnpackLog(event, "WithdrawalInitiatedExtension1", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// ParseWithdrawalInitiatedExtension1 is a log parse operation binding the contract event 0x2ef6ceb1668fdd882b1f89ddd53a666b0c1113d14cf90c0fbf97c7b1ad880fbb.
+//
+// Solidity: event WithdrawalInitiatedExtension1(bytes32 indexed hash)
+func (_L2ToL1MessagePasser *L2ToL1MessagePasserFilterer) ParseWithdrawalInitiatedExtension1(log types.Log) (*L2ToL1MessagePasserWithdrawalInitiatedExtension1, error) {
+ event := new(L2ToL1MessagePasserWithdrawalInitiatedExtension1)
+ if err := _L2ToL1MessagePasser.contract.UnpackLog(event, "WithdrawalInitiatedExtension1", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
// L2ToL1MessagePasserWithdrawerBalanceBurntIterator is returned from FilterWithdrawerBalanceBurnt and is used to iterate over the raw logs and unpacked data for WithdrawerBalanceBurnt events raised by the L2ToL1MessagePasser contract.
type L2ToL1MessagePasserWithdrawerBalanceBurntIterator struct {
Event *L2ToL1MessagePasserWithdrawerBalanceBurnt // Event containing the contract specifics and raw log
diff --git a/op-bindings/bindings/l2tol1messagepasser_deployed.go b/op-bindings/bindings/l2tol1messagepasser_deployed.go
index b3b953211f140..9f6c83895df08 100644
--- a/op-bindings/bindings/l2tol1messagepasser_deployed.go
+++ b/op-bindings/bindings/l2tol1messagepasser_deployed.go
@@ -2,4 +2,4 @@
// This file is a generated binding and any manual changes will be lost.
package bindings
-var L2ToL1MessagePasserDeployedBin = "0x60806040526004361061005e5760003560e01c806382e3702d1161004357806382e3702d146100c7578063affed0e014610107578063c2b3e5ac1461012b57600080fd5b806344df8e701461008757806354fd4d501461009c57600080fd5b366100825761008033620186a060405180602001604052806000815250610139565b005b600080fd5b34801561009357600080fd5b50610080610242565b3480156100a857600080fd5b506100b161027a565b6040516100be919061055c565b60405180910390f35b3480156100d357600080fd5b506100f76100e2366004610576565b60006020819052908152604090205460ff1681565b60405190151581526020016100be565b34801561011357600080fd5b5061011d60015481565b6040519081526020016100be565b6100806101393660046105be565b600061019e6040518060c0016040528060015481526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff1681526020013481526020018581526020018481525061031d565b6000818152602081905260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915554905191925073ffffffffffffffffffffffffffffffffffffffff8616913391907f87bf7b546c8de873abb0db5b579ec131f8d0cf5b14f39933551cf9ced23a61369061022c903490899089906106c2565b60405180910390a4505060018054810190555050565b4761024c8161036a565b60405181907f7967de617a5ac1cc7eba2d6f37570a0135afa950d8bb77cdd35f0d0b4e85a16f90600090a250565b60606102a57f0000000000000000000000000000000000000000000000000000000000000000610399565b6102ce7f0000000000000000000000000000000000000000000000000000000000000000610399565b6102f77f0000000000000000000000000000000000000000000000000000000000000000610399565b604051602001610309939291906106ea565b604051602081830303815290604052905090565b80516020808301516040808501516060860151608087015160a0880151935160009761034d979096959101610760565b604051602081830303815290604052805190602001209050919050565b80604051610377906104d6565b6040518091039082f0905080158015610394573d6000803e3d6000fd5b505050565b6060816000036103dc57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561040657806103f0816107e6565b91506103ff9050600a8361084d565b91506103e0565b60008167ffffffffffffffff8111156104215761042161058f565b6040519080825280601f01601f19166020018201604052801561044b576020820181803683370190505b5090505b84156104ce57610460600183610861565b915061046d600a86610878565b61047890603061088c565b60f81b81838151811061048d5761048d6108a4565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506104c7600a8661084d565b945061044f565b949350505050565b6008806108d483390190565b60005b838110156104fd5781810151838201526020016104e5565b8381111561050c576000848401525b50505050565b6000815180845261052a8160208601602086016104e2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061056f6020830184610512565b9392505050565b60006020828403121561058857600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156105d357600080fd5b833573ffffffffffffffffffffffffffffffffffffffff811681146105f757600080fd5b925060208401359150604084013567ffffffffffffffff8082111561061b57600080fd5b818601915086601f83011261062f57600080fd5b8135818111156106415761064161058f565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156106875761068761058f565b816040528281528960208487010111156106a057600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b8381528260208201526060604082015260006106e16060830184610512565b95945050505050565b600084516106fc8184602089016104e2565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610738816001850160208a016104e2565b600192019182015283516107538160028401602088016104e2565b0160020195945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526107ab60c0830184610512565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610817576108176107b7565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261085c5761085c61081e565b500490565b600082821015610873576108736107b7565b500390565b6000826108875761088761081e565b500690565b6000821982111561089f5761089f6107b7565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfe608060405230fffea164736f6c634300080f000a"
+var L2ToL1MessagePasserDeployedBin = "0x60806040526004361061005e5760003560e01c806382e3702d1161004357806382e3702d146100c7578063affed0e014610107578063c2b3e5ac1461012b57600080fd5b806344df8e701461008757806354fd4d501461009c57600080fd5b366100825761008033620186a060405180602001604052806000815250610139565b005b600080fd5b34801561009357600080fd5b5061008061026d565b3480156100a857600080fd5b506100b16102a5565b6040516100be9190610587565b60405180910390f35b3480156100d357600080fd5b506100f76100e23660046105a1565b60006020819052908152604090205460ff1681565b60405190151581526020016100be565b34801561011357600080fd5b5061011d60015481565b6040519081526020016100be565b6100806101393660046105e9565b600061019e6040518060c0016040528060015481526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff16815260200134815260200185815260200184815250610348565b6000818152602081905260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915554905191925073ffffffffffffffffffffffffffffffffffffffff8616913391907f87bf7b546c8de873abb0db5b579ec131f8d0cf5b14f39933551cf9ced23a61369061022c903490899089906106ed565b60405180910390a460405181907f2ef6ceb1668fdd882b1f89ddd53a666b0c1113d14cf90c0fbf97c7b1ad880fbb90600090a2505060018054810190555050565b4761027781610395565b60405181907f7967de617a5ac1cc7eba2d6f37570a0135afa950d8bb77cdd35f0d0b4e85a16f90600090a250565b60606102d07f00000000000000000000000000000000000000000000000000000000000000006103c4565b6102f97f00000000000000000000000000000000000000000000000000000000000000006103c4565b6103227f00000000000000000000000000000000000000000000000000000000000000006103c4565b60405160200161033493929190610715565b604051602081830303815290604052905090565b80516020808301516040808501516060860151608087015160a0880151935160009761037897909695910161078b565b604051602081830303815290604052805190602001209050919050565b806040516103a290610501565b6040518091039082f09050801580156103bf573d6000803e3d6000fd5b505050565b60608160000361040757505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610431578061041b81610811565b915061042a9050600a83610878565b915061040b565b60008167ffffffffffffffff81111561044c5761044c6105ba565b6040519080825280601f01601f191660200182016040528015610476576020820181803683370190505b5090505b84156104f95761048b60018361088c565b9150610498600a866108a3565b6104a39060306108b7565b60f81b8183815181106104b8576104b86108cf565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506104f2600a86610878565b945061047a565b949350505050565b6008806108ff83390190565b60005b83811015610528578181015183820152602001610510565b83811115610537576000848401525b50505050565b6000815180845261055581602086016020860161050d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061059a602083018461053d565b9392505050565b6000602082840312156105b357600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156105fe57600080fd5b833573ffffffffffffffffffffffffffffffffffffffff8116811461062257600080fd5b925060208401359150604084013567ffffffffffffffff8082111561064657600080fd5b818601915086601f83011261065a57600080fd5b81358181111561066c5761066c6105ba565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156106b2576106b26105ba565b816040528281528960208487010111156106cb57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b83815282602082015260606040820152600061070c606083018461053d565b95945050505050565b6000845161072781846020890161050d565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610763816001850160208a0161050d565b6001920191820152835161077e81600284016020880161050d565b0160020195945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526107d660c083018461053d565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610842576108426107e2565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261088757610887610849565b500490565b60008282101561089e5761089e6107e2565b500390565b6000826108b2576108b2610849565b500690565b600082198211156108ca576108ca6107e2565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfe608060405230fffea164736f6c634300080f000a"
diff --git a/op-bindings/bindings/optimismportal.go b/op-bindings/bindings/optimismportal.go
index f3ed8223e4186..dde4f3ad34469 100644
--- a/op-bindings/bindings/optimismportal.go
+++ b/op-bindings/bindings/optimismportal.go
@@ -49,7 +49,7 @@ type TypesWithdrawalTransaction struct {
// OptimismPortalMetaData contains all meta data concerning the OptimismPortal contract.
var OptimismPortalMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"_l2Oracle\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_finalizationPeriodSeconds\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"opaqueData\",\"type\":\"bytes\"}],\"name\":\"TransactionDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"WithdrawalFinalized\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_FEE_MAX_CHANGE_DENOMINATOR\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ELASTICITY_MULTIPLIER\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"FINALIZATION_PERIOD_SECONDS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIAL_BASE_FEE\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_ORACLE\",\"outputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_RESOURCE_LIMIT\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINIMUM_BASE_FEE\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TARGET_RESOURCE_LIMIT\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"_gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"_isCreation\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"depositTransaction\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structTypes.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"withdrawerStorageRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"latestBlockhash\",\"type\":\"bytes32\"}],\"internalType\":\"structTypes.OutputRootProof\",\"name\":\"_outputRootProof\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"_withdrawalProof\",\"type\":\"bytes\"}],\"name\":\"finalizeWithdrawalTransaction\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"finalizedWithdrawals\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"isBlockFinalized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2Sender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"params\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"prevBaseFee\",\"type\":\"uint128\"},{\"internalType\":\"uint64\",\"name\":\"prevBoughtGas\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"prevBlockNum\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
- Bin: "0x6101206040523480156200001257600080fd5b5060405162004130380380620041308339810160408190526200003591620002bc565b6000608081905260a052600160c0526001600160a01b0382166101005260e08190526200006162000069565b5050620002f8565b6000620000776001620000f8565b9050801562000090576000805461ff0019166101001790555b603380546001600160a01b03191661dead179055620000ae6200020a565b8015620000f5576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b60008054610100900460ff161562000191578160ff1660011480156200013157506200012f30620002ad60201b6200119b1760201c565b155b620001895760405162461bcd60e51b815260206004820152602e60248201526000805160206200411083398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b506000919050565b60005460ff808416911610620001f05760405162461bcd60e51b815260206004820152602e60248201526000805160206200411083398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840162000180565b506000805460ff191660ff92909216919091179055600190565b600054610100900460ff16620002775760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162000180565b60408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b0217600155565b6001600160a01b03163b151590565b60008060408385031215620002d057600080fd5b82516001600160a01b0381168114620002e857600080fd5b6020939093015192949293505050565b60805160a05160c05160e05161010051613dbe620003526000396000818161013401528181610a860152610cad0152600081816103bd01526115ff01526000610918015260006108ef015260006108c60152613dbe6000f3fe6080604052600436106100f65760003560e01c8063a14238e71161008a578063cff0ab9611610059578063cff0ab96146102f7578063e9e05c4214610398578063f4daa291146103ab578063fdc9fe1d146103df57600080fd5b8063a14238e71461026d578063c4fc4798146102ad578063ca3e99ba146102cd578063cd7c9789146102e257600080fd5b80636bb0291e116100c65780636bb0291e146102005780638129fc1c14610215578063867ead131461022a5780639bf62d821461024057600080fd5b80621c2ff61461012257806313620abd1461018057806354fd4d50146101b957806364b79208146101db57600080fd5b3661011d5761011b3334620186a06000604051806020016040528060008152506103f2565b005b600080fd5b34801561012e57600080fd5b506101567f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561018c57600080fd5b50610198633b9aca0081565b6040516fffffffffffffffffffffffffffffffff9091168152602001610177565b3480156101c557600080fd5b506101ce6108bf565b6040516101779190613416565b3480156101e757600080fd5b506101f2627a120081565b604051908152602001610177565b34801561020c57600080fd5b506101f2600481565b34801561022157600080fd5b5061011b610962565b34801561023657600080fd5b506101f261271081565b34801561024c57600080fd5b506033546101569073ffffffffffffffffffffffffffffffffffffffff1681565b34801561027957600080fd5b5061029d610288366004613429565b60346020526000908152604090205460ff1681565b6040519015158152602001610177565b3480156102b957600080fd5b5061029d6102c8366004613429565b610a3d565b3480156102d957600080fd5b506101f2610b02565b3480156102ee57600080fd5b506101f2600881565b34801561030357600080fd5b5060015461035f906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff9283166020850152911690820152606001610177565b61011b6103a6366004613569565b6103f2565b3480156103b757600080fd5b506101f27f000000000000000000000000000000000000000000000000000000000000000081565b61011b6103ed366004613657565b610b13565b8260005a905083156104a95773ffffffffffffffffffffffffffffffffffffffff8716156104a957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b333281146104ca575033731111000000000000000000000000000000001111015b600034888888886040516020016104e595949392919061374b565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516105559190613416565b60405180910390a45050600154600090610595907801000000000000000000000000000000000000000000000000900467ffffffffffffffff16436137df565b9050801561071e5760006105ad6004627a1200613825565b6001546105d89190700100000000000000000000000000000000900467ffffffffffffffff1661388d565b9050600060086105ec6004627a1200613825565b60015461060c9085906fffffffffffffffffffffffffffffffff16613901565b6106169190613825565b6106209190613825565b60015490915060009061066c906106569061064e9085906fffffffffffffffffffffffffffffffff166139bd565b6127106111b7565b6fffffffffffffffffffffffffffffffff6111d2565b905060018411156106df576106dc610656670de0b6b3a76400006106c8610694600883613825565b6106a690670de0b6b3a764000061388d565b6106b160018a6137df565b6106c390670de0b6b3a7640000613a31565b6111e1565b6106d29085613901565b61064e9190613825565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054849190601090610751908490700100000000000000000000000000000000900467ffffffffffffffff16613a6e565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550627a1200600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff16131561082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d6974000060648201526084016104a0565b600154600090610859906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8616613a9a565b6fffffffffffffffffffffffffffffffff169050600061087d48633b9aca00611212565b6108879083613ad2565b905060005a61089690866137df565b9050808211156108b2576108b26108ad82846137df565b611222565b5050505050505050505050565b60606108ea7f0000000000000000000000000000000000000000000000000000000000000000611250565b6109137f0000000000000000000000000000000000000000000000000000000000000000611250565b61093c7f0000000000000000000000000000000000000000000000000000000000000000611250565b60405160200161094e93929190613ae6565b604051602081830303815290604052905090565b600061096e600161138d565b905080156109a357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790556109d7611518565b8015610a3a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101829052600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae557906024016040805180830381865afa158015610acc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af09190613b5c565b9050610afb816115fb565b9392505050565b610b106004627a1200613825565b81565b60335473ffffffffffffffffffffffffffffffffffffffff1661dead14610bbc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e0060648201526084016104a0565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610c7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e74726163740060648201526084016104a0565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae557906024016040805180830381865afa158015610d08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2c9190613b5c565b9050610d37816115fb565b610dc3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4f7074696d69736d506f7274616c3a2070726f706f73616c206973206e6f742060448201527f7965742066696e616c697a65640000000000000000000000000000000000000060648201526084016104a0565b610dda610dd536869003860186613bab565b611635565b815114610e69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f66000000000000000000000000000000000000000000000060648201526084016104a0565b6000610e7487611691565b9050610ebb81866040013586868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506116c192505050565b610f47576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f66000000000000000000000000000060648201526084016104a0565b60008181526034602052604090205460ff1615610fe6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a6564000000000000000000000060648201526084016104a0565b600081815260346020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055608087015161102f90614e2090613c11565b5a10156110be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a20696e73756666696369656e742067617360448201527f20746f2066696e616c697a65207769746864726177616c00000000000000000060648201526084016104a0565b8660200151603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000611123886040015189608001518a6060015160008c60a00151611788565b50603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915082907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061118990841515815260200190565b60405180910390a25050505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000818312156111c757816111c9565b825b90505b92915050565b60008183126111c757816111c9565b60006111c9670de0b6b3a7640000836111f986611813565b6112039190613901565b61120d9190613825565b611a57565b6000818310156111c757816111c9565b6000805a90505b825a61123590836137df565b101561124b5761124482613c29565b9150611229565b505050565b60608160000361129357505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156112bd57806112a781613c29565b91506112b69050600a83613ad2565b9150611297565b60008167ffffffffffffffff8111156112d8576112d8613466565b6040519080825280601f01601f191660200182016040528015611302576020820181803683370190505b5090505b8415611385576113176001836137df565b9150611324600a86613c61565b61132f906030613c11565b60f81b81838151811061134457611344613c75565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061137e600a86613ad2565b9450611306565b949350505050565b60008054610100900460ff1615611444578160ff1660011480156113b05750303b155b61143c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104a0565b506000919050565b60005460ff8084169116106114db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104a0565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166115af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104a0565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b60007f0000000000000000000000000000000000000000000000000000000000000000826020015161162d9190613c11565b421192915050565b60008160000151826020015183604001518460600151604051602001611674949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611674979096959101613ca4565b604080516020810185905260009181018290528190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120908301819052925061177f9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f01000000000000000000000000000000000000000000000000000000000000006020830152908587611c96565b95945050505050565b6000606060008060008661ffff1667ffffffffffffffff8111156117ae576117ae613466565b6040519080825280601f01601f1916602001820160405280156117d8576020820181803683370190505b5090506000808751602089018b8e8ef191503d9250868311156117f9578692505b828152826000602083013e90999098509650505050505050565b600080821361187e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e4544000000000000000000000000000000000000000000000060448201526064016104a0565b6000606061188b84611cba565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c18213611a8857506000919050565b680755bf798b4a1bf1e58212611afa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f57000000000000000000000000000000000000000060448201526064016104a0565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b600080611ca286611d90565b9050611cb081868686611dc2565b9695505050505050565b6000808211611d25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e4544000000000000000000000000000000000000000000000060448201526064016104a0565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b60608180519060200120604051602001611dac91815260200190565b6040516020818303038152906040529050919050565b6000806000611dd2878686611dff565b91509150818015611df457508051602080830191909120875191880191909120145b979650505050505050565b600060606000611e0e85611f1a565b90506000806000611e20848a89612015565b81519295509093509150158080611e345750815b611ec0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2070726f76696465642070726f6f6620697320696e60448201527f76616c696400000000000000000000000000000000000000000000000000000060648201526084016104a0565b600081611edc5760405180602001604052806000815250611f08565b611f0886611eeb6001886137df565b81518110611efb57611efb613c75565b602002602001015161259e565b919b919a509098505050505050505050565b60606000611f27836125c8565b90506000815167ffffffffffffffff811115611f4557611f45613466565b604051908082528060200260200182016040528015611f8a57816020015b6040805180820190915260608082526020820152815260200190600190039081611f635790505b50905060005b825181101561200d576000611fbd848381518110611fb057611fb0613c75565b60200260200101516125fb565b90506040518060400160405280828152602001611fd9836125c8565b815250838381518110611fee57611fee613c75565b602002602001018190525050808061200590613c29565b915050611f90565b509392505050565b60006060818080612025876126c2565b9050600086905060008061204c604051806040016040528060608152602001606081525090565b60005b8c5181101561255a578c818151811061206a5761206a613c75565b6020026020010151915082846120809190613c11565b935061208d600188613c11565b96508360000361210e57815180516020909101208514612109576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f74206861736800000060448201526064016104a0565b61224a565b8151516020116121b057815180516020909101208514612109576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c20686173680000000000000000000000000000000000000000000000000060648201526084016104a0565b815185906121bd90613cfb565b1461224a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f652068617368000000000000000000000000000000000000000000000000000060648201526084016104a0565b61225660106001613c11565b826020015151036122c8578551841461255a57600086858151811061227d5761227d613c75565b602001015160f81c60f81b60f81c9050600083602001518260ff16815181106122a8576122a8613c75565b602002602001015190506122bb81612845565b9650600194505050612548565b6002826020015151036124c05760006122e08361287b565b90506000816000815181106122f7576122f7613c75565b016020015160f81c9050600061230e600283613d3d565b612319906002613d5f565b9050600061232a848360ff1661289f565b905060006123388b8a61289f565b9050600061234683836128d5565b905060ff85166002148061235d575060ff85166003145b156123b3578083511480156123725750808251145b1561238457612381818b613c11565b99505b507f8000000000000000000000000000000000000000000000000000000000000000995061255a945050505050565b60ff851615806123c6575060ff85166001145b15612438578251811461240257507f8000000000000000000000000000000000000000000000000000000000000000995061255a945050505050565b612429886020015160018151811061241c5761241c613c75565b6020026020010151612845565b9a509750612548945050505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e20707265666978000000000000000000000000000060648201526084016104a0565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f646500000000000000000000000000000000000000000000000060648201526084016104a0565b8061255281613c29565b91505061204f565b507f8000000000000000000000000000000000000000000000000000000000000000841486612589878661289f565b909e909d50909b509950505050505050505050565b602081015180516060916111cc916125b8906001906137df565b81518110611fb057611fb0613c75565b6040805180820182526000808252602091820152815180830190925282518252808301908201526060906111cc90612981565b6060600080600061260b85612bda565b91945092509050600081600181111561262657612626613d82565b146126b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f524c505265616465723a20696e76616c696420524c502062797465732076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b61177f856020015184846130c5565b60606000825160026126d49190613a31565b67ffffffffffffffff8111156126ec576126ec613466565b6040519080825280601f01601f191660200182016040528015612716576020820181803683370190505b50905060005b835181101561283e57600484828151811061273957612739613c75565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c8261276e836002613a31565b8151811061277e5761277e613c75565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060108482815181106127c1576127c1613c75565b01602001516127d3919060f81c613d3d565b60f81b826127e2836002613a31565b6127ed906001613c11565b815181106127fd576127fd613c75565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508061283681613c29565b91505061271c565b5092915050565b600060606020836000015110156128665761285f836131a3565b9050612872565b61286f836125fb565b90505b610afb81613cfb565b60606111cc61289a8360200151600081518110611fb057611fb0613c75565b6126c2565b6060825182106128be57506040805160208101909152600081526111cc565b6111c983838486516128d091906137df565b6131ae565b6000805b8084511180156128e95750808351115b801561296a575082818151811061290257612902613c75565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191684828151811061294157612941613c75565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156111c9578061297981613c29565b9150506128d9565b606060008061298f84612bda565b919350909150600190508160018111156129ab576129ab613d82565b14612a38576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f524c505265616465723a20696e76616c696420524c50206c6973742076616c7560448201527f650000000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b6040805160208082526104208201909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081612a515790505090506000835b8651811015612bcf5760208210612b17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2070726f766964656420524c50206c6973742065786360448201527f65656473206d6178206c697374206c656e67746800000000000000000000000060648201526084016104a0565b600080612b546040518060400160405280858c60000151612b3891906137df565b8152602001858c60200151612b4d9190613c11565b9052612bda565b509150915060405180604001604052808383612b709190613c11565b8152602001848b60200151612b859190613c11565b815250858581518110612b9a57612b9a613c75565b6020908102919091010152612bb0600185613c11565b9350612bbc8183613c11565b612bc69084613c11565b92505050612a7e565b508152949350505050565b600080600080846000015111612c72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f524c505265616465723a20524c50206974656d2063616e6e6f74206265206e7560448201527f6c6c00000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b6020840151805160001a607f8111612c975760006001600094509450945050506130be565b60b78111612d53576000612cac6080836137df565b905080876000015111612d41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f524c505265616465723a20696e76616c696420524c502073686f72742073747260448201527f696e67000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b600195509350600092506130be915050565b60bf8111612ec2576000612d6860b7836137df565b905080876000015111612dfd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f524c505265616465723a20696e76616c696420524c50206c6f6e67207374726960448201527f6e67206c656e677468000000000000000000000000000000000000000000000060648201526084016104a0565b600183015160208290036101000a9004612e178183613c11565b885111612ea6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f524c505265616465723a20696e76616c696420524c50206c6f6e67207374726960448201527f6e6700000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b612eb1826001613c11565b96509450600093506130be92505050565b60f78111612f7d576000612ed760c0836137df565b905080876000015111612f6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f524c505265616465723a20696e76616c696420524c502073686f7274206c697360448201527f740000000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b6001955093508492506130be915050565b6000612f8a60f7836137df565b90508087600001511161301f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f524c505265616465723a20696e76616c696420524c50206c6f6e67206c69737460448201527f206c656e6774680000000000000000000000000000000000000000000000000060648201526084016104a0565b600183015160208290036101000a90046130398183613c11565b8851116130a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f524c505265616465723a20696e76616c696420524c50206c6f6e67206c69737460448201526064016104a0565b6130ad826001613c11565b96509450600193506130be92505050565b9193909250565b606060008267ffffffffffffffff8111156130e2576130e2613466565b6040519080825280601f01601f19166020018201604052801561310c576020820181803683370190505b509050805160000361311f579050610afb565b600061312b8587613c11565b90506020820160005b61313f602087613ad2565b8110156131765782518252613155602084613c11565b9250613162602083613c11565b91508061316e81613c29565b915050613134565b5060006001602087066020036101000a039050808251168119845116178252839450505050509392505050565b60606111cc82613386565b60608182601f01101561321d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016104a0565b828284011015613289576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016104a0565b818301845110156132f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e647300000000000000000000000000000060448201526064016104a0565b606082158015613315576040519150600082526020820160405261337d565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561334e578051835260209283019201613336565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60606111cc8260200151600084600001516130c5565b60005b838110156133b757818101518382015260200161339f565b838111156133c6576000848401525b50505050565b600081518084526133e481602086016020860161339c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006111c960208301846133cc565b60006020828403121561343b57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461151357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff811182821017156134b8576134b8613466565b60405290565b600082601f8301126134cf57600080fd5b813567ffffffffffffffff808211156134ea576134ea613466565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561353057613530613466565b8160405283815286602085880101111561354957600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a0868803121561358157600080fd5b61358a86613442565b945060208601359350604086013567ffffffffffffffff80821682146135af57600080fd5b90935060608701359081151582146135c657600080fd5b909250608087013590808211156135dc57600080fd5b506135e9888289016134be565b9150509295509295909350565b60006080828403121561360857600080fd5b50919050565b60008083601f84011261362057600080fd5b50813567ffffffffffffffff81111561363857600080fd5b60208301915083602082850101111561365057600080fd5b9250929050565b600080600080600060e0868803121561366f57600080fd5b853567ffffffffffffffff8082111561368757600080fd5b9087019060c0828a03121561369b57600080fd5b6136a3613495565b823581526136b360208401613442565b60208201526136c460408401613442565b6040820152606083013560608201526080830135608082015260a0830135828111156136ef57600080fd5b6136fb8b8286016134be565b60a0830152509650602088013595506137178960408a016135f6565b945060c088013591508082111561372d57600080fd5b5061373a8882890161360e565b969995985093965092949392505050565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b60488201526000825161379f81604985016020870161339c565b919091016049019695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156137f1576137f16137b0565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082613834576138346137f6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615613888576138886137b0565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156138c7576138c76137b0565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156138fb576138fb6137b0565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615613942576139426137b0565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561397d5761397d6137b0565b60008712925087820587128484161615613999576139996137b0565b878505871281841616156139af576139af6137b0565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156139f7576139f76137b0565b827f8000000000000000000000000000000000000000000000000000000000000000038412811615613a2b57613a2b6137b0565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613a6957613a696137b0565b500290565b600067ffffffffffffffff808316818516808303821115613a9157613a916137b0565b01949350505050565b60006fffffffffffffffffffffffffffffffff80831681851681830481118215151615613ac957613ac96137b0565b02949350505050565b600082613ae157613ae16137f6565b500490565b60008451613af881846020890161339c565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551613b34816001850160208a0161339c565b60019201918201528351613b4f81600284016020880161339c565b0160020195945050505050565b600060408284031215613b6e57600080fd5b6040516040810181811067ffffffffffffffff82111715613b9157613b91613466565b604052825181526020928301519281019290925250919050565b600060808284031215613bbd57600080fd5b6040516080810181811067ffffffffffffffff82111715613be057613be0613466565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b60008219821115613c2457613c246137b0565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613c5a57613c5a6137b0565b5060010190565b600082613c7057613c706137f6565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152613cef60c08301846133cc565b98975050505050505050565b80516020808301519190811015613608577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b600060ff831680613d5057613d506137f6565b8060ff84160691505092915050565b600060ff821660ff841680821015613d7957613d796137b0565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e747261637420697320616c726561",
+ Bin: "0x6101206040523480156200001257600080fd5b506040516200401238038062004012833981016040819052620000359162000261565b6000608081905260a052600160c0526001600160a01b0382166101005260e08190526200006162000069565b50506200029d565b600054610100900460ff16158080156200008a5750600054600160ff909116105b80620000ba5750620000a730620001af60201b6200127e1760201c565b158015620000ba575060005460ff166001145b620001235760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000147576000805461ff0019166101001790555b603380546001600160a01b03191661dead17905562000165620001be565b8015620001ac576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6001600160a01b03163b151590565b600054610100900460ff166200022b5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016200011a565b60408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b0217600155565b600080604083850312156200027557600080fd5b82516001600160a01b03811681146200028d57600080fd5b6020939093015192949293505050565b60805160a05160c05160e05161010051613d1b620002f76000396000818161013401528181610b690152610d900152600081816103bd015261155701526000610918015260006108ef015260006108c60152613d1b6000f3fe6080604052600436106100f65760003560e01c8063a14238e71161008a578063cff0ab9611610059578063cff0ab96146102f7578063e9e05c4214610398578063f4daa291146103ab578063fdc9fe1d146103df57600080fd5b8063a14238e71461026d578063c4fc4798146102ad578063ca3e99ba146102cd578063cd7c9789146102e257600080fd5b80636bb0291e116100c65780636bb0291e146102005780638129fc1c14610215578063867ead131461022a5780639bf62d821461024057600080fd5b80621c2ff61461012257806313620abd1461018057806354fd4d50146101b957806364b79208146101db57600080fd5b3661011d5761011b3334620186a06000604051806020016040528060008152506103f2565b005b600080fd5b34801561012e57600080fd5b506101567f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561018c57600080fd5b50610198633b9aca0081565b6040516fffffffffffffffffffffffffffffffff9091168152602001610177565b3480156101c557600080fd5b506101ce6108bf565b604051610177919061336e565b3480156101e757600080fd5b506101f2627a120081565b604051908152602001610177565b34801561020c57600080fd5b506101f2600481565b34801561022157600080fd5b5061011b610962565b34801561023657600080fd5b506101f261271081565b34801561024c57600080fd5b506033546101569073ffffffffffffffffffffffffffffffffffffffff1681565b34801561027957600080fd5b5061029d610288366004613381565b60346020526000908152604090205460ff1681565b6040519015158152602001610177565b3480156102b957600080fd5b5061029d6102c8366004613381565b610b20565b3480156102d957600080fd5b506101f2610be5565b3480156102ee57600080fd5b506101f2600881565b34801561030357600080fd5b5060015461035f906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff9283166020850152911690820152606001610177565b61011b6103a63660046134c6565b6103f2565b3480156103b757600080fd5b506101f27f000000000000000000000000000000000000000000000000000000000000000081565b61011b6103ed3660046135b4565b610bf6565b8260005a905083156104a95773ffffffffffffffffffffffffffffffffffffffff8716156104a957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b333281146104ca575033731111000000000000000000000000000000001111015b600034888888886040516020016104e59594939291906136a8565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c3284604051610555919061336e565b60405180910390a45050600154600090610595907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361373c565b9050801561071e5760006105ad6004627a1200613782565b6001546105d89190700100000000000000000000000000000000900467ffffffffffffffff166137ea565b9050600060086105ec6004627a1200613782565b60015461060c9085906fffffffffffffffffffffffffffffffff1661385e565b6106169190613782565b6106209190613782565b60015490915060009061066c906106569061064e9085906fffffffffffffffffffffffffffffffff1661391a565b61271061129a565b6fffffffffffffffffffffffffffffffff6112b5565b905060018411156106df576106dc610656670de0b6b3a76400006106c8610694600883613782565b6106a690670de0b6b3a76400006137ea565b6106b160018a61373c565b6106c390670de0b6b3a764000061398e565b6112c4565b6106d2908561385e565b61064e9190613782565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054849190601090610751908490700100000000000000000000000000000000900467ffffffffffffffff166139cb565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550627a1200600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff16131561082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d6974000060648201526084016104a0565b600154600090610859906fffffffffffffffffffffffffffffffff1667ffffffffffffffff86166139f7565b6fffffffffffffffffffffffffffffffff169050600061087d48633b9aca006112f5565b6108879083613a2f565b905060005a610896908661373c565b9050808211156108b2576108b26108ad828461373c565b611305565b5050505050505050505050565b60606108ea7f0000000000000000000000000000000000000000000000000000000000000000611333565b6109137f0000000000000000000000000000000000000000000000000000000000000000611333565b61093c7f0000000000000000000000000000000000000000000000000000000000000000611333565b60405160200161094e93929190613a43565b604051602081830303815290604052905090565b600054610100900460ff16158080156109825750600054600160ff909116105b8061099c5750303b15801561099c575060005460ff166001145b610a28576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104a0565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610a8657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055610aba611470565b8015610b1d57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101829052600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae557906024016040805180830381865afa158015610baf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd39190613ab9565b9050610bde81611553565b9392505050565b610bf36004627a1200613782565b81565b60335473ffffffffffffffffffffffffffffffffffffffff1661dead14610c9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e0060648201526084016104a0565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610d5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e74726163740060648201526084016104a0565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae557906024016040805180830381865afa158015610deb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0f9190613ab9565b9050610e1a81611553565b610ea6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4f7074696d69736d506f7274616c3a2070726f706f73616c206973206e6f742060448201527f7965742066696e616c697a65640000000000000000000000000000000000000060648201526084016104a0565b610ebd610eb836869003860186613b08565b61158d565b815114610f4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f66000000000000000000000000000000000000000000000060648201526084016104a0565b6000610f57876115e9565b9050610f9e81866040013586868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061161992505050565b61102a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f66000000000000000000000000000060648201526084016104a0565b60008181526034602052604090205460ff16156110c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a6564000000000000000000000060648201526084016104a0565b600081815260346020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055608087015161111290614e2090613b6e565b5a10156111a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a20696e73756666696369656e742067617360448201527f20746f2066696e616c697a65207769746864726177616c00000000000000000060648201526084016104a0565b8660200151603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000611206886040015189608001518a6060015160008c60a001516116e0565b50603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915082907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061126c90841515815260200190565b60405180910390a25050505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000818312156112aa57816112ac565b825b90505b92915050565b60008183126112aa57816112ac565b60006112ac670de0b6b3a7640000836112dc8661176b565b6112e6919061385e565b6112f09190613782565b6119af565b6000818310156112aa57816112ac565b6000805a90505b825a611318908361373c565b101561132e5761132782613b86565b915061130c565b505050565b60608160000361137657505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156113a0578061138a81613b86565b91506113999050600a83613a2f565b915061137a565b60008167ffffffffffffffff8111156113bb576113bb6133c3565b6040519080825280601f01601f1916602001820160405280156113e5576020820181803683370190505b5090505b8415611468576113fa60018361373c565b9150611407600a86613bbe565b611412906030613b6e565b60f81b81838151811061142757611427613bd2565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611461600a86613a2f565b94506113e9565b949350505050565b600054610100900460ff16611507576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104a0565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b60007f000000000000000000000000000000000000000000000000000000000000000082602001516115859190613b6e565b421192915050565b600081600001518260200151836040015184606001516040516020016115cc949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a088015193516000976115cc979096959101613c01565b604080516020810185905260009181018290528190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506116d79101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f01000000000000000000000000000000000000000000000000000000000000006020830152908587611bee565b95945050505050565b6000606060008060008661ffff1667ffffffffffffffff811115611706576117066133c3565b6040519080825280601f01601f191660200182016040528015611730576020820181803683370190505b5090506000808751602089018b8e8ef191503d925086831115611751578692505b828152826000602083013e90999098509650505050505050565b60008082136117d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e4544000000000000000000000000000000000000000000000060448201526064016104a0565b600060606117e384611c12565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136119e057506000919050565b680755bf798b4a1bf1e58212611a52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f57000000000000000000000000000000000000000060448201526064016104a0565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b600080611bfa86611ce8565b9050611c0881868686611d1a565b9695505050505050565b6000808211611c7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e4544000000000000000000000000000000000000000000000060448201526064016104a0565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b60608180519060200120604051602001611d0491815260200190565b6040516020818303038152906040529050919050565b6000806000611d2a878686611d57565b91509150818015611d4c57508051602080830191909120875191880191909120145b979650505050505050565b600060606000611d6685611e72565b90506000806000611d78848a89611f6d565b81519295509093509150158080611d8c5750815b611e18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2070726f76696465642070726f6f6620697320696e60448201527f76616c696400000000000000000000000000000000000000000000000000000060648201526084016104a0565b600081611e345760405180602001604052806000815250611e60565b611e6086611e4360018861373c565b81518110611e5357611e53613bd2565b60200260200101516124f6565b919b919a509098505050505050505050565b60606000611e7f83612520565b90506000815167ffffffffffffffff811115611e9d57611e9d6133c3565b604051908082528060200260200182016040528015611ee257816020015b6040805180820190915260608082526020820152815260200190600190039081611ebb5790505b50905060005b8251811015611f65576000611f15848381518110611f0857611f08613bd2565b6020026020010151612553565b90506040518060400160405280828152602001611f3183612520565b815250838381518110611f4657611f46613bd2565b6020026020010181905250508080611f5d90613b86565b915050611ee8565b509392505050565b60006060818080611f7d8761261a565b90506000869050600080611fa4604051806040016040528060608152602001606081525090565b60005b8c518110156124b2578c8181518110611fc257611fc2613bd2565b602002602001015191508284611fd89190613b6e565b9350611fe5600188613b6e565b96508360000361206657815180516020909101208514612061576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f74206861736800000060448201526064016104a0565b6121a2565b81515160201161210857815180516020909101208514612061576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c20686173680000000000000000000000000000000000000000000000000060648201526084016104a0565b8151859061211590613c58565b146121a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f652068617368000000000000000000000000000000000000000000000000000060648201526084016104a0565b6121ae60106001613b6e565b8260200151510361222057855184146124b25760008685815181106121d5576121d5613bd2565b602001015160f81c60f81b60f81c9050600083602001518260ff168151811061220057612200613bd2565b602002602001015190506122138161279d565b96506001945050506124a0565b600282602001515103612418576000612238836127d3565b905060008160008151811061224f5761224f613bd2565b016020015160f81c90506000612266600283613c9a565b612271906002613cbc565b90506000612282848360ff166127f7565b905060006122908b8a6127f7565b9050600061229e838361282d565b905060ff8516600214806122b5575060ff85166003145b1561230b578083511480156122ca5750808251145b156122dc576122d9818b613b6e565b99505b507f800000000000000000000000000000000000000000000000000000000000000099506124b2945050505050565b60ff8516158061231e575060ff85166001145b15612390578251811461235a57507f800000000000000000000000000000000000000000000000000000000000000099506124b2945050505050565b612381886020015160018151811061237457612374613bd2565b602002602001015161279d565b9a5097506124a0945050505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e20707265666978000000000000000000000000000060648201526084016104a0565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f646500000000000000000000000000000000000000000000000060648201526084016104a0565b806124aa81613b86565b915050611fa7565b507f80000000000000000000000000000000000000000000000000000000000000008414866124e187866127f7565b909e909d50909b509950505050505050505050565b602081015180516060916112af916125109060019061373c565b81518110611f0857611f08613bd2565b6040805180820182526000808252602091820152815180830190925282518252808301908201526060906112af906128d9565b6060600080600061256385612b32565b91945092509050600081600181111561257e5761257e613cdf565b1461260b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f524c505265616465723a20696e76616c696420524c502062797465732076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b6116d78560200151848461301d565b606060008251600261262c919061398e565b67ffffffffffffffff811115612644576126446133c3565b6040519080825280601f01601f19166020018201604052801561266e576020820181803683370190505b50905060005b835181101561279657600484828151811061269157612691613bd2565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c826126c683600261398e565b815181106126d6576126d6613bd2565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350601084828151811061271957612719613bd2565b016020015161272b919060f81c613c9a565b60f81b8261273a83600261398e565b612745906001613b6e565b8151811061275557612755613bd2565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508061278e81613b86565b915050612674565b5092915050565b600060606020836000015110156127be576127b7836130fb565b90506127ca565b6127c783612553565b90505b610bde81613c58565b60606112af6127f28360200151600081518110611f0857611f08613bd2565b61261a565b60608251821061281657506040805160208101909152600081526112af565b6112ac8383848651612828919061373c565b613106565b6000805b8084511180156128415750808351115b80156128c2575082818151811061285a5761285a613bd2565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191684828151811061289957612899613bd2565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156112ac57806128d181613b86565b915050612831565b60606000806128e784612b32565b9193509091506001905081600181111561290357612903613cdf565b14612990576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f524c505265616465723a20696e76616c696420524c50206c6973742076616c7560448201527f650000000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b6040805160208082526104208201909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816129a95790505090506000835b8651811015612b275760208210612a6f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2070726f766964656420524c50206c6973742065786360448201527f65656473206d6178206c697374206c656e67746800000000000000000000000060648201526084016104a0565b600080612aac6040518060400160405280858c60000151612a90919061373c565b8152602001858c60200151612aa59190613b6e565b9052612b32565b509150915060405180604001604052808383612ac89190613b6e565b8152602001848b60200151612add9190613b6e565b815250858581518110612af257612af2613bd2565b6020908102919091010152612b08600185613b6e565b9350612b148183613b6e565b612b1e9084613b6e565b925050506129d6565b508152949350505050565b600080600080846000015111612bca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f524c505265616465723a20524c50206974656d2063616e6e6f74206265206e7560448201527f6c6c00000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b6020840151805160001a607f8111612bef576000600160009450945094505050613016565b60b78111612cab576000612c0460808361373c565b905080876000015111612c99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f524c505265616465723a20696e76616c696420524c502073686f72742073747260448201527f696e67000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b60019550935060009250613016915050565b60bf8111612e1a576000612cc060b78361373c565b905080876000015111612d55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f524c505265616465723a20696e76616c696420524c50206c6f6e67207374726960448201527f6e67206c656e677468000000000000000000000000000000000000000000000060648201526084016104a0565b600183015160208290036101000a9004612d6f8183613b6e565b885111612dfe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f524c505265616465723a20696e76616c696420524c50206c6f6e67207374726960448201527f6e6700000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b612e09826001613b6e565b965094506000935061301692505050565b60f78111612ed5576000612e2f60c08361373c565b905080876000015111612ec4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f524c505265616465723a20696e76616c696420524c502073686f7274206c697360448201527f740000000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b600195509350849250613016915050565b6000612ee260f78361373c565b905080876000015111612f77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f524c505265616465723a20696e76616c696420524c50206c6f6e67206c69737460448201527f206c656e6774680000000000000000000000000000000000000000000000000060648201526084016104a0565b600183015160208290036101000a9004612f918183613b6e565b885111612ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f524c505265616465723a20696e76616c696420524c50206c6f6e67206c69737460448201526064016104a0565b613005826001613b6e565b965094506001935061301692505050565b9193909250565b606060008267ffffffffffffffff81111561303a5761303a6133c3565b6040519080825280601f01601f191660200182016040528015613064576020820181803683370190505b5090508051600003613077579050610bde565b60006130838587613b6e565b90506020820160005b613097602087613a2f565b8110156130ce57825182526130ad602084613b6e565b92506130ba602083613b6e565b9150806130c681613b86565b91505061308c565b5060006001602087066020036101000a039050808251168119845116178252839450505050509392505050565b60606112af826132de565b60608182601f011015613175576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016104a0565b8282840110156131e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016104a0565b8183018451101561324e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e647300000000000000000000000000000060448201526064016104a0565b60608215801561326d57604051915060008252602082016040526132d5565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156132a657805183526020928301920161328e565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60606112af82602001516000846000015161301d565b60005b8381101561330f5781810151838201526020016132f7565b8381111561331e576000848401525b50505050565b6000815180845261333c8160208601602086016132f4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006112ac6020830184613324565b60006020828403121561339357600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff811681146133be57600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715613415576134156133c3565b60405290565b600082601f83011261342c57600080fd5b813567ffffffffffffffff80821115613447576134476133c3565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561348d5761348d6133c3565b816040528381528660208588010111156134a657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156134de57600080fd5b6134e78661339a565b945060208601359350604086013567ffffffffffffffff808216821461350c57600080fd5b909350606087013590811515821461352357600080fd5b9092506080870135908082111561353957600080fd5b506135468882890161341b565b9150509295509295909350565b60006080828403121561356557600080fd5b50919050565b60008083601f84011261357d57600080fd5b50813567ffffffffffffffff81111561359557600080fd5b6020830191508360208285010111156135ad57600080fd5b9250929050565b600080600080600060e086880312156135cc57600080fd5b853567ffffffffffffffff808211156135e457600080fd5b9087019060c0828a0312156135f857600080fd5b6136006133f2565b823581526136106020840161339a565b60208201526136216040840161339a565b6040820152606083013560608201526080830135608082015260a08301358281111561364c57600080fd5b6136588b82860161341b565b60a0830152509650602088013595506136748960408a01613553565b945060c088013591508082111561368a57600080fd5b506136978882890161356b565b969995985093965092949392505050565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b6048820152600082516136fc8160498501602087016132f4565b919091016049019695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561374e5761374e61370d565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261379157613791613753565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156137e5576137e561370d565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156138245761382461370d565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156138585761385861370d565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561389f5761389f61370d565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156138da576138da61370d565b600087129250878205871284841616156138f6576138f661370d565b8785058712818416161561390c5761390c61370d565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156139545761395461370d565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156139885761398861370d565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156139c6576139c661370d565b500290565b600067ffffffffffffffff8083168185168083038211156139ee576139ee61370d565b01949350505050565b60006fffffffffffffffffffffffffffffffff80831681851681830481118215151615613a2657613a2661370d565b02949350505050565b600082613a3e57613a3e613753565b500490565b60008451613a558184602089016132f4565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551613a91816001850160208a016132f4565b60019201918201528351613aac8160028401602088016132f4565b0160020195945050505050565b600060408284031215613acb57600080fd5b6040516040810181811067ffffffffffffffff82111715613aee57613aee6133c3565b604052825181526020928301519281019290925250919050565b600060808284031215613b1a57600080fd5b6040516080810181811067ffffffffffffffff82111715613b3d57613b3d6133c3565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b60008219821115613b8157613b8161370d565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613bb757613bb761370d565b5060010190565b600082613bcd57613bcd613753565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152613c4c60c0830184613324565b98975050505050505050565b80516020808301519190811015613565577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b600060ff831680613cad57613cad613753565b8060ff84160691505092915050565b600060ff821660ff841680821015613cd657613cd661370d565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a",
}
// OptimismPortalABI is the input ABI used to generate the binding from.
diff --git a/op-bindings/bindings/optimismportal_deployed.go b/op-bindings/bindings/optimismportal_deployed.go
index 39217a7582994..10c9773480060 100644
--- a/op-bindings/bindings/optimismportal_deployed.go
+++ b/op-bindings/bindings/optimismportal_deployed.go
@@ -2,4 +2,4 @@
// This file is a generated binding and any manual changes will be lost.
package bindings
-var OptimismPortalDeployedBin = "0x6080604052600436106100f65760003560e01c8063a14238e71161008a578063cff0ab9611610059578063cff0ab96146102f7578063e9e05c4214610398578063f4daa291146103ab578063fdc9fe1d146103df57600080fd5b8063a14238e71461026d578063c4fc4798146102ad578063ca3e99ba146102cd578063cd7c9789146102e257600080fd5b80636bb0291e116100c65780636bb0291e146102005780638129fc1c14610215578063867ead131461022a5780639bf62d821461024057600080fd5b80621c2ff61461012257806313620abd1461018057806354fd4d50146101b957806364b79208146101db57600080fd5b3661011d5761011b3334620186a06000604051806020016040528060008152506103f2565b005b600080fd5b34801561012e57600080fd5b506101567f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561018c57600080fd5b50610198633b9aca0081565b6040516fffffffffffffffffffffffffffffffff9091168152602001610177565b3480156101c557600080fd5b506101ce6108bf565b6040516101779190613416565b3480156101e757600080fd5b506101f2627a120081565b604051908152602001610177565b34801561020c57600080fd5b506101f2600481565b34801561022157600080fd5b5061011b610962565b34801561023657600080fd5b506101f261271081565b34801561024c57600080fd5b506033546101569073ffffffffffffffffffffffffffffffffffffffff1681565b34801561027957600080fd5b5061029d610288366004613429565b60346020526000908152604090205460ff1681565b6040519015158152602001610177565b3480156102b957600080fd5b5061029d6102c8366004613429565b610a3d565b3480156102d957600080fd5b506101f2610b02565b3480156102ee57600080fd5b506101f2600881565b34801561030357600080fd5b5060015461035f906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff9283166020850152911690820152606001610177565b61011b6103a6366004613569565b6103f2565b3480156103b757600080fd5b506101f27f000000000000000000000000000000000000000000000000000000000000000081565b61011b6103ed366004613657565b610b13565b8260005a905083156104a95773ffffffffffffffffffffffffffffffffffffffff8716156104a957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b333281146104ca575033731111000000000000000000000000000000001111015b600034888888886040516020016104e595949392919061374b565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516105559190613416565b60405180910390a45050600154600090610595907801000000000000000000000000000000000000000000000000900467ffffffffffffffff16436137df565b9050801561071e5760006105ad6004627a1200613825565b6001546105d89190700100000000000000000000000000000000900467ffffffffffffffff1661388d565b9050600060086105ec6004627a1200613825565b60015461060c9085906fffffffffffffffffffffffffffffffff16613901565b6106169190613825565b6106209190613825565b60015490915060009061066c906106569061064e9085906fffffffffffffffffffffffffffffffff166139bd565b6127106111b7565b6fffffffffffffffffffffffffffffffff6111d2565b905060018411156106df576106dc610656670de0b6b3a76400006106c8610694600883613825565b6106a690670de0b6b3a764000061388d565b6106b160018a6137df565b6106c390670de0b6b3a7640000613a31565b6111e1565b6106d29085613901565b61064e9190613825565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054849190601090610751908490700100000000000000000000000000000000900467ffffffffffffffff16613a6e565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550627a1200600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff16131561082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d6974000060648201526084016104a0565b600154600090610859906fffffffffffffffffffffffffffffffff1667ffffffffffffffff8616613a9a565b6fffffffffffffffffffffffffffffffff169050600061087d48633b9aca00611212565b6108879083613ad2565b905060005a61089690866137df565b9050808211156108b2576108b26108ad82846137df565b611222565b5050505050505050505050565b60606108ea7f0000000000000000000000000000000000000000000000000000000000000000611250565b6109137f0000000000000000000000000000000000000000000000000000000000000000611250565b61093c7f0000000000000000000000000000000000000000000000000000000000000000611250565b60405160200161094e93929190613ae6565b604051602081830303815290604052905090565b600061096e600161138d565b905080156109a357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790556109d7611518565b8015610a3a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101829052600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae557906024016040805180830381865afa158015610acc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af09190613b5c565b9050610afb816115fb565b9392505050565b610b106004627a1200613825565b81565b60335473ffffffffffffffffffffffffffffffffffffffff1661dead14610bbc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e0060648201526084016104a0565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610c7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e74726163740060648201526084016104a0565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae557906024016040805180830381865afa158015610d08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2c9190613b5c565b9050610d37816115fb565b610dc3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4f7074696d69736d506f7274616c3a2070726f706f73616c206973206e6f742060448201527f7965742066696e616c697a65640000000000000000000000000000000000000060648201526084016104a0565b610dda610dd536869003860186613bab565b611635565b815114610e69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f66000000000000000000000000000000000000000000000060648201526084016104a0565b6000610e7487611691565b9050610ebb81866040013586868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506116c192505050565b610f47576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f66000000000000000000000000000060648201526084016104a0565b60008181526034602052604090205460ff1615610fe6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a6564000000000000000000000060648201526084016104a0565b600081815260346020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055608087015161102f90614e2090613c11565b5a10156110be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a20696e73756666696369656e742067617360448201527f20746f2066696e616c697a65207769746864726177616c00000000000000000060648201526084016104a0565b8660200151603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000611123886040015189608001518a6060015160008c60a00151611788565b50603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915082907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061118990841515815260200190565b60405180910390a25050505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000818312156111c757816111c9565b825b90505b92915050565b60008183126111c757816111c9565b60006111c9670de0b6b3a7640000836111f986611813565b6112039190613901565b61120d9190613825565b611a57565b6000818310156111c757816111c9565b6000805a90505b825a61123590836137df565b101561124b5761124482613c29565b9150611229565b505050565b60608160000361129357505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156112bd57806112a781613c29565b91506112b69050600a83613ad2565b9150611297565b60008167ffffffffffffffff8111156112d8576112d8613466565b6040519080825280601f01601f191660200182016040528015611302576020820181803683370190505b5090505b8415611385576113176001836137df565b9150611324600a86613c61565b61132f906030613c11565b60f81b81838151811061134457611344613c75565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061137e600a86613ad2565b9450611306565b949350505050565b60008054610100900460ff1615611444578160ff1660011480156113b05750303b155b61143c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104a0565b506000919050565b60005460ff8084169116106114db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104a0565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166115af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104a0565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b60007f0000000000000000000000000000000000000000000000000000000000000000826020015161162d9190613c11565b421192915050565b60008160000151826020015183604001518460600151604051602001611674949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097611674979096959101613ca4565b604080516020810185905260009181018290528190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120908301819052925061177f9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f01000000000000000000000000000000000000000000000000000000000000006020830152908587611c96565b95945050505050565b6000606060008060008661ffff1667ffffffffffffffff8111156117ae576117ae613466565b6040519080825280601f01601f1916602001820160405280156117d8576020820181803683370190505b5090506000808751602089018b8e8ef191503d9250868311156117f9578692505b828152826000602083013e90999098509650505050505050565b600080821361187e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e4544000000000000000000000000000000000000000000000060448201526064016104a0565b6000606061188b84611cba565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c18213611a8857506000919050565b680755bf798b4a1bf1e58212611afa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f57000000000000000000000000000000000000000060448201526064016104a0565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b600080611ca286611d90565b9050611cb081868686611dc2565b9695505050505050565b6000808211611d25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e4544000000000000000000000000000000000000000000000060448201526064016104a0565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b60608180519060200120604051602001611dac91815260200190565b6040516020818303038152906040529050919050565b6000806000611dd2878686611dff565b91509150818015611df457508051602080830191909120875191880191909120145b979650505050505050565b600060606000611e0e85611f1a565b90506000806000611e20848a89612015565b81519295509093509150158080611e345750815b611ec0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2070726f76696465642070726f6f6620697320696e60448201527f76616c696400000000000000000000000000000000000000000000000000000060648201526084016104a0565b600081611edc5760405180602001604052806000815250611f08565b611f0886611eeb6001886137df565b81518110611efb57611efb613c75565b602002602001015161259e565b919b919a509098505050505050505050565b60606000611f27836125c8565b90506000815167ffffffffffffffff811115611f4557611f45613466565b604051908082528060200260200182016040528015611f8a57816020015b6040805180820190915260608082526020820152815260200190600190039081611f635790505b50905060005b825181101561200d576000611fbd848381518110611fb057611fb0613c75565b60200260200101516125fb565b90506040518060400160405280828152602001611fd9836125c8565b815250838381518110611fee57611fee613c75565b602002602001018190525050808061200590613c29565b915050611f90565b509392505050565b60006060818080612025876126c2565b9050600086905060008061204c604051806040016040528060608152602001606081525090565b60005b8c5181101561255a578c818151811061206a5761206a613c75565b6020026020010151915082846120809190613c11565b935061208d600188613c11565b96508360000361210e57815180516020909101208514612109576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f74206861736800000060448201526064016104a0565b61224a565b8151516020116121b057815180516020909101208514612109576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c20686173680000000000000000000000000000000000000000000000000060648201526084016104a0565b815185906121bd90613cfb565b1461224a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f652068617368000000000000000000000000000000000000000000000000000060648201526084016104a0565b61225660106001613c11565b826020015151036122c8578551841461255a57600086858151811061227d5761227d613c75565b602001015160f81c60f81b60f81c9050600083602001518260ff16815181106122a8576122a8613c75565b602002602001015190506122bb81612845565b9650600194505050612548565b6002826020015151036124c05760006122e08361287b565b90506000816000815181106122f7576122f7613c75565b016020015160f81c9050600061230e600283613d3d565b612319906002613d5f565b9050600061232a848360ff1661289f565b905060006123388b8a61289f565b9050600061234683836128d5565b905060ff85166002148061235d575060ff85166003145b156123b3578083511480156123725750808251145b1561238457612381818b613c11565b99505b507f8000000000000000000000000000000000000000000000000000000000000000995061255a945050505050565b60ff851615806123c6575060ff85166001145b15612438578251811461240257507f8000000000000000000000000000000000000000000000000000000000000000995061255a945050505050565b612429886020015160018151811061241c5761241c613c75565b6020026020010151612845565b9a509750612548945050505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e20707265666978000000000000000000000000000060648201526084016104a0565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f646500000000000000000000000000000000000000000000000060648201526084016104a0565b8061255281613c29565b91505061204f565b507f8000000000000000000000000000000000000000000000000000000000000000841486612589878661289f565b909e909d50909b509950505050505050505050565b602081015180516060916111cc916125b8906001906137df565b81518110611fb057611fb0613c75565b6040805180820182526000808252602091820152815180830190925282518252808301908201526060906111cc90612981565b6060600080600061260b85612bda565b91945092509050600081600181111561262657612626613d82565b146126b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f524c505265616465723a20696e76616c696420524c502062797465732076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b61177f856020015184846130c5565b60606000825160026126d49190613a31565b67ffffffffffffffff8111156126ec576126ec613466565b6040519080825280601f01601f191660200182016040528015612716576020820181803683370190505b50905060005b835181101561283e57600484828151811061273957612739613c75565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c8261276e836002613a31565b8151811061277e5761277e613c75565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060108482815181106127c1576127c1613c75565b01602001516127d3919060f81c613d3d565b60f81b826127e2836002613a31565b6127ed906001613c11565b815181106127fd576127fd613c75565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508061283681613c29565b91505061271c565b5092915050565b600060606020836000015110156128665761285f836131a3565b9050612872565b61286f836125fb565b90505b610afb81613cfb565b60606111cc61289a8360200151600081518110611fb057611fb0613c75565b6126c2565b6060825182106128be57506040805160208101909152600081526111cc565b6111c983838486516128d091906137df565b6131ae565b6000805b8084511180156128e95750808351115b801561296a575082818151811061290257612902613c75565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191684828151811061294157612941613c75565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156111c9578061297981613c29565b9150506128d9565b606060008061298f84612bda565b919350909150600190508160018111156129ab576129ab613d82565b14612a38576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f524c505265616465723a20696e76616c696420524c50206c6973742076616c7560448201527f650000000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b6040805160208082526104208201909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081612a515790505090506000835b8651811015612bcf5760208210612b17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2070726f766964656420524c50206c6973742065786360448201527f65656473206d6178206c697374206c656e67746800000000000000000000000060648201526084016104a0565b600080612b546040518060400160405280858c60000151612b3891906137df565b8152602001858c60200151612b4d9190613c11565b9052612bda565b509150915060405180604001604052808383612b709190613c11565b8152602001848b60200151612b859190613c11565b815250858581518110612b9a57612b9a613c75565b6020908102919091010152612bb0600185613c11565b9350612bbc8183613c11565b612bc69084613c11565b92505050612a7e565b508152949350505050565b600080600080846000015111612c72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f524c505265616465723a20524c50206974656d2063616e6e6f74206265206e7560448201527f6c6c00000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b6020840151805160001a607f8111612c975760006001600094509450945050506130be565b60b78111612d53576000612cac6080836137df565b905080876000015111612d41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f524c505265616465723a20696e76616c696420524c502073686f72742073747260448201527f696e67000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b600195509350600092506130be915050565b60bf8111612ec2576000612d6860b7836137df565b905080876000015111612dfd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f524c505265616465723a20696e76616c696420524c50206c6f6e67207374726960448201527f6e67206c656e677468000000000000000000000000000000000000000000000060648201526084016104a0565b600183015160208290036101000a9004612e178183613c11565b885111612ea6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f524c505265616465723a20696e76616c696420524c50206c6f6e67207374726960448201527f6e6700000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b612eb1826001613c11565b96509450600093506130be92505050565b60f78111612f7d576000612ed760c0836137df565b905080876000015111612f6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f524c505265616465723a20696e76616c696420524c502073686f7274206c697360448201527f740000000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b6001955093508492506130be915050565b6000612f8a60f7836137df565b90508087600001511161301f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f524c505265616465723a20696e76616c696420524c50206c6f6e67206c69737460448201527f206c656e6774680000000000000000000000000000000000000000000000000060648201526084016104a0565b600183015160208290036101000a90046130398183613c11565b8851116130a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f524c505265616465723a20696e76616c696420524c50206c6f6e67206c69737460448201526064016104a0565b6130ad826001613c11565b96509450600193506130be92505050565b9193909250565b606060008267ffffffffffffffff8111156130e2576130e2613466565b6040519080825280601f01601f19166020018201604052801561310c576020820181803683370190505b509050805160000361311f579050610afb565b600061312b8587613c11565b90506020820160005b61313f602087613ad2565b8110156131765782518252613155602084613c11565b9250613162602083613c11565b91508061316e81613c29565b915050613134565b5060006001602087066020036101000a039050808251168119845116178252839450505050509392505050565b60606111cc82613386565b60608182601f01101561321d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016104a0565b828284011015613289576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016104a0565b818301845110156132f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e647300000000000000000000000000000060448201526064016104a0565b606082158015613315576040519150600082526020820160405261337d565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561334e578051835260209283019201613336565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60606111cc8260200151600084600001516130c5565b60005b838110156133b757818101518382015260200161339f565b838111156133c6576000848401525b50505050565b600081518084526133e481602086016020860161339c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006111c960208301846133cc565b60006020828403121561343b57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461151357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff811182821017156134b8576134b8613466565b60405290565b600082601f8301126134cf57600080fd5b813567ffffffffffffffff808211156134ea576134ea613466565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561353057613530613466565b8160405283815286602085880101111561354957600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a0868803121561358157600080fd5b61358a86613442565b945060208601359350604086013567ffffffffffffffff80821682146135af57600080fd5b90935060608701359081151582146135c657600080fd5b909250608087013590808211156135dc57600080fd5b506135e9888289016134be565b9150509295509295909350565b60006080828403121561360857600080fd5b50919050565b60008083601f84011261362057600080fd5b50813567ffffffffffffffff81111561363857600080fd5b60208301915083602082850101111561365057600080fd5b9250929050565b600080600080600060e0868803121561366f57600080fd5b853567ffffffffffffffff8082111561368757600080fd5b9087019060c0828a03121561369b57600080fd5b6136a3613495565b823581526136b360208401613442565b60208201526136c460408401613442565b6040820152606083013560608201526080830135608082015260a0830135828111156136ef57600080fd5b6136fb8b8286016134be565b60a0830152509650602088013595506137178960408a016135f6565b945060c088013591508082111561372d57600080fd5b5061373a8882890161360e565b969995985093965092949392505050565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b60488201526000825161379f81604985016020870161339c565b919091016049019695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156137f1576137f16137b0565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082613834576138346137f6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615613888576138886137b0565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156138c7576138c76137b0565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156138fb576138fb6137b0565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615613942576139426137b0565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561397d5761397d6137b0565b60008712925087820587128484161615613999576139996137b0565b878505871281841616156139af576139af6137b0565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156139f7576139f76137b0565b827f8000000000000000000000000000000000000000000000000000000000000000038412811615613a2b57613a2b6137b0565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613a6957613a696137b0565b500290565b600067ffffffffffffffff808316818516808303821115613a9157613a916137b0565b01949350505050565b60006fffffffffffffffffffffffffffffffff80831681851681830481118215151615613ac957613ac96137b0565b02949350505050565b600082613ae157613ae16137f6565b500490565b60008451613af881846020890161339c565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551613b34816001850160208a0161339c565b60019201918201528351613b4f81600284016020880161339c565b0160020195945050505050565b600060408284031215613b6e57600080fd5b6040516040810181811067ffffffffffffffff82111715613b9157613b91613466565b604052825181526020928301519281019290925250919050565b600060808284031215613bbd57600080fd5b6040516080810181811067ffffffffffffffff82111715613be057613be0613466565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b60008219821115613c2457613c246137b0565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613c5a57613c5a6137b0565b5060010190565b600082613c7057613c706137f6565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152613cef60c08301846133cc565b98975050505050505050565b80516020808301519190811015613608577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b600060ff831680613d5057613d506137f6565b8060ff84160691505092915050565b600060ff821660ff841680821015613d7957613d796137b0565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a"
+var OptimismPortalDeployedBin = "0x6080604052600436106100f65760003560e01c8063a14238e71161008a578063cff0ab9611610059578063cff0ab96146102f7578063e9e05c4214610398578063f4daa291146103ab578063fdc9fe1d146103df57600080fd5b8063a14238e71461026d578063c4fc4798146102ad578063ca3e99ba146102cd578063cd7c9789146102e257600080fd5b80636bb0291e116100c65780636bb0291e146102005780638129fc1c14610215578063867ead131461022a5780639bf62d821461024057600080fd5b80621c2ff61461012257806313620abd1461018057806354fd4d50146101b957806364b79208146101db57600080fd5b3661011d5761011b3334620186a06000604051806020016040528060008152506103f2565b005b600080fd5b34801561012e57600080fd5b506101567f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561018c57600080fd5b50610198633b9aca0081565b6040516fffffffffffffffffffffffffffffffff9091168152602001610177565b3480156101c557600080fd5b506101ce6108bf565b604051610177919061336e565b3480156101e757600080fd5b506101f2627a120081565b604051908152602001610177565b34801561020c57600080fd5b506101f2600481565b34801561022157600080fd5b5061011b610962565b34801561023657600080fd5b506101f261271081565b34801561024c57600080fd5b506033546101569073ffffffffffffffffffffffffffffffffffffffff1681565b34801561027957600080fd5b5061029d610288366004613381565b60346020526000908152604090205460ff1681565b6040519015158152602001610177565b3480156102b957600080fd5b5061029d6102c8366004613381565b610b20565b3480156102d957600080fd5b506101f2610be5565b3480156102ee57600080fd5b506101f2600881565b34801561030357600080fd5b5060015461035f906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff9283166020850152911690820152606001610177565b61011b6103a63660046134c6565b6103f2565b3480156103b757600080fd5b506101f27f000000000000000000000000000000000000000000000000000000000000000081565b61011b6103ed3660046135b4565b610bf6565b8260005a905083156104a95773ffffffffffffffffffffffffffffffffffffffff8716156104a957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b333281146104ca575033731111000000000000000000000000000000001111015b600034888888886040516020016104e59594939291906136a8565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c3284604051610555919061336e565b60405180910390a45050600154600090610595907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361373c565b9050801561071e5760006105ad6004627a1200613782565b6001546105d89190700100000000000000000000000000000000900467ffffffffffffffff166137ea565b9050600060086105ec6004627a1200613782565b60015461060c9085906fffffffffffffffffffffffffffffffff1661385e565b6106169190613782565b6106209190613782565b60015490915060009061066c906106569061064e9085906fffffffffffffffffffffffffffffffff1661391a565b61271061129a565b6fffffffffffffffffffffffffffffffff6112b5565b905060018411156106df576106dc610656670de0b6b3a76400006106c8610694600883613782565b6106a690670de0b6b3a76400006137ea565b6106b160018a61373c565b6106c390670de0b6b3a764000061398e565b6112c4565b6106d2908561385e565b61064e9190613782565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054849190601090610751908490700100000000000000000000000000000000900467ffffffffffffffff166139cb565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550627a1200600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff16131561082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d6974000060648201526084016104a0565b600154600090610859906fffffffffffffffffffffffffffffffff1667ffffffffffffffff86166139f7565b6fffffffffffffffffffffffffffffffff169050600061087d48633b9aca006112f5565b6108879083613a2f565b905060005a610896908661373c565b9050808211156108b2576108b26108ad828461373c565b611305565b5050505050505050505050565b60606108ea7f0000000000000000000000000000000000000000000000000000000000000000611333565b6109137f0000000000000000000000000000000000000000000000000000000000000000611333565b61093c7f0000000000000000000000000000000000000000000000000000000000000000611333565b60405160200161094e93929190613a43565b604051602081830303815290604052905090565b600054610100900460ff16158080156109825750600054600160ff909116105b8061099c5750303b15801561099c575060005460ff166001145b610a28576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104a0565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610a8657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055610aba611470565b8015610b1d57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101829052600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae557906024016040805180830381865afa158015610baf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd39190613ab9565b9050610bde81611553565b9392505050565b610bf36004627a1200613782565b81565b60335473ffffffffffffffffffffffffffffffffffffffff1661dead14610c9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e0060648201526084016104a0565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610d5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e74726163740060648201526084016104a0565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae557906024016040805180830381865afa158015610deb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0f9190613ab9565b9050610e1a81611553565b610ea6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4f7074696d69736d506f7274616c3a2070726f706f73616c206973206e6f742060448201527f7965742066696e616c697a65640000000000000000000000000000000000000060648201526084016104a0565b610ebd610eb836869003860186613b08565b61158d565b815114610f4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f66000000000000000000000000000000000000000000000060648201526084016104a0565b6000610f57876115e9565b9050610f9e81866040013586868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061161992505050565b61102a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f66000000000000000000000000000060648201526084016104a0565b60008181526034602052604090205460ff16156110c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a6564000000000000000000000060648201526084016104a0565b600081815260346020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055608087015161111290614e2090613b6e565b5a10156111a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a20696e73756666696369656e742067617360448201527f20746f2066696e616c697a65207769746864726177616c00000000000000000060648201526084016104a0565b8660200151603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000611206886040015189608001518a6060015160008c60a001516116e0565b50603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915082907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061126c90841515815260200190565b60405180910390a25050505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000818312156112aa57816112ac565b825b90505b92915050565b60008183126112aa57816112ac565b60006112ac670de0b6b3a7640000836112dc8661176b565b6112e6919061385e565b6112f09190613782565b6119af565b6000818310156112aa57816112ac565b6000805a90505b825a611318908361373c565b101561132e5761132782613b86565b915061130c565b505050565b60608160000361137657505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156113a0578061138a81613b86565b91506113999050600a83613a2f565b915061137a565b60008167ffffffffffffffff8111156113bb576113bb6133c3565b6040519080825280601f01601f1916602001820160405280156113e5576020820181803683370190505b5090505b8415611468576113fa60018361373c565b9150611407600a86613bbe565b611412906030613b6e565b60f81b81838151811061142757611427613bd2565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611461600a86613a2f565b94506113e9565b949350505050565b600054610100900460ff16611507576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104a0565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b60007f000000000000000000000000000000000000000000000000000000000000000082602001516115859190613b6e565b421192915050565b600081600001518260200151836040015184606001516040516020016115cc949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a088015193516000976115cc979096959101613c01565b604080516020810185905260009181018290528190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506116d79101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f01000000000000000000000000000000000000000000000000000000000000006020830152908587611bee565b95945050505050565b6000606060008060008661ffff1667ffffffffffffffff811115611706576117066133c3565b6040519080825280601f01601f191660200182016040528015611730576020820181803683370190505b5090506000808751602089018b8e8ef191503d925086831115611751578692505b828152826000602083013e90999098509650505050505050565b60008082136117d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e4544000000000000000000000000000000000000000000000060448201526064016104a0565b600060606117e384611c12565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136119e057506000919050565b680755bf798b4a1bf1e58212611a52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f57000000000000000000000000000000000000000060448201526064016104a0565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b600080611bfa86611ce8565b9050611c0881868686611d1a565b9695505050505050565b6000808211611c7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e4544000000000000000000000000000000000000000000000060448201526064016104a0565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b60608180519060200120604051602001611d0491815260200190565b6040516020818303038152906040529050919050565b6000806000611d2a878686611d57565b91509150818015611d4c57508051602080830191909120875191880191909120145b979650505050505050565b600060606000611d6685611e72565b90506000806000611d78848a89611f6d565b81519295509093509150158080611d8c5750815b611e18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2070726f76696465642070726f6f6620697320696e60448201527f76616c696400000000000000000000000000000000000000000000000000000060648201526084016104a0565b600081611e345760405180602001604052806000815250611e60565b611e6086611e4360018861373c565b81518110611e5357611e53613bd2565b60200260200101516124f6565b919b919a509098505050505050505050565b60606000611e7f83612520565b90506000815167ffffffffffffffff811115611e9d57611e9d6133c3565b604051908082528060200260200182016040528015611ee257816020015b6040805180820190915260608082526020820152815260200190600190039081611ebb5790505b50905060005b8251811015611f65576000611f15848381518110611f0857611f08613bd2565b6020026020010151612553565b90506040518060400160405280828152602001611f3183612520565b815250838381518110611f4657611f46613bd2565b6020026020010181905250508080611f5d90613b86565b915050611ee8565b509392505050565b60006060818080611f7d8761261a565b90506000869050600080611fa4604051806040016040528060608152602001606081525090565b60005b8c518110156124b2578c8181518110611fc257611fc2613bd2565b602002602001015191508284611fd89190613b6e565b9350611fe5600188613b6e565b96508360000361206657815180516020909101208514612061576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f74206861736800000060448201526064016104a0565b6121a2565b81515160201161210857815180516020909101208514612061576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c20686173680000000000000000000000000000000000000000000000000060648201526084016104a0565b8151859061211590613c58565b146121a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f652068617368000000000000000000000000000000000000000000000000000060648201526084016104a0565b6121ae60106001613b6e565b8260200151510361222057855184146124b25760008685815181106121d5576121d5613bd2565b602001015160f81c60f81b60f81c9050600083602001518260ff168151811061220057612200613bd2565b602002602001015190506122138161279d565b96506001945050506124a0565b600282602001515103612418576000612238836127d3565b905060008160008151811061224f5761224f613bd2565b016020015160f81c90506000612266600283613c9a565b612271906002613cbc565b90506000612282848360ff166127f7565b905060006122908b8a6127f7565b9050600061229e838361282d565b905060ff8516600214806122b5575060ff85166003145b1561230b578083511480156122ca5750808251145b156122dc576122d9818b613b6e565b99505b507f800000000000000000000000000000000000000000000000000000000000000099506124b2945050505050565b60ff8516158061231e575060ff85166001145b15612390578251811461235a57507f800000000000000000000000000000000000000000000000000000000000000099506124b2945050505050565b612381886020015160018151811061237457612374613bd2565b602002602001015161279d565b9a5097506124a0945050505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e20707265666978000000000000000000000000000060648201526084016104a0565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f646500000000000000000000000000000000000000000000000060648201526084016104a0565b806124aa81613b86565b915050611fa7565b507f80000000000000000000000000000000000000000000000000000000000000008414866124e187866127f7565b909e909d50909b509950505050505050505050565b602081015180516060916112af916125109060019061373c565b81518110611f0857611f08613bd2565b6040805180820182526000808252602091820152815180830190925282518252808301908201526060906112af906128d9565b6060600080600061256385612b32565b91945092509050600081600181111561257e5761257e613cdf565b1461260b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f524c505265616465723a20696e76616c696420524c502062797465732076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b6116d78560200151848461301d565b606060008251600261262c919061398e565b67ffffffffffffffff811115612644576126446133c3565b6040519080825280601f01601f19166020018201604052801561266e576020820181803683370190505b50905060005b835181101561279657600484828151811061269157612691613bd2565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c826126c683600261398e565b815181106126d6576126d6613bd2565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350601084828151811061271957612719613bd2565b016020015161272b919060f81c613c9a565b60f81b8261273a83600261398e565b612745906001613b6e565b8151811061275557612755613bd2565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508061278e81613b86565b915050612674565b5092915050565b600060606020836000015110156127be576127b7836130fb565b90506127ca565b6127c783612553565b90505b610bde81613c58565b60606112af6127f28360200151600081518110611f0857611f08613bd2565b61261a565b60608251821061281657506040805160208101909152600081526112af565b6112ac8383848651612828919061373c565b613106565b6000805b8084511180156128415750808351115b80156128c2575082818151811061285a5761285a613bd2565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191684828151811061289957612899613bd2565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156112ac57806128d181613b86565b915050612831565b60606000806128e784612b32565b9193509091506001905081600181111561290357612903613cdf565b14612990576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f524c505265616465723a20696e76616c696420524c50206c6973742076616c7560448201527f650000000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b6040805160208082526104208201909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816129a95790505090506000835b8651811015612b275760208210612a6f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2070726f766964656420524c50206c6973742065786360448201527f65656473206d6178206c697374206c656e67746800000000000000000000000060648201526084016104a0565b600080612aac6040518060400160405280858c60000151612a90919061373c565b8152602001858c60200151612aa59190613b6e565b9052612b32565b509150915060405180604001604052808383612ac89190613b6e565b8152602001848b60200151612add9190613b6e565b815250858581518110612af257612af2613bd2565b6020908102919091010152612b08600185613b6e565b9350612b148183613b6e565b612b1e9084613b6e565b925050506129d6565b508152949350505050565b600080600080846000015111612bca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f524c505265616465723a20524c50206974656d2063616e6e6f74206265206e7560448201527f6c6c00000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b6020840151805160001a607f8111612bef576000600160009450945094505050613016565b60b78111612cab576000612c0460808361373c565b905080876000015111612c99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f524c505265616465723a20696e76616c696420524c502073686f72742073747260448201527f696e67000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b60019550935060009250613016915050565b60bf8111612e1a576000612cc060b78361373c565b905080876000015111612d55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f524c505265616465723a20696e76616c696420524c50206c6f6e67207374726960448201527f6e67206c656e677468000000000000000000000000000000000000000000000060648201526084016104a0565b600183015160208290036101000a9004612d6f8183613b6e565b885111612dfe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f524c505265616465723a20696e76616c696420524c50206c6f6e67207374726960448201527f6e6700000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b612e09826001613b6e565b965094506000935061301692505050565b60f78111612ed5576000612e2f60c08361373c565b905080876000015111612ec4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f524c505265616465723a20696e76616c696420524c502073686f7274206c697360448201527f740000000000000000000000000000000000000000000000000000000000000060648201526084016104a0565b600195509350849250613016915050565b6000612ee260f78361373c565b905080876000015111612f77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f524c505265616465723a20696e76616c696420524c50206c6f6e67206c69737460448201527f206c656e6774680000000000000000000000000000000000000000000000000060648201526084016104a0565b600183015160208290036101000a9004612f918183613b6e565b885111612ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f524c505265616465723a20696e76616c696420524c50206c6f6e67206c69737460448201526064016104a0565b613005826001613b6e565b965094506001935061301692505050565b9193909250565b606060008267ffffffffffffffff81111561303a5761303a6133c3565b6040519080825280601f01601f191660200182016040528015613064576020820181803683370190505b5090508051600003613077579050610bde565b60006130838587613b6e565b90506020820160005b613097602087613a2f565b8110156130ce57825182526130ad602084613b6e565b92506130ba602083613b6e565b9150806130c681613b86565b91505061308c565b5060006001602087066020036101000a039050808251168119845116178252839450505050509392505050565b60606112af826132de565b60608182601f011015613175576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016104a0565b8282840110156131e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016104a0565b8183018451101561324e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e647300000000000000000000000000000060448201526064016104a0565b60608215801561326d57604051915060008252602082016040526132d5565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156132a657805183526020928301920161328e565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60606112af82602001516000846000015161301d565b60005b8381101561330f5781810151838201526020016132f7565b8381111561331e576000848401525b50505050565b6000815180845261333c8160208601602086016132f4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006112ac6020830184613324565b60006020828403121561339357600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff811681146133be57600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715613415576134156133c3565b60405290565b600082601f83011261342c57600080fd5b813567ffffffffffffffff80821115613447576134476133c3565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561348d5761348d6133c3565b816040528381528660208588010111156134a657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a086880312156134de57600080fd5b6134e78661339a565b945060208601359350604086013567ffffffffffffffff808216821461350c57600080fd5b909350606087013590811515821461352357600080fd5b9092506080870135908082111561353957600080fd5b506135468882890161341b565b9150509295509295909350565b60006080828403121561356557600080fd5b50919050565b60008083601f84011261357d57600080fd5b50813567ffffffffffffffff81111561359557600080fd5b6020830191508360208285010111156135ad57600080fd5b9250929050565b600080600080600060e086880312156135cc57600080fd5b853567ffffffffffffffff808211156135e457600080fd5b9087019060c0828a0312156135f857600080fd5b6136006133f2565b823581526136106020840161339a565b60208201526136216040840161339a565b6040820152606083013560608201526080830135608082015260a08301358281111561364c57600080fd5b6136588b82860161341b565b60a0830152509650602088013595506136748960408a01613553565b945060c088013591508082111561368a57600080fd5b506136978882890161356b565b969995985093965092949392505050565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b6048820152600082516136fc8160498501602087016132f4565b919091016049019695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561374e5761374e61370d565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261379157613791613753565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156137e5576137e561370d565b500590565b6000808312837f8000000000000000000000000000000000000000000000000000000000000000018312811516156138245761382461370d565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156138585761385861370d565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561389f5761389f61370d565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156138da576138da61370d565b600087129250878205871284841616156138f6576138f661370d565b8785058712818416161561390c5761390c61370d565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156139545761395461370d565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156139885761398861370d565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156139c6576139c661370d565b500290565b600067ffffffffffffffff8083168185168083038211156139ee576139ee61370d565b01949350505050565b60006fffffffffffffffffffffffffffffffff80831681851681830481118215151615613a2657613a2661370d565b02949350505050565b600082613a3e57613a3e613753565b500490565b60008451613a558184602089016132f4565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551613a91816001850160208a016132f4565b60019201918201528351613aac8160028401602088016132f4565b0160020195945050505050565b600060408284031215613acb57600080fd5b6040516040810181811067ffffffffffffffff82111715613aee57613aee6133c3565b604052825181526020928301519281019290925250919050565b600060808284031215613b1a57600080fd5b6040516080810181811067ffffffffffffffff82111715613b3d57613b3d6133c3565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b60008219821115613b8157613b8161370d565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613bb757613bb761370d565b5060010190565b600082613bcd57613bcd613753565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152613c4c60c0830184613324565b98975050505050505050565b80516020808301519190811015613565577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b600060ff831680613cad57613cad613753565b8060ff84160691505092915050565b600060ff821660ff841680821015613cd657613cd661370d565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a"
diff --git a/op-bindings/gen_bindings.sh b/op-bindings/gen_bindings.sh
index dd80d28bb5992..8319c0288a216 100755
--- a/op-bindings/gen_bindings.sh
+++ b/op-bindings/gen_bindings.sh
@@ -19,8 +19,11 @@ need_cmd() {
need_cmd forge
need_cmd abigen
-
-TYPE=$1
+NAME=$1
+# This can handle both fully qualified syntax or just
+# the name of the contract.
+# Fully qualified: path-to-contract-file:contract-name
+TYPE=$(echo "$NAME" | cut -d ':' -f2)
PACKAGE=$2
# Convert to lower case to respect golang package naming conventions
@@ -35,9 +38,9 @@ CWD=$(pwd)
# Build contracts
cd ${CONTRACTS_PATH}
forge build
-forge inspect ${TYPE} abi > ${TEMP}/${TYPE}.abi
-forge inspect ${TYPE} bytecode > ${TEMP}/${TYPE}.bin
-forge inspect ${TYPE} deployedBytecode > ${CWD}/bin/${TYPE_LOWER}_deployed.hex
+forge inspect ${NAME} abi > ${TEMP}/${TYPE}.abi
+forge inspect ${NAME} bytecode > ${TEMP}/${TYPE}.bin
+forge inspect ${NAME} deployedBytecode > ${CWD}/bin/${TYPE_LOWER}_deployed.hex
# Run ABIGEN
cd ${CWD}
diff --git a/op-bindings/go.mod b/op-bindings/go.mod
index 16e2bfc8ddabf..d8db292890087 100644
--- a/op-bindings/go.mod
+++ b/op-bindings/go.mod
@@ -3,7 +3,7 @@ module github.com/ethereum-optimism/optimism/op-bindings
go 1.18
require (
- github.com/ethereum/go-ethereum v1.10.20
+ github.com/ethereum/go-ethereum v1.10.21
github.com/stretchr/testify v1.7.2
)
@@ -41,4 +41,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
-replace github.com/ethereum/go-ethereum v1.10.20 => github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220715235548-70b02481016d
+replace github.com/ethereum/go-ethereum v1.10.21 => github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220803173305-1c9d4cc76a6e
diff --git a/op-bindings/go.sum b/op-bindings/go.sum
index 08ba986bbfdf7..cde610dd5049f 100644
--- a/op-bindings/go.sum
+++ b/op-bindings/go.sum
@@ -28,8 +28,8 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
-github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220715235548-70b02481016d h1:w0DBXhp0sv0bWRDOCA/Y6yHOALU7qLLLf5/kE3YfFr4=
-github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220715235548-70b02481016d/go.mod h1:m2m08SAQ8XB0VcVBoDg9n74Dw5PUMl3hzv1NXVBFPfg=
+github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220803173305-1c9d4cc76a6e h1:hz+iywXjnqz6xA3lTLvtNL9OZyX76pS5SER4kZBmQLs=
+github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220803173305-1c9d4cc76a6e/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
diff --git a/op-e2e/go.mod b/op-e2e/go.mod
index 4154356d8f615..d90aa11448274 100644
--- a/op-e2e/go.mod
+++ b/op-e2e/go.mod
@@ -7,7 +7,7 @@ require (
github.com/ethereum-optimism/optimism/op-bindings v0.3.0
github.com/ethereum-optimism/optimism/op-node v0.3.0
github.com/ethereum-optimism/optimism/op-proposer v0.3.0
- github.com/ethereum/go-ethereum v1.10.20
+ github.com/ethereum/go-ethereum v1.10.21
github.com/libp2p/go-libp2p v0.18.1
github.com/libp2p/go-libp2p-core v0.15.0
github.com/miguelmota/go-ethereum-hdwallet v0.1.1
@@ -161,4 +161,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
-replace github.com/ethereum/go-ethereum v1.10.20 => github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220715235548-70b02481016d
+replace github.com/ethereum/go-ethereum v1.10.21 => github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220803173305-1c9d4cc76a6e
diff --git a/op-e2e/go.sum b/op-e2e/go.sum
index 6fc24d02ec4b4..f54c178d2acc2 100644
--- a/op-e2e/go.sum
+++ b/op-e2e/go.sum
@@ -245,8 +245,8 @@ github.com/ethereum-optimism/optimism/op-node v0.3.0 h1:jep/cbIbP7fjBSAR48yk5NJV
github.com/ethereum-optimism/optimism/op-node v0.3.0/go.mod h1:iF9AhYjr8jNeoCDNP/Vs/ywQ2USZU5L66AxZbSAUi0E=
github.com/ethereum-optimism/optimism/op-proposer v0.3.0 h1:K1ipZt3TLD0BJi7tKOmx8tCLXj9i4f4baBIhbPmUxk4=
github.com/ethereum-optimism/optimism/op-proposer v0.3.0/go.mod h1:GcQ9VCWz2zEVexecq5IYo/2eadK/y7IBOEfx4YV1QJk=
-github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220715235548-70b02481016d h1:w0DBXhp0sv0bWRDOCA/Y6yHOALU7qLLLf5/kE3YfFr4=
-github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220715235548-70b02481016d/go.mod h1:m2m08SAQ8XB0VcVBoDg9n74Dw5PUMl3hzv1NXVBFPfg=
+github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220803173305-1c9d4cc76a6e h1:hz+iywXjnqz6xA3lTLvtNL9OZyX76pS5SER4kZBmQLs=
+github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220803173305-1c9d4cc76a6e/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg=
github.com/ethereum/go-ethereum v1.10.4/go.mod h1:nEE0TP5MtxGzOMd7egIrbPJMQBnhVU3ELNxhBglIzhg=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
diff --git a/op-node/cmd/main.go b/op-node/cmd/main.go
index 9a4bf1a0512e3..232f1f6e6b953 100644
--- a/op-node/cmd/main.go
+++ b/op-node/cmd/main.go
@@ -2,9 +2,14 @@ package main
import (
"context"
+ "net"
+ "net/http"
"os"
"os/signal"
"syscall"
+ "time"
+
+ "github.com/ethereum-optimism/optimism/op-node/cmd/p2p"
"github.com/ethereum-optimism/optimism/op-node/metrics"
@@ -50,13 +55,19 @@ func main() {
)
app := cli.NewApp()
- app.Flags = flags.Flags
app.Version = VersionWithMeta
- app.Name = "opnode"
+ app.Flags = flags.Flags
+ app.Name = "op-node"
app.Usage = "Optimism Rollup Node"
- app.Description = "The deposit only rollup node drives the L2 execution engine based on L1 deposits."
-
+ app.Description = "The Optimism Rollup Node derives L2 block inputs from L1 data and drives an external L2 Execution Engine to build a L2 chain."
app.Action = RollupNodeMain
+ app.Commands = []cli.Command{
+ {
+ Name: "p2p",
+ Subcommands: p2p.Subcommands,
+ },
+ }
+
err := app.Run(os.Args)
if err != nil {
log.Crit("Application failed", "message", err)
@@ -101,6 +112,27 @@ func RollupNodeMain(ctx *cli.Context) error {
m.RecordUp()
log.Info("Rollup node started")
+ if cfg.Pprof.Enabled {
+ var srv http.Server
+ srv.Addr = net.JoinHostPort(cfg.Pprof.ListenAddr, cfg.Pprof.ListenPort)
+ // Start pprof server + register it's shutdown
+ go func() {
+ log.Info("pprof server started", "addr", srv.Addr)
+ if err := srv.ListenAndServe(); err != http.ErrServerClosed {
+ log.Error("error in pprof server", "err", err)
+ } else {
+ log.Info("pprof server shutting down")
+ }
+
+ }()
+ defer func() {
+ shutCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ err := srv.Shutdown(shutCtx)
+ log.Info("pprof server shut down", "err", err)
+ }()
+ }
+
interruptChannel := make(chan os.Signal, 1)
signal.Notify(interruptChannel, []os.Signal{
os.Interrupt,
diff --git a/op-node/cmd/p2p/cmd.go b/op-node/cmd/p2p/cmd.go
new file mode 100644
index 0000000000000..8a6e4bc384b01
--- /dev/null
+++ b/op-node/cmd/p2p/cmd.go
@@ -0,0 +1,106 @@
+package p2p
+
+import (
+ "crypto/rand"
+ "encoding/hex"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "strings"
+
+ "github.com/libp2p/go-libp2p-core/crypto"
+ "github.com/libp2p/go-libp2p-core/peer"
+ "github.com/urfave/cli"
+)
+
+func Priv2PeerID(r io.Reader) (string, error) {
+ b, err := readHexData(r)
+ if err != nil {
+ return "", nil
+ }
+
+ p, err := crypto.UnmarshalSecp256k1PrivateKey(b)
+ if err != nil {
+ return "", fmt.Errorf("failed to parse priv key from %d bytes: %w", len(b), err)
+ }
+
+ pid, err := peer.IDFromPrivateKey(p)
+ if err != nil {
+ return "", fmt.Errorf("failed to parse peer ID from private key: %w", err)
+ }
+ return pid.String(), nil
+}
+
+func Pub2PeerID(r io.Reader) (string, error) {
+ b, err := readHexData(r)
+ if err != nil {
+ return "", nil
+ }
+
+ p, err := crypto.UnmarshalSecp256k1PublicKey(b)
+ if err != nil {
+ return "", fmt.Errorf("failed to parse pub key from %d bytes: %w", len(b), err)
+ }
+
+ pid, err := peer.IDFromPublicKey(p)
+ if err != nil {
+ return "", fmt.Errorf("failed to parse peer ID from public key: %w", err)
+ }
+
+ return pid.String(), nil
+}
+
+func readHexData(r io.Reader) ([]byte, error) {
+ data, err := ioutil.ReadAll(r)
+ if err != nil {
+ return nil, err
+ }
+
+ rawStr := strings.TrimSpace(string(data))
+ rawStr = strings.TrimPrefix(rawStr, "0x")
+ b, err := hex.DecodeString(rawStr)
+ if err != nil {
+ return nil, fmt.Errorf("p2p key is not formatted in hex chars: %w", err)
+ }
+ return b, nil
+}
+
+var Subcommands = cli.Commands{
+ {
+ Name: "priv2id",
+ Usage: "Reads a private key from STDIN, and returns a peer ID",
+ Action: func(ctx *cli.Context) error {
+ key, err := Priv2PeerID(os.Stdin)
+ if err != nil {
+ return err
+ }
+ fmt.Println(key)
+ return nil
+ },
+ },
+ {
+ Name: "pub2id",
+ Usage: "Reads a public key from STDIN, and returns a peer ID",
+ Action: func(ctx *cli.Context) error {
+ key, err := Pub2PeerID(os.Stdin)
+ if err != nil {
+ return err
+ }
+ fmt.Println(key)
+ return nil
+ },
+ },
+ {
+ Name: "genkey",
+ Usage: "Generates a private key",
+ Action: func(ctx *cli.Context) error {
+ buf := make([]byte, 32)
+ if _, err := rand.Read(buf); err != nil {
+ return fmt.Errorf("failed to get entropy: %w", err)
+ }
+ fmt.Println(hex.EncodeToString(buf))
+ return nil
+ },
+ },
+}
diff --git a/op-node/cmd/p2p/cmd_test.go b/op-node/cmd/p2p/cmd_test.go
new file mode 100644
index 0000000000000..c2acd8beb2e87
--- /dev/null
+++ b/op-node/cmd/p2p/cmd_test.go
@@ -0,0 +1,35 @@
+package p2p
+
+import (
+ "bytes"
+ "encoding/hex"
+ "testing"
+
+ "github.com/libp2p/go-libp2p-core/crypto"
+ "github.com/libp2p/go-libp2p-core/peer"
+ "github.com/stretchr/testify/require"
+)
+
+func TestPrivPub2PeerID(t *testing.T) {
+ priv, pub, err := crypto.GenerateKeyPair(crypto.Secp256k1, 32)
+ require.NoError(t, err)
+ privRaw, err := priv.Raw()
+ require.NoError(t, err)
+ pubRaw, err := pub.Raw()
+ require.NoError(t, err)
+
+ t.Run("with a private key", func(t *testing.T) {
+ privPidLib, err := peer.IDFromPrivateKey(priv)
+ require.NoError(t, err)
+ privPidImpl, err := Priv2PeerID(bytes.NewReader([]byte(hex.EncodeToString(privRaw))))
+ require.NoError(t, err)
+ require.Equal(t, privPidLib.String(), privPidImpl)
+ })
+ t.Run("with a public key", func(t *testing.T) {
+ pubPidLib, err := peer.IDFromPublicKey(pub)
+ require.NoError(t, err)
+ pubPidImpl, err := Pub2PeerID(bytes.NewReader([]byte(hex.EncodeToString(pubRaw))))
+ require.NoError(t, err)
+ require.Equal(t, pubPidLib.String(), pubPidImpl)
+ })
+}
diff --git a/op-node/flags/flags.go b/op-node/flags/flags.go
index 4d6141bd85a13..ab84905a19c59 100644
--- a/op-node/flags/flags.go
+++ b/op-node/flags/flags.go
@@ -1,6 +1,10 @@
package flags
-import "github.com/urfave/cli"
+import (
+ "fmt"
+
+ "github.com/urfave/cli"
+)
// Flags
@@ -13,35 +17,30 @@ func prefixEnvVar(name string) string {
var (
/* Required Flags */
L1NodeAddr = cli.StringFlag{
- Name: "l1",
- Usage: "Address of L1 User JSON-RPC endpoint to use (eth namespace required)",
- Required: true,
- Value: "http://127.0.0.1:8545",
- EnvVar: prefixEnvVar("L1_ETH_RPC"),
+ Name: "l1",
+ Usage: "Address of L1 User JSON-RPC endpoint to use (eth namespace required)",
+ Value: "http://127.0.0.1:8545",
+ EnvVar: prefixEnvVar("L1_ETH_RPC"),
}
L2EngineAddr = cli.StringFlag{
- Name: "l2",
- Usage: "Address of L2 Engine JSON-RPC endpoints to use (engine and eth namespace required)",
- Required: true,
- EnvVar: prefixEnvVar("L2_ENGINE_RPC"),
+ Name: "l2",
+ Usage: "Address of L2 Engine JSON-RPC endpoints to use (engine and eth namespace required)",
+ EnvVar: prefixEnvVar("L2_ENGINE_RPC"),
}
RollupConfig = cli.StringFlag{
- Name: "rollup.config",
- Usage: "Rollup chain parameters",
- Required: true,
- EnvVar: prefixEnvVar("ROLLUP_CONFIG"),
+ Name: "rollup.config",
+ Usage: "Rollup chain parameters",
+ EnvVar: prefixEnvVar("ROLLUP_CONFIG"),
}
RPCListenAddr = cli.StringFlag{
- Name: "rpc.addr",
- Usage: "RPC listening address",
- Required: true,
- EnvVar: prefixEnvVar("RPC_ADDR"),
+ Name: "rpc.addr",
+ Usage: "RPC listening address",
+ EnvVar: prefixEnvVar("RPC_ADDR"),
}
RPCListenPort = cli.IntFlag{
- Name: "rpc.port",
- Usage: "RPC listening port",
- Required: true,
- EnvVar: prefixEnvVar("RPC_PORT"),
+ Name: "rpc.port",
+ Usage: "RPC listening port",
+ EnvVar: prefixEnvVar("RPC_PORT"),
}
/* Optional Flags */
@@ -111,6 +110,23 @@ var (
Value: 7300,
EnvVar: prefixEnvVar("METRICS_PORT"),
}
+ PprofEnabledFlag = cli.BoolFlag{
+ Name: "pprof.enabled",
+ Usage: "Enable the pprof server",
+ EnvVar: prefixEnvVar("PPROF_ENABLED"),
+ }
+ PprofAddrFlag = cli.StringFlag{
+ Name: "pprof.addr",
+ Usage: "pprof listening address",
+ Value: "0.0.0.0",
+ EnvVar: prefixEnvVar("PPROF_ADDR"),
+ }
+ PprofPortFlag = cli.IntFlag{
+ Name: "pprof.port",
+ Usage: "pprof listening port",
+ Value: 6060,
+ EnvVar: prefixEnvVar("PPROF_PORT"),
+ }
SnapshotLog = cli.StringFlag{
Name: "snapshotlog.file",
@@ -139,8 +155,34 @@ var optionalFlags = append([]cli.Flag{
MetricsEnabledFlag,
MetricsAddrFlag,
MetricsPortFlag,
+ PprofEnabledFlag,
+ PprofAddrFlag,
+ PprofPortFlag,
SnapshotLog,
}, p2pFlags...)
// Flags contains the list of configuration options available to the binary.
var Flags = append(requiredFlags, optionalFlags...)
+
+func CheckRequired(ctx *cli.Context) error {
+ l1NodeAddr := ctx.GlobalString(L1NodeAddr.Name)
+ if l1NodeAddr == "" {
+ return fmt.Errorf("flag %s is required", L1NodeAddr.Name)
+ }
+ l2EngineAddr := ctx.GlobalString(L2EngineAddr.Name)
+ if l2EngineAddr == "" {
+ return fmt.Errorf("flag %s is required", L2EngineAddr.Name)
+ }
+ rollupConfig := ctx.GlobalString(RollupConfig.Name)
+ if rollupConfig == "" {
+ return fmt.Errorf("flag %s is required", RollupConfig.Name)
+ }
+ rpcListenAddr := ctx.GlobalString(RPCListenAddr.Name)
+ if rpcListenAddr == "" {
+ return fmt.Errorf("flag %s is required", RPCListenAddr.Name)
+ }
+ if !ctx.GlobalIsSet(RPCListenPort.Name) {
+ return fmt.Errorf("flag %s is required", RPCListenPort.Name)
+ }
+ return nil
+}
diff --git a/op-node/flags/flags_test.go b/op-node/flags/flags_test.go
index 48d9f3598cea3..80d05648615f7 100644
--- a/op-node/flags/flags_test.go
+++ b/op-node/flags/flags_test.go
@@ -7,16 +7,6 @@ import (
"github.com/urfave/cli"
)
-// TestRequiredFlagsSetRequired asserts that all flags deemed required properly
-// have the Required field set to true.
-func TestRequiredFlagsSetRequired(t *testing.T) {
- for _, flag := range requiredFlags {
- reqFlag, ok := flag.(cli.RequiredFlag)
- require.True(t, ok)
- require.True(t, reqFlag.IsRequired())
- }
-}
-
// TestOptionalFlagsDontSetRequired asserts that all flags deemed optional set
// the Required field to false.
func TestOptionalFlagsDontSetRequired(t *testing.T) {
diff --git a/op-node/go.mod b/op-node/go.mod
index 6fe0ce156867b..a9dec7095c6e1 100644
--- a/op-node/go.mod
+++ b/op-node/go.mod
@@ -4,7 +4,7 @@ go 1.18
require (
github.com/ethereum-optimism/optimism/op-bindings v0.3.0
- github.com/ethereum/go-ethereum v1.10.20
+ github.com/ethereum/go-ethereum v1.10.21
github.com/golang/snappy v0.0.4
github.com/google/go-cmp v0.5.8
github.com/hashicorp/go-multierror v1.1.1
@@ -173,7 +173,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
-replace github.com/ethereum/go-ethereum v1.10.20 => github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220715235548-70b02481016d
-
-// For local debugging:
-// replace github.com/ethereum/go-ethereum v1.10.17 => ../go-ethereum
+replace github.com/ethereum/go-ethereum v1.10.21 => github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220803173305-1c9d4cc76a6e
diff --git a/op-node/go.sum b/op-node/go.sum
index c0e0644c32d63..b7d76bd34bd8f 100644
--- a/op-node/go.sum
+++ b/op-node/go.sum
@@ -193,8 +193,8 @@ github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ethereum-optimism/optimism/op-bindings v0.3.0 h1:d2Mwb8FzR2zuhW0sS5xFKWz/6VFPTEIE+XINqZj0Rv4=
github.com/ethereum-optimism/optimism/op-bindings v0.3.0/go.mod h1:CrvUVIISKcyJ7o27ub/HY4Kq9wEJQxrGmWthTqxPSGo=
-github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220715235548-70b02481016d h1:w0DBXhp0sv0bWRDOCA/Y6yHOALU7qLLLf5/kE3YfFr4=
-github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220715235548-70b02481016d/go.mod h1:m2m08SAQ8XB0VcVBoDg9n74Dw5PUMl3hzv1NXVBFPfg=
+github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220803173305-1c9d4cc76a6e h1:hz+iywXjnqz6xA3lTLvtNL9OZyX76pS5SER4kZBmQLs=
+github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220803173305-1c9d4cc76a6e/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fjl/memsize v0.0.1 h1:+zhkb+dhUgx0/e+M8sF0QqiouvMQUiKR+QYvdxIOKcQ=
github.com/fjl/memsize v0.0.1/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
diff --git a/op-node/metrics/metrics.go b/op-node/metrics/metrics.go
index 5cec5eb73e51a..1c4e3e6a907e5 100644
--- a/op-node/metrics/metrics.go
+++ b/op-node/metrics/metrics.go
@@ -7,6 +7,7 @@ import (
"net"
"net/http"
"strconv"
+ "time"
"github.com/ethereum/go-ethereum"
"github.com/prometheus/client_golang/prometheus/collectors"
@@ -27,14 +28,24 @@ const (
)
type Metrics struct {
- Info *prometheus.GaugeVec
- Up prometheus.Gauge
+ Info *prometheus.GaugeVec
+ Up prometheus.Gauge
+
RPCServerRequestsTotal *prometheus.CounterVec
RPCServerRequestDurationSeconds *prometheus.HistogramVec
RPCClientRequestsTotal *prometheus.CounterVec
RPCClientRequestDurationSeconds *prometheus.HistogramVec
RPCClientResponsesTotal *prometheus.CounterVec
+ DerivationIdle prometheus.Gauge
+ PipelineResetsTotal prometheus.Counter
+ LastPipelineResetUnix prometheus.Gauge
+ UnsafePayloadsTotal prometheus.Counter
+ DerivationErrorsTotal prometheus.Counter
+ Heads *prometheus.GaugeVec
+
+ TransactionsSequencedTotal prometheus.Counter
+
registry *prometheus.Registry
}
@@ -60,6 +71,7 @@ func NewMetrics(procName string) *Metrics {
Name: "up",
Help: "1 if the op node has finished starting up",
}),
+
RPCServerRequestsTotal: promauto.With(registry).NewCounterVec(prometheus.CounterOpts{
Namespace: ns,
Subsystem: RPCServerSubsystem,
@@ -103,6 +115,46 @@ func NewMetrics(procName string) *Metrics {
"method",
"error",
}),
+
+ DerivationIdle: promauto.With(registry).NewGauge(prometheus.GaugeOpts{
+ Namespace: ns,
+ Name: "derivation_idle",
+ Help: "1 if the derivation pipeline is idle",
+ }),
+ PipelineResetsTotal: promauto.With(registry).NewCounter(prometheus.CounterOpts{
+ Namespace: ns,
+ Name: "pipeline_resets_total",
+ Help: "Count of derivation pipeline resets",
+ }),
+ LastPipelineResetUnix: promauto.With(registry).NewGauge(prometheus.GaugeOpts{
+ Namespace: ns,
+ Name: "last_pipeline_reset_unix",
+ Help: "Timestamp of last pipeline reset",
+ }),
+ UnsafePayloadsTotal: promauto.With(registry).NewCounter(prometheus.CounterOpts{
+ Namespace: ns,
+ Name: "unsafe_payloads_total",
+ Help: "Count of unsafe payloads received via p2p",
+ }),
+ DerivationErrorsTotal: promauto.With(registry).NewCounter(prometheus.CounterOpts{
+ Namespace: ns,
+ Name: "derivation_errors_total",
+ Help: "Count of total derivation errors",
+ }),
+ Heads: promauto.With(registry).NewGaugeVec(prometheus.GaugeOpts{
+ Namespace: ns,
+ Name: "heads",
+ Help: "Gauge representing the different L1/L2 heads",
+ }, []string{
+ "type",
+ }),
+
+ TransactionsSequencedTotal: promauto.With(registry).NewGauge(prometheus.GaugeOpts{
+ Namespace: ns,
+ Name: "transactions_sequenced_total",
+ Help: "Count of total transactions sequenced",
+ }),
+
registry: registry,
}
}
@@ -166,6 +218,24 @@ func (m *Metrics) RecordRPCClientResponse(method string, err error) {
m.RPCClientResponsesTotal.WithLabelValues(method, errStr).Inc()
}
+func (m *Metrics) SetDerivationIdle(status bool) {
+ var val float64
+ if status {
+ val = 1
+ }
+ m.DerivationIdle.Set(val)
+}
+
+func (m *Metrics) SetHead(kind string, num uint64) {
+ m.Heads.WithLabelValues(kind).Set(float64(num))
+}
+
+func (m *Metrics) RecordPipelineReset() {
+ m.PipelineResetsTotal.Inc()
+ m.DerivationErrorsTotal.Inc()
+ m.LastPipelineResetUnix.Set(float64(time.Now().Unix()))
+}
+
// Serve starts the metrics server on the given hostname and port.
// The server will be closed when the passed-in context is cancelled.
func (m *Metrics) Serve(ctx context.Context, hostname string, port int) error {
diff --git a/op-node/node/config.go b/op-node/node/config.go
index a544e512607de..2ab26ebfe3b3b 100644
--- a/op-node/node/config.go
+++ b/op-node/node/config.go
@@ -28,6 +28,8 @@ type Config struct {
Metrics MetricsConfig
+ Pprof PprofConfig
+
// Optional
Tracer Tracer
}
@@ -59,6 +61,16 @@ func (m MetricsConfig) Check() error {
return nil
}
+type PprofConfig struct {
+ Enabled bool
+ ListenAddr string
+ ListenPort string
+}
+
+func (p PprofConfig) Check() error {
+ return nil
+}
+
// Check verifies that the given configuration makes sense
func (cfg *Config) Check() error {
if err := cfg.L2.Check(); err != nil {
@@ -70,6 +82,9 @@ func (cfg *Config) Check() error {
if err := cfg.Metrics.Check(); err != nil {
return fmt.Errorf("metrics config error: %w", err)
}
+ if err := cfg.Pprof.Check(); err != nil {
+ return fmt.Errorf("pprof config error: %w", err)
+ }
if cfg.P2P != nil {
if err := cfg.P2P.Check(); err != nil {
return fmt.Errorf("p2p config error: %w", err)
diff --git a/op-node/node/node.go b/op-node/node/node.go
index 1c2c0b9c71556..5883e54e7fff9 100644
--- a/op-node/node/node.go
+++ b/op-node/node/node.go
@@ -144,7 +144,7 @@ func (n *OpNode) initL2(ctx context.Context, cfg *Config, snapshotLog log.Logger
return err
}
- n.l2Engine = driver.NewDriver(&cfg.Driver, &cfg.Rollup, source, n.l1Source, n, n.log, snapshotLog)
+ n.l2Engine = driver.NewDriver(&cfg.Driver, &cfg.Rollup, source, n.l1Source, n, n.log, snapshotLog, n.metrics)
return nil
}
diff --git a/op-node/rollup/derive/attributes.go b/op-node/rollup/derive/attributes.go
index dcf2f7a98520c..e6822b950a2ae 100644
--- a/op-node/rollup/derive/attributes.go
+++ b/op-node/rollup/derive/attributes.go
@@ -22,7 +22,7 @@ type L1ReceiptsFetcher interface {
// by setting NoTxPool=false as sequencer, or by appending batch transactions as verifier.
// The severity of the error is returned; a crit=false error means there was a temporary issue, like a failed RPC or time-out.
// A crit=true error means the input arguments are inconsistent or invalid.
-func PreparePayloadAttributes(ctx context.Context, cfg *rollup.Config, dl L1ReceiptsFetcher, l2Parent eth.L2BlockRef, epoch eth.BlockID) (attrs *eth.PayloadAttributes, crit bool, err error) {
+func PreparePayloadAttributes(ctx context.Context, cfg *rollup.Config, dl L1ReceiptsFetcher, l2Parent eth.L2BlockRef, timestamp uint64, epoch eth.BlockID) (attrs *eth.PayloadAttributes, crit bool, err error) {
var l1Info eth.L1Info
var depositTxs []hexutil.Bytes
var seqNumber uint64
@@ -68,7 +68,7 @@ func PreparePayloadAttributes(ctx context.Context, cfg *rollup.Config, dl L1Rece
txs = append(txs, depositTxs...)
return ð.PayloadAttributes{
- Timestamp: hexutil.Uint64(l2Parent.Time + cfg.BlockTime),
+ Timestamp: hexutil.Uint64(timestamp),
PrevRandao: eth.Bytes32(l1Info.MixDigest()),
SuggestedFeeRecipient: cfg.FeeRecipientAddress,
Transactions: txs,
diff --git a/op-node/rollup/derive/attributes_queue.go b/op-node/rollup/derive/attributes_queue.go
index 920fc8f8b0979..bff530879826e 100644
--- a/op-node/rollup/derive/attributes_queue.go
+++ b/op-node/rollup/derive/attributes_queue.go
@@ -55,7 +55,7 @@ func (aq *AttributesQueue) Step(ctx context.Context, outer Progress) error {
fetchCtx, cancel := context.WithTimeout(ctx, 20*time.Second)
defer cancel()
- attrs, crit, err := PreparePayloadAttributes(fetchCtx, aq.config, aq.dl, aq.next.SafeL2Head(), batch.Epoch())
+ attrs, crit, err := PreparePayloadAttributes(fetchCtx, aq.config, aq.dl, aq.next.SafeL2Head(), batch.Timestamp, batch.Epoch())
if err != nil {
if crit {
return fmt.Errorf("failed to prepare payload attributes for batch: %v", err)
diff --git a/op-node/rollup/derive/attributes_queue_test.go b/op-node/rollup/derive/attributes_queue_test.go
index bc4b3af78f116..ca3ab8572d56b 100644
--- a/op-node/rollup/derive/attributes_queue_test.go
+++ b/op-node/rollup/derive/attributes_queue_test.go
@@ -70,7 +70,7 @@ func TestAttributesQueue_Step(t *testing.T) {
batch := &BatchData{BatchV1{
EpochNum: rollup.Epoch(l1Info.InfoNum),
EpochHash: l1Info.InfoHash,
- Timestamp: 12345,
+ Timestamp: safeHead.Time + cfg.BlockTime,
Transactions: []eth.Data{eth.Data("foobar"), eth.Data("example")},
}}
diff --git a/op-node/rollup/derive/attributes_test.go b/op-node/rollup/derive/attributes_test.go
index e9fb18dbbed4b..bcd988c2ed009 100644
--- a/op-node/rollup/derive/attributes_test.go
+++ b/op-node/rollup/derive/attributes_test.go
@@ -31,11 +31,12 @@ func TestPreparePayloadAttributes(t *testing.T) {
l1Fetcher := &testutils.MockL1Source{}
defer l1Fetcher.AssertExpectations(t)
l2Parent := testutils.RandomL2BlockRef(rng)
+ l2Time := l2Parent.Time + cfg.BlockTime
l1Info := testutils.RandomL1Info(rng)
l1Info.InfoNum = l2Parent.L1Origin.Number + 1
epoch := l1Info.ID()
l1Fetcher.ExpectFetch(epoch.Hash, l1Info, nil, nil, nil)
- _, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, epoch)
+ _, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, l2Time, epoch)
require.NotNil(t, err, "inconsistent L1 origin error expected")
require.True(t, crit, "inconsistent L1 origin transition must be handled like a critical error with reorg")
})
@@ -44,10 +45,11 @@ func TestPreparePayloadAttributes(t *testing.T) {
l1Fetcher := &testutils.MockL1Source{}
defer l1Fetcher.AssertExpectations(t)
l2Parent := testutils.RandomL2BlockRef(rng)
+ l2Time := l2Parent.Time + cfg.BlockTime
l1Info := testutils.RandomL1Info(rng)
l1Info.InfoNum = l2Parent.L1Origin.Number
epoch := l1Info.ID()
- _, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, epoch)
+ _, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, l2Time, epoch)
require.NotNil(t, err, "inconsistent L1 origin error expected")
require.True(t, crit, "inconsistent L1 origin transition must be handled like a critical error with reorg")
})
@@ -56,11 +58,12 @@ func TestPreparePayloadAttributes(t *testing.T) {
l1Fetcher := &testutils.MockL1Source{}
defer l1Fetcher.AssertExpectations(t)
l2Parent := testutils.RandomL2BlockRef(rng)
+ l2Time := l2Parent.Time + cfg.BlockTime
epoch := l2Parent.L1Origin
epoch.Number += 1
mockRPCErr := errors.New("mock rpc error")
l1Fetcher.ExpectFetch(epoch.Hash, nil, nil, nil, mockRPCErr)
- _, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, epoch)
+ _, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, l2Time, epoch)
require.ErrorIs(t, err, mockRPCErr, "mock rpc error expected")
require.False(t, crit, "rpc errors should not be critical, it is not necessary to reorg")
})
@@ -69,10 +72,11 @@ func TestPreparePayloadAttributes(t *testing.T) {
l1Fetcher := &testutils.MockL1Source{}
defer l1Fetcher.AssertExpectations(t)
l2Parent := testutils.RandomL2BlockRef(rng)
+ l2Time := l2Parent.Time + cfg.BlockTime
epoch := l2Parent.L1Origin
mockRPCErr := errors.New("mock rpc error")
l1Fetcher.ExpectInfoByHash(epoch.Hash, nil, mockRPCErr)
- _, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, epoch)
+ _, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, l2Time, epoch)
require.ErrorIs(t, err, mockRPCErr, "mock rpc error expected")
require.False(t, crit, "rpc errors should not be critical, it is not necessary to reorg")
})
@@ -81,6 +85,7 @@ func TestPreparePayloadAttributes(t *testing.T) {
l1Fetcher := &testutils.MockL1Source{}
defer l1Fetcher.AssertExpectations(t)
l2Parent := testutils.RandomL2BlockRef(rng)
+ l2Time := l2Parent.Time + cfg.BlockTime
l1Info := testutils.RandomL1Info(rng)
l1Info.InfoParentHash = l2Parent.L1Origin.Hash
l1Info.InfoNum = l2Parent.L1Origin.Number + 1
@@ -88,7 +93,7 @@ func TestPreparePayloadAttributes(t *testing.T) {
l1InfoTx, err := L1InfoDepositBytes(0, l1Info)
require.NoError(t, err)
l1Fetcher.ExpectFetch(epoch.Hash, l1Info, nil, nil, nil)
- attrs, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, epoch)
+ attrs, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, l2Time, epoch)
require.NoError(t, err)
require.False(t, crit)
require.NotNil(t, attrs)
@@ -104,6 +109,7 @@ func TestPreparePayloadAttributes(t *testing.T) {
l1Fetcher := &testutils.MockL1Source{}
defer l1Fetcher.AssertExpectations(t)
l2Parent := testutils.RandomL2BlockRef(rng)
+ l2Time := l2Parent.Time + cfg.BlockTime
l1Info := testutils.RandomL1Info(rng)
l1Info.InfoParentHash = l2Parent.L1Origin.Hash
l1Info.InfoNum = l2Parent.L1Origin.Number + 1
@@ -126,7 +132,7 @@ func TestPreparePayloadAttributes(t *testing.T) {
// txs are ignored, API is a bit bloated to previous approach. Only l1Info and receipts matter.
l1Txs := make(types.Transactions, len(receipts))
l1Fetcher.ExpectFetch(epoch.Hash, l1Info, l1Txs, receipts, nil)
- attrs, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, epoch)
+ attrs, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, l2Time, epoch)
require.NoError(t, err)
require.False(t, crit)
require.NotNil(t, attrs)
@@ -142,6 +148,7 @@ func TestPreparePayloadAttributes(t *testing.T) {
l1Fetcher := &testutils.MockL1Source{}
defer l1Fetcher.AssertExpectations(t)
l2Parent := testutils.RandomL2BlockRef(rng)
+ l2Time := l2Parent.Time + cfg.BlockTime
l1Info := testutils.RandomL1Info(rng)
l1Info.InfoHash = l2Parent.L1Origin.Hash
l1Info.InfoNum = l2Parent.L1Origin.Number
@@ -151,7 +158,7 @@ func TestPreparePayloadAttributes(t *testing.T) {
require.NoError(t, err)
l1Fetcher.ExpectInfoByHash(epoch.Hash, l1Info, nil)
- attrs, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, epoch)
+ attrs, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, l2Time, epoch)
require.NoError(t, err)
require.False(t, crit)
require.NotNil(t, attrs)
diff --git a/op-node/rollup/derive/channel_bank.go b/op-node/rollup/derive/channel_bank.go
index 74d7063d34cf4..64ca3fcdd580f 100644
--- a/op-node/rollup/derive/channel_bank.go
+++ b/op-node/rollup/derive/channel_bank.go
@@ -1,8 +1,8 @@
package derive
import (
+ "bytes"
"context"
- "encoding/binary"
"fmt"
"io"
@@ -81,85 +81,72 @@ func (ib *ChannelBank) IngestData(data []byte) error {
if data[0] != DerivationVersion0 {
return fmt.Errorf("unrecognized derivation version: %d", data)
}
+ buf := bytes.NewBuffer(data[1:])
ib.prune()
- offset := 1
- if len(data[offset:]) < minimumFrameSize {
+ if buf.Len() < minimumFrameSize {
return fmt.Errorf("data must be at least have one frame")
}
// Iterate over all frames. They may have different channel IDs to indicate that they stream consumer should reset.
for {
- if len(data) < offset+ChannelIDDataSize+1 {
+ // Don't try to unmarshal from an empty buffer.
+ // The if done checks should catch most/all of this case though.
+ if buf.Len() < ChannelIDDataSize+1 {
return nil
}
- var chID ChannelID
- copy(chID.Data[:], data[offset:])
- offset += ChannelIDDataSize
- chIDTime, n := binary.Uvarint(data[offset:])
- if n <= 0 {
- return fmt.Errorf("failed to read frame number")
+ done := false
+ var f Frame
+ if err := (&f).UnmarshalBinary(buf); err == io.EOF {
+ done = true
+ } else if err != nil {
+ return fmt.Errorf("failed to unmarshal a frame: %w", err)
+
}
- offset += n
- chID.Time = chIDTime
// stop reading and ignore remaining data if we encounter a zeroed ID
- if chID == (ChannelID{}) {
+ if f.ID == (ChannelID{}) {
+ ib.log.Info("empty channel ID")
return nil
}
- frameNumber, n := binary.Uvarint(data[offset:])
- if n <= 0 {
- return fmt.Errorf("failed to read frame number")
- }
- offset += n
-
- frameLength, n := binary.Uvarint(data[offset:])
- if n <= 0 {
- return fmt.Errorf("failed to read frame length")
- }
- offset += n
-
- if remaining := uint64(len(data) - offset); remaining < frameLength {
- return fmt.Errorf("not enough data left for frame: %d < %d", remaining, frameLength)
- }
- frameData := data[offset : uint64(offset)+frameLength]
- offset += int(frameLength)
-
- if offset >= len(data) {
- return fmt.Errorf("failed to read frame end byte, no data left, offset past length %d", len(data))
- }
- isLastNum := data[offset]
- if isLastNum > 1 {
- return fmt.Errorf("invalid isLast bool value: %d", data[offset])
- }
- isLast := isLastNum == 1
- offset += 1
-
// check if the channel is not timed out
- if chID.Time+ib.cfg.ChannelTimeout < ib.progress.Origin.Time {
- ib.log.Info("channel is timed out, ignore frame", "channel", chID, "id_time", chID.Time, "frame", frameNumber)
+ if f.ID.Time+ib.cfg.ChannelTimeout < ib.progress.Origin.Time {
+ ib.log.Info("channel is timed out, ignore frame", "channel", f.ID, "id_time", f.ID.Time, "frame", f.FrameNumber)
+ if done {
+ return nil
+ }
continue
}
// check if the channel is not included too soon (otherwise timeouts wouldn't be effective)
- if chID.Time > ib.progress.Origin.Time {
- ib.log.Info("channel claims to be from the future, ignore frame", "channel", chID, "id_time", chID.Time, "frame", frameNumber)
+ if f.ID.Time > ib.progress.Origin.Time {
+ ib.log.Info("channel claims to be from the future, ignore frame", "channel", f.ID, "id_time", f.ID.Time, "frame", f.FrameNumber)
+ if done {
+ return nil
+ }
continue
}
- currentCh, ok := ib.channels[chID]
+ currentCh, ok := ib.channels[f.ID]
if !ok { // create new channel if it doesn't exist yet
- currentCh = &ChannelIn{id: chID}
- ib.channels[chID] = currentCh
- ib.channelQueue = append(ib.channelQueue, chID)
+ currentCh = &ChannelIn{id: f.ID}
+ ib.channels[f.ID] = currentCh
+ ib.channelQueue = append(ib.channelQueue, f.ID)
}
- ib.log.Debug("ingesting frame", "channel", chID, "frame_number", frameNumber, "length", len(frameData))
- if err := currentCh.IngestData(frameNumber, isLast, frameData); err != nil {
- ib.log.Debug("failed to ingest frame into channel", "channel", chID, "frame_number", frameNumber, "err", err)
+ ib.log.Debug("ingesting frame", "channel", f.ID, "frame_number", f.FrameNumber, "length", len(f.Data))
+ if err := currentCh.IngestData(f.FrameNumber, f.IsLast, f.Data); err != nil {
+ ib.log.Debug("failed to ingest frame into channel", "channel", f.ID, "frame_number", f.FrameNumber, "err", err)
+ if done {
+ return nil
+ }
continue
}
+
+ if done {
+ return nil
+ }
}
}
diff --git a/op-node/rollup/derive/channel_frame.go b/op-node/rollup/derive/channel_frame.go
new file mode 100644
index 0000000000000..5c277005ff77c
--- /dev/null
+++ b/op-node/rollup/derive/channel_frame.go
@@ -0,0 +1,133 @@
+package derive
+
+import (
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+)
+
+// Frames cannot be larger than 1 MB.
+// Data transactions that carry frames are generally not larger than 128 KB due to L1 network conditions,
+// but we leave space to grow larger anyway (gas limit allows for more data).
+const MaxFrameLen = 1_000_000
+
+var ErrNotEnoughFrameBytes = errors.New("not enough available bytes for the frame")
+
+// Data Format
+//
+// frame = channel_id ++ frame_number ++ frame_data_length ++ frame_data ++ is_last
+//
+// channel_id = random ++ timestamp
+// random = bytes32
+// timestamp = uvarint
+// frame_number = uvarint
+// frame_data_length = uvarint
+// frame_data = bytes
+// is_last = bool
+
+type Frame struct {
+ ID ChannelID
+ FrameNumber uint64
+ Data []byte
+ IsLast bool
+}
+
+// MarshalBinary writes the frame to `w`.
+// It returns the number of bytes written as well as any
+// error encountered while writing.
+func (f *Frame) MarshalBinary(w io.Writer) (int, error) {
+ n, err := w.Write(f.ID.Data[:])
+ if err != nil {
+ return n, err
+ }
+ l, err := w.Write(makeUVarint(f.ID.Time))
+ n += l
+ if err != nil {
+ return n, err
+ }
+ l, err = w.Write(makeUVarint(f.FrameNumber))
+ n += l
+ if err != nil {
+ return n, err
+ }
+
+ l, err = w.Write(makeUVarint(uint64(len(f.Data))))
+ n += l
+ if err != nil {
+ return n, err
+ }
+ l, err = w.Write(f.Data)
+ n += l
+ if err != nil {
+ return n, err
+ }
+ if f.IsLast {
+ l, err = w.Write([]byte{1})
+ n += l
+ if err != nil {
+ return n, err
+ }
+ } else {
+ l, err = w.Write([]byte{0})
+ n += l
+ if err != nil {
+ return n, err
+ }
+ }
+ return n, nil
+}
+
+type ByteReader interface {
+ io.Reader
+ io.ByteReader
+}
+
+// UnmarshalBinary consumes a full frame from the reader.
+// If `r` fails a read, it returns the error from the reader
+// The reader will be left in a partially read state.
+func (f *Frame) UnmarshalBinary(r ByteReader) error {
+ _, err := io.ReadFull(r, f.ID.Data[:])
+ if err != nil {
+ return fmt.Errorf("error reading ID: %w", err)
+ }
+ f.ID.Time, err = binary.ReadUvarint(r)
+ if err != nil {
+ return fmt.Errorf("error reading ID.Time: %w", err)
+ }
+ // stop reading and ignore remaining data if we encounter a zeroed ID
+ if f.ID == (ChannelID{}) {
+ return io.EOF
+ }
+ f.FrameNumber, err = binary.ReadUvarint(r)
+ if err != nil {
+ return fmt.Errorf("error reading frame number: %w", err)
+ }
+
+ frameLength, err := binary.ReadUvarint(r)
+ if err != nil {
+ return fmt.Errorf("error reading frame length: %w", err)
+ }
+
+ // Cap frame length to MaxFrameLen (currently 1MB)
+ if frameLength > MaxFrameLen {
+ return fmt.Errorf("frameLength is too large: %d", frameLength)
+ }
+ f.Data = make([]byte, int(frameLength))
+ if _, err := io.ReadFull(r, f.Data); err != nil {
+ return fmt.Errorf("error reading frame data: %w", err)
+ }
+
+ isLastByte, err := r.ReadByte()
+ if err != nil && err != io.EOF {
+ return fmt.Errorf("error reading final byte: %w", err)
+ }
+ if isLastByte == 0 {
+ f.IsLast = false
+ } else if isLastByte == 1 {
+ f.IsLast = true
+ } else {
+ return errors.New("invalid byte as is_last")
+ }
+ return err
+}
diff --git a/op-node/rollup/derive/channel_out.go b/op-node/rollup/derive/channel_out.go
index ca83fcb4305ec..085fb3b22eb1c 100644
--- a/op-node/rollup/derive/channel_out.go
+++ b/op-node/rollup/derive/channel_out.go
@@ -6,7 +6,6 @@ import (
"crypto/rand"
"encoding/binary"
"errors"
- "fmt"
"io"
"github.com/ethereum-optimism/optimism/op-node/rollup"
@@ -114,41 +113,38 @@ func (co *ChannelOut) Close() error {
// Returns nil if there is still more buffered data.
// Returns and error if it ran into an error during processing.
func (co *ChannelOut) OutputFrame(w *bytes.Buffer, maxSize uint64) error {
- w.Write(co.id.Data[:])
- w.Write(makeUVarint(co.id.Time))
- w.Write(makeUVarint(co.frame))
+ f := Frame{
+ ID: co.id,
+ FrameNumber: co.frame,
+ }
+ // Copy data from the local buffer into the frame data buffer
+ // Don't go past the maxSize even with the max possible uvarints
// +1 for single byte of frame content, +1 for lastFrame bool
- if uint64(w.Len())+2 > maxSize {
- return fmt.Errorf("no more space: %d > %d", w.Len(), maxSize)
+ // +24 for maximum uvarints
+ // +32 for the data ID
+ maxDataSize := maxSize - 32 - 24 - 1 - 1
+ if maxDataSize >= uint64(co.buf.Len()) {
+ maxDataSize = uint64(co.buf.Len())
+ // If we are closed & will not spill past the current frame, end it.
+ if co.closed {
+ f.IsLast = true
+ }
}
+ f.Data = make([]byte, maxDataSize)
- remaining := maxSize - uint64(w.Len())
- maxFrameLen := remaining - 1 // -1 for the bool at the end
- // estimate how many bytes we lose with encoding the length of the frame
- // by encoding the max length (larger uvarints take more space)
- maxFrameLen -= uint64(len(makeUVarint(maxFrameLen)))
-
- // Pull the data into a temporary buffer b/c we use uvarints to record the length
- // Could theoretically use the min of co.buf.Len() & maxFrameLen
- co.scratch.Reset()
- _, err := io.CopyN(&co.scratch, &co.buf, int64(maxFrameLen))
- if err != nil && err != io.EOF {
+ if _, err := io.ReadFull(&co.buf, f.Data); err != nil {
return err
}
- frameLen := uint64(co.scratch.Len())
- co.offset += frameLen
- w.Write(makeUVarint(frameLen))
- if _, err := w.ReadFrom(&co.scratch); err != nil {
+
+ if _, err := f.MarshalBinary(w); err != nil {
return err
}
+
co.frame += 1
- // Only mark as closed if the channel is closed & there is no more data available
- if co.closed && err == io.EOF {
- w.WriteByte(1)
+ if f.IsLast {
return io.EOF
} else {
- w.WriteByte(0)
return nil
}
}
diff --git a/op-node/rollup/derive/deposit_log.go b/op-node/rollup/derive/deposit_log.go
index c3bcca2b6a7da..fd0a00e29ecf2 100644
--- a/op-node/rollup/derive/deposit_log.go
+++ b/op-node/rollup/derive/deposit_log.go
@@ -77,6 +77,7 @@ func UnmarshalDepositLogEvent(ev *types.Log) (*types.DepositTx, error) {
}
dep.SourceHash = source.SourceHash()
dep.From = from
+ dep.IsSystemTransaction = false
var err error
switch version {
diff --git a/op-node/rollup/derive/l1_block_info.go b/op-node/rollup/derive/l1_block_info.go
index 2364d3260d35d..7256c940176e5 100644
--- a/op-node/rollup/derive/l1_block_info.go
+++ b/op-node/rollup/derive/l1_block_info.go
@@ -102,17 +102,17 @@ func L1InfoDeposit(seqNumber uint64, block eth.L1Info) (*types.DepositTx, error)
L1BlockHash: block.Hash(),
SeqNumber: seqNumber,
}
- // Uses ~30k normal case
- // Uses ~70k on first transaction
- // Round up to 75k to ensure that we always have enough gas.
+ // Set a very large gas limit with `IsSystemTransaction` to ensure
+ // that the L1 Attributes Transaction does not run out of gas.
return &types.DepositTx{
- SourceHash: source.SourceHash(),
- From: L1InfoDepositerAddress,
- To: &L1BlockAddress,
- Mint: nil,
- Value: big.NewInt(0),
- Gas: 150_000, // TODO: temporary work around. Block 1 seems to require more gas than specced.
- Data: data,
+ SourceHash: source.SourceHash(),
+ From: L1InfoDepositerAddress,
+ To: &L1BlockAddress,
+ Mint: nil,
+ Value: big.NewInt(0),
+ Gas: 150_000_000,
+ IsSystemTransaction: true,
+ Data: data,
}, nil
}
diff --git a/op-node/rollup/driver/driver.go b/op-node/rollup/driver/driver.go
index 031b4e2132cd9..52789e8a13683 100644
--- a/op-node/rollup/driver/driver.go
+++ b/op-node/rollup/driver/driver.go
@@ -4,6 +4,8 @@ import (
"context"
"math/big"
+ "github.com/ethereum-optimism/optimism/op-node/metrics"
+
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/l1"
"github.com/ethereum-optimism/optimism/op-node/l2"
@@ -56,7 +58,7 @@ type Network interface {
PublishL2Payload(ctx context.Context, payload *eth.ExecutionPayload) error
}
-func NewDriver(driverCfg *Config, cfg *rollup.Config, l2 *l2.Source, l1 *l1.Source, network Network, log log.Logger, snapshotLog log.Logger) *Driver {
+func NewDriver(driverCfg *Config, cfg *rollup.Config, l2 *l2.Source, l1 *l1.Source, network Network, log log.Logger, snapshotLog log.Logger, metrics *metrics.Metrics) *Driver {
output := &outputImpl{
Config: cfg,
dl: l1,
@@ -67,7 +69,7 @@ func NewDriver(driverCfg *Config, cfg *rollup.Config, l2 *l2.Source, l1 *l1.Sour
var state *state
verifConfDepth := NewConfDepth(driverCfg.VerifierConfDepth, func() eth.L1BlockRef { return state.l1Head }, l1)
derivationPipeline := derive.NewDerivationPipeline(log, cfg, verifConfDepth, l2)
- state = NewState(driverCfg, log, snapshotLog, cfg, l1, l2, output, derivationPipeline, network)
+ state = NewState(driverCfg, log, snapshotLog, cfg, l1, l2, output, derivationPipeline, network, metrics)
return &Driver{s: state}
}
diff --git a/op-node/rollup/driver/state.go b/op-node/rollup/driver/state.go
index 4b6b9162dd0d3..7ad59fa23fc36 100644
--- a/op-node/rollup/driver/state.go
+++ b/op-node/rollup/driver/state.go
@@ -9,6 +9,7 @@ import (
"time"
"github.com/ethereum-optimism/optimism/op-node/eth"
+ "github.com/ethereum-optimism/optimism/op-node/metrics"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum/go-ethereum/log"
)
@@ -67,6 +68,7 @@ type state struct {
output outputInterface
network Network // may be nil, network for is optional
+ metrics *metrics.Metrics
log log.Logger
snapshotLog log.Logger
done chan struct{}
@@ -77,7 +79,7 @@ type state struct {
// NewState creates a new driver state. State changes take effect though
// the given output, derivation pipeline and network interfaces.
func NewState(driverCfg *Config, log log.Logger, snapshotLog log.Logger, config *rollup.Config, l1Chain L1Chain, l2Chain L2Chain,
- output outputInterface, derivationPipeline DerivationPipeline, network Network) *state {
+ output outputInterface, derivationPipeline DerivationPipeline, network Network, metrics *metrics.Metrics) *state {
return &state{
derivation: derivationPipeline,
idleDerivation: false,
@@ -91,6 +93,7 @@ func NewState(driverCfg *Config, log log.Logger, snapshotLog log.Logger, config
l2: l2Chain,
output: output,
network: network,
+ metrics: metrics,
l1Heads: make(chan eth.L1BlockRef, 10),
unsafeL2Payloads: make(chan *eth.ExecutionPayload, 10),
}
@@ -105,6 +108,8 @@ func (s *state) Start(ctx context.Context) error {
}
s.l1Head = l1Head
s.l2Head, _ = s.l2.L2BlockRefByNumber(ctx, nil)
+ s.metrics.SetHead("l1", s.l1Head.Number)
+ s.metrics.SetHead("l2_unsafe", s.l2Head.Number)
s.derivation.Reset()
@@ -151,6 +156,7 @@ func (s *state) handleNewL1Block(newL1Head eth.L1BlockRef) {
// This could either be a long L1 extension, or a reorg. Both can be handled the same way.
s.log.Warn("L1 Head signal indicates an L1 re-org", "old_l1_head", s.l1Head, "new_l1_head_parent", newL1Head.ParentHash, "new_l1_head", newL1Head)
}
+ s.metrics.SetHead("l1", newL1Head.Number)
s.l1Head = newL1Head
}
@@ -238,6 +244,7 @@ func (s *state) createNewL2Block(ctx context.Context) error {
s.l2Head = newUnsafeL2Head
s.log.Info("Sequenced new l2 block", "l2Head", s.l2Head, "l1Origin", s.l2Head.L1Origin, "txs", len(payload.Transactions), "time", s.l2Head.Time)
+ s.metrics.TransactionsSequencedTotal.Add(float64(len(payload.Transactions)))
if s.network != nil {
if err := s.network.PublishL2Payload(ctx, payload); err != nil {
@@ -315,6 +322,7 @@ func (s *state) eventLoop() {
cancel()
if err != nil {
s.log.Error("Error creating new L2 block", "err", err)
+ s.metrics.DerivationErrorsTotal.Inc()
}
// We need to catch up to the next origin as quickly as possible. We can do this by
@@ -330,6 +338,7 @@ func (s *state) eventLoop() {
s.snapshot("New unsafe payload")
s.log.Info("Optimistically queueing unsafe L2 execution payload", "id", payload.ID())
s.derivation.AddUnsafePayload(payload)
+ s.metrics.UnsafePayloadsTotal.Inc()
reqStep()
case newL1Head := <-s.l1Heads:
@@ -338,6 +347,7 @@ func (s *state) eventLoop() {
s.handleNewL1Block(newL1Head)
reqStep() // a new L1 head may mean we have the data to not get an EOF again.
case <-stepReqCh:
+ s.metrics.SetDerivationIdle(false)
s.idleDerivation = false
s.log.Debug("Derivation process step", "onto_origin", s.derivation.Progress().Origin, "onto_closed", s.derivation.Progress().Closed)
stepCtx, cancel := context.WithTimeout(ctx, time.Second*10) // TODO pick a timeout for executing a single step
@@ -346,16 +356,21 @@ func (s *state) eventLoop() {
if err == io.EOF {
s.log.Debug("Derivation process went idle", "progress", s.derivation.Progress().Origin)
s.idleDerivation = true
+ s.metrics.SetDerivationIdle(true)
continue
} else if err != nil {
// If the pipeline corrupts, e.g. due to a reorg, simply reset it
s.log.Warn("Derivation pipeline is reset", "err", err)
s.derivation.Reset()
+ s.metrics.RecordPipelineReset()
} else {
finalized, safe, unsafe := s.derivation.Finalized(), s.derivation.SafeL2Head(), s.derivation.UnsafeL2Head()
// log sync progress when it changes
if s.l2Finalized != finalized || s.l2SafeHead != safe || s.l2Head != unsafe {
s.log.Info("Sync progress", "finalized", finalized, "safe", safe, "unsafe", unsafe)
+ s.metrics.SetHead("l2_finalized", finalized.Number)
+ s.metrics.SetHead("l2_safe", safe.Number)
+ s.metrics.SetHead("l2_unsafe", unsafe.Number)
}
// update the heads
s.l2Finalized = finalized
diff --git a/op-node/rollup/driver/step.go b/op-node/rollup/driver/step.go
index 9597d98e97dc4..6ef3cef86e4ff 100644
--- a/op-node/rollup/driver/step.go
+++ b/op-node/rollup/driver/step.go
@@ -25,7 +25,7 @@ func (d *outputImpl) createNewBlock(ctx context.Context, l2Head eth.L2BlockRef,
fetchCtx, cancel := context.WithTimeout(ctx, time.Second*20)
defer cancel()
- attrs, _, err := derive.PreparePayloadAttributes(fetchCtx, d.Config, d.dl, l2Head, l1Origin.ID())
+ attrs, _, err := derive.PreparePayloadAttributes(fetchCtx, d.Config, d.dl, l2Head, l2Head.Time+d.Config.BlockTime, l1Origin.ID())
if err != nil {
return l2Head, nil, err
}
diff --git a/op-node/service.go b/op-node/service.go
index 4b51c1b433d30..d9e3892bbb7dc 100644
--- a/op-node/service.go
+++ b/op-node/service.go
@@ -24,6 +24,10 @@ import (
// NewConfig creates a Config from the provided flags or environment variables.
func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) {
+ if err := flags.CheckRequired(ctx); err != nil {
+ return nil, err
+ }
+
rollupConfig, err := NewRollupConfig(ctx)
if err != nil {
return nil, err
@@ -68,6 +72,11 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) {
ListenAddr: ctx.GlobalString(flags.MetricsAddrFlag.Name),
ListenPort: ctx.GlobalInt(flags.MetricsPortFlag.Name),
},
+ Pprof: node.PprofConfig{
+ Enabled: ctx.GlobalBool(flags.PprofEnabledFlag.Name),
+ ListenAddr: ctx.GlobalString(flags.PprofAddrFlag.Name),
+ ListenPort: ctx.GlobalString(flags.PprofPortFlag.Name),
+ },
P2P: p2pConfig,
P2PSigner: p2pSignerSetup,
}
diff --git a/op-node/testutils/deposits.go b/op-node/testutils/deposits.go
index ae24177cfce6d..e0070c0d4a33d 100644
--- a/op-node/testutils/deposits.go
+++ b/op-node/testutils/deposits.go
@@ -25,13 +25,14 @@ func GenerateDeposit(sourceHash common.Hash, rng *rand.Rand) *types.DepositTx {
}
dep := &types.DepositTx{
- SourceHash: sourceHash,
- From: RandomAddress(rng),
- To: to,
- Value: RandomETH(rng, 200),
- Gas: uint64(rng.Int63n(10 * 1e6)), // 10 M gas max
- Data: data,
- Mint: mint,
+ SourceHash: sourceHash,
+ From: RandomAddress(rng),
+ To: to,
+ Value: RandomETH(rng, 200),
+ Gas: uint64(rng.Int63n(10 * 1e6)), // 10 M gas max
+ Data: data,
+ Mint: mint,
+ IsSystemTransaction: false,
}
return dep
}
diff --git a/op-node/withdrawals/utils.go b/op-node/withdrawals/utils.go
index 8cdcedc1c5aa6..4ec8eb277035a 100644
--- a/op-node/withdrawals/utils.go
+++ b/op-node/withdrawals/utils.go
@@ -1,6 +1,7 @@
package withdrawals
import (
+ "bytes"
"context"
"errors"
"fmt"
@@ -172,8 +173,15 @@ func FinalizeWithdrawalParameters(ctx context.Context, l2client ProofClient, txH
if err != nil {
return FinalizedWithdrawalParameters{}, err
}
+ ev1, err := ParseWithdrawalInitiatedExtension1(receipt)
+ if err != nil {
+ return FinalizedWithdrawalParameters{}, err
+ }
// Generate then verify the withdrawal proof
withdrawalHash, err := WithdrawalHash(ev)
+ if !bytes.Equal(withdrawalHash[:], ev1.Hash[:]) {
+ return FinalizedWithdrawalParameters{}, errors.New("Computed withdrawal hash incorrectly")
+ }
if err != nil {
return FinalizedWithdrawalParameters{}, err
}
@@ -255,14 +263,52 @@ func ParseWithdrawalInitiated(receipt *types.Receipt) (*bindings.L2ToL1MessagePa
if err != nil {
return nil, err
}
- if len(receipt.Logs) != 1 {
- return nil, errors.New("invalid length of logs")
+ abi, err := bindings.L2ToL1MessagePasserMetaData.GetAbi()
+ if err != nil {
+ return nil, err
}
- ev, err := contract.ParseWithdrawalInitiated(*receipt.Logs[0])
+
+ for _, log := range receipt.Logs {
+ event, err := abi.EventByID(log.Topics[0])
+ if err != nil {
+ return nil, err
+ }
+ if event.Name == "WithdrawalInitiated" {
+ ev, err := contract.ParseWithdrawalInitiated(*log)
+ if err != nil {
+ return nil, fmt.Errorf("failed to parse log: %w", err)
+ }
+ return ev, nil
+ }
+ }
+ return nil, errors.New("Unable to find WithdrawalInitiated event")
+}
+
+// ParseWithdrawalInitiatedExtension1 parses
+func ParseWithdrawalInitiatedExtension1(receipt *types.Receipt) (*bindings.L2ToL1MessagePasserWithdrawalInitiatedExtension1, error) {
+ contract, err := bindings.NewL2ToL1MessagePasser(common.Address{}, nil)
+ if err != nil {
+ return nil, err
+ }
+ abi, err := bindings.L2ToL1MessagePasserMetaData.GetAbi()
if err != nil {
- return nil, fmt.Errorf("failed to parse log: %w", err)
+ return nil, err
+ }
+
+ for _, log := range receipt.Logs {
+ event, err := abi.EventByID(log.Topics[0])
+ if err != nil {
+ return nil, err
+ }
+ if event.Name == "WithdrawalInitiatedExtension1" {
+ ev, err := contract.ParseWithdrawalInitiatedExtension1(*log)
+ if err != nil {
+ return nil, fmt.Errorf("failed to parse log: %w", err)
+ }
+ return ev, nil
+ }
}
- return ev, nil
+ return nil, errors.New("Unable to find WithdrawalInitiatedExtension1 event")
}
// StorageSlotOfWithdrawalHash determines the storage slot of the Withdrawer contract to look at
diff --git a/op-proposer/config.go b/op-proposer/config.go
index c319550f688d2..9ab5e452774e0 100644
--- a/op-proposer/config.go
+++ b/op-proposer/config.go
@@ -49,6 +49,9 @@ type Config struct {
// the l2output transactions.
L2OutputHDPath string
+ // PrivateKey is the private key used for l2output transactions.
+ PrivateKey string
+
/* Optional Params */
// LogLevel is the lowest log level that will be output.
@@ -57,6 +60,11 @@ type Config struct {
// LogTerminal if true, will log to stdout in terminal format. Otherwise the
// output will be in JSON format.
LogTerminal bool
+
+ // Flags for the pprof server
+ PprofEnabled bool
+ PprofAddr string
+ PprofPort string
}
// NewConfig parses the Config from the provided flags or environment variables.
@@ -73,8 +81,12 @@ func NewConfig(ctx *cli.Context) Config {
ResubmissionTimeout: ctx.GlobalDuration(flags.ResubmissionTimeoutFlag.Name),
Mnemonic: ctx.GlobalString(flags.MnemonicFlag.Name),
L2OutputHDPath: ctx.GlobalString(flags.L2OutputHDPathFlag.Name),
+ PrivateKey: ctx.GlobalString(flags.PrivateKeyFlag.Name),
/* Optional Flags */
- LogLevel: ctx.GlobalString(flags.LogLevelFlag.Name),
- LogTerminal: ctx.GlobalBool(flags.LogTerminalFlag.Name),
+ LogLevel: ctx.GlobalString(flags.LogLevelFlag.Name),
+ LogTerminal: ctx.GlobalBool(flags.LogTerminalFlag.Name),
+ PprofEnabled: ctx.GlobalBool(flags.PprofEnabledFlag.Name),
+ PprofAddr: ctx.GlobalString(flags.PprofAddrFlag.Name),
+ PprofPort: ctx.GlobalString(flags.PprofPortFlag.Name),
}
}
diff --git a/op-proposer/flags/flags.go b/op-proposer/flags/flags.go
index 20a35daf473b3..b967c73bfc484 100644
--- a/op-proposer/flags/flags.go
+++ b/op-proposer/flags/flags.go
@@ -70,15 +70,18 @@ var (
Name: "mnemonic",
Usage: "The mnemonic used to derive the wallets for either the " +
"sequencer or the l2output",
- Required: true,
- EnvVar: prefixEnvVar("MNEMONIC"),
+ EnvVar: prefixEnvVar("MNEMONIC"),
}
L2OutputHDPathFlag = cli.StringFlag{
Name: "l2-output-hd-path",
Usage: "The HD path used to derive the l2output wallet from the " +
"mnemonic. The mnemonic flag must also be set.",
- Required: true,
- EnvVar: prefixEnvVar("L2_OUTPUT_HD_PATH"),
+ EnvVar: prefixEnvVar("L2_OUTPUT_HD_PATH"),
+ }
+ PrivateKeyFlag = cli.StringFlag{
+ Name: "private-key",
+ Usage: "The private key to use with the l2output wallet. Must not be used with mnemonic.",
+ EnvVar: prefixEnvVar("PRIVATE_KEY"),
}
/* Optional Flags */
@@ -95,6 +98,23 @@ var (
"in JSON format.",
EnvVar: prefixEnvVar("LOG_TERMINAL"),
}
+ PprofEnabledFlag = cli.BoolFlag{
+ Name: "pprof.enabled",
+ Usage: "Enable the pprof server",
+ EnvVar: prefixEnvVar("PPROF_ENABLED"),
+ }
+ PprofAddrFlag = cli.StringFlag{
+ Name: "pprof.addr",
+ Usage: "pprof listening address",
+ Value: "0.0.0.0",
+ EnvVar: prefixEnvVar("PPROF_ADDR"),
+ }
+ PprofPortFlag = cli.IntFlag{
+ Name: "pprof.port",
+ Usage: "pprof listening port",
+ Value: 6060,
+ EnvVar: prefixEnvVar("PPROF_PORT"),
+ }
)
var requiredFlags = []cli.Flag{
@@ -106,13 +126,17 @@ var requiredFlags = []cli.Flag{
NumConfirmationsFlag,
SafeAbortNonceTooLowCountFlag,
ResubmissionTimeoutFlag,
- MnemonicFlag,
- L2OutputHDPathFlag,
}
var optionalFlags = []cli.Flag{
+ MnemonicFlag,
+ L2OutputHDPathFlag,
+ PrivateKeyFlag,
LogLevelFlag,
LogTerminalFlag,
+ PprofEnabledFlag,
+ PprofAddrFlag,
+ PprofPortFlag,
}
// Flags contains the list of configuration options available to the binary.
diff --git a/op-proposer/go.mod b/op-proposer/go.mod
index 66b69adad403d..644fcdf3083f4 100644
--- a/op-proposer/go.mod
+++ b/op-proposer/go.mod
@@ -5,7 +5,7 @@ go 1.18
require (
github.com/ethereum-optimism/optimism/op-bindings v0.3.0
github.com/ethereum-optimism/optimism/op-node v0.3.0
- github.com/ethereum/go-ethereum v1.10.20
+ github.com/ethereum/go-ethereum v1.10.21
github.com/miguelmota/go-ethereum-hdwallet v0.1.1
github.com/stretchr/testify v1.8.0
github.com/urfave/cli v1.22.5
@@ -60,4 +60,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
-replace github.com/ethereum/go-ethereum v1.10.20 => github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220715235548-70b02481016d
+replace github.com/ethereum/go-ethereum v1.10.21 => github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220803173305-1c9d4cc76a6e
diff --git a/op-proposer/go.sum b/op-proposer/go.sum
index 4a1776a762f4c..c46184c2344d6 100644
--- a/op-proposer/go.sum
+++ b/op-proposer/go.sum
@@ -181,8 +181,8 @@ github.com/ethereum-optimism/optimism/op-bindings v0.3.0 h1:d2Mwb8FzR2zuhW0sS5xF
github.com/ethereum-optimism/optimism/op-bindings v0.3.0/go.mod h1:CrvUVIISKcyJ7o27ub/HY4Kq9wEJQxrGmWthTqxPSGo=
github.com/ethereum-optimism/optimism/op-node v0.3.0 h1:jep/cbIbP7fjBSAR48yk5NJVEoGYvoNlYI00KpBI6Mw=
github.com/ethereum-optimism/optimism/op-node v0.3.0/go.mod h1:iF9AhYjr8jNeoCDNP/Vs/ywQ2USZU5L66AxZbSAUi0E=
-github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220715235548-70b02481016d h1:w0DBXhp0sv0bWRDOCA/Y6yHOALU7qLLLf5/kE3YfFr4=
-github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220715235548-70b02481016d/go.mod h1:m2m08SAQ8XB0VcVBoDg9n74Dw5PUMl3hzv1NXVBFPfg=
+github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220803173305-1c9d4cc76a6e h1:hz+iywXjnqz6xA3lTLvtNL9OZyX76pS5SER4kZBmQLs=
+github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220803173305-1c9d4cc76a6e/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg=
github.com/ethereum/go-ethereum v1.10.4/go.mod h1:nEE0TP5MtxGzOMd7egIrbPJMQBnhVU3ELNxhBglIzhg=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
diff --git a/op-proposer/l2_output_submitter.go b/op-proposer/l2_output_submitter.go
index 111b046c90d11..24e95ac00d2a1 100644
--- a/op-proposer/l2_output_submitter.go
+++ b/op-proposer/l2_output_submitter.go
@@ -2,12 +2,20 @@ package op_proposer
import (
"context"
+ "crypto/ecdsa"
+ "errors"
"fmt"
+ "net"
+ "net/http"
+ _ "net/http/pprof"
"os"
"os/signal"
+ "strings"
"syscall"
"time"
+ "github.com/ethereum/go-ethereum/crypto"
+
"github.com/ethereum-optimism/optimism/op-proposer/drivers/l2output"
"github.com/ethereum-optimism/optimism/op-proposer/rollupclient"
"github.com/ethereum-optimism/optimism/op-proposer/txmgr"
@@ -68,6 +76,27 @@ func Main(version string) func(ctx *cli.Context) error {
l.Info("L2 Output Submitter started")
+ if cfg.PprofEnabled {
+ var srv http.Server
+ srv.Addr = net.JoinHostPort(cfg.PprofAddr, cfg.PprofPort)
+ // Start pprof server + register it's shutdown
+ go func() {
+ l.Info("pprof server started", "addr", srv.Addr)
+ if err := srv.ListenAndServe(); err != http.ErrServerClosed {
+ l.Error("error in pprof server", "err", err)
+ } else {
+ l.Info("pprof server shutting down")
+ }
+
+ }()
+ defer func() {
+ shutCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ err := srv.Shutdown(shutCtx)
+ l.Info("pprof server shut down", "err", err)
+ }()
+ }
+
interruptChannel := make(chan os.Signal, 1)
signal.Notify(interruptChannel, []os.Signal{
os.Interrupt,
@@ -97,20 +126,33 @@ func NewL2OutputSubmitter(
) (*L2OutputSubmitter, error) {
ctx := context.Background()
+ var l2OutputPrivKey *ecdsa.PrivateKey
+ var err error
- // Parse l2output wallet private key and L2OO contract address.
- wallet, err := hdwallet.NewFromMnemonic(cfg.Mnemonic)
- if err != nil {
- return nil, err
+ if cfg.PrivateKey != "" && cfg.Mnemonic != "" {
+ return nil, errors.New("cannot specify both a private key and a mnemonic")
}
- l2OutputPrivKey, err := wallet.PrivateKey(accounts.Account{
- URL: accounts.URL{
- Path: cfg.L2OutputHDPath,
- },
- })
- if err != nil {
- return nil, err
+ if cfg.PrivateKey == "" {
+ // Parse l2output wallet private key and L2OO contract address.
+ wallet, err := hdwallet.NewFromMnemonic(cfg.Mnemonic)
+ if err != nil {
+ return nil, err
+ }
+
+ l2OutputPrivKey, err = wallet.PrivateKey(accounts.Account{
+ URL: accounts.URL{
+ Path: cfg.L2OutputHDPath,
+ },
+ })
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ l2OutputPrivKey, err = crypto.HexToECDSA(strings.TrimPrefix(cfg.PrivateKey, "0x"))
+ if err != nil {
+ return nil, err
+ }
}
l2ooAddress, err := parseAddress(cfg.L2OOAddress)
diff --git a/ops-bedrock/devnet-up.sh b/ops-bedrock/devnet-up.sh
index 2a1bdfed316b7..f98db3c4a06da 100755
--- a/ops-bedrock/devnet-up.sh
+++ b/ops-bedrock/devnet-up.sh
@@ -58,9 +58,9 @@ function wait_up {
mkdir -p ./.devnet
if [ ! -f ./.devnet/rollup.json ]; then
- GENESIS_TIMESTAMP=$(date +%s | xargs printf "0x%x")
+ L1_GENESIS_TIMESTAMP=$(date +%s | xargs printf "0x%x")
else
- GENESIS_TIMESTAMP=$(jq '.timestamp' < .devnet/genesis-l1.json)
+ L1_GENESIS_TIMESTAMP=$(jq '.timestamp' < .devnet/genesis-l1.json)
fi
# Regenerate the L1 genesis file if necessary. The existence of the genesis
@@ -69,7 +69,7 @@ if [ ! -f ./.devnet/genesis-l1.json ]; then
echo "Regenerating L1 genesis."
(
cd $CONTRACTS_BEDROCK
- L2OO_STARTING_BLOCK_TIMESTAMP=$GENESIS_TIMESTAMP npx hardhat genesis-l1 \
+ L1_GENESIS_TIMESTAMP=$L1_GENESIS_TIMESTAMP npx hardhat genesis-l1 \
--outfile genesis-l1.json
mv genesis-l1.json ../../.devnet/genesis-l1.json
)
@@ -89,7 +89,7 @@ if [ ! -d $CONTRACTS_BEDROCK/deployments/$NETWORK ]; then
(
echo "Deploying contracts."
cd $CONTRACTS_BEDROCK
- L2OO_STARTING_BLOCK_TIMESTAMP=$GENESIS_TIMESTAMP yarn hardhat --network $NETWORK deploy
+ L1_GENESIS_TIMESTAMP=$L1_GENESIS_TIMESTAMP yarn hardhat --network $NETWORK deploy
)
else
echo "Contracts already deployed, skipping."
@@ -99,7 +99,7 @@ if [ ! -f ./.devnet/genesis-l2.json ]; then
(
echo "Creating L2 genesis file."
cd $CONTRACTS_BEDROCK
- L2OO_STARTING_BLOCK_TIMESTAMP=$GENESIS_TIMESTAMP npx hardhat --network $NETWORK genesis-l2
+ L1_GENESIS_TIMESTAMP=$L1_GENESIS_TIMESTAMP npx hardhat --network $NETWORK genesis-l2
mv genesis.json ../../.devnet/genesis-l2.json
echo "Created L2 genesis."
)
@@ -120,7 +120,7 @@ if [ ! -f ./.devnet/rollup.json ]; then
(
echo "Building rollup config..."
cd $CONTRACTS_BEDROCK
- L2OO_STARTING_BLOCK_TIMESTAMP=$GENESIS_TIMESTAMP npx hardhat rollup-config --network $NETWORK
+ L1_GENESIS_TIMESTAMP=$L1_GENESIS_TIMESTAMP npx hardhat --network $NETWORK rollup-config
mv rollup.json ../../.devnet/rollup.json
)
else
diff --git a/ops-bedrock/docker-compose.yml b/ops-bedrock/docker-compose.yml
index bc1666e87e949..7cf7cb39e5c08 100644
--- a/ops-bedrock/docker-compose.yml
+++ b/ops-bedrock/docker-compose.yml
@@ -63,10 +63,12 @@ services:
--metrics.enabled
--metrics.addr=0.0.0.0
--metrics.port=7300
+ --pprof.enabled
ports:
- "7545:8545"
- "9003:9003"
- "7300:7300"
+ - "6060:6060"
volumes:
- ${PWD}/p2p-sequencer-key.txt:/config/p2p-sequencer-key.txt
- ${PWD}/p2p-node-key.txt:/config/p2p-node-key.txt
@@ -82,11 +84,13 @@ services:
build:
context: ../
dockerfile: ./op-proposer/Dockerfile
+ ports:
+ - "6062:6060"
environment:
L1_ETH_RPC: http://l1:8545
L2_ETH_RPC: http://l2:8545
ROLLUP_RPC: http://op-node:8545
- OUTPUT_SUBMITTER_POLL_INTERVAL: 10s
+ OUTPUT_SUBMITTER_POLL_INTERVAL: 1s
OUTPUT_SUBMITTER_NUM_CONFIRMATIONS: 1
OUTPUT_SUBMITTER_SAFE_ABORT_NONCE_TOO_LOW_COUNT: 3
OUTPUT_SUBMITTER_RESUBMISSION_TIMEOUT: 30s
@@ -94,6 +98,7 @@ services:
OUTPUT_SUBMITTER_L2_OUTPUT_HD_PATH: "m/44'/60'/0'/0/1"
OUTPUT_SUBMITTER_LOG_TERMINAL: "true"
L2OO_ADDRESS: "${L2OO_ADDRESS}"
+ OUTPUT_SUBMITTER_PPROF_ENABLED: "true"
op-batcher:
depends_on:
@@ -103,6 +108,8 @@ services:
build:
context: ../
dockerfile: ./op-batcher/Dockerfile
+ ports:
+ - "6061:6060"
environment:
L1_ETH_RPC: http://l1:8545
L2_ETH_RPC: http://l2:8545
@@ -116,10 +123,10 @@ services:
BATCH_SUBMITTER_RESUBMISSION_TIMEOUT: 30s
BATCH_SUBMITTER_MNEMONIC: test test test test test test test test test test test junk
BATCH_SUBMITTER_SEQUENCER_HD_PATH: "m/44'/60'/0'/0/2"
- BATCH_SUBMITTER_SEQUENCER_HISTORY_DB_FILENAME: "history_db.json"
BATCH_SUBMITTER_SEQUENCER_GENESIS_HASH: "${SEQUENCER_GENESIS_HASH}"
BATCH_SUBMITTER_SEQUENCER_BATCH_INBOX_ADDRESS: "${SEQUENCER_BATCH_INBOX_ADDRESS}"
BATCH_SUBMITTER_LOG_TERMINAL: "true"
+ BATCH_SUBMITTER_PPROF_ENABLED: "true"
stateviz:
build:
diff --git a/ops/docker/foundry/Dockerfile b/ops/docker/foundry/Dockerfile
index 9c2860e2d2788..2461c7e114aea 100644
--- a/ops/docker/foundry/Dockerfile
+++ b/ops/docker/foundry/Dockerfile
@@ -9,7 +9,7 @@ WORKDIR /opt/foundry
# Only diff from upstream docker image is this clone instead
# of COPY. We select a specific commit to use.
RUN git clone https://github.com/foundry-rs/foundry.git . \
- && git checkout 3c49efe58ca4bdeec4729490501da06914446405
+ && git checkout 64fe4acc97e6d76551cea7598c201f05ecd65639
RUN source $HOME/.profile && cargo build --release \
&& strip /opt/foundry/target/release/forge \
diff --git a/package.json b/package.json
index 048a434d1a76e..221ff71fca3bc 100644
--- a/package.json
+++ b/package.json
@@ -46,6 +46,9 @@
"lint:ts:check": "yarn lerna run lint:ts:check",
"lint:check": "yarn lerna run lint:check",
"lint:fix": "yarn lerna run lint:fix --parallel",
+ "lint:specs:fix": "yarn run markdownlint-cli2-fix \"./specs/**/*.md\"",
+ "lint:specs:check": "yarn run markdownlint-cli2 \"./specs/**/*.md\"",
+ "lint:specs:toc": "yarn run doctoc '--title=**Table of Contents**' ./specs",
"postinstall": "patch-package",
"ready": "yarn lint && yarn test",
"prepare": "husky install",
@@ -63,7 +66,7 @@
"chai": "^4.2.0",
"copyfiles": "^2.3.0",
"depcheck": "^1.4.3",
- "doctoc": "2.1.0",
+ "doctoc": "^2.2.0",
"eslint": "^8.16.0",
"eslint-config-prettier": "^8.3.0",
"eslint-config-standard": "^16.0.3",
@@ -79,7 +82,7 @@
"lerna": "^4.0.0",
"lint-staged": "11.0.0",
"markdownlint": "^0.24.0",
- "markdownlint-cli2": "^0.3.2",
+ "markdownlint-cli2": "0.4.0",
"mkdirp": "^1.0.4",
"mocha": "^8.4.0",
"nyc": "^15.1.0",
diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot
index 21763758c72b8..600e3d8ba4922 100644
--- a/packages/contracts-bedrock/.gas-snapshot
+++ b/packages/contracts-bedrock/.gas-snapshot
@@ -1,9 +1,9 @@
-GasBenchMark_L1CrossDomainMessenger:test_L1MessengerSendMessage_benchmark_0() (gas: 263435)
-GasBenchMark_L1CrossDomainMessenger:test_L1MessengerSendMessage_benchmark_1() (gas: 77595)
-GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 354407)
-GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 118585)
-GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 354429)
-GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 118560)
+GasBenchMark_L1CrossDomainMessenger:test_L1MessengerSendMessage_benchmark_0() (gas: 263442)
+GasBenchMark_L1CrossDomainMessenger:test_L1MessengerSendMessage_benchmark_1() (gas: 77602)
+GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 354414)
+GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 118592)
+GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 354436)
+GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 118567)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 45432)
GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 68671)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 74964)
@@ -33,26 +33,26 @@ L1BlockTest:test_updateValues() (gas: 28193)
L1BlockNumberTest:test_fallback() (gas: 18677)
L1BlockNumberTest:test_getL1BlockNumber() (gas: 10668)
L1BlockNumberTest:test_receive() (gas: 25340)
-L1CrossDomainMessenger_Test:testCannot_L1MessengerPause() (gas: 24500)
-L1CrossDomainMessenger_Test:testCannot_L1MessengerUnpause() (gas: 24536)
+L1CrossDomainMessenger_Test:testCannot_L1MessengerPause() (gas: 24515)
+L1CrossDomainMessenger_Test:testCannot_L1MessengerUnpause() (gas: 24562)
L1CrossDomainMessenger_Test:test_L1MessengerMessageVersion() (gas: 24716)
-L1CrossDomainMessenger_Test:test_L1MessengerPause() (gas: 48005)
-L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageFirstStuckSecondSucceeds() (gas: 201779)
-L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageRevertsOnReentrancy() (gas: 195102)
-L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageSucceeds() (gas: 77841)
-L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageToSystemContract() (gas: 67957)
-L1CrossDomainMessenger_Test:test_L1MessengerRelayShouldRevertIfPaused() (gas: 60463)
-L1CrossDomainMessenger_Test:test_L1MessengerReplayMessageWithValue() (gas: 38169)
-L1CrossDomainMessenger_Test:test_L1MessengerSendMessage() (gas: 301583)
-L1CrossDomainMessenger_Test:test_L1MessengerTwiceSendMessage() (gas: 1492570)
-L1CrossDomainMessenger_Test:test_L1MessengerUnpause() (gas: 40872)
-L1CrossDomainMessenger_Test:test_L1MessengerXDomainSenderReverts() (gas: 24316)
-L1CrossDomainMessenger_Test:test_L1MessengerxDomainMessageSenderResets() (gas: 86376)
-L1StandardBridge_Test:test_depositERC20() (gas: 579490)
-L1StandardBridge_Test:test_depositERC20To() (gas: 581697)
-L1StandardBridge_Test:test_depositETH() (gas: 373948)
-L1StandardBridge_Test:test_depositETHTo() (gas: 331084)
-L1StandardBridge_Test:test_finalizeBridgeERC20FailSendBack() (gas: 681445)
+L1CrossDomainMessenger_Test:test_L1MessengerPause() (gas: 48053)
+L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageFirstStuckSecondSucceeds() (gas: 201827)
+L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageRevertsOnReentrancy() (gas: 195126)
+L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageSucceeds() (gas: 77865)
+L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageToSystemContract() (gas: 68005)
+L1CrossDomainMessenger_Test:test_L1MessengerRelayShouldRevertIfPaused() (gas: 60526)
+L1CrossDomainMessenger_Test:test_L1MessengerReplayMessageWithValue() (gas: 38193)
+L1CrossDomainMessenger_Test:test_L1MessengerSendMessage() (gas: 301590)
+L1CrossDomainMessenger_Test:test_L1MessengerTwiceSendMessage() (gas: 1492584)
+L1CrossDomainMessenger_Test:test_L1MessengerUnpause() (gas: 40948)
+L1CrossDomainMessenger_Test:test_L1MessengerXDomainSenderReverts() (gas: 24305)
+L1CrossDomainMessenger_Test:test_L1MessengerxDomainMessageSenderResets() (gas: 86378)
+L1StandardBridge_Test:test_depositERC20() (gas: 579497)
+L1StandardBridge_Test:test_depositERC20To() (gas: 581704)
+L1StandardBridge_Test:test_depositETH() (gas: 373955)
+L1StandardBridge_Test:test_depositETHTo() (gas: 331091)
+L1StandardBridge_Test:test_finalizeBridgeERC20FailSendBack() (gas: 681451)
L1StandardBridge_Test:test_finalizeERC20Withdrawal() (gas: 490132)
L1StandardBridge_Test:test_finalizeETHWithdrawal() (gas: 64273)
L1StandardBridge_Test:test_initialize() (gas: 26334)
@@ -60,55 +60,55 @@ L1StandardBridge_Test:test_onlyEOADepositERC20() (gas: 22376)
L1StandardBridge_Test:test_onlyEOADepositETH() (gas: 40859)
L1StandardBridge_Test:test_onlyL2BridgeFinalizeERC20Withdrawal() (gas: 36268)
L1StandardBridge_Test:test_onlyPortalFinalizeERC20Withdrawal() (gas: 35573)
-L1StandardBridge_Test:test_receive() (gas: 520566)
-L2CrossDomainMessenger_Test:testCannot_L2MessengerPause() (gas: 10845)
-L2CrossDomainMessenger_Test:test_L1MessengerRelayMessageRevertsOnReentrancy() (gas: 171930)
+L1StandardBridge_Test:test_receive() (gas: 520573)
+L2CrossDomainMessenger_Test:testCannot_L2MessengerPause() (gas: 10860)
+L2CrossDomainMessenger_Test:test_L1MessengerRelayMessageRevertsOnReentrancy() (gas: 171954)
L2CrossDomainMessenger_Test:test_L2MessengerMessageVersion() (gas: 8411)
-L2CrossDomainMessenger_Test:test_L2MessengerPause() (gas: 31749)
-L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageFirstStuckSecondSucceeds() (gas: 172920)
-L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageSucceeds() (gas: 57372)
-L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageToSystemContract() (gas: 36193)
-L2CrossDomainMessenger_Test:test_L2MessengerRelayShouldRevertIfPaused() (gas: 41619)
-L2CrossDomainMessenger_Test:test_L2MessengerSendMessage() (gas: 121522)
-L2CrossDomainMessenger_Test:test_L2MessengerTwiceSendMessage() (gas: 135934)
-L2CrossDomainMessenger_Test:test_L2MessengerXDomainSenderReverts() (gas: 10609)
-L2CrossDomainMessenger_Test:test_L2MessengerxDomainMessageSenderResets() (gas: 54887)
+L2CrossDomainMessenger_Test:test_L2MessengerPause() (gas: 31797)
+L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageFirstStuckSecondSucceeds() (gas: 172968)
+L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageSucceeds() (gas: 57396)
+L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageToSystemContract() (gas: 36217)
+L2CrossDomainMessenger_Test:test_L2MessengerRelayShouldRevertIfPaused() (gas: 41682)
+L2CrossDomainMessenger_Test:test_L2MessengerSendMessage() (gas: 122833)
+L2CrossDomainMessenger_Test:test_L2MessengerTwiceSendMessage() (gas: 138556)
+L2CrossDomainMessenger_Test:test_L2MessengerXDomainSenderReverts() (gas: 10598)
+L2CrossDomainMessenger_Test:test_L2MessengerxDomainMessageSenderResets() (gas: 54889)
L2OutputOracleTest:testCannot_ProposeWithUnmatchedBlockhash() (gas: 26829)
-L2OutputOracleTest:testCannot_deleteL2Output_ifNotOwner() (gas: 25097)
-L2OutputOracleTest:testCannot_deleteL2Output_withWrongRoot() (gas: 91432)
-L2OutputOracleTest:testCannot_deleteL2Output_withWrongTime() (gas: 87426)
+L2OutputOracleTest:testCannot_deleteL2Output_ifNotOwner() (gas: 25123)
+L2OutputOracleTest:testCannot_deleteL2Output_withWrongRoot() (gas: 91445)
+L2OutputOracleTest:testCannot_deleteL2Output_withWrongTime() (gas: 87450)
L2OutputOracleTest:testCannot_proposeEmptyOutput() (gas: 24128)
L2OutputOracleTest:testCannot_proposeFutureTimetamp() (gas: 26097)
L2OutputOracleTest:testCannot_proposeL2OutputIfNotProposer() (gas: 23564)
L2OutputOracleTest:testCannot_proposeOnWrongFork() (gas: 26424)
L2OutputOracleTest:testCannot_proposeUnexpectedBlockNumber() (gas: 25983)
-L2OutputOracleTest:test_changeProposer() (gas: 56052)
+L2OutputOracleTest:test_changeProposer() (gas: 56139)
L2OutputOracleTest:test_computeL2Timestamp() (gas: 30288)
L2OutputOracleTest:test_constructor() (gas: 49046)
-L2OutputOracleTest:test_deleteOutput() (gas: 77223)
+L2OutputOracleTest:test_deleteOutput() (gas: 77242)
L2OutputOracleTest:test_getL2Output() (gas: 88508)
L2OutputOracleTest:test_latestBlockNumber() (gas: 76284)
L2OutputOracleTest:test_nextBlockNumber() (gas: 15232)
L2OutputOracleTest:test_proposeWithBlockhashAndHeight() (gas: 75046)
L2OutputOracleTest:test_proposingAnotherOutput() (gas: 76881)
-L2OutputOracleTest:test_updateOwner() (gas: 34580)
-L2OutputOracleUpgradeable_Test:test_cannotInitImpl() (gas: 19428)
-L2OutputOracleUpgradeable_Test:test_cannotInitProxy() (gas: 24427)
+L2OutputOracleTest:test_updateOwner() (gas: 34619)
+L2OutputOracleUpgradeable_Test:test_cannotInitImpl() (gas: 19555)
+L2OutputOracleUpgradeable_Test:test_cannotInitProxy() (gas: 24554)
L2OutputOracleUpgradeable_Test:test_initValuesOnProxy() (gas: 39086)
-L2OutputOracleUpgradeable_Test:test_upgrading() (gas: 230843)
-L2StandardBridge_Test:test_ERC20BridgeFailed_whenLocalTokenIsBridge() (gas: 134196)
+L2OutputOracleUpgradeable_Test:test_upgrading() (gas: 180632)
+L2StandardBridge_Test:test_ERC20BridgeFailed_whenLocalTokenIsBridge() (gas: 135507)
L2StandardBridge_Test:test_cannotWithdrawEthWithoutSendingIt() (gas: 21619)
-L2StandardBridge_Test:test_finalizeBridgeERC20FailSendBack() (gas: 499320)
+L2StandardBridge_Test:test_finalizeBridgeERC20FailSendBack() (gas: 500368)
L2StandardBridge_Test:test_finalizeDeposit() (gas: 93125)
-L2StandardBridge_Test:test_finalizeDeposit_failsToCompleteOutboundTransfer() (gas: 141211)
+L2StandardBridge_Test:test_finalizeDeposit_failsToCompleteOutboundTransfer() (gas: 142522)
L2StandardBridge_Test:test_initialize() (gas: 14823)
-L2StandardBridge_Test:test_receive() (gas: 137760)
-L2StandardBridge_Test:test_withdraw() (gas: 353308)
-L2StandardBridge_Test:test_withdrawTo() (gas: 354064)
+L2StandardBridge_Test:test_receive() (gas: 139070)
+L2StandardBridge_Test:test_withdraw() (gas: 354357)
+L2StandardBridge_Test:test_withdrawTo() (gas: 355112)
L2StandardBridge_Test:test_withdraw_onlyEOA() (gas: 251674)
-L2ToL1MessagePasserTest:test_burn() (gas: 112246)
-L2ToL1MessagePasserTest:test_initiateWithdrawal_fromContract() (gas: 68198)
-L2ToL1MessagePasserTest:test_initiateWithdrawal_fromEOA() (gas: 75284)
+L2ToL1MessagePasserTest:test_burn() (gas: 113395)
+L2ToL1MessagePasserTest:test_initiateWithdrawal_fromContract() (gas: 72486)
+L2ToL1MessagePasserTest:test_initiateWithdrawal_fromEOA() (gas: 76433)
LegacyERC20ETH_Test:test_approve() (gas: 10796)
LegacyERC20ETH_Test:test_burn() (gas: 10681)
LegacyERC20ETH_Test:test_crossDomain() (gas: 10577)
@@ -131,24 +131,31 @@ OptimismMintableTokenFactory_Test:test_bridge() (gas: 7663)
OptimismMintableTokenFactory_Test:test_createStandardL2Token() (gas: 1112929)
OptimismMintableTokenFactory_Test:test_createStandardL2TokenSameTwice() (gas: 2208763)
OptimismMintableTokenFactory_Test:test_createStandardL2TokenShouldRevertIfRemoteIsZero() (gas: 9398)
-OptimismPortalUpgradeable_Test:test_cannotInitImpl() (gas: 10686)
-OptimismPortalUpgradeable_Test:test_cannotInitProxy() (gas: 15662)
+OptimismPortalUpgradeable_Test:test_cannotInitImpl() (gas: 10813)
+OptimismPortalUpgradeable_Test:test_cannotInitProxy() (gas: 15789)
OptimismPortalUpgradeable_Test:test_initValuesOnProxy() (gas: 15967)
-OptimismPortalUpgradeable_Test:test_upgrading() (gas: 230843)
-OptimismPortal_Test:test_OptimismPortalConstructor() (gas: 17319)
+OptimismPortalUpgradeable_Test:test_upgrading() (gas: 180632)
+OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_revertsOnInsufficientGas() (gas: 160788)
+OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_revertsOnInvalidOutputRootProof() (gas: 81241)
+OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_revertsOnRecentWithdrawal() (gas: 53001)
+OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_revertsOnReentrancy() (gas: 205566)
+OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_revertsOnReplay() (gas: 278941)
+OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_revertsOnSelfCall() (gas: 50539)
+OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_revertsOninvalidWithdrawalProof() (gas: 148562)
+OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_succeeds() (gas: 187013)
+OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails() (gas: 289662)
+OptimismPortal_Test:test_OptimismPortalConstructor() (gas: 17341)
OptimismPortal_Test:test_OptimismPortalContractCreationReverts() (gas: 14199)
OptimismPortal_Test:test_OptimismPortalReceiveEth() (gas: 127534)
-OptimismPortal_Test:test_cannotVerifyRecentWithdrawal() (gas: 25613)
OptimismPortal_Test:test_depositTransaction_NoValueContract() (gas: 76668)
-OptimismPortal_Test:test_depositTransaction_NoValueEOA() (gas: 76992)
-OptimismPortal_Test:test_depositTransaction_createWithZeroValueForContract() (gas: 76673)
+OptimismPortal_Test:test_depositTransaction_NoValueEOA() (gas: 76969)
+OptimismPortal_Test:test_depositTransaction_createWithZeroValueForContract() (gas: 76650)
OptimismPortal_Test:test_depositTransaction_createWithZeroValueForEOA() (gas: 76994)
OptimismPortal_Test:test_depositTransaction_withEthValueAndContractContractCreation() (gas: 83694)
OptimismPortal_Test:test_depositTransaction_withEthValueAndEOAContractCreation() (gas: 75881)
-OptimismPortal_Test:test_depositTransaction_withEthValueFromContract() (gas: 83356)
+OptimismPortal_Test:test_depositTransaction_withEthValueFromContract() (gas: 83333)
OptimismPortal_Test:test_depositTransaction_withEthValueFromEOA() (gas: 83993)
-OptimismPortal_Test:test_invalidWithdrawalProof() (gas: 38103)
-OptimismPortal_Test:test_isBlockFinalized() (gas: 113703)
+OptimismPortal_Test:test_isBlockFinalized() (gas: 113725)
OptimismPortal_Test:test_simple_isBlockFinalized() (gas: 26630)
Proxy_Test:test_clashingFunctionSignatures() (gas: 101427)
Proxy_Test:test_implementationKey() (gas: 20942)
@@ -265,11 +272,11 @@ ResourceMetering_Test:test_updateParamsNoChange() (gas: 13956)
ResourceMetering_Test:test_updateTenEmptyBlocks() (gas: 20571)
ResourceMetering_Test:test_updateTwoEmptyBlocks() (gas: 20594)
ResourceMetering_Test:test_useMaxSucceeds() (gas: 8017134)
-ResourceMetering_Test:test_useMoreThanMaxReverts() (gas: 16047)
+ResourceMetering_Test:test_useMoreThanMaxReverts() (gas: 16058)
Semver_Test:test_behindProxy() (gas: 506906)
Semver_Test:test_version() (gas: 9487)
SequencerFeeVault_Test:test_constructor() (gas: 7678)
SequencerFeeVault_Test:test_minWithdrawalAmount() (gas: 5440)
SequencerFeeVault_Test:test_receive() (gas: 17338)
SequencerFeeVault_Test:test_revertWithdraw() (gas: 9342)
-SequencerFeeVault_Test:test_withdraw() (gas: 148623)
+SequencerFeeVault_Test:test_withdraw() (gas: 149933)
diff --git a/packages/contracts-bedrock/contracts/L1/OptimismPortal.sol b/packages/contracts-bedrock/contracts/L1/OptimismPortal.sol
index af34c0b782174..38660f1718607 100644
--- a/packages/contracts-bedrock/contracts/L1/OptimismPortal.sol
+++ b/packages/contracts-bedrock/contracts/L1/OptimismPortal.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
-import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
+import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import { ExcessivelySafeCall } from "excessively-safe-call/src/ExcessivelySafeCall.sol";
import { L2OutputOracle } from "./L2OutputOracle.sol";
import { Types } from "../libraries/Types.sol";
@@ -136,6 +136,8 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
// Prevent users from creating a deposit transaction where this address is the message
// sender on L2.
+ // In the context of the proxy delegate calling to this implementation,
+ // address(this) will return the address of the proxy.
require(
_tx.target != address(this),
"OptimismPortal: you cannot send messages to the portal contract"
diff --git a/packages/contracts-bedrock/contracts/L1/ResourceMetering.sol b/packages/contracts-bedrock/contracts/L1/ResourceMetering.sol
index 50ac1724277ac..8782c81003369 100644
--- a/packages/contracts-bedrock/contracts/L1/ResourceMetering.sol
+++ b/packages/contracts-bedrock/contracts/L1/ResourceMetering.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
-import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
+import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
import { SignedMath } from "@openzeppelin/contracts/utils/math/SignedMath.sol";
import { FixedPointMathLib } from "@rari-capital/solmate/src/utils/FixedPointMathLib.sol";
diff --git a/packages/contracts-bedrock/contracts/L2/L2ToL1MessagePasser.sol b/packages/contracts-bedrock/contracts/L2/L2ToL1MessagePasser.sol
index 543acbc432edc..a4c8011521e70 100644
--- a/packages/contracts-bedrock/contracts/L2/L2ToL1MessagePasser.sol
+++ b/packages/contracts-bedrock/contracts/L2/L2ToL1MessagePasser.sol
@@ -49,6 +49,14 @@ contract L2ToL1MessagePasser is Semver {
bytes data
);
+ /**
+ * @notice Emitted any time a withdrawal is initiated. An extension to
+ * WithdrawalInitiated so that the interface is maintained.
+ *
+ * @param hash The hash of the withdrawal
+ */
+ event WithdrawalInitiatedExtension1(bytes32 indexed hash);
+
/**
* @notice Emitted when the balance of this contract is burned.
*
@@ -106,6 +114,8 @@ contract L2ToL1MessagePasser is Semver {
sentMessages[withdrawalHash] = true;
emit WithdrawalInitiated(nonce, msg.sender, _target, msg.value, _gasLimit, _data);
+ emit WithdrawalInitiatedExtension1(withdrawalHash);
+
unchecked {
++nonce;
}
diff --git a/packages/contracts-bedrock/contracts/libraries/Encoding.sol b/packages/contracts-bedrock/contracts/libraries/Encoding.sol
index e0e27355c229a..985d6c1a580e7 100644
--- a/packages/contracts-bedrock/contracts/libraries/Encoding.sol
+++ b/packages/contracts-bedrock/contracts/libraries/Encoding.sol
@@ -13,6 +13,8 @@ library Encoding {
/**
* @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent
* to the L2 system. Useful for searching for a deposit in the L2 system.
+ * This currently only supports user deposits and not system
+ * transactions.
*
* @param _tx User deposit transaction to encode.
*
@@ -24,14 +26,15 @@ library Encoding {
returns (bytes memory)
{
bytes32 source = Hashing.hashDepositSource(_tx.l1BlockHash, _tx.logIndex);
- bytes[] memory raw = new bytes[](7);
+ bytes[] memory raw = new bytes[](8);
raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));
raw[1] = RLPWriter.writeAddress(_tx.from);
raw[2] = _tx.isCreation ? RLPWriter.writeBytes("") : RLPWriter.writeAddress(_tx.to);
raw[3] = RLPWriter.writeUint(_tx.mint);
raw[4] = RLPWriter.writeUint(_tx.value);
raw[5] = RLPWriter.writeUint(uint256(_tx.gasLimit));
- raw[6] = RLPWriter.writeBytes(_tx.data);
+ raw[6] = RLPWriter.writeBool(false);
+ raw[7] = RLPWriter.writeBytes(_tx.data);
return abi.encodePacked(uint8(0x7e), RLPWriter.writeList(raw));
}
diff --git a/packages/contracts-bedrock/contracts/libraries/Types.sol b/packages/contracts-bedrock/contracts/libraries/Types.sol
index d14caa2a80764..98887e6922b47 100644
--- a/packages/contracts-bedrock/contracts/libraries/Types.sol
+++ b/packages/contracts-bedrock/contracts/libraries/Types.sol
@@ -34,10 +34,10 @@ library Types {
struct UserDepositTransaction {
address from;
address to;
+ bool isCreation;
uint256 value;
uint256 mint;
uint64 gasLimit;
- bool isCreation;
bytes data;
bytes32 l1BlockHash;
uint256 logIndex;
diff --git a/packages/contracts-bedrock/contracts/test/CommonTest.t.sol b/packages/contracts-bedrock/contracts/test/CommonTest.t.sol
index 34fe1d8c12c7a..5f0813ce8cc1f 100644
--- a/packages/contracts-bedrock/contracts/test/CommonTest.t.sol
+++ b/packages/contracts-bedrock/contracts/test/CommonTest.t.sol
@@ -15,9 +15,10 @@ import { L2CrossDomainMessenger } from "../L2/L2CrossDomainMessenger.sol";
import { AddressAliasHelper } from "../vendor/AddressAliasHelper.sol";
import { LegacyERC20ETH } from "../legacy/LegacyERC20ETH.sol";
import { Predeploys } from "../libraries/Predeploys.sol";
+import { Types } from "../libraries/Types.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { Proxy } from "../universal/Proxy.sol";
-import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
+import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import { ResolvedDelegateProxy } from "../legacy/ResolvedDelegateProxy.sol";
import { AddressManager } from "../legacy/AddressManager.sol";
import { L1ChugSplashProxy } from "../legacy/L1ChugSplashProxy.sol";
@@ -78,7 +79,6 @@ contract CommonTest is Test {
abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data)
);
}
-
}
contract L2OutputOracle_Initializer is CommonTest {
@@ -457,24 +457,26 @@ contract Bridge_Initializer is Messenger_Initializer {
}
contract FFIInterface is Test {
- function getFinalizeWithdrawalTransactionInputs(
- uint256 _nonce,
- address _sender,
- address _target,
- uint64 _value,
- uint256 _gasLimit,
- bytes memory _data
- ) external returns (bytes32, bytes32, bytes32, bytes32, bytes memory) {
+ function getFinalizeWithdrawalTransactionInputs(Types.WithdrawalTransaction memory _tx)
+ external
+ returns (
+ bytes32,
+ bytes32,
+ bytes32,
+ bytes32,
+ bytes memory
+ )
+ {
string[] memory cmds = new string[](9);
cmds[0] = "node";
cmds[1] = "dist/scripts/differential-testing.js";
cmds[2] = "getFinalizeWithdrawalTransactionInputs";
- cmds[3] = vm.toString(_nonce);
- cmds[4] = vm.toString(_sender);
- cmds[5] = vm.toString(_target);
- cmds[6] = vm.toString(_value);
- cmds[7] = vm.toString(_gasLimit);
- cmds[8] = vm.toString(_data);
+ cmds[3] = vm.toString(_tx.nonce);
+ cmds[4] = vm.toString(_tx.sender);
+ cmds[5] = vm.toString(_tx.target);
+ cmds[6] = vm.toString(_tx.value);
+ cmds[7] = vm.toString(_tx.gasLimit);
+ cmds[8] = vm.toString(_tx.data);
bytes memory result = vm.ffi(cmds);
(
@@ -574,11 +576,32 @@ contract FFIInterface is Test {
cmds[8] = vm.toString(_value);
cmds[9] = vm.toString(_gas);
cmds[10] = vm.toString(_data);
- bytes memory result = vm.ffi(cmds);
+ bytes memory result = vm.ffi(cmds);
return abi.decode(result, (bytes32));
}
+ function encodeDepositTransaction(
+ Types.UserDepositTransaction calldata txn
+ ) external returns (bytes memory) {
+ string[] memory cmds = new string[](12);
+ cmds[0] = "node";
+ cmds[1] = "dist/scripts/differential-testing.js";
+ cmds[2] = "encodeDepositTransaction";
+ cmds[3] = vm.toString(txn.from);
+ cmds[4] = vm.toString(txn.to);
+ cmds[5] = vm.toString(txn.value);
+ cmds[6] = vm.toString(txn.mint);
+ cmds[7] = vm.toString(txn.gasLimit);
+ cmds[8] = vm.toString(txn.isCreation);
+ cmds[9] = vm.toString(txn.data);
+ cmds[10] = vm.toString(txn.l1BlockHash);
+ cmds[11] = vm.toString(txn.logIndex);
+
+ bytes memory result = vm.ffi(cmds);
+ return abi.decode(result, (bytes));
+ }
+
function encodeCrossDomainMessage(
uint256 _nonce,
address _sender,
diff --git a/packages/contracts-bedrock/contracts/test/Encoding.t.sol b/packages/contracts-bedrock/contracts/test/Encoding.t.sol
index 0c3ba6cb873ec..c21fad77c4a99 100644
--- a/packages/contracts-bedrock/contracts/test/Encoding.t.sol
+++ b/packages/contracts-bedrock/contracts/test/Encoding.t.sol
@@ -65,4 +65,35 @@ contract Encoding_Test is CommonTest {
assertEq(encoding, _encoding);
}
+
+ function test_encodeDepositTransaction_differential(
+ address _from,
+ address _to,
+ uint256 _mint,
+ uint256 _value,
+ uint64 _gas,
+ bool isCreate,
+ bytes memory _data,
+ uint256 _logIndex
+ ) external {
+ Types.UserDepositTransaction memory t = Types.UserDepositTransaction(
+ _from,
+ _to,
+ isCreate,
+ _value,
+ _mint,
+ _gas,
+ _data,
+ bytes32(uint256(0)),
+ _logIndex
+ );
+
+ bytes memory txn = Encoding.encodeDepositTransaction(t);
+ bytes memory _txn = ffi.encodeDepositTransaction(t);
+
+ assertEq(
+ txn,
+ _txn
+ );
+ }
}
diff --git a/packages/contracts-bedrock/contracts/test/Hashing.t.sol b/packages/contracts-bedrock/contracts/test/Hashing.t.sol
index 29b4f814eee12..81f1fedebcd26 100644
--- a/packages/contracts-bedrock/contracts/test/Hashing.t.sol
+++ b/packages/contracts-bedrock/contracts/test/Hashing.t.sol
@@ -127,10 +127,10 @@ contract Hashing_Test is CommonTest {
Types.UserDepositTransaction(
_from,
_to,
+ false, // isCreate
_value,
_mint,
_gas,
- false, // isCreate
_data,
bytes32(uint256(0)),
_logIndex
diff --git a/packages/contracts-bedrock/contracts/test/L2ToL1MessagePasser.t.sol b/packages/contracts-bedrock/contracts/test/L2ToL1MessagePasser.t.sol
index 2b6422bd16bcf..6f23e0e5dab00 100644
--- a/packages/contracts-bedrock/contracts/test/L2ToL1MessagePasser.t.sol
+++ b/packages/contracts-bedrock/contracts/test/L2ToL1MessagePasser.t.sol
@@ -18,6 +18,8 @@ contract L2ToL1MessagePasserTest is CommonTest {
bytes data
);
+ event WithdrawalInitiatedExtension1(bytes32 indexed hash);
+
event WithdrawerBalanceBurnt(uint256 indexed amount);
function setUp() virtual public {
@@ -36,6 +38,20 @@ contract L2ToL1MessagePasserTest is CommonTest {
hex""
);
+ bytes32 withdrawalHash = Hashing.hashWithdrawal(
+ Types.WithdrawalTransaction(
+ messagePasser.nonce(),
+ address(this),
+ address(4),
+ 100,
+ 64000,
+ hex""
+ )
+ );
+
+ vm.expectEmit(true, true, true, true);
+ emit WithdrawalInitiatedExtension1(withdrawalHash);
+
vm.deal(address(this), 2**64);
messagePasser.initiateWithdrawal{ value: 100 }(
address(4),
diff --git a/packages/contracts-bedrock/contracts/test/OptimismPortal.t.sol b/packages/contracts-bedrock/contracts/test/OptimismPortal.t.sol
index 89da96bfaa4ba..1e87a37d4862a 100644
--- a/packages/contracts-bedrock/contracts/test/OptimismPortal.t.sol
+++ b/packages/contracts-bedrock/contracts/test/OptimismPortal.t.sol
@@ -10,7 +10,6 @@ import { Hashing } from "../libraries/Hashing.sol";
import { Proxy } from "../universal/Proxy.sol";
contract OptimismPortal_Test is Portal_Initializer {
-
function test_OptimismPortalConstructor() external {
assertEq(op.FINALIZATION_PERIOD_SECONDS(), 7 days);
assertEq(address(op.L2_ORACLE()), address(oracle));
@@ -215,62 +214,11 @@ contract OptimismPortal_Test is Portal_Initializer {
assertEq(address(op).balance, NON_ZERO_VALUE);
}
- function test_cannotVerifyRecentWithdrawal() external {
- Types.OutputRootProof memory outputRootProof = Types
- .OutputRootProof({
- version: bytes32(0),
- stateRoot: bytes32(0),
- withdrawerStorageRoot: bytes32(0),
- latestBlockhash: bytes32(0)
- });
- // Setup the Oracle to return an output with a recent timestamp
- uint256 recentTimestamp = block.timestamp - 1000;
- vm.mockCall(
- address(op.L2_ORACLE()),
- abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
- abi.encode(Types.OutputProposal(bytes32(uint256(1)), recentTimestamp))
- );
-
- vm.expectRevert("OptimismPortal: proposal is not yet finalized");
- op.finalizeWithdrawalTransaction(Types.WithdrawalTransaction(0, alice, alice, 0, 0, hex""), 0, outputRootProof, hex"");
- }
-
- function test_invalidWithdrawalProof() external {
- vm.mockCall(
- address(op.L2_ORACLE()),
- abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
- abi.encode(Types.OutputProposal(bytes32(uint256(1)), block.timestamp))
- );
-
- Types.OutputRootProof memory outputRootProof = Types
- .OutputRootProof({
- version: bytes32(0),
- stateRoot: bytes32(0),
- withdrawerStorageRoot: bytes32(0),
- latestBlockhash: bytes32(0)
- });
-
- vm.warp(
- oracle.getL2Output(oracle.latestBlockNumber()).timestamp +
- op.FINALIZATION_PERIOD_SECONDS() + 1
- );
-
- vm.expectRevert("OptimismPortal: invalid output root proof");
- op.finalizeWithdrawalTransaction(Types.WithdrawalTransaction(0, alice, alice, 0, 0, hex""), 0, outputRootProof, hex"");
- }
-
function test_simple_isBlockFinalized() external {
vm.mockCall(
address(op.L2_ORACLE()),
- abi.encodeWithSelector(
- L2OutputOracle.getL2Output.selector
- ),
- abi.encode(
- Types.OutputProposal(
- bytes32(uint256(1)),
- startingBlockNumber
- )
- )
+ abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
+ abi.encode(Types.OutputProposal(bytes32(uint256(1)), startingBlockNumber))
);
// warp to the finalization period
@@ -310,51 +258,310 @@ contract OptimismPortal_Test is Portal_Initializer {
vm.expectRevert("L2OutputOracle: No output found for that block number.");
assertEq(op.isBlockFinalized(checkpoint + 1), false);
}
+}
+
+contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
+ // Reusable default values for a test withdrawal
+ Types.WithdrawalTransaction _defaultTx;
+
+ uint256 _proposedBlockNumber;
+ bytes32 _stateRoot;
+ bytes32 _storageRoot;
+ bytes32 _outputRoot;
+ bytes32 _withdrawalHash;
+ bytes _withdrawalProof;
+ Types.OutputRootProof internal _outputRootProof;
+
+ event WithdrawalFinalized(bytes32 indexed, bool success);
+
+ // Use a constructor to set the storage vars above, so as to minimize the number of ffi calls.
+ constructor() {
+ super.setUp();
+ _defaultTx = Types.WithdrawalTransaction({
+ nonce: 0,
+ sender: alice,
+ target: bob,
+ value: 100,
+ gasLimit: 100_000,
+ data: hex""
+ });
+ // Get withdrawal proof data we can use for testing.
+ (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi
+ .getFinalizeWithdrawalTransactionInputs(_defaultTx);
+
+ // Setup a dummy output root proof for reuse.
+ _outputRootProof = Types.OutputRootProof({
+ version: bytes32(uint256(0)),
+ stateRoot: _stateRoot,
+ withdrawerStorageRoot: _storageRoot,
+ latestBlockhash: bytes32(uint256(0))
+ });
+ _proposedBlockNumber = oracle.nextBlockNumber();
+ }
+
+ // Get the system into a nice ready-to-use state.
+ function setUp() public override {
+ // Configure the oracle to return the output root we've prepared.
+ vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1);
+ vm.prank(oracle.proposer());
+ oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);
+
+ // Warp beyond the finalization period for the block we've proposed.
+ vm.warp(
+ oracle.getL2Output(_proposedBlockNumber).timestamp +
+ op.FINALIZATION_PERIOD_SECONDS() +
+ 1
+ );
+ // Fund the portal so that we can withdraw ETH.
+ vm.deal(address(op), 0xFFFFFFFF);
+ }
+
+ // Test: finalizeWithdrawalTransaction succeeds and emits the WithdrawalFinalized event.
+ function test_finalizeWithdrawalTransaction_succeeds() external {
+ uint256 bobBalanceBefore = address(bob).balance;
+ vm.expectEmit(true, true, true, true);
+ emit WithdrawalFinalized(_withdrawalHash, true);
+ op.finalizeWithdrawalTransaction(
+ _defaultTx,
+ _proposedBlockNumber,
+ _outputRootProof,
+ _withdrawalProof
+ );
+ assert(address(bob).balance == bobBalanceBefore + 100);
+ }
+
+ // Test: finalizeWithdrawalTransaction fails because the target reverts,
+ // and emits the WithdrawalFinalized event with success=false.
+ function test_finalizeWithdrawalTransaction_targetFails() external {
+ uint256 bobBalanceBefore = address(bob).balance;
+ vm.etch(bob, hex"fe"); // Contract with just the invalid opcode.
+
+ vm.expectEmit(true, true, true, true);
+ emit WithdrawalFinalized(_withdrawalHash, false);
+ op.finalizeWithdrawalTransaction(
+ _defaultTx,
+ _proposedBlockNumber,
+ _outputRootProof,
+ _withdrawalProof
+ );
+ assert(address(bob).balance == bobBalanceBefore);
+ }
+
+ // Test: finalizeWithdrawalTransaction cannot finalize a withdrawal with itself (the OptimismPortal) as the target.
+ function test_finalizeWithdrawalTransaction_revertsOnSelfCall() external {
+ _defaultTx.target = address(op);
+ vm.expectRevert("OptimismPortal: you cannot send messages to the portal contract");
+ op.finalizeWithdrawalTransaction(
+ _defaultTx,
+ _proposedBlockNumber,
+ _outputRootProof,
+ _withdrawalProof
+ );
+ }
+
+ // Test: finalizeWithdrawalTransaction reverts if the outputRootProof does not match the output root
+ function test_finalizeWithdrawalTransaction_revertsOnInvalidOutputRootProof() external {
+ // Modify the version to invalidate the withdrawal proof.
+ _outputRootProof.version = bytes32(uint256(1));
+ vm.expectRevert("OptimismPortal: invalid output root proof");
+ op.finalizeWithdrawalTransaction(
+ _defaultTx,
+ _proposedBlockNumber,
+ _outputRootProof,
+ _withdrawalProof
+ );
+ }
+
+ // Test: finalizeWithdrawalTransaction reverts if the finalization period has not yet passed.
+ function test_finalizeWithdrawalTransaction_revertsOnRecentWithdrawal() external {
+ // Setup the Oracle to return an output with a recent timestamp
+ uint256 recentTimestamp = block.timestamp - 1000;
+ vm.mockCall(
+ address(op.L2_ORACLE()),
+ abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
+ abi.encode(bytes32(uint256(1)), recentTimestamp)
+ );
+
+ vm.expectRevert("OptimismPortal: proposal is not yet finalized");
+ op.finalizeWithdrawalTransaction(
+ _defaultTx,
+ _proposedBlockNumber,
+ _outputRootProof,
+ _withdrawalProof
+ );
+ }
+
+ // Test: finalizeWithdrawalTransaction reverts if the withdrawal has already been finalized.
+ function test_finalizeWithdrawalTransaction_revertsOnReplay() external {
+ vm.expectEmit(true, true, true, true);
+ emit WithdrawalFinalized(_withdrawalHash, true);
+ op.finalizeWithdrawalTransaction(
+ _defaultTx,
+ _proposedBlockNumber,
+ _outputRootProof,
+ _withdrawalProof
+ );
+ vm.expectRevert("OptimismPortal: withdrawal has already been finalized");
+ op.finalizeWithdrawalTransaction(
+ _defaultTx,
+ _proposedBlockNumber,
+ _outputRootProof,
+ _withdrawalProof
+ );
+ }
+
+ // Test: finalizeWithdrawalTransaction reverts if insufficient gas is supplied.
+ function test_finalizeWithdrawalTransaction_revertsOnInsufficientGas() external {
+ // This number was identified through trial and error.
+ uint256 gasLimit = 150_000;
+ Types.WithdrawalTransaction memory insufficientGasTx = Types.WithdrawalTransaction({
+ nonce: 0,
+ sender: alice,
+ target: bob,
+ value: 100,
+ gasLimit: gasLimit,
+ data: hex""
+ });
+ (
+ bytes32 stateRoot,
+ bytes32 storageRoot,
+ ,
+ ,
+ bytes memory withdrawalProof
+ ) = ffi.getFinalizeWithdrawalTransactionInputs(insufficientGasTx);
+ Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({
+ version: bytes32(0),
+ stateRoot: stateRoot,
+ withdrawerStorageRoot: storageRoot,
+ latestBlockhash: bytes32(0)
+ });
+ vm.mockCall(
+ address(op.L2_ORACLE()),
+ abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
+ abi.encode(Hashing.hashOutputRootProof(outputRootProof), _proposedBlockNumber)
+ );
+ vm.expectRevert("OptimismPortal: insufficient gas to finalize withdrawal");
+ op.finalizeWithdrawalTransaction{ gas: gasLimit }(
+ insufficientGasTx,
+ _proposedBlockNumber,
+ outputRootProof,
+ withdrawalProof
+ );
+ }
+
+ // Test: finalizeWithdrawalTransaction reverts if the proof is invalid due to non-existence of
+ // the withdrawal.
+ function test_finalizeWithdrawalTransaction_revertsOninvalidWithdrawalProof() external {
+ // modify the default test values to invalidate the proof.
+ _defaultTx.data = hex"abcd";
+ vm.expectRevert("OptimismPortal: invalid withdrawal inclusion proof");
+ op.finalizeWithdrawalTransaction(
+ _defaultTx,
+ _proposedBlockNumber,
+ _outputRootProof,
+ _withdrawalProof
+ );
+ }
+
+ // Utility function used in the subsequent test. This is necessary to assert that the
+ // reentrant call will revert.
+ function callPortalAndExpectRevert() external payable {
+ vm.expectRevert("OptimismPortal: can only trigger one withdrawal per transaction");
+ // Arguments here don't matter, as the require check is the first thing that happens.
+ op.finalizeWithdrawalTransaction(_defaultTx, 0, _outputRootProof, hex"");
+ // Assert that the withdrawal was not finalized.
+ assertFalse(op.finalizedWithdrawals(Hashing.hashWithdrawal(_defaultTx)));
+ }
+
+ // Test: finalizeWithdrawalTransaction reverts if a sub-call attempts to finalize another
+ // withdrawal.
+ function test_finalizeWithdrawalTransaction_revertsOnReentrancy() external {
+ uint256 bobBalanceBefore = address(bob).balance;
+ // Copy and modify the default test values to attempt a reentrant call by first calling to
+ // this contract's callPortalAndExpectRevert() function above.
+ Types.WithdrawalTransaction memory _testTx = _defaultTx;
+ _testTx.target = address(this);
+ _testTx.data = abi.encodeWithSelector(this.callPortalAndExpectRevert.selector);
+
+ // Get modified proof inputs.
+ (
+ bytes32 stateRoot,
+ bytes32 storageRoot,
+ bytes32 outputRoot,
+ bytes32 withdrawalHash,
+ bytes memory withdrawalProof
+ ) = ffi.getFinalizeWithdrawalTransactionInputs(_testTx);
+ Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({
+ version: bytes32(0),
+ stateRoot: stateRoot,
+ withdrawerStorageRoot: storageRoot,
+ latestBlockhash: bytes32(0)
+ });
+
+ // Setup the Oracle to return the outputRoot we want as well as a finalized timestamp.
+ uint256 finalizedTimestamp = block.timestamp - op.FINALIZATION_PERIOD_SECONDS() - 1;
+ vm.mockCall(
+ address(op.L2_ORACLE()),
+ abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
+ abi.encode(Types.OutputProposal(outputRoot, finalizedTimestamp))
+ );
+
+ // Assert that this contract is called with the expected data (i.e. the function signature of
+ // callPortalAndExpectRevert).
+ vm.expectCall(address(this), _testTx.data);
+ vm.expectEmit(true, true, true, true);
+ // Assert that the withdrawal should be finalized, and that the sub-call passes (because the
+ // assertions in callPortalAndExpectRevert pass).
+ emit WithdrawalFinalized(withdrawalHash, true);
+ op.finalizeWithdrawalTransaction(
+ _testTx,
+ _proposedBlockNumber,
+ outputRootProof,
+ withdrawalProof
+ );
+ // Ensure that bob's balance was not changed by the reentrant call.
+ assert(address(bob).balance == bobBalanceBefore);
+ }
function test_finalizeWithdrawalTransaction_differential(
address _sender,
address _target,
- uint64 _value,
- uint8 _gasLimit,
+ uint256 _value,
+ uint256 _gasLimit,
bytes memory _data
) external {
// Cannot call the optimism portal
vm.assume(_target != address(op));
+ // Total ETH supply is currently about 120M ETH.
+ vm.assume(_value < 200_000_000 ether);
+ vm.assume(_gasLimit < 50_000_000);
uint256 _nonce = messagePasser.nonce();
-
+ Types.WithdrawalTransaction memory _tx = Types.WithdrawalTransaction({
+ nonce: _nonce,
+ sender: _sender,
+ target: _target,
+ value: _value,
+ gasLimit: _gasLimit,
+ data: _data
+ });
(
bytes32 stateRoot,
bytes32 storageRoot,
bytes32 outputRoot,
bytes32 withdrawalHash,
bytes memory withdrawalProof
- ) = ffi.getFinalizeWithdrawalTransactionInputs(
- _nonce,
- _sender,
- _target,
- _value,
- uint256(_gasLimit),
- _data
- );
+ ) = ffi.getFinalizeWithdrawalTransactionInputs(_tx);
- // Ensure the values returned from ffi are correct
- assertEq(outputRoot, Hashing.hashOutputRootProof(Types.OutputRootProof({
+ Types.OutputRootProof memory proof = Types.OutputRootProof({
version: bytes32(uint256(0)),
stateRoot: stateRoot,
withdrawerStorageRoot: storageRoot,
latestBlockhash: bytes32(uint256(0))
- })));
-
- assertEq(withdrawalHash, Hashing.hashWithdrawal(
- Types.WithdrawalTransaction(
- _nonce,
- _sender,
- _target,
- _value,
- uint64(_gasLimit),
- _data
- )
- ));
+ });
+
+ // Ensure the values returned from ffi are correct
+ assertEq(outputRoot, Hashing.hashOutputRootProof(proof));
+ assertEq(withdrawalHash, Hashing.hashWithdrawal(_tx));
// Mock the call to the oracle
vm.mockCall(
@@ -365,33 +572,17 @@ contract OptimismPortal_Test is Portal_Initializer {
// Start the withdrawal, it must be initiated by the _sender and the
// correct value must be passed along
- vm.deal(_sender, _value);
- vm.prank(_sender);
- messagePasser.initiateWithdrawal{ value: _value }(
- _target,
- uint256(_gasLimit),
- _data
- );
+ vm.deal(_tx.sender, _tx.value);
+ vm.prank(_tx.sender);
+ messagePasser.initiateWithdrawal{ value: _tx.value }(_tx.target, _tx.gasLimit, _tx.data);
// Ensure that the sentMessages is correct
assertEq(messagePasser.sentMessages(withdrawalHash), true);
vm.warp(op.FINALIZATION_PERIOD_SECONDS() + 1);
- op.finalizeWithdrawalTransaction{ value: _value }(
- Types.WithdrawalTransaction(
- messagePasser.nonce() - 1,
- _sender,
- _target,
- _value,
- uint64(_gasLimit),
- _data
- ),
+ op.finalizeWithdrawalTransaction{ value: _tx.value }(
+ _tx,
100, // l2BlockNumber
- Types.OutputRootProof({
- version: bytes32(uint256(0)),
- stateRoot: stateRoot,
- withdrawerStorageRoot: storageRoot,
- latestBlockhash: bytes32(uint256(0))
- }),
+ proof,
withdrawalProof
);
}
diff --git a/packages/contracts-bedrock/deploy-config/devnetL1.ts b/packages/contracts-bedrock/deploy-config/devnetL1.ts
index b436c606a1e58..8a8df23833c07 100644
--- a/packages/contracts-bedrock/deploy-config/devnetL1.ts
+++ b/packages/contracts-bedrock/deploy-config/devnetL1.ts
@@ -2,19 +2,20 @@ import { ethers } from 'ethers'
const { env } = process
-const startingTimestamp =
- typeof env.L2OO_STARTING_BLOCK_TIMESTAMP === 'string'
- ? ethers.BigNumber.from(env.L2OO_STARTING_BLOCK_TIMESTAMP).toNumber()
+const l1GenesisTimestamp =
+ typeof env.L1_GENESIS_TIMESTAMP === 'string'
+ ? ethers.BigNumber.from(env.L1_GENESIS_TIMESTAMP).toNumber()
: Math.floor(Date.now() / 1000)
const config = {
- submissionInterval: 6,
+ submissionInterval: 20,
genesisOutput: ethers.constants.HashZero,
historicalBlocks: 0,
+ l1StartingBlockTag: 'earliest',
startingBlockNumber: 0,
l2BlockTime: 2,
- startingTimestamp,
+ l1GenesisTimestamp,
sequencerAddress: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
l2CrossDomainMessengerOwner: ethers.constants.AddressZero,
@@ -52,7 +53,7 @@ const config = {
outputOracleOwner: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
optimismL2FeeRecipient: '0xd9c09e21b57c98e58a80552c170989b426766aa7',
- batchSenderAddress: '0xDe3829A23DF1479438622a08a116E8Eb3f620BB5',
+ batchSenderAddress: '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',
}
export default config
diff --git a/packages/contracts-bedrock/deploy-config/goerli.ts b/packages/contracts-bedrock/deploy-config/goerli.ts
index 5338b86fdfa7a..93347179520e4 100644
--- a/packages/contracts-bedrock/deploy-config/goerli.ts
+++ b/packages/contracts-bedrock/deploy-config/goerli.ts
@@ -1,7 +1,8 @@
import { ethers } from 'ethers'
-const sequencerAddress = '0x0631f9bccb86548dc4a574c730a46d6ca283a338'
-const startingTimestamp = 1656654016
+const sequencerAddress = '0x6c23a0dcdfc44b7a57bed148de598895e398d984'
+const l1StartingBlockTag =
+ '0xafce66a0a2446856112e4069b275ad32b1f4a607888f9c4c59eddf9be81f8670'
const config = {
submissionInterval: 6,
@@ -9,7 +10,7 @@ const config = {
historicalBlocks: 0,
startingBlockNumber: 0,
l2BlockTime: 2,
- startingTimestamp,
+ l1StartingBlockTag,
sequencerAddress,
l2CrossDomainMessengerOwner: ethers.constants.AddressZero,
@@ -41,12 +42,12 @@ const config = {
sequencerWindowSize: 120,
channelTimeout: 120,
- proxyAdmin: '0x05e22b779967b86fb9572e8292090be2d5c1cab7',
- optimismBaseFeeRecipient: '0xec4f588262821a7c1f722e5bc40dc5332335c47f',
- optimismL1FeeRecipient: '0x8fd8d6b9e556cf4791ff9c99a56420ac2fdd2b59',
- optimismL2FeeRecipient: '0x7890eee9efd42496c63f3ec71bf61bf96af088d0',
- outputOracleOwner: '0x0f01ce071078396040a4a0de613aa024aba2d18f',
- batchSenderAddress: '0x32b317fc8d35e015cd9942bc9c7cecaf7f651838',
+ proxyAdmin: '0xe584e1b833ca80020130b1b69f84f90479076168',
+ optimismBaseFeeRecipient: '0xf116a24056b647e3211d095c667e951536cdebaa',
+ optimismL1FeeRecipient: '0xc731837b696ca3d9720d23336925368ceaa58f83',
+ optimismL2FeeRecipient: '0x26862c200bd48c19f39d9e1cd88a3b439611d911',
+ outputOracleOwner: '0x6925b8704ff96dee942623d6fb5e946ef5884b63',
+ batchSenderAddress: '0xa11d2b908470e17923fff184d48269bebbd9b2a5',
}
export default config
diff --git a/packages/contracts-bedrock/deploy-config/hardhat.ts b/packages/contracts-bedrock/deploy-config/hardhat.ts
index 217c63a20321c..596c5b03c6253 100644
--- a/packages/contracts-bedrock/deploy-config/hardhat.ts
+++ b/packages/contracts-bedrock/deploy-config/hardhat.ts
@@ -2,9 +2,9 @@ import { ethers } from 'ethers'
const { env } = process
-const startingTimestamp =
- typeof env.L2OO_STARTING_BLOCK_TIMESTAMP === 'string'
- ? ethers.BigNumber.from(env.L2OO_STARTING_BLOCK_TIMESTAMP).toNumber()
+const l1GenesisTimestamp =
+ typeof env.L1_GENESIS_TIMESTAMP === 'string'
+ ? ethers.BigNumber.from(env.L1_GENESIS_TIMESTAMP).toNumber()
: Math.floor(Date.now() / 1000)
const config = {
@@ -12,8 +12,9 @@ const config = {
genesisOutput: ethers.constants.HashZero,
historicalBlocks: 0,
startingBlockNumber: 0,
+ l1StartingBlockTag: 'earliest',
l2BlockTime: 2,
- startingTimestamp,
+ l1GenesisTimestamp,
sequencerAddress: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
maxSequencerDrift: 10,
sequencerWindowSize: 4,
diff --git a/packages/contracts-bedrock/deploy/000-L2OutputOracle.deploy.ts b/packages/contracts-bedrock/deploy/000-L2OutputOracle.deploy.ts
index 0cc44305e7b05..776212ad3528f 100644
--- a/packages/contracts-bedrock/deploy/000-L2OutputOracle.deploy.ts
+++ b/packages/contracts-bedrock/deploy/000-L2OutputOracle.deploy.ts
@@ -10,13 +10,10 @@ const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const { deployConfig } = hre
- if (
- typeof deployConfig.startingTimestamp !== 'number' ||
- isNaN(deployConfig.startingTimestamp)
- ) {
- throw new Error(
- 'Cannot deploy L2OutputOracle without specifying a valid startingTimestamp.'
- )
+ const l1 = hre.ethers.provider
+ const l1StartingBlock = await l1.getBlock(deployConfig.l1StartingBlockTag)
+ if (l1StartingBlock === null) {
+ throw new Error(`Cannot fetch block tag ${deployConfig.l1StartingBlockTag}`)
}
await deploy('L2OutputOracleProxy', {
@@ -34,7 +31,7 @@ const deployFn: DeployFunction = async (hre) => {
deployConfig.genesisOutput,
deployConfig.historicalBlocks,
deployConfig.startingBlockNumber,
- deployConfig.startingTimestamp,
+ l1StartingBlock.timestamp,
deployConfig.l2BlockTime,
deployConfig.sequencerAddress,
deployConfig.outputOracleOwner,
@@ -84,7 +81,7 @@ const deployFn: DeployFunction = async (hre) => {
}
const startingTimestamp = await L2OutputOracle.STARTING_TIMESTAMP()
- if (!startingTimestamp.eq(BigNumber.from(deployConfig.startingTimestamp))) {
+ if (!startingTimestamp.eq(BigNumber.from(l1StartingBlock.timestamp))) {
throw new Error('starting timestamp misconfigured')
}
const l2BlockTime = await L2OutputOracle.L2_BLOCK_TIME()
diff --git a/packages/contracts-bedrock/deploy/001-OptimismPortal.deploy.ts b/packages/contracts-bedrock/deploy/001-OptimismPortal.deploy.ts
index 19ed03afef1a3..22761a87ec627 100644
--- a/packages/contracts-bedrock/deploy/001-OptimismPortal.deploy.ts
+++ b/packages/contracts-bedrock/deploy/001-OptimismPortal.deploy.ts
@@ -17,7 +17,7 @@ const deployFn: DeployFunction = async (hre) => {
waitConfirmations: deployConfig.deploymentWaitConfirmations,
})
- const oracle = await get('L2OutputOracle')
+ const oracle = await get('L2OutputOracleProxy')
await deploy('OptimismPortal', {
from: deployer,
diff --git a/packages/contracts-bedrock/deployments/goerli/L1CrossDomainMessengerProxy.json b/packages/contracts-bedrock/deployments/goerli/L1CrossDomainMessengerProxy.json
index fe32c925b440f..a356fb3dbf21c 100644
--- a/packages/contracts-bedrock/deployments/goerli/L1CrossDomainMessengerProxy.json
+++ b/packages/contracts-bedrock/deployments/goerli/L1CrossDomainMessengerProxy.json
@@ -1,5 +1,5 @@
{
- "address": "0xFa81801E2F87694F4d7883b7E6e78ac546050E51",
+ "address": "0xad09e764Dd3CFbA038d152e00bb1651B6f56e2A5",
"abi": [
{
"inputs": [
@@ -123,45 +123,49 @@
],
"stateMutability": "payable",
"type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
}
],
- "transactionHash": "0x580e1e922cbca246529a81d4dd0fcdf56cfeb40769c5f91d4abce562df09b94a",
+ "transactionHash": "0x27159b679808440df4dfe6eff360d0bfb8218368566355123769b4b5f746f41b",
"receipt": {
"to": null,
"from": "0x3a605B442055DF2898E18cF518feb2e2A6BD0D31",
- "contractAddress": "0xFa81801E2F87694F4d7883b7E6e78ac546050E51",
- "transactionIndex": 1,
- "gasUsed": "520158",
- "logsBloom": "0x00200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000008000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "blockHash": "0xde8ba6cbdd8780230ac54915852192fa0aa8e142fe28cedbbd922087c5d51daa",
- "transactionHash": "0x580e1e922cbca246529a81d4dd0fcdf56cfeb40769c5f91d4abce562df09b94a",
+ "contractAddress": "0xad09e764Dd3CFbA038d152e00bb1651B6f56e2A5",
+ "transactionIndex": 0,
+ "gasUsed": "523812",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000100000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0x50fd0bf31bfb098699624dbd21e02fc074cb317903c7d2b6832c87e37df99a3e",
+ "transactionHash": "0x27159b679808440df4dfe6eff360d0bfb8218368566355123769b4b5f746f41b",
"logs": [
{
- "transactionIndex": 1,
- "blockNumber": 7209635,
- "transactionHash": "0x580e1e922cbca246529a81d4dd0fcdf56cfeb40769c5f91d4abce562df09b94a",
- "address": "0xFa81801E2F87694F4d7883b7E6e78ac546050E51",
+ "transactionIndex": 0,
+ "blockNumber": 7289814,
+ "transactionHash": "0x27159b679808440df4dfe6eff360d0bfb8218368566355123769b4b5f746f41b",
+ "address": "0xad09e764Dd3CFbA038d152e00bb1651B6f56e2A5",
"topics": [
"0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"
],
"data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a605b442055df2898e18cf518feb2e2a6bd0d31",
"logIndex": 0,
- "blockHash": "0xde8ba6cbdd8780230ac54915852192fa0aa8e142fe28cedbbd922087c5d51daa"
+ "blockHash": "0x50fd0bf31bfb098699624dbd21e02fc074cb317903c7d2b6832c87e37df99a3e"
}
],
- "blockNumber": 7209635,
- "cumulativeGasUsed": "541158",
+ "blockNumber": 7289814,
+ "cumulativeGasUsed": "523812",
"status": 1,
"byzantium": true
},
"args": [
"0x3a605B442055DF2898E18cF518feb2e2A6BD0D31"
],
- "numDeployments": 1,
- "solcInputHash": "599c82b18bfb932a0753a57de385b407",
- "metadata": "\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.10+commit.fc410830\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_admin\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"previousAdmin\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"newAdmin\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"AdminChanged\\\",\\\"type\\\":\\\"event\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"implementation\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"Upgraded\\\",\\\"type\\\":\\\"event\\\"},{\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"fallback\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"admin\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_admin\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"changeAdmin\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"implementation\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_implementation\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"upgradeTo\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_implementation\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"_data\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"name\\\":\\\"upgradeToAndCall\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"function\\\"}],\\\"devdoc\\\":{\\\"events\\\":{\\\"AdminChanged(address,address)\\\":{\\\"params\\\":{\\\"newAdmin\\\":\\\"The new owner of the contract\\\",\\\"previousAdmin\\\":\\\"The previous owner of the contract\\\"}},\\\"Upgraded(address)\\\":{\\\"params\\\":{\\\"implementation\\\":\\\"The address of the implementation contract\\\"}}},\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{\\\"admin()\\\":{\\\"returns\\\":{\\\"_0\\\":\\\"Owner address.\\\"}},\\\"changeAdmin(address)\\\":{\\\"params\\\":{\\\"_admin\\\":\\\"New owner of the proxy contract.\\\"}},\\\"constructor\\\":{\\\"params\\\":{\\\"_admin\\\":\\\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\\\"}},\\\"implementation()\\\":{\\\"returns\\\":{\\\"_0\\\":\\\"Implementation address.\\\"}},\\\"upgradeTo(address)\\\":{\\\"params\\\":{\\\"_implementation\\\":\\\"Address of the implementation contract.\\\"}},\\\"upgradeToAndCall(address,bytes)\\\":{\\\"params\\\":{\\\"_data\\\":\\\"Calldata to delegatecall the new implementation with.\\\",\\\"_implementation\\\":\\\"Address of the implementation contract.\\\"}}},\\\"title\\\":\\\"Proxy\\\",\\\"version\\\":1},\\\"userdoc\\\":{\\\"events\\\":{\\\"AdminChanged(address,address)\\\":{\\\"notice\\\":\\\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\\\"},\\\"Upgraded(address)\\\":{\\\"notice\\\":\\\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\\\"}},\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{\\\"admin()\\\":{\\\"notice\\\":\\\"Gets the owner of the proxy contract.\\\"},\\\"changeAdmin(address)\\\":{\\\"notice\\\":\\\"Changes the owner of the proxy contract. Only callable by the owner.\\\"},\\\"constructor\\\":{\\\"notice\\\":\\\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\\\"},\\\"implementation()\\\":{\\\"notice\\\":\\\"Queries the implementation address.\\\"},\\\"upgradeTo(address)\\\":{\\\"notice\\\":\\\"Set the implementation contract address. The code at the given address will execute when this contract is called.\\\"},\\\"upgradeToAndCall(address,bytes)\\\":{\\\"notice\\\":\\\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\\\"}},\\\"notice\\\":\\\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\\\",\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"contracts/universal/Proxy.sol\\\":\\\"Proxy\\\"},\\\"evmVersion\\\":\\\"london\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"none\\\"},\\\"optimizer\\\":{\\\"enabled\\\":true,\\\"runs\\\":999999},\\\"remappings\\\":[\\\":@openzeppelin/=node_modules/@openzeppelin/\\\",\\\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\\\",\\\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\\\",\\\":@rari-capital/=node_modules/@rari-capital/\\\",\\\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\\\",\\\":contracts/=contracts/\\\",\\\":ds-test/=node_modules/ds-test/src/\\\",\\\":excessively-safe-call/=node_modules/excessively-safe-call/\\\",\\\":forge-std/=node_modules/forge-std/src/\\\",\\\":test/=test/\\\"]},\\\"sources\\\":{\\\"contracts/universal/Proxy.sol\\\":{\\\"keccak256\\\":\\\"0xfbd3b9b280c82e08ed10690e0aa683cfa97417139f83349e89a38e01f9601422\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://579a350f080617001c0f747414e5160f7b1c571c381137a759b54d8278450531\\\",\\\"dweb:/ipfs/QmP2wjj8pGwXx64oYCGftF1XbKceMge9ByqxdrX8UjEdR9\\\"]}},\\\"version\\\":1}\"",
- "bytecode": "0x608060405234801561001057600080fd5b5060405161090738038061090783398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108e78339815191525490565b6000805160206108e7833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b6107f6806100f16000396000f3fe60806040526004361061005a5760003560e01c80635c60da1b116100435780635c60da1b146100ad5780638f283970146100e7578063f851a440146101075761005a565b80633659cfe6146100645780634f1ef28614610084575b61006261011c565b005b34801561007057600080fd5b5061006261007f3660046106c8565b610213565b6100976100923660046106e3565b610285565b6040516100a49190610766565b60405180910390f35b3480156100b957600080fd5b506100c2610408565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100a4565b3480156100f357600080fd5b506100626101023660046106c8565b61049f565b34801561011357600080fd5b506100c2610506565b60006101467f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff81166101f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061020d573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061026c575033155b1561027d5761027a81610592565b50565b61027a61011c565b60606102af7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102e6575033155b156103f9576102f484610592565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161031e9291906107d9565b600060405180830381855af49150503d8060008114610359576040519150601f19603f3d011682016040523d82523d6000602084013e61035e565b606091505b5091509150816103f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101e7565b91506104019050565b61040161011c565b9392505050565b60006104327fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610469575033155b1561049457507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b61049c61011c565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104f8575033155b1561027d5761027a816105fa565b60006105307fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610567575033155b1561049457507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106247fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106c357600080fd5b919050565b6000602082840312156106da57600080fd5b6104018261069f565b6000806000604084860312156106f857600080fd5b6107018461069f565b9250602084013567ffffffffffffffff8082111561071e57600080fd5b818601915086601f83011261073257600080fd5b81358181111561074157600080fd5b87602082850101111561075357600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b8181101561079357858101830151858201604001528201610777565b818111156107a5576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080a000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103",
- "deployedBytecode": "0x60806040526004361061005a5760003560e01c80635c60da1b116100435780635c60da1b146100ad5780638f283970146100e7578063f851a440146101075761005a565b80633659cfe6146100645780634f1ef28614610084575b61006261011c565b005b34801561007057600080fd5b5061006261007f3660046106c8565b610213565b6100976100923660046106e3565b610285565b6040516100a49190610766565b60405180910390f35b3480156100b957600080fd5b506100c2610408565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100a4565b3480156100f357600080fd5b506100626101023660046106c8565b61049f565b34801561011357600080fd5b506100c2610506565b60006101467f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff81166101f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061020d573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061026c575033155b1561027d5761027a81610592565b50565b61027a61011c565b60606102af7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102e6575033155b156103f9576102f484610592565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161031e9291906107d9565b600060405180830381855af49150503d8060008114610359576040519150601f19603f3d011682016040523d82523d6000602084013e61035e565b606091505b5091509150816103f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101e7565b91506104019050565b61040161011c565b9392505050565b60006104327fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610469575033155b1561049457507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b61049c61011c565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104f8575033155b1561027d5761027a816105fa565b60006105307fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610567575033155b1561049457507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106247fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106c357600080fd5b919050565b6000602082840312156106da57600080fd5b6104018261069f565b6000806000604084860312156106f857600080fd5b6107018461069f565b9250602084013567ffffffffffffffff8082111561071e57600080fd5b818601915086601f83011261073257600080fd5b81358181111561074157600080fd5b87602082850101111561075357600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b8181101561079357858101830151858201604001528201610777565b818111156107a5576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080a000a",
+ "numDeployments": 2,
+ "solcInputHash": "58f505918460d798ebe5c901024780d7",
+ "metadata": "\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.15+commit.e14f2714\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_admin\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"previousAdmin\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"newAdmin\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"AdminChanged\\\",\\\"type\\\":\\\"event\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"implementation\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"Upgraded\\\",\\\"type\\\":\\\"event\\\"},{\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"fallback\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"admin\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_admin\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"changeAdmin\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"implementation\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_implementation\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"upgradeTo\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_implementation\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"_data\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"name\\\":\\\"upgradeToAndCall\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"function\\\"},{\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"receive\\\"}],\\\"devdoc\\\":{\\\"events\\\":{\\\"AdminChanged(address,address)\\\":{\\\"params\\\":{\\\"newAdmin\\\":\\\"The new owner of the contract\\\",\\\"previousAdmin\\\":\\\"The previous owner of the contract\\\"}},\\\"Upgraded(address)\\\":{\\\"params\\\":{\\\"implementation\\\":\\\"The address of the implementation contract\\\"}}},\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{\\\"admin()\\\":{\\\"returns\\\":{\\\"_0\\\":\\\"Owner address.\\\"}},\\\"changeAdmin(address)\\\":{\\\"params\\\":{\\\"_admin\\\":\\\"New owner of the proxy contract.\\\"}},\\\"constructor\\\":{\\\"params\\\":{\\\"_admin\\\":\\\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\\\"}},\\\"implementation()\\\":{\\\"returns\\\":{\\\"_0\\\":\\\"Implementation address.\\\"}},\\\"upgradeTo(address)\\\":{\\\"params\\\":{\\\"_implementation\\\":\\\"Address of the implementation contract.\\\"}},\\\"upgradeToAndCall(address,bytes)\\\":{\\\"params\\\":{\\\"_data\\\":\\\"Calldata to delegatecall the new implementation with.\\\",\\\"_implementation\\\":\\\"Address of the implementation contract.\\\"}}},\\\"title\\\":\\\"Proxy\\\",\\\"version\\\":1},\\\"userdoc\\\":{\\\"events\\\":{\\\"AdminChanged(address,address)\\\":{\\\"notice\\\":\\\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\\\"},\\\"Upgraded(address)\\\":{\\\"notice\\\":\\\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\\\"}},\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{\\\"admin()\\\":{\\\"notice\\\":\\\"Gets the owner of the proxy contract.\\\"},\\\"changeAdmin(address)\\\":{\\\"notice\\\":\\\"Changes the owner of the proxy contract. Only callable by the owner.\\\"},\\\"constructor\\\":{\\\"notice\\\":\\\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\\\"},\\\"implementation()\\\":{\\\"notice\\\":\\\"Queries the implementation address.\\\"},\\\"upgradeTo(address)\\\":{\\\"notice\\\":\\\"Set the implementation contract address. The code at the given address will execute when this contract is called.\\\"},\\\"upgradeToAndCall(address,bytes)\\\":{\\\"notice\\\":\\\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\\\"}},\\\"notice\\\":\\\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\\\",\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"contracts/universal/Proxy.sol\\\":\\\"Proxy\\\"},\\\"evmVersion\\\":\\\"london\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"none\\\"},\\\"optimizer\\\":{\\\"enabled\\\":true,\\\"runs\\\":999999},\\\"remappings\\\":[\\\":@eth-optimism/contracts-periphery/=node_modules/@eth-optimism/contracts-periphery/contracts/\\\",\\\":@openzeppelin/=node_modules/@openzeppelin/\\\",\\\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\\\",\\\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\\\",\\\":@rari-capital/=node_modules/@rari-capital/\\\",\\\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\\\",\\\":contracts/=contracts/\\\",\\\":ds-test/=node_modules/ds-test/src/\\\",\\\":excessively-safe-call/=node_modules/excessively-safe-call/\\\",\\\":forge-std/=node_modules/forge-std/src/\\\"]},\\\"sources\\\":{\\\"contracts/universal/Proxy.sol\\\":{\\\"keccak256\\\":\\\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://8f2247604d527f560edbb851c43b6c16b37e34972ddb305e16dd73623b8288cd\\\",\\\"dweb:/ipfs/QmfM8sLAZrxrnqyRdt1XJ5LyJh4wKbeEqk3VkvxG7BDqFj\\\"]}},\\\"version\\\":1}\"",
+ "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103",
+ "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a",
"devdoc": {
"version": 1,
"kind": "dev",
diff --git a/packages/contracts-bedrock/deployments/goerli/L1StandardBridgeProxy.json b/packages/contracts-bedrock/deployments/goerli/L1StandardBridgeProxy.json
index af1f97c036e00..833894f776336 100644
--- a/packages/contracts-bedrock/deployments/goerli/L1StandardBridgeProxy.json
+++ b/packages/contracts-bedrock/deployments/goerli/L1StandardBridgeProxy.json
@@ -1,5 +1,5 @@
{
- "address": "0x8D421F3880eBBF8DF62165d542baF08a62bDe913",
+ "address": "0x893Bba7EB5Edea040885465a315FD69FbB39F372",
"abi": [
{
"inputs": [
@@ -123,45 +123,49 @@
],
"stateMutability": "payable",
"type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
}
],
- "transactionHash": "0xf2207c1d7b4e179c46225f44785fbc9882a944393c1c306fb47923f9d1db054c",
+ "transactionHash": "0xeb21cbe5a80031c3965188e9c034524c268683ee134514f3b6df67e61c797c8e",
"receipt": {
"to": null,
"from": "0x3a605B442055DF2898E18cF518feb2e2A6BD0D31",
- "contractAddress": "0x8D421F3880eBBF8DF62165d542baF08a62bDe913",
+ "contractAddress": "0x893Bba7EB5Edea040885465a315FD69FbB39F372",
"transactionIndex": 0,
- "gasUsed": "520158",
- "logsBloom": "0x00000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "blockHash": "0xc169aa9cfa3c64f0ba68c2bbd4f7deafb29d56b00e91a73c26346cfdc2071fc6",
- "transactionHash": "0xf2207c1d7b4e179c46225f44785fbc9882a944393c1c306fb47923f9d1db054c",
+ "gasUsed": "523812",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000080000000000000000000000000000000000",
+ "blockHash": "0xc6b23ab6ab0cf171665793bd00389a602f7582e5ec1029a1ec994ddc3526ffb4",
+ "transactionHash": "0xeb21cbe5a80031c3965188e9c034524c268683ee134514f3b6df67e61c797c8e",
"logs": [
{
"transactionIndex": 0,
- "blockNumber": 7209638,
- "transactionHash": "0xf2207c1d7b4e179c46225f44785fbc9882a944393c1c306fb47923f9d1db054c",
- "address": "0x8D421F3880eBBF8DF62165d542baF08a62bDe913",
+ "blockNumber": 7289818,
+ "transactionHash": "0xeb21cbe5a80031c3965188e9c034524c268683ee134514f3b6df67e61c797c8e",
+ "address": "0x893Bba7EB5Edea040885465a315FD69FbB39F372",
"topics": [
"0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"
],
"data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a605b442055df2898e18cf518feb2e2a6bd0d31",
"logIndex": 0,
- "blockHash": "0xc169aa9cfa3c64f0ba68c2bbd4f7deafb29d56b00e91a73c26346cfdc2071fc6"
+ "blockHash": "0xc6b23ab6ab0cf171665793bd00389a602f7582e5ec1029a1ec994ddc3526ffb4"
}
],
- "blockNumber": 7209638,
- "cumulativeGasUsed": "520158",
+ "blockNumber": 7289818,
+ "cumulativeGasUsed": "523812",
"status": 1,
"byzantium": true
},
"args": [
"0x3a605B442055DF2898E18cF518feb2e2A6BD0D31"
],
- "numDeployments": 1,
- "solcInputHash": "599c82b18bfb932a0753a57de385b407",
- "metadata": "\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.10+commit.fc410830\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_admin\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"previousAdmin\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"newAdmin\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"AdminChanged\\\",\\\"type\\\":\\\"event\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"implementation\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"Upgraded\\\",\\\"type\\\":\\\"event\\\"},{\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"fallback\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"admin\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_admin\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"changeAdmin\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"implementation\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_implementation\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"upgradeTo\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_implementation\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"_data\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"name\\\":\\\"upgradeToAndCall\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"function\\\"}],\\\"devdoc\\\":{\\\"events\\\":{\\\"AdminChanged(address,address)\\\":{\\\"params\\\":{\\\"newAdmin\\\":\\\"The new owner of the contract\\\",\\\"previousAdmin\\\":\\\"The previous owner of the contract\\\"}},\\\"Upgraded(address)\\\":{\\\"params\\\":{\\\"implementation\\\":\\\"The address of the implementation contract\\\"}}},\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{\\\"admin()\\\":{\\\"returns\\\":{\\\"_0\\\":\\\"Owner address.\\\"}},\\\"changeAdmin(address)\\\":{\\\"params\\\":{\\\"_admin\\\":\\\"New owner of the proxy contract.\\\"}},\\\"constructor\\\":{\\\"params\\\":{\\\"_admin\\\":\\\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\\\"}},\\\"implementation()\\\":{\\\"returns\\\":{\\\"_0\\\":\\\"Implementation address.\\\"}},\\\"upgradeTo(address)\\\":{\\\"params\\\":{\\\"_implementation\\\":\\\"Address of the implementation contract.\\\"}},\\\"upgradeToAndCall(address,bytes)\\\":{\\\"params\\\":{\\\"_data\\\":\\\"Calldata to delegatecall the new implementation with.\\\",\\\"_implementation\\\":\\\"Address of the implementation contract.\\\"}}},\\\"title\\\":\\\"Proxy\\\",\\\"version\\\":1},\\\"userdoc\\\":{\\\"events\\\":{\\\"AdminChanged(address,address)\\\":{\\\"notice\\\":\\\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\\\"},\\\"Upgraded(address)\\\":{\\\"notice\\\":\\\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\\\"}},\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{\\\"admin()\\\":{\\\"notice\\\":\\\"Gets the owner of the proxy contract.\\\"},\\\"changeAdmin(address)\\\":{\\\"notice\\\":\\\"Changes the owner of the proxy contract. Only callable by the owner.\\\"},\\\"constructor\\\":{\\\"notice\\\":\\\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\\\"},\\\"implementation()\\\":{\\\"notice\\\":\\\"Queries the implementation address.\\\"},\\\"upgradeTo(address)\\\":{\\\"notice\\\":\\\"Set the implementation contract address. The code at the given address will execute when this contract is called.\\\"},\\\"upgradeToAndCall(address,bytes)\\\":{\\\"notice\\\":\\\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\\\"}},\\\"notice\\\":\\\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\\\",\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"contracts/universal/Proxy.sol\\\":\\\"Proxy\\\"},\\\"evmVersion\\\":\\\"london\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"none\\\"},\\\"optimizer\\\":{\\\"enabled\\\":true,\\\"runs\\\":999999},\\\"remappings\\\":[\\\":@openzeppelin/=node_modules/@openzeppelin/\\\",\\\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\\\",\\\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\\\",\\\":@rari-capital/=node_modules/@rari-capital/\\\",\\\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\\\",\\\":contracts/=contracts/\\\",\\\":ds-test/=node_modules/ds-test/src/\\\",\\\":excessively-safe-call/=node_modules/excessively-safe-call/\\\",\\\":forge-std/=node_modules/forge-std/src/\\\",\\\":test/=test/\\\"]},\\\"sources\\\":{\\\"contracts/universal/Proxy.sol\\\":{\\\"keccak256\\\":\\\"0xfbd3b9b280c82e08ed10690e0aa683cfa97417139f83349e89a38e01f9601422\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://579a350f080617001c0f747414e5160f7b1c571c381137a759b54d8278450531\\\",\\\"dweb:/ipfs/QmP2wjj8pGwXx64oYCGftF1XbKceMge9ByqxdrX8UjEdR9\\\"]}},\\\"version\\\":1}\"",
- "bytecode": "0x608060405234801561001057600080fd5b5060405161090738038061090783398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108e78339815191525490565b6000805160206108e7833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b6107f6806100f16000396000f3fe60806040526004361061005a5760003560e01c80635c60da1b116100435780635c60da1b146100ad5780638f283970146100e7578063f851a440146101075761005a565b80633659cfe6146100645780634f1ef28614610084575b61006261011c565b005b34801561007057600080fd5b5061006261007f3660046106c8565b610213565b6100976100923660046106e3565b610285565b6040516100a49190610766565b60405180910390f35b3480156100b957600080fd5b506100c2610408565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100a4565b3480156100f357600080fd5b506100626101023660046106c8565b61049f565b34801561011357600080fd5b506100c2610506565b60006101467f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff81166101f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061020d573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061026c575033155b1561027d5761027a81610592565b50565b61027a61011c565b60606102af7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102e6575033155b156103f9576102f484610592565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161031e9291906107d9565b600060405180830381855af49150503d8060008114610359576040519150601f19603f3d011682016040523d82523d6000602084013e61035e565b606091505b5091509150816103f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101e7565b91506104019050565b61040161011c565b9392505050565b60006104327fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610469575033155b1561049457507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b61049c61011c565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104f8575033155b1561027d5761027a816105fa565b60006105307fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610567575033155b1561049457507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106247fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106c357600080fd5b919050565b6000602082840312156106da57600080fd5b6104018261069f565b6000806000604084860312156106f857600080fd5b6107018461069f565b9250602084013567ffffffffffffffff8082111561071e57600080fd5b818601915086601f83011261073257600080fd5b81358181111561074157600080fd5b87602082850101111561075357600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b8181101561079357858101830151858201604001528201610777565b818111156107a5576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080a000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103",
- "deployedBytecode": "0x60806040526004361061005a5760003560e01c80635c60da1b116100435780635c60da1b146100ad5780638f283970146100e7578063f851a440146101075761005a565b80633659cfe6146100645780634f1ef28614610084575b61006261011c565b005b34801561007057600080fd5b5061006261007f3660046106c8565b610213565b6100976100923660046106e3565b610285565b6040516100a49190610766565b60405180910390f35b3480156100b957600080fd5b506100c2610408565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100a4565b3480156100f357600080fd5b506100626101023660046106c8565b61049f565b34801561011357600080fd5b506100c2610506565b60006101467f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff81166101f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061020d573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061026c575033155b1561027d5761027a81610592565b50565b61027a61011c565b60606102af7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102e6575033155b156103f9576102f484610592565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161031e9291906107d9565b600060405180830381855af49150503d8060008114610359576040519150601f19603f3d011682016040523d82523d6000602084013e61035e565b606091505b5091509150816103f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101e7565b91506104019050565b61040161011c565b9392505050565b60006104327fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610469575033155b1561049457507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b61049c61011c565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104f8575033155b1561027d5761027a816105fa565b60006105307fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610567575033155b1561049457507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106247fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106c357600080fd5b919050565b6000602082840312156106da57600080fd5b6104018261069f565b6000806000604084860312156106f857600080fd5b6107018461069f565b9250602084013567ffffffffffffffff8082111561071e57600080fd5b818601915086601f83011261073257600080fd5b81358181111561074157600080fd5b87602082850101111561075357600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b8181101561079357858101830151858201604001528201610777565b818111156107a5576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080a000a",
+ "numDeployments": 2,
+ "solcInputHash": "58f505918460d798ebe5c901024780d7",
+ "metadata": "\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.15+commit.e14f2714\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_admin\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"previousAdmin\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"newAdmin\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"AdminChanged\\\",\\\"type\\\":\\\"event\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"implementation\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"Upgraded\\\",\\\"type\\\":\\\"event\\\"},{\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"fallback\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"admin\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_admin\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"changeAdmin\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"implementation\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_implementation\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"upgradeTo\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_implementation\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"_data\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"name\\\":\\\"upgradeToAndCall\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"function\\\"},{\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"receive\\\"}],\\\"devdoc\\\":{\\\"events\\\":{\\\"AdminChanged(address,address)\\\":{\\\"params\\\":{\\\"newAdmin\\\":\\\"The new owner of the contract\\\",\\\"previousAdmin\\\":\\\"The previous owner of the contract\\\"}},\\\"Upgraded(address)\\\":{\\\"params\\\":{\\\"implementation\\\":\\\"The address of the implementation contract\\\"}}},\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{\\\"admin()\\\":{\\\"returns\\\":{\\\"_0\\\":\\\"Owner address.\\\"}},\\\"changeAdmin(address)\\\":{\\\"params\\\":{\\\"_admin\\\":\\\"New owner of the proxy contract.\\\"}},\\\"constructor\\\":{\\\"params\\\":{\\\"_admin\\\":\\\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\\\"}},\\\"implementation()\\\":{\\\"returns\\\":{\\\"_0\\\":\\\"Implementation address.\\\"}},\\\"upgradeTo(address)\\\":{\\\"params\\\":{\\\"_implementation\\\":\\\"Address of the implementation contract.\\\"}},\\\"upgradeToAndCall(address,bytes)\\\":{\\\"params\\\":{\\\"_data\\\":\\\"Calldata to delegatecall the new implementation with.\\\",\\\"_implementation\\\":\\\"Address of the implementation contract.\\\"}}},\\\"title\\\":\\\"Proxy\\\",\\\"version\\\":1},\\\"userdoc\\\":{\\\"events\\\":{\\\"AdminChanged(address,address)\\\":{\\\"notice\\\":\\\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\\\"},\\\"Upgraded(address)\\\":{\\\"notice\\\":\\\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\\\"}},\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{\\\"admin()\\\":{\\\"notice\\\":\\\"Gets the owner of the proxy contract.\\\"},\\\"changeAdmin(address)\\\":{\\\"notice\\\":\\\"Changes the owner of the proxy contract. Only callable by the owner.\\\"},\\\"constructor\\\":{\\\"notice\\\":\\\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\\\"},\\\"implementation()\\\":{\\\"notice\\\":\\\"Queries the implementation address.\\\"},\\\"upgradeTo(address)\\\":{\\\"notice\\\":\\\"Set the implementation contract address. The code at the given address will execute when this contract is called.\\\"},\\\"upgradeToAndCall(address,bytes)\\\":{\\\"notice\\\":\\\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\\\"}},\\\"notice\\\":\\\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\\\",\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"contracts/universal/Proxy.sol\\\":\\\"Proxy\\\"},\\\"evmVersion\\\":\\\"london\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"none\\\"},\\\"optimizer\\\":{\\\"enabled\\\":true,\\\"runs\\\":999999},\\\"remappings\\\":[\\\":@eth-optimism/contracts-periphery/=node_modules/@eth-optimism/contracts-periphery/contracts/\\\",\\\":@openzeppelin/=node_modules/@openzeppelin/\\\",\\\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\\\",\\\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\\\",\\\":@rari-capital/=node_modules/@rari-capital/\\\",\\\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\\\",\\\":contracts/=contracts/\\\",\\\":ds-test/=node_modules/ds-test/src/\\\",\\\":excessively-safe-call/=node_modules/excessively-safe-call/\\\",\\\":forge-std/=node_modules/forge-std/src/\\\"]},\\\"sources\\\":{\\\"contracts/universal/Proxy.sol\\\":{\\\"keccak256\\\":\\\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://8f2247604d527f560edbb851c43b6c16b37e34972ddb305e16dd73623b8288cd\\\",\\\"dweb:/ipfs/QmfM8sLAZrxrnqyRdt1XJ5LyJh4wKbeEqk3VkvxG7BDqFj\\\"]}},\\\"version\\\":1}\"",
+ "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103",
+ "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a",
"devdoc": {
"version": 1,
"kind": "dev",
diff --git a/packages/contracts-bedrock/deployments/goerli/L2OutputOracleProxy.json b/packages/contracts-bedrock/deployments/goerli/L2OutputOracleProxy.json
index 6dd61ba9ab53a..e71e4cfae649a 100644
--- a/packages/contracts-bedrock/deployments/goerli/L2OutputOracleProxy.json
+++ b/packages/contracts-bedrock/deployments/goerli/L2OutputOracleProxy.json
@@ -1,5 +1,5 @@
{
- "address": "0x9772e58A8B40d81582da6E225A8E36f5E4989B9b",
+ "address": "0xa2308A6BC540E85d5b52cc84B82BCB06dB47507c",
"abi": [
{
"inputs": [
@@ -123,45 +123,49 @@
],
"stateMutability": "payable",
"type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
}
],
- "transactionHash": "0x4d21e4d3cc206ce9a420f215ccebc91d86457644125c07eee8e63a30a805351e",
+ "transactionHash": "0xcdecfee3701d004158baf56d64c862fbcdafd5d2ba1e061e695f5317025c2bd2",
"receipt": {
"to": null,
"from": "0x3a605B442055DF2898E18cF518feb2e2A6BD0D31",
- "contractAddress": "0x9772e58A8B40d81582da6E225A8E36f5E4989B9b",
- "transactionIndex": 2,
- "gasUsed": "520158",
- "logsBloom": "0x00000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000001000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "blockHash": "0xf775c8fbe7136bea1e1348fa9981f4607fecb599c3681875dded572df0797c52",
- "transactionHash": "0x4d21e4d3cc206ce9a420f215ccebc91d86457644125c07eee8e63a30a805351e",
+ "contractAddress": "0xa2308A6BC540E85d5b52cc84B82BCB06dB47507c",
+ "transactionIndex": 0,
+ "gasUsed": "523812",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000100000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0xb917b13fd4aff1d6dd83de1213dc66281c0be6180d5c0a6f99c8d67524db6f67",
+ "transactionHash": "0xcdecfee3701d004158baf56d64c862fbcdafd5d2ba1e061e695f5317025c2bd2",
"logs": [
{
- "transactionIndex": 2,
- "blockNumber": 7209628,
- "transactionHash": "0x4d21e4d3cc206ce9a420f215ccebc91d86457644125c07eee8e63a30a805351e",
- "address": "0x9772e58A8B40d81582da6E225A8E36f5E4989B9b",
+ "transactionIndex": 0,
+ "blockNumber": 7289806,
+ "transactionHash": "0xcdecfee3701d004158baf56d64c862fbcdafd5d2ba1e061e695f5317025c2bd2",
+ "address": "0xa2308A6BC540E85d5b52cc84B82BCB06dB47507c",
"topics": [
"0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"
],
"data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a605b442055df2898e18cf518feb2e2a6bd0d31",
"logIndex": 0,
- "blockHash": "0xf775c8fbe7136bea1e1348fa9981f4607fecb599c3681875dded572df0797c52"
+ "blockHash": "0xb917b13fd4aff1d6dd83de1213dc66281c0be6180d5c0a6f99c8d67524db6f67"
}
],
- "blockNumber": 7209628,
- "cumulativeGasUsed": "601820",
+ "blockNumber": 7289806,
+ "cumulativeGasUsed": "523812",
"status": 1,
"byzantium": true
},
"args": [
"0x3a605B442055DF2898E18cF518feb2e2A6BD0D31"
],
- "numDeployments": 1,
- "solcInputHash": "599c82b18bfb932a0753a57de385b407",
- "metadata": "\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.10+commit.fc410830\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_admin\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"previousAdmin\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"newAdmin\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"AdminChanged\\\",\\\"type\\\":\\\"event\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"implementation\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"Upgraded\\\",\\\"type\\\":\\\"event\\\"},{\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"fallback\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"admin\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_admin\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"changeAdmin\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"implementation\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_implementation\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"upgradeTo\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_implementation\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"_data\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"name\\\":\\\"upgradeToAndCall\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"function\\\"}],\\\"devdoc\\\":{\\\"events\\\":{\\\"AdminChanged(address,address)\\\":{\\\"params\\\":{\\\"newAdmin\\\":\\\"The new owner of the contract\\\",\\\"previousAdmin\\\":\\\"The previous owner of the contract\\\"}},\\\"Upgraded(address)\\\":{\\\"params\\\":{\\\"implementation\\\":\\\"The address of the implementation contract\\\"}}},\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{\\\"admin()\\\":{\\\"returns\\\":{\\\"_0\\\":\\\"Owner address.\\\"}},\\\"changeAdmin(address)\\\":{\\\"params\\\":{\\\"_admin\\\":\\\"New owner of the proxy contract.\\\"}},\\\"constructor\\\":{\\\"params\\\":{\\\"_admin\\\":\\\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\\\"}},\\\"implementation()\\\":{\\\"returns\\\":{\\\"_0\\\":\\\"Implementation address.\\\"}},\\\"upgradeTo(address)\\\":{\\\"params\\\":{\\\"_implementation\\\":\\\"Address of the implementation contract.\\\"}},\\\"upgradeToAndCall(address,bytes)\\\":{\\\"params\\\":{\\\"_data\\\":\\\"Calldata to delegatecall the new implementation with.\\\",\\\"_implementation\\\":\\\"Address of the implementation contract.\\\"}}},\\\"title\\\":\\\"Proxy\\\",\\\"version\\\":1},\\\"userdoc\\\":{\\\"events\\\":{\\\"AdminChanged(address,address)\\\":{\\\"notice\\\":\\\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\\\"},\\\"Upgraded(address)\\\":{\\\"notice\\\":\\\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\\\"}},\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{\\\"admin()\\\":{\\\"notice\\\":\\\"Gets the owner of the proxy contract.\\\"},\\\"changeAdmin(address)\\\":{\\\"notice\\\":\\\"Changes the owner of the proxy contract. Only callable by the owner.\\\"},\\\"constructor\\\":{\\\"notice\\\":\\\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\\\"},\\\"implementation()\\\":{\\\"notice\\\":\\\"Queries the implementation address.\\\"},\\\"upgradeTo(address)\\\":{\\\"notice\\\":\\\"Set the implementation contract address. The code at the given address will execute when this contract is called.\\\"},\\\"upgradeToAndCall(address,bytes)\\\":{\\\"notice\\\":\\\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\\\"}},\\\"notice\\\":\\\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\\\",\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"contracts/universal/Proxy.sol\\\":\\\"Proxy\\\"},\\\"evmVersion\\\":\\\"london\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"none\\\"},\\\"optimizer\\\":{\\\"enabled\\\":true,\\\"runs\\\":999999},\\\"remappings\\\":[\\\":@openzeppelin/=node_modules/@openzeppelin/\\\",\\\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\\\",\\\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\\\",\\\":@rari-capital/=node_modules/@rari-capital/\\\",\\\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\\\",\\\":contracts/=contracts/\\\",\\\":ds-test/=node_modules/ds-test/src/\\\",\\\":excessively-safe-call/=node_modules/excessively-safe-call/\\\",\\\":forge-std/=node_modules/forge-std/src/\\\",\\\":test/=test/\\\"]},\\\"sources\\\":{\\\"contracts/universal/Proxy.sol\\\":{\\\"keccak256\\\":\\\"0xfbd3b9b280c82e08ed10690e0aa683cfa97417139f83349e89a38e01f9601422\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://579a350f080617001c0f747414e5160f7b1c571c381137a759b54d8278450531\\\",\\\"dweb:/ipfs/QmP2wjj8pGwXx64oYCGftF1XbKceMge9ByqxdrX8UjEdR9\\\"]}},\\\"version\\\":1}\"",
- "bytecode": "0x608060405234801561001057600080fd5b5060405161090738038061090783398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108e78339815191525490565b6000805160206108e7833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b6107f6806100f16000396000f3fe60806040526004361061005a5760003560e01c80635c60da1b116100435780635c60da1b146100ad5780638f283970146100e7578063f851a440146101075761005a565b80633659cfe6146100645780634f1ef28614610084575b61006261011c565b005b34801561007057600080fd5b5061006261007f3660046106c8565b610213565b6100976100923660046106e3565b610285565b6040516100a49190610766565b60405180910390f35b3480156100b957600080fd5b506100c2610408565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100a4565b3480156100f357600080fd5b506100626101023660046106c8565b61049f565b34801561011357600080fd5b506100c2610506565b60006101467f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff81166101f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061020d573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061026c575033155b1561027d5761027a81610592565b50565b61027a61011c565b60606102af7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102e6575033155b156103f9576102f484610592565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161031e9291906107d9565b600060405180830381855af49150503d8060008114610359576040519150601f19603f3d011682016040523d82523d6000602084013e61035e565b606091505b5091509150816103f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101e7565b91506104019050565b61040161011c565b9392505050565b60006104327fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610469575033155b1561049457507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b61049c61011c565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104f8575033155b1561027d5761027a816105fa565b60006105307fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610567575033155b1561049457507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106247fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106c357600080fd5b919050565b6000602082840312156106da57600080fd5b6104018261069f565b6000806000604084860312156106f857600080fd5b6107018461069f565b9250602084013567ffffffffffffffff8082111561071e57600080fd5b818601915086601f83011261073257600080fd5b81358181111561074157600080fd5b87602082850101111561075357600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b8181101561079357858101830151858201604001528201610777565b818111156107a5576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080a000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103",
- "deployedBytecode": "0x60806040526004361061005a5760003560e01c80635c60da1b116100435780635c60da1b146100ad5780638f283970146100e7578063f851a440146101075761005a565b80633659cfe6146100645780634f1ef28614610084575b61006261011c565b005b34801561007057600080fd5b5061006261007f3660046106c8565b610213565b6100976100923660046106e3565b610285565b6040516100a49190610766565b60405180910390f35b3480156100b957600080fd5b506100c2610408565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100a4565b3480156100f357600080fd5b506100626101023660046106c8565b61049f565b34801561011357600080fd5b506100c2610506565b60006101467f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff81166101f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061020d573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061026c575033155b1561027d5761027a81610592565b50565b61027a61011c565b60606102af7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102e6575033155b156103f9576102f484610592565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161031e9291906107d9565b600060405180830381855af49150503d8060008114610359576040519150601f19603f3d011682016040523d82523d6000602084013e61035e565b606091505b5091509150816103f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101e7565b91506104019050565b61040161011c565b9392505050565b60006104327fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610469575033155b1561049457507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b61049c61011c565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104f8575033155b1561027d5761027a816105fa565b60006105307fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610567575033155b1561049457507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106247fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106c357600080fd5b919050565b6000602082840312156106da57600080fd5b6104018261069f565b6000806000604084860312156106f857600080fd5b6107018461069f565b9250602084013567ffffffffffffffff8082111561071e57600080fd5b818601915086601f83011261073257600080fd5b81358181111561074157600080fd5b87602082850101111561075357600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b8181101561079357858101830151858201604001528201610777565b818111156107a5576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080a000a",
+ "numDeployments": 2,
+ "solcInputHash": "58f505918460d798ebe5c901024780d7",
+ "metadata": "\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.15+commit.e14f2714\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_admin\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"previousAdmin\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"newAdmin\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"AdminChanged\\\",\\\"type\\\":\\\"event\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"implementation\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"Upgraded\\\",\\\"type\\\":\\\"event\\\"},{\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"fallback\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"admin\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_admin\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"changeAdmin\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"implementation\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_implementation\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"upgradeTo\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_implementation\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"_data\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"name\\\":\\\"upgradeToAndCall\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"function\\\"},{\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"receive\\\"}],\\\"devdoc\\\":{\\\"events\\\":{\\\"AdminChanged(address,address)\\\":{\\\"params\\\":{\\\"newAdmin\\\":\\\"The new owner of the contract\\\",\\\"previousAdmin\\\":\\\"The previous owner of the contract\\\"}},\\\"Upgraded(address)\\\":{\\\"params\\\":{\\\"implementation\\\":\\\"The address of the implementation contract\\\"}}},\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{\\\"admin()\\\":{\\\"returns\\\":{\\\"_0\\\":\\\"Owner address.\\\"}},\\\"changeAdmin(address)\\\":{\\\"params\\\":{\\\"_admin\\\":\\\"New owner of the proxy contract.\\\"}},\\\"constructor\\\":{\\\"params\\\":{\\\"_admin\\\":\\\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\\\"}},\\\"implementation()\\\":{\\\"returns\\\":{\\\"_0\\\":\\\"Implementation address.\\\"}},\\\"upgradeTo(address)\\\":{\\\"params\\\":{\\\"_implementation\\\":\\\"Address of the implementation contract.\\\"}},\\\"upgradeToAndCall(address,bytes)\\\":{\\\"params\\\":{\\\"_data\\\":\\\"Calldata to delegatecall the new implementation with.\\\",\\\"_implementation\\\":\\\"Address of the implementation contract.\\\"}}},\\\"title\\\":\\\"Proxy\\\",\\\"version\\\":1},\\\"userdoc\\\":{\\\"events\\\":{\\\"AdminChanged(address,address)\\\":{\\\"notice\\\":\\\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\\\"},\\\"Upgraded(address)\\\":{\\\"notice\\\":\\\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\\\"}},\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{\\\"admin()\\\":{\\\"notice\\\":\\\"Gets the owner of the proxy contract.\\\"},\\\"changeAdmin(address)\\\":{\\\"notice\\\":\\\"Changes the owner of the proxy contract. Only callable by the owner.\\\"},\\\"constructor\\\":{\\\"notice\\\":\\\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\\\"},\\\"implementation()\\\":{\\\"notice\\\":\\\"Queries the implementation address.\\\"},\\\"upgradeTo(address)\\\":{\\\"notice\\\":\\\"Set the implementation contract address. The code at the given address will execute when this contract is called.\\\"},\\\"upgradeToAndCall(address,bytes)\\\":{\\\"notice\\\":\\\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\\\"}},\\\"notice\\\":\\\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\\\",\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"contracts/universal/Proxy.sol\\\":\\\"Proxy\\\"},\\\"evmVersion\\\":\\\"london\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"none\\\"},\\\"optimizer\\\":{\\\"enabled\\\":true,\\\"runs\\\":999999},\\\"remappings\\\":[\\\":@eth-optimism/contracts-periphery/=node_modules/@eth-optimism/contracts-periphery/contracts/\\\",\\\":@openzeppelin/=node_modules/@openzeppelin/\\\",\\\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\\\",\\\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\\\",\\\":@rari-capital/=node_modules/@rari-capital/\\\",\\\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\\\",\\\":contracts/=contracts/\\\",\\\":ds-test/=node_modules/ds-test/src/\\\",\\\":excessively-safe-call/=node_modules/excessively-safe-call/\\\",\\\":forge-std/=node_modules/forge-std/src/\\\"]},\\\"sources\\\":{\\\"contracts/universal/Proxy.sol\\\":{\\\"keccak256\\\":\\\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://8f2247604d527f560edbb851c43b6c16b37e34972ddb305e16dd73623b8288cd\\\",\\\"dweb:/ipfs/QmfM8sLAZrxrnqyRdt1XJ5LyJh4wKbeEqk3VkvxG7BDqFj\\\"]}},\\\"version\\\":1}\"",
+ "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103",
+ "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a",
"devdoc": {
"version": 1,
"kind": "dev",
diff --git a/packages/contracts-bedrock/deployments/goerli/OptimismPortalProxy.json b/packages/contracts-bedrock/deployments/goerli/OptimismPortalProxy.json
index dd5bafb23076b..482f27c869c99 100644
--- a/packages/contracts-bedrock/deployments/goerli/OptimismPortalProxy.json
+++ b/packages/contracts-bedrock/deployments/goerli/OptimismPortalProxy.json
@@ -1,5 +1,5 @@
{
- "address": "0xC12B10618Cdf8195902E9f7DC8359a0Bc1ea2379",
+ "address": "0x1234662682c85fa6fB375416d14DB965Eba222ba",
"abi": [
{
"inputs": [
@@ -123,45 +123,49 @@
],
"stateMutability": "payable",
"type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
}
],
- "transactionHash": "0xbb0aeb35deaff2f93a6ea462d514b4462534d6aee5bd356585ede8044ae098d1",
+ "transactionHash": "0xcec244552f0ea450616b653dc83ac1d6c75a6208253868aea4623febb16cbeee",
"receipt": {
"to": null,
"from": "0x3a605B442055DF2898E18cF518feb2e2A6BD0D31",
- "contractAddress": "0xC12B10618Cdf8195902E9f7DC8359a0Bc1ea2379",
- "transactionIndex": 4,
- "gasUsed": "520158",
- "logsBloom": "0x00000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "blockHash": "0x2ad0808029fd9b077185eb37f589afb547da2f86d3860441cf44b62be4c91765",
- "transactionHash": "0xbb0aeb35deaff2f93a6ea462d514b4462534d6aee5bd356585ede8044ae098d1",
+ "contractAddress": "0x1234662682c85fa6fB375416d14DB965Eba222ba",
+ "transactionIndex": 0,
+ "gasUsed": "523812",
+ "logsBloom": "0x04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000200000000000000000000000000000000000000000000000000000000000",
+ "blockHash": "0xafce66a0a2446856112e4069b275ad32b1f4a607888f9c4c59eddf9be81f8670",
+ "transactionHash": "0xcec244552f0ea450616b653dc83ac1d6c75a6208253868aea4623febb16cbeee",
"logs": [
{
- "transactionIndex": 4,
- "blockNumber": 7209631,
- "transactionHash": "0xbb0aeb35deaff2f93a6ea462d514b4462534d6aee5bd356585ede8044ae098d1",
- "address": "0xC12B10618Cdf8195902E9f7DC8359a0Bc1ea2379",
+ "transactionIndex": 0,
+ "blockNumber": 7289810,
+ "transactionHash": "0xcec244552f0ea450616b653dc83ac1d6c75a6208253868aea4623febb16cbeee",
+ "address": "0x1234662682c85fa6fB375416d14DB965Eba222ba",
"topics": [
"0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"
],
"data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a605b442055df2898e18cf518feb2e2a6bd0d31",
- "logIndex": 7,
- "blockHash": "0x2ad0808029fd9b077185eb37f589afb547da2f86d3860441cf44b62be4c91765"
+ "logIndex": 0,
+ "blockHash": "0xafce66a0a2446856112e4069b275ad32b1f4a607888f9c4c59eddf9be81f8670"
}
],
- "blockNumber": 7209631,
- "cumulativeGasUsed": "954151",
+ "blockNumber": 7289810,
+ "cumulativeGasUsed": "523812",
"status": 1,
"byzantium": true
},
"args": [
"0x3a605B442055DF2898E18cF518feb2e2A6BD0D31"
],
- "numDeployments": 1,
- "solcInputHash": "599c82b18bfb932a0753a57de385b407",
- "metadata": "\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.10+commit.fc410830\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_admin\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"previousAdmin\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"newAdmin\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"AdminChanged\\\",\\\"type\\\":\\\"event\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"implementation\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"Upgraded\\\",\\\"type\\\":\\\"event\\\"},{\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"fallback\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"admin\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_admin\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"changeAdmin\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"implementation\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_implementation\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"upgradeTo\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_implementation\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"_data\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"name\\\":\\\"upgradeToAndCall\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"function\\\"}],\\\"devdoc\\\":{\\\"events\\\":{\\\"AdminChanged(address,address)\\\":{\\\"params\\\":{\\\"newAdmin\\\":\\\"The new owner of the contract\\\",\\\"previousAdmin\\\":\\\"The previous owner of the contract\\\"}},\\\"Upgraded(address)\\\":{\\\"params\\\":{\\\"implementation\\\":\\\"The address of the implementation contract\\\"}}},\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{\\\"admin()\\\":{\\\"returns\\\":{\\\"_0\\\":\\\"Owner address.\\\"}},\\\"changeAdmin(address)\\\":{\\\"params\\\":{\\\"_admin\\\":\\\"New owner of the proxy contract.\\\"}},\\\"constructor\\\":{\\\"params\\\":{\\\"_admin\\\":\\\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\\\"}},\\\"implementation()\\\":{\\\"returns\\\":{\\\"_0\\\":\\\"Implementation address.\\\"}},\\\"upgradeTo(address)\\\":{\\\"params\\\":{\\\"_implementation\\\":\\\"Address of the implementation contract.\\\"}},\\\"upgradeToAndCall(address,bytes)\\\":{\\\"params\\\":{\\\"_data\\\":\\\"Calldata to delegatecall the new implementation with.\\\",\\\"_implementation\\\":\\\"Address of the implementation contract.\\\"}}},\\\"title\\\":\\\"Proxy\\\",\\\"version\\\":1},\\\"userdoc\\\":{\\\"events\\\":{\\\"AdminChanged(address,address)\\\":{\\\"notice\\\":\\\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\\\"},\\\"Upgraded(address)\\\":{\\\"notice\\\":\\\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\\\"}},\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{\\\"admin()\\\":{\\\"notice\\\":\\\"Gets the owner of the proxy contract.\\\"},\\\"changeAdmin(address)\\\":{\\\"notice\\\":\\\"Changes the owner of the proxy contract. Only callable by the owner.\\\"},\\\"constructor\\\":{\\\"notice\\\":\\\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\\\"},\\\"implementation()\\\":{\\\"notice\\\":\\\"Queries the implementation address.\\\"},\\\"upgradeTo(address)\\\":{\\\"notice\\\":\\\"Set the implementation contract address. The code at the given address will execute when this contract is called.\\\"},\\\"upgradeToAndCall(address,bytes)\\\":{\\\"notice\\\":\\\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\\\"}},\\\"notice\\\":\\\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\\\",\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"contracts/universal/Proxy.sol\\\":\\\"Proxy\\\"},\\\"evmVersion\\\":\\\"london\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"none\\\"},\\\"optimizer\\\":{\\\"enabled\\\":true,\\\"runs\\\":999999},\\\"remappings\\\":[\\\":@openzeppelin/=node_modules/@openzeppelin/\\\",\\\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\\\",\\\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\\\",\\\":@rari-capital/=node_modules/@rari-capital/\\\",\\\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\\\",\\\":contracts/=contracts/\\\",\\\":ds-test/=node_modules/ds-test/src/\\\",\\\":excessively-safe-call/=node_modules/excessively-safe-call/\\\",\\\":forge-std/=node_modules/forge-std/src/\\\",\\\":test/=test/\\\"]},\\\"sources\\\":{\\\"contracts/universal/Proxy.sol\\\":{\\\"keccak256\\\":\\\"0xfbd3b9b280c82e08ed10690e0aa683cfa97417139f83349e89a38e01f9601422\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://579a350f080617001c0f747414e5160f7b1c571c381137a759b54d8278450531\\\",\\\"dweb:/ipfs/QmP2wjj8pGwXx64oYCGftF1XbKceMge9ByqxdrX8UjEdR9\\\"]}},\\\"version\\\":1}\"",
- "bytecode": "0x608060405234801561001057600080fd5b5060405161090738038061090783398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108e78339815191525490565b6000805160206108e7833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b6107f6806100f16000396000f3fe60806040526004361061005a5760003560e01c80635c60da1b116100435780635c60da1b146100ad5780638f283970146100e7578063f851a440146101075761005a565b80633659cfe6146100645780634f1ef28614610084575b61006261011c565b005b34801561007057600080fd5b5061006261007f3660046106c8565b610213565b6100976100923660046106e3565b610285565b6040516100a49190610766565b60405180910390f35b3480156100b957600080fd5b506100c2610408565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100a4565b3480156100f357600080fd5b506100626101023660046106c8565b61049f565b34801561011357600080fd5b506100c2610506565b60006101467f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff81166101f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061020d573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061026c575033155b1561027d5761027a81610592565b50565b61027a61011c565b60606102af7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102e6575033155b156103f9576102f484610592565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161031e9291906107d9565b600060405180830381855af49150503d8060008114610359576040519150601f19603f3d011682016040523d82523d6000602084013e61035e565b606091505b5091509150816103f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101e7565b91506104019050565b61040161011c565b9392505050565b60006104327fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610469575033155b1561049457507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b61049c61011c565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104f8575033155b1561027d5761027a816105fa565b60006105307fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610567575033155b1561049457507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106247fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106c357600080fd5b919050565b6000602082840312156106da57600080fd5b6104018261069f565b6000806000604084860312156106f857600080fd5b6107018461069f565b9250602084013567ffffffffffffffff8082111561071e57600080fd5b818601915086601f83011261073257600080fd5b81358181111561074157600080fd5b87602082850101111561075357600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b8181101561079357858101830151858201604001528201610777565b818111156107a5576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080a000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103",
- "deployedBytecode": "0x60806040526004361061005a5760003560e01c80635c60da1b116100435780635c60da1b146100ad5780638f283970146100e7578063f851a440146101075761005a565b80633659cfe6146100645780634f1ef28614610084575b61006261011c565b005b34801561007057600080fd5b5061006261007f3660046106c8565b610213565b6100976100923660046106e3565b610285565b6040516100a49190610766565b60405180910390f35b3480156100b957600080fd5b506100c2610408565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100a4565b3480156100f357600080fd5b506100626101023660046106c8565b61049f565b34801561011357600080fd5b506100c2610506565b60006101467f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff81166101f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061020d573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061026c575033155b1561027d5761027a81610592565b50565b61027a61011c565b60606102af7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102e6575033155b156103f9576102f484610592565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161031e9291906107d9565b600060405180830381855af49150503d8060008114610359576040519150601f19603f3d011682016040523d82523d6000602084013e61035e565b606091505b5091509150816103f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101e7565b91506104019050565b61040161011c565b9392505050565b60006104327fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610469575033155b1561049457507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b61049c61011c565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104f8575033155b1561027d5761027a816105fa565b60006105307fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610567575033155b1561049457507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106247fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106c357600080fd5b919050565b6000602082840312156106da57600080fd5b6104018261069f565b6000806000604084860312156106f857600080fd5b6107018461069f565b9250602084013567ffffffffffffffff8082111561071e57600080fd5b818601915086601f83011261073257600080fd5b81358181111561074157600080fd5b87602082850101111561075357600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b8181101561079357858101830151858201604001528201610777565b818111156107a5576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080a000a",
+ "numDeployments": 2,
+ "solcInputHash": "58f505918460d798ebe5c901024780d7",
+ "metadata": "\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.15+commit.e14f2714\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_admin\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"previousAdmin\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"newAdmin\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"AdminChanged\\\",\\\"type\\\":\\\"event\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"implementation\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"Upgraded\\\",\\\"type\\\":\\\"event\\\"},{\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"fallback\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"admin\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_admin\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"changeAdmin\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"implementation\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_implementation\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"upgradeTo\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_implementation\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"_data\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"name\\\":\\\"upgradeToAndCall\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"function\\\"},{\\\"stateMutability\\\":\\\"payable\\\",\\\"type\\\":\\\"receive\\\"}],\\\"devdoc\\\":{\\\"events\\\":{\\\"AdminChanged(address,address)\\\":{\\\"params\\\":{\\\"newAdmin\\\":\\\"The new owner of the contract\\\",\\\"previousAdmin\\\":\\\"The previous owner of the contract\\\"}},\\\"Upgraded(address)\\\":{\\\"params\\\":{\\\"implementation\\\":\\\"The address of the implementation contract\\\"}}},\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{\\\"admin()\\\":{\\\"returns\\\":{\\\"_0\\\":\\\"Owner address.\\\"}},\\\"changeAdmin(address)\\\":{\\\"params\\\":{\\\"_admin\\\":\\\"New owner of the proxy contract.\\\"}},\\\"constructor\\\":{\\\"params\\\":{\\\"_admin\\\":\\\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\\\"}},\\\"implementation()\\\":{\\\"returns\\\":{\\\"_0\\\":\\\"Implementation address.\\\"}},\\\"upgradeTo(address)\\\":{\\\"params\\\":{\\\"_implementation\\\":\\\"Address of the implementation contract.\\\"}},\\\"upgradeToAndCall(address,bytes)\\\":{\\\"params\\\":{\\\"_data\\\":\\\"Calldata to delegatecall the new implementation with.\\\",\\\"_implementation\\\":\\\"Address of the implementation contract.\\\"}}},\\\"title\\\":\\\"Proxy\\\",\\\"version\\\":1},\\\"userdoc\\\":{\\\"events\\\":{\\\"AdminChanged(address,address)\\\":{\\\"notice\\\":\\\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\\\"},\\\"Upgraded(address)\\\":{\\\"notice\\\":\\\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\\\"}},\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{\\\"admin()\\\":{\\\"notice\\\":\\\"Gets the owner of the proxy contract.\\\"},\\\"changeAdmin(address)\\\":{\\\"notice\\\":\\\"Changes the owner of the proxy contract. Only callable by the owner.\\\"},\\\"constructor\\\":{\\\"notice\\\":\\\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\\\"},\\\"implementation()\\\":{\\\"notice\\\":\\\"Queries the implementation address.\\\"},\\\"upgradeTo(address)\\\":{\\\"notice\\\":\\\"Set the implementation contract address. The code at the given address will execute when this contract is called.\\\"},\\\"upgradeToAndCall(address,bytes)\\\":{\\\"notice\\\":\\\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\\\"}},\\\"notice\\\":\\\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\\\",\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"contracts/universal/Proxy.sol\\\":\\\"Proxy\\\"},\\\"evmVersion\\\":\\\"london\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"none\\\"},\\\"optimizer\\\":{\\\"enabled\\\":true,\\\"runs\\\":999999},\\\"remappings\\\":[\\\":@eth-optimism/contracts-periphery/=node_modules/@eth-optimism/contracts-periphery/contracts/\\\",\\\":@openzeppelin/=node_modules/@openzeppelin/\\\",\\\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\\\",\\\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\\\",\\\":@rari-capital/=node_modules/@rari-capital/\\\",\\\":@rari-capital/solmate/=node_modules/@rari-capital/solmate/\\\",\\\":contracts/=contracts/\\\",\\\":ds-test/=node_modules/ds-test/src/\\\",\\\":excessively-safe-call/=node_modules/excessively-safe-call/\\\",\\\":forge-std/=node_modules/forge-std/src/\\\"]},\\\"sources\\\":{\\\"contracts/universal/Proxy.sol\\\":{\\\"keccak256\\\":\\\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://8f2247604d527f560edbb851c43b6c16b37e34972ddb305e16dd73623b8288cd\\\",\\\"dweb:/ipfs/QmfM8sLAZrxrnqyRdt1XJ5LyJh4wKbeEqk3VkvxG7BDqFj\\\"]}},\\\"version\\\":1}\"",
+ "bytecode": "0x608060405234801561001057600080fd5b5060405161091838038061091883398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206108f88339815191525490565b6000805160206108f8833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610807806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103",
+ "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a",
"devdoc": {
"version": 1,
"kind": "dev",
diff --git a/packages/contracts-bedrock/foundry.toml b/packages/contracts-bedrock/foundry.toml
index a6ff109d2ba02..0a5b63e7a64ba 100644
--- a/packages/contracts-bedrock/foundry.toml
+++ b/packages/contracts-bedrock/foundry.toml
@@ -1,4 +1,4 @@
-[default]
+[profile.default]
src = 'contracts'
out = 'forge-artifacts'
optimizer = true
@@ -16,8 +16,9 @@ remappings = [
extra_output = ['devdoc', 'userdoc', 'metadata', 'storageLayout']
bytecode_hash = 'none'
build_info = true
+build_info_path = 'artifacts/build-info'
ffi = true
fuzz_runs = 16
-[ci]
+[profile.ci]
fuzz_runs = 512
diff --git a/packages/contracts-bedrock/hardhat.config.ts b/packages/contracts-bedrock/hardhat.config.ts
index ac1579be21e74..ba22ed99d886d 100644
--- a/packages/contracts-bedrock/hardhat.config.ts
+++ b/packages/contracts-bedrock/hardhat.config.ts
@@ -9,11 +9,7 @@ import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy'
// Hardhat tasks
-import './tasks/genesis-l1'
-import './tasks/genesis-l2'
-import './tasks/deposits'
-import './tasks/rekey'
-import './tasks/rollup-config'
+import './tasks'
subtask(TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS).setAction(
async (_, __, runSuper) => {
@@ -44,6 +40,11 @@ const config: HardhatUserConfig = {
url: process.env.L1_RPC || '',
accounts: [process.env.PRIVATE_KEY_DEPLOYER || ethers.constants.HashZero],
},
+ deployer: {
+ chainId: Number(process.env.CHAIN_ID),
+ url: process.env.L1_RPC || '',
+ accounts: [process.env.PRIVATE_KEY_DEPLOYER || ethers.constants.HashZero],
+ },
},
foundry: {
buildInfo: true,
@@ -72,18 +73,15 @@ const config: HardhatUserConfig = {
historicalBlocks: {
type: 'number',
},
- startingBlockNumber: {
- type: 'number',
- },
- startingTimestamp: {
- type: 'number',
- },
sequencerAddress: {
type: 'address',
},
outputOracleOwner: {
type: 'address',
},
+ l1StartingBlockTag: {
+ type: 'string',
+ },
},
external: {
contracts: [
diff --git a/packages/contracts-bedrock/package.json b/packages/contracts-bedrock/package.json
index 26a6f2209c7ed..3f51ae9fe489c 100644
--- a/packages/contracts-bedrock/package.json
+++ b/packages/contracts-bedrock/package.json
@@ -8,19 +8,20 @@
"files": [
"dist/**/*.js",
"dist/**/*.d.ts",
- "dist/types/*.ts",
+ "dist/types/**/*.ts",
"artifacts/contracts/**/*.json",
"deployments/**/*.json",
"contracts/**/*.sol"
],
"scripts": {
"build:forge": "forge build",
+ "build:differential": "tsc scripts/differential-testing.ts --outDir dist --moduleResolution node --esModuleInterop",
"prebuild": "yarn ts-node scripts/verifyFoundryInstall.ts",
"build": "hardhat compile && yarn autogen:artifacts && yarn build:ts && yarn typechain",
"build:ts": "tsc -p tsconfig.json",
"autogen:artifacts": "ts-node scripts/generate-artifacts.ts",
"deploy": "hardhat deploy",
- "test": "yarn build:ts && forge test",
+ "test": "yarn build:differential && forge test",
"gas-snapshot": "forge snapshot",
"storage-snapshot": "./scripts/storage-snapshot.sh",
"slither": "./scripts/slither.sh",
@@ -36,30 +37,29 @@
},
"dependencies": {
"@eth-optimism/core-utils": "^0.9.2",
- "@ethereumjs/trie": "^5.0.0-beta.1",
- "@ethereumjs/util": "^8.0.0-beta.1",
- "@openzeppelin/contracts": "^4.5.0",
- "@openzeppelin/contracts-upgradeable": "^4.5.2",
+ "@openzeppelin/contracts": "4.6.0",
+ "@openzeppelin/contracts-upgradeable": "4.7.1",
"@rari-capital/solmate": "https://github.com/rari-capital/solmate.git#8f9b23f8838670afda0fd8983f2c41e8037ae6bc",
- "bip39": "^3.0.4",
"ds-test": "https://github.com/dapphub/ds-test.git#9310e879db8ba3ea6d5c6489a579118fd264a3f5",
- "ethereumjs-wallet": "^1.0.2",
"ethers": "^5.6.8",
- "excessively-safe-call": "https://github.com/nomad-xyz/ExcessivelySafeCall.git#4fcdfd3593d21381f696c790fa6180b8ef559c1e",
+ "excessively-safe-call": "https://github.com/nomad-xyz/ExcessivelySafeCall.git#81cd99ce3e69117d665d7601c330ea03b97acce0",
"forge-std": "https://github.com/foundry-rs/forge-std.git#f18682b2874fc57d7c80a511fed0b35ec4201ffa",
- "hardhat": "^2.9.6",
- "merkle-patricia-tree": "^4.2.4",
- "rlp": "^2.2.7"
+ "hardhat": "^2.9.6"
},
"devDependencies": {
"@eth-optimism/hardhat-deploy-config": "^0.2.1",
+ "@ethereumjs/trie": "^5.0.0-beta.1",
+ "@ethereumjs/util": "^8.0.0-beta.1",
+ "ethereumjs-wallet": "^1.0.2",
"@defi-wonderland/smock": "^2.0.2",
- "@foundry-rs/hardhat-forge": "^0.1.12",
+ "@foundry-rs/hardhat-forge": "^0.1.16",
+ "@foundry-rs/easy-foundryup": "^0.1.3",
"@nomiclabs/hardhat-ethers": "^2.0.0",
"@nomiclabs/hardhat-waffle": "^2.0.0",
"@typechain/ethers-v5": "^10.1.0",
"@typescript-eslint/eslint-plugin": "^5.26.0",
"@typescript-eslint/parser": "^4.29.1",
+ "bip39": "^3.0.4",
"chai": "^4.2.0",
"command-exists": "1.2.9",
"dotenv": "^16.0.0",
diff --git a/packages/contracts-bedrock/scripts/differential-testing.ts b/packages/contracts-bedrock/scripts/differential-testing.ts
index 5ed83b01a4fa4..849911b86ca17 100644
--- a/packages/contracts-bedrock/scripts/differential-testing.ts
+++ b/packages/contracts-bedrock/scripts/differential-testing.ts
@@ -93,6 +93,7 @@ const command = args[0]
value,
gas,
data,
+ isSystemTransaction: false,
domain: SourceHashDomain.UserDeposit,
})
@@ -101,6 +102,34 @@ const command = args[0]
process.stdout.write(output)
break
}
+ case 'encodeDepositTransaction': {
+ const from = args[1]
+ const to = args[2]
+ const value = BigNumber.from(args[3])
+ const mint = BigNumber.from(args[4])
+ const gasLimit = BigNumber.from(args[5])
+ const isCreate = args[6] === 'true' ? true : false
+ const data = args[7]
+ const l1BlockHash = args[8]
+ const logIndex = BigNumber.from(args[9])
+
+ const tx = new DepositTx({
+ from,
+ to: isCreate ? null : to,
+ value,
+ mint,
+ gas: gasLimit,
+ data,
+ l1BlockHash,
+ logIndex,
+ domain: SourceHashDomain.UserDeposit,
+ })
+
+ const raw = tx.encode()
+ const output = utils.defaultAbiCoder.encode(['bytes'], [raw])
+ process.stdout.write(output)
+ break
+ }
case 'hashWithdrawal': {
const nonce = BigNumber.from(args[1])
const sender = args[2]
diff --git a/packages/contracts-bedrock/scripts/slither.sh b/packages/contracts-bedrock/scripts/slither.sh
index 49f48c8908f35..7aa2f8a0ddcac 100755
--- a/packages/contracts-bedrock/scripts/slither.sh
+++ b/packages/contracts-bedrock/scripts/slither.sh
@@ -1,8 +1,11 @@
#!/bin/bash
-if [ ! -d forge-artifacts/build-info ]; then
- npx hardhat compile
-fi
+rm -rf artifacts forge-artifacts
+
+# Handle slither bug unable to work with the foundry tests
+TEMP=$(mktemp -d)
+mv contracts/test $TEMP/test
-cp -rf forge-artifacts/build-info artifacts/build-info
slither .
+
+mv $TEMP/test contracts/test
diff --git a/packages/contracts-bedrock/tasks/check-l2-config.ts b/packages/contracts-bedrock/tasks/check-l2-config.ts
new file mode 100644
index 0000000000000..4c730489ac9c6
--- /dev/null
+++ b/packages/contracts-bedrock/tasks/check-l2-config.ts
@@ -0,0 +1,31 @@
+import { task, types } from 'hardhat/config'
+import { providers } from 'ethers'
+import '@nomiclabs/hardhat-ethers'
+
+import { predeploys, getContractInterface } from '../src'
+
+task('check-l2-config', 'Validate L2 config')
+ .addParam(
+ 'l2ProviderUrl',
+ 'L2 provider URL.',
+ 'http://localhost:9545',
+ types.string
+ )
+ .setAction(async (args, hre) => {
+ const { l2ProviderUrl } = args
+ const l2Provider = new providers.JsonRpcProvider(l2ProviderUrl)
+
+ const OptimismMintableERC20Factory = new hre.ethers.Contract(
+ predeploys.OptimismMintableERC20Factory,
+ getContractInterface('OptimismMintableERC20Factory'),
+ l2Provider
+ )
+
+ const bridge = await OptimismMintableERC20Factory.bridge()
+ console.log(`OptimismMintableERC20Factory.bridge() -> ${bridge}`)
+ if (bridge !== predeploys.L2StandardBridge) {
+ throw new Error(
+ `L2StandardBridge not set correctly. Got ${bridge}, expected ${predeploys.L2StandardBridge}`
+ )
+ }
+ })
diff --git a/packages/contracts-bedrock/tasks/check-op-node.ts b/packages/contracts-bedrock/tasks/check-op-node.ts
new file mode 100644
index 0000000000000..bf32274f4f1ec
--- /dev/null
+++ b/packages/contracts-bedrock/tasks/check-op-node.ts
@@ -0,0 +1,20 @@
+import { task, types } from 'hardhat/config'
+import { OpNodeProvider } from '@eth-optimism/core-utils'
+
+// TODO(tynes): add in config validation
+task('check-op-node', 'Validate the config of the op-node')
+ .addParam(
+ 'opNodeUrl',
+ 'URL of the OP Node.',
+ 'http://localhost:7545',
+ types.string
+ )
+ .setAction(async (args) => {
+ const provider = new OpNodeProvider(args.opNodeUrl)
+
+ const syncStatus = await provider.syncStatus()
+ console.log(JSON.stringify(syncStatus, null, 2))
+
+ const config = await provider.rollupConfig()
+ console.log(JSON.stringify(config, null, 2))
+ })
diff --git a/packages/contracts-bedrock/tasks/forge-verify.ts b/packages/contracts-bedrock/tasks/forge-verify.ts
new file mode 100644
index 0000000000000..767c05a3ef22e
--- /dev/null
+++ b/packages/contracts-bedrock/tasks/forge-verify.ts
@@ -0,0 +1,128 @@
+import { spawn as spawn } from 'child_process'
+
+import { task, types } from 'hardhat/config'
+import * as foundryup from '@foundry-rs/easy-foundryup'
+import 'hardhat-deploy'
+import { ethers } from 'ethers'
+
+interface ForgeVerifyArgs {
+ chainId: string
+ compilerVersion: string
+ constructorArgs: string
+ optimizerRuns: number
+ contractAddress: string
+ contractName: string
+ etherscanApiKey: string
+}
+
+const verifyArgs = (opts: ForgeVerifyArgs): string[] => {
+ const allArgs: string[] = []
+
+ if (!opts.chainId) {
+ throw new Error(`No chain-id provided`)
+ }
+ allArgs.push(`--chain`, opts.chainId)
+
+ if (opts.compilerVersion) {
+ allArgs.push('--compiler-version', opts.compilerVersion)
+ }
+ if (opts.constructorArgs) {
+ allArgs.push('--constructor-args', opts.constructorArgs)
+ }
+ if (typeof opts.optimizerRuns === 'number') {
+ allArgs.push('--num-of-optimizations', opts.optimizerRuns.toString())
+ }
+ allArgs.push('--watch')
+
+ if (!opts.contractAddress) {
+ throw new Error('No contract address provided')
+ }
+ allArgs.push(opts.contractAddress)
+ if (!opts.contractName) {
+ throw new Error('No contract name provided')
+ }
+ allArgs.push(opts.contractName)
+ if (!opts.etherscanApiKey) {
+ throw new Error('No Etherscan API key provided')
+ }
+ allArgs.push(opts.etherscanApiKey)
+ return allArgs
+}
+
+const spawnVerify = async (opts: ForgeVerifyArgs): Promise => {
+ const args = ['verify-contract', ...verifyArgs(opts)]
+ const forgeCmd = await foundryup.getForgeCommand()
+ return new Promise((resolve) => {
+ const process = spawn(forgeCmd, args, {
+ stdio: 'inherit',
+ })
+ process.on('exit', (code) => {
+ resolve(code === 0)
+ })
+ })
+}
+
+task('forge-contract-verify', 'Verify contracts using forge')
+ .addOptionalParam(
+ 'contract',
+ 'Name of the contract to verify',
+ '',
+ types.string
+ )
+ .addOptionalParam(
+ 'etherscanApiKey',
+ 'Etherscan API key',
+ process.env.ETHERSCAN_API_KEY,
+ types.string
+ )
+ .setAction(async (args, hre) => {
+ const deployments = await hre.deployments.all()
+ if (args.contract !== '') {
+ if (!deployments[args.contract]) {
+ throw new Error(
+ `Contract ${args.contract} not found in ${hre.network} deployments`
+ )
+ }
+ }
+
+ for (const [contract, deployment] of Object.entries(deployments)) {
+ if (args.contract !== '' && args.contract !== contract) {
+ continue
+ }
+
+ const chainId = await hre.getChainId()
+ const contractAddress = deployment.address
+ const etherscanApiKey = args.etherscanApiKey
+
+ let metadata = deployment.metadata as any
+ // Handle double nested JSON stringify
+ while (typeof metadata === 'string') {
+ metadata = JSON.parse(metadata) as any
+ }
+
+ const contractName = Object.values(
+ metadata.settings.compilationTarget
+ )[0].toString()
+ const compilerVersion = metadata.compiler.version
+
+ const iface = new ethers.utils.Interface(deployment.abi)
+ const constructorArgs = iface.encodeDeploy(deployment.args)
+ const optimizerRuns = metadata.settings.optimizer
+
+ const success = await spawnVerify({
+ chainId,
+ compilerVersion,
+ constructorArgs,
+ optimizerRuns,
+ contractAddress,
+ contractName,
+ etherscanApiKey,
+ })
+
+ if (success) {
+ console.log(`Contract verification successful for ${contractName}`)
+ } else {
+ console.log(`Contract verification unsuccesful for ${contractName}`)
+ }
+ }
+ })
diff --git a/packages/contracts-bedrock/tasks/genesis-l1.ts b/packages/contracts-bedrock/tasks/genesis-l1.ts
index e01043582f545..deac7649c1161 100644
--- a/packages/contracts-bedrock/tasks/genesis-l1.ts
+++ b/packages/contracts-bedrock/tasks/genesis-l1.ts
@@ -61,7 +61,7 @@ task('genesis-l1', 'create a genesis config')
}
}
- const timestamp = hre.deployConfig.startingTimestamp
+ const timestamp = hre.deployConfig.l1GenesisTimestamp
if (timestamp === undefined) {
throw new Error('Must configure starting block timestamp')
}
diff --git a/packages/contracts-bedrock/tasks/genesis-l2.ts b/packages/contracts-bedrock/tasks/genesis-l2.ts
index 7aa1d1fab1fba..60a3de25e4c68 100644
--- a/packages/contracts-bedrock/tasks/genesis-l2.ts
+++ b/packages/contracts-bedrock/tasks/genesis-l2.ts
@@ -5,12 +5,19 @@ import assert from 'assert'
import { OptimismGenesis, State } from '@eth-optimism/core-utils'
import 'hardhat-deploy'
import '@eth-optimism/hardhat-deploy-config'
-import { ethers } from 'ethers'
+import { ethers, utils, BigNumber } from 'ethers'
import { task } from 'hardhat/config'
import { HardhatRuntimeEnvironment } from 'hardhat/types'
+import {
+ CompilerOutputSource,
+ CompilerOutputContract,
+ BuildInfo,
+} from 'hardhat/types/artifacts'
import { predeploys } from '../src'
+const { hexZeroPad, hexConcat, hexDataSlice, getAddress } = utils
+
const prefix = '0x420000000000000000000000000000000000'
const implementationSlot =
'0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc'
@@ -18,11 +25,16 @@ const adminSlot =
'0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103'
const toCodeAddr = (addr: string) => {
- const address = ethers.utils.hexConcat([
+ const address = hexConcat([
'0xc0d3c0d3c0d3c0d3c0d3c0d3c0d3c0d3c0d3',
'0x' + addr.slice(prefix.length),
])
- return ethers.utils.getAddress(address)
+ return getAddress(address)
+}
+
+const toBytes32 = (num: number): string => {
+ const big = BigNumber.from(num)
+ return hexZeroPad(big.toHexString(), 32)
}
const assertEvenLength = (str: string) => {
@@ -46,6 +58,141 @@ const getStorageLayout = async (
throw new Error(`Cannot locate storageLayout for ${name}`)
}
+// Find the contract and source from the build info
+const findContractAndSource = (name: string, buildInfo: BuildInfo) => {
+ const sources = buildInfo.output.sources
+ const contracts = buildInfo.output.contracts
+
+ const compilerOutputContracts: CompilerOutputContract[] = []
+ for (const [contractName, contract] of Object.entries(contracts)) {
+ if (path.basename(contractName, '.sol') === name) {
+ compilerOutputContracts.push(contract[name])
+ }
+ }
+ if (compilerOutputContracts.length === 0) {
+ throw new Error(`Cannot find compiler output contract for ${name}`)
+ }
+ if (compilerOutputContracts.length !== 1) {
+ console.log(`Unexpected number of contracts for ${name}`)
+ }
+ const outputContract = compilerOutputContracts[0]
+
+ const compilerOutputSources: CompilerOutputSource[] = []
+ for (const [contractName, source] of Object.entries(sources)) {
+ if (path.basename(contractName, '.sol') === name) {
+ compilerOutputSources.push(source as CompilerOutputSource)
+ }
+ }
+ if (compilerOutputSources.length === 0) {
+ throw new Error(`Cannot find compiler output source for ${name}`)
+ }
+ if (compilerOutputSources.length !== 1) {
+ console.log(`Unexpected number of sources for ${name}`)
+ }
+ const outputSource = compilerOutputSources[0]
+
+ return { outputContract, outputSource }
+}
+
+const replaceImmutables = async (
+ hre: HardhatRuntimeEnvironment,
+ name: string,
+ immutables: object
+): Promise => {
+ const artifact = await hre.artifacts.readArtifact(name)
+ const buildInfo = await hre.artifacts.getBuildInfo(name)
+
+ const { outputContract, outputSource } = findContractAndSource(
+ name,
+ buildInfo
+ )
+
+ // Get the immutable references. They look like this:
+ // { ast-id: [ {start, length} ] }
+ const immutableReferences =
+ outputContract.evm.deployedBytecode.immutableReferences
+
+ const names = {}
+ // Recursively find all of the immutables by traversing the solc output ast
+ const findNames = (ast: any) => {
+ // Add the name of the variable if it is an immutable
+ const isImmutable = ast.mutability === 'immutable'
+ const isASTNode = typeof ast.name === 'string' && typeof ast.id === 'number'
+ if (isASTNode && isImmutable) {
+ names[ast.name] = ast.id
+ }
+ // Iterate over each node
+ if (Array.isArray(ast.nodes)) {
+ for (const node of ast.nodes) {
+ findNames(node)
+ }
+ }
+ // Handle contracts that are inherited from
+ if (Array.isArray(ast.baseContracts)) {
+ for (const baseContract of ast.baseContracts) {
+ if (baseContract.baseName) {
+ const base = findContractAndSource(
+ baseContract.baseName.name,
+ buildInfo
+ )
+ findNames(base.outputSource.ast)
+ }
+ }
+ }
+ }
+
+ findNames(outputSource.ast)
+
+ let deployedBytecode = artifact.deployedBytecode
+ const presize = deployedBytecode.length
+
+ // For each of the immutables, put the value into the bytecode
+ for (const [key, value] of Object.entries(immutables)) {
+ const astId = names[key]
+ if (!astId) {
+ throw new Error(`Unknown immutable ${key} in contract ${name}`)
+ }
+ const offsets = immutableReferences[astId]
+ if (!offsets) {
+ throw new Error(`Unknown AST id ${astId} in contract ${name}`)
+ }
+
+ // Insert the value at each one
+ for (const offset of offsets) {
+ if (offset.length !== 32) {
+ throw new Error(
+ `Immutable slicing must be updated to handle arbitrary size immutables`
+ )
+ }
+
+ // Ensure that the value being sliced out is 0
+ const val = hexDataSlice(
+ deployedBytecode,
+ offset.start,
+ offset.start + offset.length
+ )
+ if (!BigNumber.from(val).eq(0)) {
+ throw new Error(`Unexpected value in immutable bytecode ${val}`)
+ }
+
+ deployedBytecode = ethers.utils.hexConcat([
+ hexDataSlice(deployedBytecode, 0, offset.start),
+ hexZeroPad(value, 32),
+ hexDataSlice(deployedBytecode, offset.start + offset.length),
+ ])
+ }
+ }
+
+ // Ensure that the bytecode is the same size
+ if (presize !== deployedBytecode.length) {
+ throw new Error(
+ `Size mismatch! Before ${presize}, after ${deployedBytecode.length}`
+ )
+ }
+
+ return deployedBytecode
+}
+
task('genesis-l2', 'create a genesis config')
.addOptionalParam(
'outfile',
@@ -138,7 +285,7 @@ task('genesis-l2', 'create a genesis config')
const predeployAddrs = new Set()
for (const addr of Object.values(predeploys)) {
- predeployAddrs.add(ethers.utils.getAddress(addr))
+ predeployAddrs.add(getAddress(addr))
}
const alloc: State = {}
@@ -146,15 +293,13 @@ task('genesis-l2', 'create a genesis config')
// Set a proxy at each predeploy address
const proxy = await hre.artifacts.readArtifact('Proxy')
for (let i = 0; i <= 2048; i++) {
- const num = ethers.utils.hexZeroPad('0x' + i.toString(16), 2)
- const addr = ethers.utils.getAddress(
- ethers.utils.hexConcat([prefix, num])
- )
+ const num = hexZeroPad('0x' + i.toString(16), 2)
+ const addr = getAddress(ethers.utils.hexConcat([prefix, num]))
// There is no proxy at LegacyERC20ETH or the GovernanceToken
if (
- addr === ethers.utils.getAddress(predeploys.LegacyERC20ETH) ||
- addr === ethers.utils.getAddress(predeploys.GovernanceToken)
+ addr === getAddress(predeploys.LegacyERC20ETH) ||
+ addr === getAddress(predeploys.GovernanceToken)
) {
continue
}
@@ -168,9 +313,9 @@ task('genesis-l2', 'create a genesis config')
},
}
- if (predeployAddrs.has(ethers.utils.getAddress(addr))) {
+ if (predeployAddrs.has(getAddress(addr))) {
const predeploy = Object.entries(predeploys).find(([, address]) => {
- return ethers.utils.getAddress(address) === addr
+ return getAddress(address) === addr
})
// Really shouldn't happen, since predeployAddrs is a set generated from predeploys.
@@ -211,7 +356,7 @@ task('genesis-l2', 'create a genesis config')
buf.writeUInt16BE(i, 0)
const addr = ethers.utils.hexConcat([
'0x000000000000000000000000000000000000',
- ethers.utils.hexZeroPad(buf, 2),
+ hexZeroPad(buf, 2),
])
alloc[addr] = {
balance: '0x1',
@@ -251,6 +396,44 @@ task('genesis-l2', 'create a genesis config')
}
}
+ // Note: this currently only supports up to 32 byte values.
+ // Things less than 32 bytes will be left padded with 0 bytes
+ const immutables = {
+ OptimismMintableERC20Factory: {
+ bridge: predeploys.L2StandardBridge,
+ },
+ GasPriceOracle: {
+ MAJOR_VERSION: toBytes32(0),
+ MINOR_VERSION: toBytes32(0),
+ PATCH_VERSION: toBytes32(1),
+ },
+ L1Block: {
+ MAJOR_VERSION: toBytes32(0),
+ MINOR_VERSION: toBytes32(0),
+ PATCH_VERSION: toBytes32(1),
+ },
+ L2CrossDomainMessenger: {
+ MAJOR_VERSION: toBytes32(0),
+ MINOR_VERSION: toBytes32(0),
+ PATCH_VERSION: toBytes32(1),
+ },
+ L2StandardBridge: {
+ MAJOR_VERSION: toBytes32(0),
+ MINOR_VERSION: toBytes32(0),
+ PATCH_VERSION: toBytes32(1),
+ },
+ L2ToL1MessagePasser: {
+ MAJOR_VERSION: toBytes32(0),
+ MINOR_VERSION: toBytes32(0),
+ PATCH_VERSION: toBytes32(1),
+ },
+ SequencerFeeVault: {
+ MAJOR_VERSION: toBytes32(0),
+ MINOR_VERSION: toBytes32(0),
+ PATCH_VERSION: toBytes32(1),
+ },
+ }
+
// Set the predeploys in the state
for (const [name, addr] of Object.entries(predeploys)) {
if (name === 'GovernanceToken') {
@@ -262,16 +445,35 @@ task('genesis-l2', 'create a genesis config')
const allocAddr = name === 'LegacyERC20ETH' ? addr : toCodeAddr(addr)
assertEvenLength(allocAddr)
+ const immutableConfig = immutables[name]
+ const deployedBytecode = immutableConfig
+ ? await replaceImmutables(hre, name, immutableConfig)
+ : artifact.deployedBytecode
+
+ assertEvenLength(deployedBytecode)
+
+ // TODO(tynes): initialize contracts that should be initialized
+ // in the implementations here
alloc[allocAddr] = {
nonce: '0x00',
balance: '0x00',
- code: artifact.deployedBytecode,
+ code: deployedBytecode,
storage: {},
}
}
- const portal = await hre.deployments.get('OptimismPortalProxy')
- const l1StartingBlock = await l1.getBlock(portal.receipt.blockHash)
+ const l1StartingBlock = await l1.getBlock(deployConfig.l1StartingBlockTag)
+ if (l1StartingBlock === null) {
+ throw new Error(
+ `Cannot fetch block tag ${deployConfig.l1StartingBlockTag}`
+ )
+ }
+
+ if (l1StartingBlock === null) {
+ console.log(`Unable to fetch L1 starting timestamp`)
+ }
+
+ const startingTimestamp = l1StartingBlock?.timestamp || 0
const genesis: OptimismGenesis = {
config: {
@@ -296,7 +498,7 @@ task('genesis-l2', 'create a genesis config')
},
nonce: '0x1234',
difficulty: '0x1',
- timestamp: ethers.BigNumber.from(l1StartingBlock.timestamp).toHexString(),
+ timestamp: ethers.BigNumber.from(startingTimestamp).toHexString(),
gasLimit: deployConfig.genesisBlockGasLimit,
extraData: deployConfig.genesisBlockExtradata,
alloc,
diff --git a/packages/contracts-bedrock/tasks/index.ts b/packages/contracts-bedrock/tasks/index.ts
new file mode 100644
index 0000000000000..5d8bf450bc836
--- /dev/null
+++ b/packages/contracts-bedrock/tasks/index.ts
@@ -0,0 +1,9 @@
+import './genesis-l1'
+import './genesis-l2'
+import './deposits'
+import './rekey'
+import './rollup-config'
+import './check-op-node'
+import './check-l2-config'
+import './watch'
+import './forge-verify'
diff --git a/packages/contracts-bedrock/tasks/rollup-config.ts b/packages/contracts-bedrock/tasks/rollup-config.ts
index 268d2b39e47fe..f80b0d5233410 100644
--- a/packages/contracts-bedrock/tasks/rollup-config.ts
+++ b/packages/contracts-bedrock/tasks/rollup-config.ts
@@ -23,13 +23,18 @@ task('rollup-config', 'create a genesis config')
const l2Genesis = await l2.getBlock('earliest')
const portal = await hre.deployments.get('OptimismPortalProxy')
- const l1StartingBlock = await l1.getBlock(portal.receipt.blockHash)
+ const l1StartingBlock = await l1.getBlock(deployConfig.l1StartingBlockTag)
+ if (l1StartingBlock === null) {
+ throw new Error(
+ `Cannot fetch block tag ${deployConfig.l1StartingBlockTag}`
+ )
+ }
const config: OpNodeConfig = {
genesis: {
l1: {
- hash: portal.receipt.blockHash,
- number: portal.receipt.blockNumber,
+ hash: l1StartingBlock.hash,
+ number: l1StartingBlock.number,
},
l2: {
hash: l2Genesis.hash,
diff --git a/packages/contracts-bedrock/tasks/watch.ts b/packages/contracts-bedrock/tasks/watch.ts
new file mode 100644
index 0000000000000..0c6687950a294
--- /dev/null
+++ b/packages/contracts-bedrock/tasks/watch.ts
@@ -0,0 +1,156 @@
+import { task, types } from 'hardhat/config'
+import '@nomiclabs/hardhat-ethers'
+import 'hardhat-deploy'
+import { OpNodeProvider, sleep } from '@eth-optimism/core-utils'
+
+import { predeploys } from '../src'
+
+task('watch', 'Watch an Optimism System')
+ .addParam(
+ 'l1ProviderUrl',
+ 'L1 provider URL.',
+ 'http://localhost:8545',
+ types.string
+ )
+ .addParam(
+ 'l2ProviderUrl',
+ 'L2 provider URL.',
+ 'http://localhost:9545',
+ types.string
+ )
+ .addParam(
+ 'opNodeProviderUrl',
+ 'op-node provider URL',
+ 'http://localhost:7545',
+ types.string
+ )
+ .setAction(async (args, hre) => {
+ const { utils } = hre.ethers
+
+ const l1Provider = new hre.ethers.providers.StaticJsonRpcProvider(
+ args.l1Provider
+ )
+ const l2Provider = new hre.ethers.providers.StaticJsonRpcProvider(
+ args.l2ProviderUrl
+ )
+
+ const contracts = {}
+ const deployments = await hre.deployments.all()
+ for (const [contract, deployment] of Object.entries(deployments)) {
+ contracts[contract] = deployment.address
+ }
+ console.log('Deployed Contracts')
+ console.table(contracts)
+
+ const opNodeProvider = new OpNodeProvider(args.opNodeProviderUrl)
+ const opNodeConfig = await opNodeProvider.rollupConfig()
+ console.log('op-node config')
+ console.table({
+ 'layer-one-hash': opNodeConfig.genesis.l1.hash,
+ 'layer-one-number': opNodeConfig.genesis.l1.number,
+ 'layer-two-hash': opNodeConfig.genesis.l2.hash,
+ 'layer-two-number': opNodeConfig.genesis.l2.number,
+ 'layer-two-time': opNodeConfig.genesis.l2_time,
+ 'block-time': opNodeConfig.block_time,
+ 'max-sequencer-drift': opNodeConfig.max_sequencer_drift,
+ 'seq-window-size': opNodeConfig.seq_window_size,
+ 'channel-timeout': opNodeConfig.channel_timeout,
+ 'l1-chain-id': opNodeConfig.l1_chain_id,
+ 'l2-chain-id': opNodeConfig.l2_chain_id,
+ 'p2p-sequencer-address': opNodeConfig.p2p_sequencer_address,
+ 'fee-recipient-address': opNodeConfig.fee_recipient_address,
+ 'batch-inbox-address': opNodeConfig.batch_inbox_address,
+ 'batch-sender-address': opNodeConfig.batch_sender_address,
+ 'deposit-contract-address': opNodeConfig.deposit_contract_address,
+ })
+
+ const Deployment__L2OutputOracle = await hre.deployments.get(
+ 'L2OutputOracle'
+ )
+
+ const Deployment__L2OutputOracleProxy = await hre.deployments.get(
+ 'L2OutputOracleProxy'
+ )
+
+ const L2OutputOracle = new hre.ethers.Contract(
+ Deployment__L2OutputOracleProxy.address,
+ Deployment__L2OutputOracle.abi,
+ l1Provider
+ )
+
+ const proposer = await L2OutputOracle.proposer()
+ console.log(`L2OutputOracle proposer ${proposer}`)
+ console.log()
+
+ setInterval(async () => {
+ const latestBlockNumber = await L2OutputOracle.latestBlockNumber()
+ console.log(
+ `L2OutputOracle latest block number: ${latestBlockNumber.toString()}`
+ )
+ console.log()
+ }, 10000)
+
+ l1Provider.on('block', async (num) => {
+ const block = await l1Provider.getBlockWithTransactions(num)
+ for (const txn of block.transactions) {
+ const to = utils.getAddress(txn.to || hre.ethers.constants.AddressZero)
+ const from = utils.getAddress(txn.from)
+ const isBatchSender =
+ utils.getAddress(txn.from) ===
+ utils.getAddress(opNodeConfig.batch_sender_address)
+ const isBatchInbox =
+ to === utils.getAddress(opNodeConfig.batch_inbox_address)
+
+ const isOutputOracle =
+ to === utils.getAddress(L2OutputOracle.address) &&
+ from === utils.getAddress(proposer)
+
+ if (isBatchSender && isBatchInbox) {
+ console.log('Batch submitted:')
+ console.log(` tx hash: ${txn.hash}`)
+ console.log(` tx data: ${txn.data}`)
+ console.log()
+ }
+
+ if (isOutputOracle) {
+ console.log('L2 Output Submitted:')
+ const data = L2OutputOracle.interface.parseTransaction(txn)
+ console.log(` tx hash: ${txn.hash}`)
+ console.log(` output root: ${data.args._outputRoot}`)
+ console.log(` l2 blocknum: ${data.args._l2BlockNumber}`)
+ console.log(` l1 blockhash: ${data.args._l1Blockhash}`)
+ console.log(` l1 blocknum: ${data.args._l1BlockNumber}`)
+ console.log()
+ }
+ }
+ })
+
+ const L1Block = await hre.ethers.getContractAt(
+ 'L1Block',
+ predeploys.L1Block
+ )
+
+ l2Provider.on('block', async (num) => {
+ const block = await l2Provider.getBlockWithTransactions(num)
+ for (const txn of block.transactions) {
+ const to = utils.getAddress(txn.to || hre.ethers.constants.AddressZero)
+
+ if (to === utils.getAddress(predeploys.L1Block)) {
+ const data = L1Block.interface.parseTransaction(txn)
+ console.log('L1Block values updated')
+ console.log(` tx hash: ${txn.hash}`)
+ console.log(` number: ${data.args._number}`)
+ console.log(` timestamp: ${data.args._timestamp}`)
+ console.log(` basefee: ${data.args._basefee}`)
+ console.log(` hash: ${data.args._hash}`)
+ console.log(` sequenceNumber: ${data.args._sequenceNumber}`)
+ console.log()
+ }
+ }
+ })
+
+ setInterval(async () => {
+ await sleep(100000)
+ })
+ await sleep(100000)
+ })
diff --git a/packages/contracts-bedrock/tsconfig.json b/packages/contracts-bedrock/tsconfig.json
index e52b25676cce8..e5df8a66de318 100644
--- a/packages/contracts-bedrock/tsconfig.json
+++ b/packages/contracts-bedrock/tsconfig.json
@@ -1,9 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
- "rootDir": ".",
+ "rootDir": "./src",
"outDir": "./dist"
},
- "exclude": ["hardhat.config.ts", "deploy", "tasks", "test"],
- "include": ["src/**/*", "scripts/**/*"]
+ "include": ["src/**/*"]
}
diff --git a/packages/contracts-periphery/foundry.toml b/packages/contracts-periphery/foundry.toml
index 18ad5e4e7d9f0..1c45c01997e8e 100644
--- a/packages/contracts-periphery/foundry.toml
+++ b/packages/contracts-periphery/foundry.toml
@@ -1,4 +1,4 @@
-[default]
+[profile.default]
# The source directory
src = 'contracts/universal'
# The test directory
diff --git a/packages/contracts/docs/AddressUpgradeable.md b/packages/contracts/docs/AddressUpgradeable.md
new file mode 100644
index 0000000000000..456cdd15df4da
--- /dev/null
+++ b/packages/contracts/docs/AddressUpgradeable.md
@@ -0,0 +1,12 @@
+# AddressUpgradeable
+
+
+
+
+
+
+
+*Collection of functions related to the address type*
+
+
+
diff --git a/packages/contracts/docs/ContextUpgradeable.md b/packages/contracts/docs/ContextUpgradeable.md
index 18f33b80f1bc6..ee4e93ff7b715 100644
--- a/packages/contracts/docs/ContextUpgradeable.md
+++ b/packages/contracts/docs/ContextUpgradeable.md
@@ -9,4 +9,23 @@
*Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.*
+## Events
+
+### Initialized
+
+```solidity
+event Initialized(uint8 version)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| version | uint8 | undefined |
+
+
diff --git a/packages/contracts/docs/Initializable.md b/packages/contracts/docs/Initializable.md
index bc953adafc465..0421ee0059c4b 100644
--- a/packages/contracts/docs/Initializable.md
+++ b/packages/contracts/docs/Initializable.md
@@ -6,7 +6,26 @@
-*This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.*
+*This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. The initialization functions use a version number. Once a version number is used, it is consumed and cannot be reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in case an upgrade adds a module that needs to be initialized. For example: [.hljs-theme-light.nopadding] ``` contract MyToken is ERC20Upgradeable { function initialize() initializer public { __ERC20_init("MyToken", "MTK"); } } contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { function initializeV2() reinitializer(2) public { __ERC20Permit_init("MyToken"); } } ``` TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. [CAUTION] ==== Avoid leaving a contract uninitialized. An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: [.hljs-theme-light.nopadding] ```*
+
+
+## Events
+
+### Initialized
+
+```solidity
+event Initialized(uint8 version)
+```
+
+
+
+*Triggered when the contract has been initialized or reinitialized.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| version | uint8 | undefined |
diff --git a/packages/contracts/docs/L1CrossDomainMessenger.md b/packages/contracts/docs/L1CrossDomainMessenger.md
index e7ae8abad46f1..d3f86fb39f962 100644
--- a/packages/contracts/docs/L1CrossDomainMessenger.md
+++ b/packages/contracts/docs/L1CrossDomainMessenger.md
@@ -331,6 +331,22 @@ event FailedRelayedMessage(bytes32 indexed msgHash)
|---|---|---|
| msgHash `indexed` | bytes32 | undefined |
+### Initialized
+
+```solidity
+event Initialized(uint8 version)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| version | uint8 | undefined |
+
### MessageAllowed
```solidity
diff --git a/packages/contracts/docs/OwnableUpgradeable.md b/packages/contracts/docs/OwnableUpgradeable.md
index 53a8b1603ec8b..12a9b6ea85384 100644
--- a/packages/contracts/docs/OwnableUpgradeable.md
+++ b/packages/contracts/docs/OwnableUpgradeable.md
@@ -58,6 +58,22 @@ function transferOwnership(address newOwner) external nonpayable
## Events
+### Initialized
+
+```solidity
+event Initialized(uint8 version)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| version | uint8 | undefined |
+
### OwnershipTransferred
```solidity
diff --git a/packages/contracts/docs/PausableUpgradeable.md b/packages/contracts/docs/PausableUpgradeable.md
index ed2f541504b2f..36c58d67113f5 100644
--- a/packages/contracts/docs/PausableUpgradeable.md
+++ b/packages/contracts/docs/PausableUpgradeable.md
@@ -31,6 +31,22 @@ function paused() external view returns (bool)
## Events
+### Initialized
+
+```solidity
+event Initialized(uint8 version)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| version | uint8 | undefined |
+
### Paused
```solidity
diff --git a/packages/contracts/docs/ReentrancyGuardUpgradeable.md b/packages/contracts/docs/ReentrancyGuardUpgradeable.md
index 6955ca2de5975..bec27dda28f43 100644
--- a/packages/contracts/docs/ReentrancyGuardUpgradeable.md
+++ b/packages/contracts/docs/ReentrancyGuardUpgradeable.md
@@ -9,4 +9,23 @@
*Contract module that helps prevent reentrant calls to a function. Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier available, which can be applied to functions to make sure there are no nested (reentrant) calls to them. Note that because there is a single `nonReentrant` guard, functions marked as `nonReentrant` may not call one another. This can be worked around by making those functions `private`, and then adding `external` `nonReentrant` entry points to them. TIP: If you would like to learn more about reentrancy and alternative ways to protect against it, check out our blog post https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].*
+## Events
+
+### Initialized
+
+```solidity
+event Initialized(uint8 version)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| version | uint8 | undefined |
+
+
diff --git a/packages/core-utils/package.json b/packages/core-utils/package.json
index ee4172d78d305..b33b7370c37c9 100644
--- a/packages/core-utils/package.json
+++ b/packages/core-utils/package.json
@@ -35,6 +35,8 @@
"@ethersproject/abstract-provider": "^5.6.1",
"@ethersproject/providers": "^5.6.8",
"@ethersproject/transactions": "^5.6.2",
+ "@ethersproject/properties": "^5.6.0",
+ "@ethersproject/web": "^5.6.1",
"bufio": "^1.0.7",
"chai": "^4.3.4",
"ethers": "^5.6.8"
diff --git a/packages/core-utils/src/optimism/deposit-transaction.ts b/packages/core-utils/src/optimism/deposit-transaction.ts
index c84f6c24a657d..f234872eb5aca 100644
--- a/packages/core-utils/src/optimism/deposit-transaction.ts
+++ b/packages/core-utils/src/optimism/deposit-transaction.ts
@@ -10,6 +10,10 @@ import {
const { hexDataSlice, stripZeros, hexConcat, keccak256, zeroPad } = utils
+const formatBoolean = (value: boolean): Uint8Array => {
+ return value ? new Uint8Array([1]) : new Uint8Array([])
+}
+
const formatNumber = (value: BigNumberish, name: string): Uint8Array => {
const result = stripZeros(BigNumber.from(value).toHexString())
if (result.length > 32) {
@@ -18,6 +22,16 @@ const formatNumber = (value: BigNumberish, name: string): Uint8Array => {
return result
}
+const handleBoolean = (value: string): boolean => {
+ if (value === '0x') {
+ return false
+ }
+ if (value === '0x01') {
+ return true
+ }
+ throw new Error(`invalid boolean RLP hex value ${value}`)
+}
+
const handleNumber = (value: string): BigNumber => {
if (value === '0x') {
return ethers.constants.Zero
@@ -45,6 +59,7 @@ interface DepositTxOpts {
mint: BigNumberish
value: BigNumberish
gas: BigNumberish
+ isSystemTransaction: boolean
data: string
domain?: SourceHashDomain
l1BlockHash?: string
@@ -68,6 +83,7 @@ export class DepositTx {
public mint: BigNumberish
public value: BigNumberish
public gas: BigNumberish
+ public isSystemTransaction: boolean
public data: BigNumberish
public domain?: SourceHashDomain
@@ -82,6 +98,7 @@ export class DepositTx {
this.mint = opts.mint!
this.value = opts.value!
this.gas = opts.gas!
+ this.isSystemTransaction = opts.isSystemTransaction || false
this.data = opts.data!
this.domain = opts.domain
this.l1BlockHash = opts.l1BlockHash
@@ -130,6 +147,7 @@ export class DepositTx {
formatNumber(this.mint || 0, 'mint'),
formatNumber(this.value || 0, 'value'),
formatNumber(this.gas || 0, 'gas'),
+ formatBoolean(this.isSystemTransaction),
this.data || '0x',
]
@@ -145,15 +163,15 @@ export class DepositTx {
throw new Error(`Invalid type ${payload[0]}`)
}
this.version = payload[1]
-
- const transaction = utils.RLP.decode(payload.slice(2))
+ const transaction = utils.RLP.decode(payload.slice(1))
this._sourceHash = transaction[0]
this.from = handleAddress(transaction[1])
this.to = handleAddress(transaction[2])
this.mint = handleNumber(transaction[3])
this.value = handleNumber(transaction[4])
this.gas = handleNumber(transaction[5])
- this.data = transaction[6]
+ this.isSystemTransaction = handleBoolean(transaction[6])
+ this.data = transaction[7]
if ('l1BlockHash' in extra) {
this.l1BlockHash = extra.l1BlockHash
@@ -229,6 +247,7 @@ export class DepositTx {
offset += 1
this.to = isCreation === true ? null : event.args.to
const length = opaqueData.length - offset
+ this.isSystemTransaction = false
this.data = hexDataSlice(opaqueData, offset, offset + length)
this.domain = SourceHashDomain.UserDeposit
this.l1BlockHash = event.blockHash
diff --git a/packages/core-utils/src/optimism/hashing.ts b/packages/core-utils/src/optimism/hashing.ts
index d639d18366a53..8a48b7e2852fa 100644
--- a/packages/core-utils/src/optimism/hashing.ts
+++ b/packages/core-utils/src/optimism/hashing.ts
@@ -9,6 +9,18 @@ import {
big1,
} from './encoding'
+/**
+ * Bedrock output oracle data.
+ */
+export interface BedrockOutputData {
+ outputRoot: string
+ l1Timestamp: number
+ l2BlockNumber: number
+}
+
+/**
+ * Bedrock state commitment
+ */
export interface OutputRootProof {
version: string
stateRoot: string
@@ -16,6 +28,23 @@ export interface OutputRootProof {
latestBlockhash: string
}
+/**
+ * Bedrock proof data required to finalize an L2 to L1 message.
+ */
+export interface BedrockCrossChainMessageProof {
+ outputRootProof: OutputRootProof
+ withdrawalProof: string
+}
+
+/**
+ * Parameters that govern the L2OutputOracle.
+ */
+export type L2OutputOracleParameters = {
+ submissionInterval: number
+ startingBlockNumber: number
+ l2BlockTime: number
+}
+
/**
* Hahses a cross domain message.
*
diff --git a/packages/core-utils/src/optimism/index.ts b/packages/core-utils/src/optimism/index.ts
index 5691eb6528542..1d892ef2bc3d1 100644
--- a/packages/core-utils/src/optimism/index.ts
+++ b/packages/core-utils/src/optimism/index.ts
@@ -10,3 +10,4 @@ export * from './op-node'
export * from './deposit-transaction'
export * from './encoding'
export * from './hashing'
+export * from './op-provider'
diff --git a/packages/core-utils/src/optimism/op-provider.ts b/packages/core-utils/src/optimism/op-provider.ts
new file mode 100644
index 0000000000000..dda73a1dd6ad7
--- /dev/null
+++ b/packages/core-utils/src/optimism/op-provider.ts
@@ -0,0 +1,158 @@
+import EventEmitter from 'events'
+
+import { BigNumber } from 'ethers'
+import { deepCopy } from '@ethersproject/properties'
+import { ConnectionInfo, fetchJson } from '@ethersproject/web'
+
+const getResult = (payload: {
+ error?: { code?: number; data?: any; message?: string }
+ result?: any
+}): any => {
+ if (payload.error) {
+ const error: any = new Error(payload.error.message)
+ error.code = payload.error.code
+ error.data = payload.error.data
+ throw error
+ }
+ return payload.result
+}
+
+export interface BlockDescriptor {
+ hash: string
+ number: BigNumber
+ parentHash: string
+ timestamp: BigNumber
+}
+
+export interface L2BlockDescriptor extends BlockDescriptor {
+ l1Origin: {
+ hash: string
+ number: BigNumber
+ }
+ sequencerNumber: BigNumber
+}
+
+export interface SyncStatusResponse {
+ currentL1: BlockDescriptor
+ headL1: BlockDescriptor
+ unsafeL2: L2BlockDescriptor
+ safeL2: L2BlockDescriptor
+ finalizedL2: L2BlockDescriptor
+}
+
+export class OpNodeProvider extends EventEmitter {
+ readonly connection: ConnectionInfo
+ private _nextId: number = 0
+
+ constructor(url?: ConnectionInfo | string) {
+ super()
+
+ if (typeof url === 'string') {
+ this.connection = { url }
+ } else {
+ this.connection = url
+ }
+ }
+
+ async syncStatus(): Promise {
+ const result = await this.send('optimism_syncStatus', [])
+
+ return {
+ currentL1: {
+ hash: result.current_l1.hash,
+ number: BigNumber.from(result.current_l1.number),
+ parentHash: result.current_l1.parentHash,
+ timestamp: BigNumber.from(result.current_l1.timestamp),
+ },
+ headL1: {
+ hash: result.head_l1.hash,
+ number: BigNumber.from(result.head_l1.number),
+ parentHash: result.head_l1.parentHash,
+ timestamp: BigNumber.from(result.head_l1.timestamp),
+ },
+ unsafeL2: {
+ hash: result.unsafe_l2.hash,
+ number: BigNumber.from(result.unsafe_l2.number),
+ parentHash: result.unsafe_l2.parentHash,
+ timestamp: BigNumber.from(result.unsafe_l2.timestamp),
+ l1Origin: {
+ hash: result.unsafe_l2.l1origin.hash,
+ number: BigNumber.from(result.unsafe_l2.l1origin.number),
+ },
+ sequencerNumber: BigNumber.from(result.unsafe_l2.sequenceNumber),
+ },
+ safeL2: {
+ hash: result.safe_l2.hash,
+ number: BigNumber.from(result.safe_l2.number),
+ parentHash: result.safe_l2.parentHash,
+ timestamp: BigNumber.from(result.safe_l2.timestamp),
+ l1Origin: {
+ hash: result.safe_l2.l1origin.hash,
+ number: BigNumber.from(result.safe_l2.l1origin.number),
+ },
+ sequencerNumber: BigNumber.from(result.safe_l2.sequenceNumber),
+ },
+ finalizedL2: {
+ hash: result.finalized_l2.hash,
+ number: BigNumber.from(result.finalized_l2.number),
+ parentHash: result.finalized_l2.parentHash,
+ timestamp: BigNumber.from(result.finalized_l2.timestamp),
+ l1Origin: {
+ hash: result.finalized_l2.l1origin.hash,
+ number: BigNumber.from(result.finalized_l2.l1origin.number),
+ },
+ sequencerNumber: BigNumber.from(result.finalized_l2.sequenceNumber),
+ },
+ }
+ }
+
+ // TODO(tynes): turn the response into a stronger type
+ async rollupConfig() {
+ const result = await this.send('optimism_rollupConfig', [])
+ return result
+ }
+
+ send(method: string, params: Array): Promise {
+ const request = {
+ method,
+ params,
+ id: this._nextId++,
+ jsonrpc: '2.0',
+ }
+
+ this.emit('debug', {
+ action: 'request',
+ request: deepCopy(request),
+ provider: this,
+ })
+
+ const result = fetchJson(
+ this.connection,
+ JSON.stringify(request),
+ getResult
+ ).then(
+ (res) => {
+ this.emit('debug', {
+ action: 'response',
+ request,
+ response: res,
+ provider: this,
+ })
+
+ return res
+ },
+ (error) => {
+ this.emit('debug', {
+ action: 'response',
+ error,
+ request,
+ provider: this,
+ })
+
+ throw error
+ }
+ )
+
+ return result
+ }
+}
diff --git a/packages/hardhat-deploy-config/src/plugin.ts b/packages/hardhat-deploy-config/src/plugin.ts
index 725c379671a18..42f405e1d6eb5 100644
--- a/packages/hardhat-deploy-config/src/plugin.ts
+++ b/packages/hardhat-deploy-config/src/plugin.ts
@@ -1,4 +1,5 @@
import * as path from 'path'
+import * as fs from 'fs'
import { extendEnvironment, extendConfig } from 'hardhat/config'
import {
@@ -28,9 +29,16 @@ const normalizePath = (
export const loadDeployConfig = (hre: HardhatRuntimeEnvironment): any => {
let config: any
try {
- config =
+ const base = `${hre.config.paths.deployConfig}/${hre.network.name}`
+ if (fs.existsSync(`${base}.ts`)) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
- require(`${hre.config.paths.deployConfig}/${hre.network.name}.ts`).default
+ config = require(`${base}.ts`).default
+ } else if (fs.existsSync(`${base}.json`)) {
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
+ config = require(`${base}.json`)
+ } else {
+ throw new Error('not found')
+ }
} catch (err) {
throw new Error(
`error while loading deploy config for network: ${hre.network.name}, ${err}`
diff --git a/packages/integration-tests-bedrock/foundry.toml b/packages/integration-tests-bedrock/foundry.toml
index b47fac2d111a2..fe98fbe9ef1ee 100644
--- a/packages/integration-tests-bedrock/foundry.toml
+++ b/packages/integration-tests-bedrock/foundry.toml
@@ -1,4 +1,4 @@
-[default]
+[profile.default]
src = 'contracts'
out = 'forge-artifacts'
optimizer = true
diff --git a/packages/sdk/hardhat.config.ts b/packages/sdk/hardhat.config.ts
index aeea1c1de447b..6d3290f54cf13 100644
--- a/packages/sdk/hardhat.config.ts
+++ b/packages/sdk/hardhat.config.ts
@@ -2,6 +2,9 @@ import { HardhatUserConfig } from 'hardhat/types'
import '@nomiclabs/hardhat-ethers'
import '@nomiclabs/hardhat-waffle'
+import 'hardhat-deploy'
+
+import './tasks/deposit'
const config: HardhatUserConfig = {
solidity: {
@@ -10,6 +13,25 @@ const config: HardhatUserConfig = {
paths: {
sources: './test/contracts',
},
+ networks: {
+ devnetL1: {
+ url: 'http://localhost:8545',
+ accounts: [
+ 'ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',
+ ],
+ },
+ },
+ external: {
+ contracts: [
+ {
+ artifacts: '../contracts-bedrock/artifacts',
+ },
+ ],
+ deployments: {
+ devnetL1: ['../contracts-bedrock/deployments/devnetL1'],
+ goerli: ['../contracts-bedrock/deployments/goerli'],
+ },
+ },
}
export default config
diff --git a/packages/sdk/package.json b/packages/sdk/package.json
index f9be264de1765..51584ec2f566b 100644
--- a/packages/sdk/package.json
+++ b/packages/sdk/package.json
@@ -41,6 +41,7 @@
"ethereum-waffle": "^3.4.0",
"ethers": "^5.6.8",
"hardhat": "^2.9.6",
+ "hardhat-deploy": "^0.11.4",
"nyc": "^15.1.0",
"typedoc": "^0.22.13",
"mocha": "^10.0.0"
@@ -48,6 +49,7 @@
"dependencies": {
"@eth-optimism/contracts": "0.5.31",
"@eth-optimism/core-utils": "0.9.2",
+ "@eth-optimism/contracts-bedrock": "0.5.2",
"lodash": "^4.17.21",
"merkletreejs": "^0.2.27",
"rlp": "^2.2.7"
diff --git a/packages/sdk/src/adapters/eth-bridge.ts b/packages/sdk/src/adapters/eth-bridge.ts
index 028535bfcfe35..1eb15702275c0 100644
--- a/packages/sdk/src/adapters/eth-bridge.ts
+++ b/packages/sdk/src/adapters/eth-bridge.ts
@@ -42,12 +42,12 @@ export class ETHBridgeAdapter extends StandardBridgeAdapter {
.map((event) => {
return {
direction: MessageDirection.L1_TO_L2,
- from: event.args._from,
- to: event.args._to,
+ from: event.args.from,
+ to: event.args.to,
l1Token: ethers.constants.AddressZero,
l2Token: predeploys.OVM_ETH,
- amount: event.args._amount,
- data: event.args._data,
+ amount: event.args.amount,
+ data: event.args.extraData,
logIndex: event.logIndex,
blockNumber: event.blockNumber,
transactionHash: event.transactionHash,
@@ -76,19 +76,19 @@ export class ETHBridgeAdapter extends StandardBridgeAdapter {
.filter((event) => {
// Only find ETH withdrawals.
return (
- hexStringEquals(event.args._l1Token, ethers.constants.AddressZero) &&
- hexStringEquals(event.args._l2Token, predeploys.OVM_ETH)
+ hexStringEquals(event.args.l1Token, ethers.constants.AddressZero) &&
+ hexStringEquals(event.args.l2Token, predeploys.OVM_ETH)
)
})
.map((event) => {
return {
direction: MessageDirection.L2_TO_L1,
- from: event.args._from,
- to: event.args._to,
- l1Token: event.args._l1Token,
- l2Token: event.args._l2Token,
- amount: event.args._amount,
- data: event.args._data,
+ from: event.args.from,
+ to: event.args.to,
+ l1Token: event.args.l1Token,
+ l2Token: event.args.l2Token,
+ amount: event.args.amount,
+ data: event.args.extraData,
logIndex: event.logIndex,
blockNumber: event.blockNumber,
transactionHash: event.transactionHash,
@@ -178,7 +178,10 @@ export class ETHBridgeAdapter extends StandardBridgeAdapter {
amount,
0, // L1 gas not required.
'0x', // No data.
- opts?.overrides || {}
+ {
+ ...omit(opts?.overrides || {}, 'value'),
+ value: this.messenger.bedrock ? amount : 0,
+ }
)
} else {
return this.l2Bridge.populateTransaction.withdrawTo(
@@ -187,7 +190,10 @@ export class ETHBridgeAdapter extends StandardBridgeAdapter {
amount,
0, // L1 gas not required.
'0x', // No data.
- opts?.overrides || {}
+ {
+ ...omit(opts?.overrides || {}, 'value'),
+ value: this.messenger.bedrock ? amount : 0,
+ }
)
}
},
diff --git a/packages/sdk/src/adapters/standard-bridge.ts b/packages/sdk/src/adapters/standard-bridge.ts
index 63db67de35717..22d9a7d562cda 100644
--- a/packages/sdk/src/adapters/standard-bridge.ts
+++ b/packages/sdk/src/adapters/standard-bridge.ts
@@ -12,7 +12,8 @@ import {
TransactionResponse,
BlockTag,
} from '@ethersproject/abstract-provider'
-import { getContractInterface, predeploys } from '@eth-optimism/contracts'
+import { predeploys } from '@eth-optimism/contracts'
+import { getContractInterface } from '@eth-optimism/contracts-bedrock'
import { hexStringEquals } from '@eth-optimism/core-utils'
import {
@@ -54,7 +55,7 @@ export class StandardBridgeAdapter implements IBridgeAdapter {
)
this.l2Bridge = new Contract(
toAddress(opts.l2Bridge),
- getContractInterface('IL2ERC20Bridge'),
+ getContractInterface('L2StandardBridge'),
this.messenger.l2Provider
)
}
@@ -82,19 +83,19 @@ export class StandardBridgeAdapter implements IBridgeAdapter {
// adapter. Bridges that are not the ETH bridge should not be able to handle or even
// present ETH deposits or withdrawals.
return (
- !hexStringEquals(event.args._l1Token, ethers.constants.AddressZero) &&
- !hexStringEquals(event.args._l2Token, predeploys.OVM_ETH)
+ !hexStringEquals(event.args.l1Token, ethers.constants.AddressZero) &&
+ !hexStringEquals(event.args.l2Token, predeploys.OVM_ETH)
)
})
.map((event) => {
return {
direction: MessageDirection.L1_TO_L2,
- from: event.args._from,
- to: event.args._to,
- l1Token: event.args._l1Token,
- l2Token: event.args._l2Token,
- amount: event.args._amount,
- data: event.args._data,
+ from: event.args.from,
+ to: event.args.to,
+ l1Token: event.args.l1Token,
+ l2Token: event.args.l2Token,
+ amount: event.args.amount,
+ data: event.args.extraData,
logIndex: event.logIndex,
blockNumber: event.blockNumber,
transactionHash: event.transactionHash,
@@ -125,19 +126,19 @@ export class StandardBridgeAdapter implements IBridgeAdapter {
// adapter. Bridges that are not the ETH bridge should not be able to handle or even
// present ETH deposits or withdrawals.
return (
- !hexStringEquals(event.args._l1Token, ethers.constants.AddressZero) &&
- !hexStringEquals(event.args._l2Token, predeploys.OVM_ETH)
+ !hexStringEquals(event.args.l1Token, ethers.constants.AddressZero) &&
+ !hexStringEquals(event.args.l2Token, predeploys.OVM_ETH)
)
})
.map((event) => {
return {
direction: MessageDirection.L2_TO_L1,
- from: event.args._from,
- to: event.args._to,
- l1Token: event.args._l1Token,
- l2Token: event.args._l2Token,
- amount: event.args._amount,
- data: event.args._data,
+ from: event.args.from,
+ to: event.args.to,
+ l1Token: event.args.l1Token,
+ l2Token: event.args.l2Token,
+ amount: event.args.amount,
+ data: event.args.extraData,
logIndex: event.logIndex,
blockNumber: event.blockNumber,
transactionHash: event.transactionHash,
@@ -156,10 +157,9 @@ export class StandardBridgeAdapter implements IBridgeAdapter {
try {
const contract = new Contract(
toAddress(l2Token),
- getContractInterface('L2StandardERC20'),
+ getContractInterface('OptimismMintableERC20'),
this.messenger.l2Provider
)
-
// Don't support ETH deposits or withdrawals via this bridge.
if (
hexStringEquals(toAddress(l1Token), ethers.constants.AddressZero) ||
@@ -170,6 +170,7 @@ export class StandardBridgeAdapter implements IBridgeAdapter {
// Make sure the L1 token matches.
const remoteL1Token = await contract.l1Token()
+
if (!hexStringEquals(remoteL1Token, toAddress(l1Token))) {
return false
}
@@ -203,7 +204,7 @@ export class StandardBridgeAdapter implements IBridgeAdapter {
const token = new Contract(
toAddress(l1Token),
- getContractInterface('L2StandardERC20'), // Any ERC20 will do
+ getContractInterface('OptimismMintableERC20'), // Any ERC20 will do
this.messenger.l1Provider
)
@@ -270,7 +271,7 @@ export class StandardBridgeAdapter implements IBridgeAdapter {
const token = new Contract(
toAddress(l1Token),
- getContractInterface('L2StandardERC20'), // Any ERC20 will do
+ getContractInterface('OptimismMintableERC20'), // Any ERC20 will do
this.messenger.l1Provider
)
diff --git a/packages/sdk/src/cross-chain-messenger.ts b/packages/sdk/src/cross-chain-messenger.ts
index f4346793c67cd..816c3a223cf86 100644
--- a/packages/sdk/src/cross-chain-messenger.ts
+++ b/packages/sdk/src/cross-chain-messenger.ts
@@ -5,13 +5,27 @@ import {
TransactionReceipt,
TransactionResponse,
TransactionRequest,
+ Log,
} from '@ethersproject/abstract-provider'
import { Signer } from '@ethersproject/abstract-signer'
import { ethers, BigNumber, Overrides, CallOverrides } from 'ethers'
-import { sleep, remove0x } from '@eth-optimism/core-utils'
-import { predeploys } from '@eth-optimism/contracts'
+import {
+ sleep,
+ remove0x,
+ toHexString,
+ toRpcHexString,
+ hashWithdrawal,
+ encodeCrossDomainMessageV0,
+ hashCrossDomainMessage,
+ L2OutputOracleParameters,
+ BedrockOutputData,
+ BedrockCrossChainMessageProof,
+} from '@eth-optimism/core-utils'
+import { getContractInterface, predeploys } from '@eth-optimism/contracts'
+import * as rlp from 'rlp'
import {
+ CoreCrossChainMessage,
ICrossChainMessenger,
OEContracts,
OEContractsLike,
@@ -42,10 +56,8 @@ import {
DeepPartial,
getAllOEContracts,
getBridgeAdapters,
- hashCrossChainMessage,
makeMerkleTreeProof,
makeStateTrieProof,
- encodeCrossChainMessage,
DEPOSIT_CONFIRMATION_BLOCKS,
CHAIN_BLOCK_TIMES,
} from './utils'
@@ -59,6 +71,9 @@ export class CrossChainMessenger implements ICrossChainMessenger {
public bridges: BridgeAdapters
public depositConfirmationBlocks: number
public l1BlockTimeSeconds: number
+ public bedrock: boolean
+
+ private _l2OutputOracleParameters: L2OutputOracleParameters
/**
* Creates a new CrossChainProvider instance.
@@ -72,6 +87,7 @@ export class CrossChainMessenger implements ICrossChainMessenger {
* @param opts.l1BlockTimeSeconds Optional estimated block time in seconds for the L1 chain.
* @param opts.contracts Optional contract address overrides.
* @param opts.bridges Optional bridge address list.
+ * @param opts.bedrock Whether or not to enable Bedrock compatibility.
*/
constructor(opts: {
l1SignerOrProvider: SignerOrProviderLike
@@ -82,7 +98,9 @@ export class CrossChainMessenger implements ICrossChainMessenger {
l1BlockTimeSeconds?: NumberLike
contracts?: DeepPartial
bridges?: BridgeAdapterData
+ bedrock?: boolean
}) {
+ this.bedrock = opts.bedrock ?? false
this.l1SignerOrProvider = toSignerOrProvider(opts.l1SignerOrProvider)
this.l2SignerOrProvider = toSignerOrProvider(opts.l2SignerOrProvider)
@@ -151,6 +169,26 @@ export class CrossChainMessenger implements ICrossChainMessenger {
}
}
+ public async getL2OutputOracleParameters(): Promise {
+ if (this._l2OutputOracleParameters) {
+ return this._l2OutputOracleParameters
+ }
+
+ this._l2OutputOracleParameters = {
+ submissionInterval: (
+ await this.contracts.l1.L2OutputOracle.SUBMISSION_INTERVAL()
+ ).toNumber(),
+ startingBlockNumber: (
+ await this.contracts.l1.L2OutputOracle.STARTING_BLOCK_NUMBER()
+ ).toNumber(),
+ l2BlockTime: (
+ await this.contracts.l1.L2OutputOracle.L2_BLOCK_TIME()
+ ).toNumber(),
+ }
+
+ return this._l2OutputOracleParameters
+ }
+
public async getMessagesByTransaction(
transaction: TransactionLike,
opts: {
@@ -203,6 +241,19 @@ export class CrossChainMessenger implements ICrossChainMessenger {
return parsed.name === 'SentMessage'
})
.map((log) => {
+ // Try to pull out the value field, but only if the very next log is a SentMessageExtraData
+ // event which was introduced in the Bedrock upgrade.
+ let value = ethers.BigNumber.from(0)
+ if (receipt.logs.length > log.logIndex + 1) {
+ const next = receipt.logs[log.logIndex + 1]
+ if (next.address === messenger.address) {
+ const nextParsed = messenger.interface.parseLog(next)
+ if (nextParsed.name === 'SentMessageExtension1') {
+ value = nextParsed.args.value
+ }
+ }
+ }
+
// Convert each SentMessage log into a message object
const parsed = messenger.interface.parseLog(log)
return {
@@ -211,7 +262,8 @@ export class CrossChainMessenger implements ICrossChainMessenger {
sender: parsed.args.sender,
message: parsed.args.message,
messageNonce: parsed.args.messageNonce,
- gasLimit: parsed.args.gasLimit,
+ value,
+ minGasLimit: parsed.args.gasLimit,
logIndex: log.logIndex,
blockNumber: log.blockNumber,
transactionHash: log.transactionHash,
@@ -373,20 +425,32 @@ export class CrossChainMessenger implements ICrossChainMessenger {
}
} else {
if (receipt === null) {
- const stateRoot = await this.getMessageStateRoot(resolved)
- if (stateRoot === null) {
- return MessageStatus.STATE_ROOT_NOT_PUBLISHED
+ let timestamp: number
+ if (this.bedrock) {
+ const output = await this.getMessageBedrockOutput(resolved)
+ if (output === null) {
+ return MessageStatus.STATE_ROOT_NOT_PUBLISHED
+ }
+
+ timestamp = output.l1Timestamp
} else {
- const challengePeriod = await this.getChallengePeriodSeconds()
- const targetBlock = await this.l1Provider.getBlock(
- stateRoot.batch.blockNumber
- )
- const latestBlock = await this.l1Provider.getBlock('latest')
- if (targetBlock.timestamp + challengePeriod > latestBlock.timestamp) {
- return MessageStatus.IN_CHALLENGE_PERIOD
- } else {
- return MessageStatus.READY_FOR_RELAY
+ const stateRoot = await this.getMessageStateRoot(resolved)
+ if (stateRoot === null) {
+ return MessageStatus.STATE_ROOT_NOT_PUBLISHED
}
+
+ const bn = stateRoot.batch.blockNumber
+ const block = await this.l1Provider.getBlock(bn)
+ timestamp = block.timestamp
+ }
+
+ const challengePeriod = await this.getChallengePeriodSeconds()
+ const latestBlock = await this.l1Provider.getBlock('latest')
+
+ if (timestamp + challengePeriod > latestBlock.timestamp) {
+ return MessageStatus.IN_CHALLENGE_PERIOD
+ } else {
+ return MessageStatus.READY_FOR_RELAY
}
} else {
if (receipt.receiptStatus === MessageReceiptStatus.RELAYED_SUCCEEDED) {
@@ -402,7 +466,14 @@ export class CrossChainMessenger implements ICrossChainMessenger {
message: MessageLike
): Promise {
const resolved = await this.toCrossChainMessage(message)
- const messageHash = hashCrossChainMessage(resolved)
+ const messageHash = hashCrossDomainMessage(
+ resolved.messageNonce,
+ resolved.sender,
+ resolved.target,
+ resolved.value,
+ resolved.minGasLimit,
+ resolved.message
+ )
// Here we want the messenger that will receive the message, not the one that sent it.
const messenger =
@@ -642,11 +713,56 @@ export class CrossChainMessenger implements ICrossChainMessenger {
}
public async getChallengePeriodSeconds(): Promise {
- const challengePeriod =
- await this.contracts.l1.StateCommitmentChain.FRAUD_PROOF_WINDOW()
+ const challengePeriod = this.bedrock
+ ? await this.contracts.l1.OptimismPortal.FINALIZATION_PERIOD_SECONDS()
+ : await this.contracts.l1.StateCommitmentChain.FRAUD_PROOF_WINDOW()
return challengePeriod.toNumber()
}
+ public async getMessageBedrockOutput(
+ message: MessageLike
+ ): Promise {
+ const resolved = await this.toCrossChainMessage(message)
+
+ // Outputs are only a thing for L2 to L1 messages.
+ if (resolved.direction === MessageDirection.L1_TO_L2) {
+ throw new Error(`cannot get a state root for an L1 to L2 message`)
+ }
+
+ const l2OutputOracleParameters = await this.getL2OutputOracleParameters()
+
+ // TODO: better way to do this
+ let number =
+ resolved.blockNumber - l2OutputOracleParameters.startingBlockNumber
+ while (number % l2OutputOracleParameters.submissionInterval !== 0) {
+ number++
+ }
+
+ // TODO: Handle old messages from before Bedrock upgrade.
+ const events = await this.contracts.l1.L2OutputOracle.queryFilter(
+ this.contracts.l1.L2OutputOracle.filters.OutputProposed(
+ undefined,
+ undefined,
+ number
+ )
+ )
+
+ if (events.length === 0) {
+ return null
+ }
+
+ // Should not happen
+ if (events.length > 1) {
+ throw new Error(`multiple output roots found for message`)
+ }
+
+ return {
+ outputRoot: events[0].args.l2Output,
+ l1Timestamp: events[0].args.l1Timestamp.toNumber(),
+ l2BlockNumber: events[0].args.l2BlockNumber.toNumber(),
+ }
+ }
+
public async getMessageStateRoot(
message: MessageLike
): Promise {
@@ -826,8 +942,12 @@ export class CrossChainMessenger implements ICrossChainMessenger {
// https://docs.soliditylang.org/en/v0.8.4/internals/layout_in_storage.html#mappings-and-dynamic-arrays
const messageSlot = ethers.utils.keccak256(
ethers.utils.keccak256(
- encodeCrossChainMessage(resolved) +
- remove0x(this.contracts.l2.L2CrossDomainMessenger.address)
+ encodeCrossDomainMessageV0(
+ resolved.target,
+ resolved.sender,
+ resolved.message,
+ resolved.messageNonce
+ ) + remove0x(this.contracts.l2.L2CrossDomainMessenger.address)
) + '00'.repeat(32)
)
@@ -848,9 +968,142 @@ export class CrossChainMessenger implements ICrossChainMessenger {
stateRoot.stateRootIndexInBatch
),
},
- stateTrieWitness: stateTrieProof.accountProof,
- storageTrieWitness: stateTrieProof.storageProof,
+ stateTrieWitness: toHexString(rlp.encode(stateTrieProof.accountProof)),
+ storageTrieWitness: toHexString(rlp.encode(stateTrieProof.storageProof)),
+ }
+ }
+
+ public async getBedrockMessageProof(
+ message: MessageLike
+ ): Promise<
+ [BedrockCrossChainMessageProof, BedrockOutputData, CoreCrossChainMessage]
+ > {
+ const resolved = await this.toCrossChainMessage(message)
+ if (resolved.direction === MessageDirection.L1_TO_L2) {
+ throw new Error(`can only generate proofs for L2 to L1 messages`)
+ }
+
+ const output = await this.getMessageBedrockOutput(resolved)
+ if (output === null) {
+ throw new Error(`state root for message not yet published`)
+ }
+
+ const receipt = await this.l2Provider.getTransactionReceipt(
+ resolved.transactionHash
+ )
+
+ interface WithdrawalEntry {
+ withdrawalInitiated: any
+ withdrawalInitiatedExtension1: any
+ }
+
+ // Handle multiple withdrawals in the same tx and be backwards
+ // compatible without WithdrawalInitiatedExtension1
+ const logs: Partial<{ number: WithdrawalEntry }> = {}
+ for (const [i, log] of Object.entries(receipt.logs)) {
+ if (log.address === predeploys.OVM_L2ToL1MessagePasser) {
+ const decoded =
+ this.contracts.l2.L2ToL1MessagePasser.interface.parseLog(log)
+ // Find the withdrawal initiated events
+ if (decoded.name === 'WithdrawalInitiated') {
+ logs[log.logIndex] = {
+ withdrawalInitiated: decoded.args,
+ withdrawalInitiatedExtension1: null,
+ }
+ if (receipt.logs[i + 1]) {
+ const next =
+ this.contracts.l2.L2ToL1MessagePasser.interface.parseLog(
+ receipt.logs[i + 1]
+ )
+ if (next.name === 'WithdrawalInitiatedExtension1') {
+ logs[log.logIndex].withdrawalInitiatedExtension1 = next.args
+ }
+ }
+ }
+ }
+ }
+
+ // TODO(tynes): be able to handle transactions that do multiple withdrawals
+ // in a single transaction. Right now just go for the first one.
+ const withdrawal = Object.values(logs)[0]
+ if (!withdrawal) {
+ throw new Error(
+ `Cannot find withdrawal logs for ${resolved.transactionHash}`
+ )
+ }
+
+ const withdrawalHash = hashWithdrawal(
+ withdrawal.withdrawalInitiated.nonce,
+ withdrawal.withdrawalInitiated.sender,
+ withdrawal.withdrawalInitiated.target,
+ withdrawal.withdrawalInitiated.value,
+ withdrawal.withdrawalInitiated.gasLimit,
+ withdrawal.withdrawalInitiated.data
+ )
+
+ // Sanity check
+ if (withdrawal.withdrawalInitiatedExtension1) {
+ if (withdrawal.withdrawalInitiatedExtension1.hash !== withdrawalHash) {
+ throw new Error(`Mismatched withdrawal hashes`)
+ }
}
+
+ // TODO: turn into util
+ const preimage = ethers.utils.defaultAbiCoder.encode(
+ ['bytes32', 'uint256'],
+ [withdrawalHash, ethers.constants.HashZero]
+ )
+ const isMessageSent =
+ await this.contracts.l2.L2ToL1MessagePasser.sentMessages(withdrawalHash)
+
+ if (!isMessageSent) {
+ throw new Error(`Withdrawal not initiated on L2`)
+ }
+
+ const messageSlot = ethers.utils.keccak256(preimage)
+
+ const stateTrieProof = await makeStateTrieProof(
+ this.l2Provider as ethers.providers.JsonRpcProvider,
+ output.l2BlockNumber,
+ this.contracts.l2.OVM_L2ToL1MessagePasser.address,
+ messageSlot
+ )
+
+ // Sanity check that the value is set to 1 in the state
+ if (!stateTrieProof.storageValue.eq(1)) {
+ throw new Error(`Withdrawal hash ${withdrawalHash} is not set in state`)
+ }
+
+ const block = await (
+ this.l2Provider as ethers.providers.JsonRpcProvider
+ ).send('eth_getBlockByNumber', [
+ toRpcHexString(output.l2BlockNumber),
+ false,
+ ])
+
+ return [
+ {
+ outputRootProof: {
+ // TODO: Handle multiple versions in the future
+ version: ethers.constants.HashZero,
+ stateRoot: block.stateRoot,
+ withdrawerStorageRoot: stateTrieProof.storageRoot,
+ latestBlockhash: block.hash,
+ },
+ withdrawalProof: ethers.utils.RLP.encode(stateTrieProof.storageProof),
+ // withdrawalProof: toHexString(rlp.encode(stateTrieProof.storageProof)),
+ },
+ output,
+ // TODO(tynes): use better type, typechain?
+ {
+ messageNonce: withdrawal.withdrawalInitiated.nonce,
+ sender: withdrawal.withdrawalInitiated.sender,
+ target: withdrawal.withdrawalInitiated.target,
+ value: withdrawal.withdrawalInitiated.value,
+ minGasLimit: withdrawal.withdrawalInitiated.gasLimit,
+ message: withdrawal.withdrawalInitiated.data,
+ },
+ ]
}
public async sendMessage(
@@ -1033,15 +1286,30 @@ export class CrossChainMessenger implements ICrossChainMessenger {
throw new Error(`cannot resend L2 to L1 message`)
}
- return this.contracts.l1.L1CrossDomainMessenger.populateTransaction.replayMessage(
- resolved.target,
- resolved.sender,
- resolved.message,
- resolved.messageNonce,
- resolved.gasLimit,
- messageGasLimit,
- opts?.overrides || {}
- )
+ if (this.bedrock) {
+ return this.populateTransaction.finalizeMessage(resolved, {
+ ...(opts || {}),
+ overrides: {
+ ...opts?.overrides,
+ gasLimit: messageGasLimit,
+ },
+ })
+ } else {
+ const legacyL1XDM = new ethers.Contract(
+ this.contracts.l1.L1CrossDomainMessenger.address,
+ getContractInterface('L1CrossDomainMessenger'),
+ this.l1SignerOrProvider
+ )
+ return legacyL1XDM.populateTransaction.replayMessage(
+ resolved.target,
+ resolved.sender,
+ resolved.message,
+ resolved.messageNonce,
+ resolved.minGasLimit,
+ messageGasLimit,
+ opts?.overrides || {}
+ )
+ }
},
finalizeMessage: async (
@@ -1055,15 +1323,48 @@ export class CrossChainMessenger implements ICrossChainMessenger {
throw new Error(`cannot finalize L1 to L2 message`)
}
- const proof = await this.getMessageProof(resolved)
- return this.contracts.l1.L1CrossDomainMessenger.populateTransaction.relayMessage(
- resolved.target,
- resolved.sender,
- resolved.message,
- resolved.messageNonce,
- proof,
- opts?.overrides || {}
- )
+ if (this.bedrock) {
+ const [proof, output, withdrawalTx] = await this.getBedrockMessageProof(
+ message
+ )
+
+ return this.contracts.l1.OptimismPortal.populateTransaction.finalizeWithdrawalTransaction(
+ [
+ withdrawalTx.messageNonce,
+ withdrawalTx.sender,
+ withdrawalTx.target,
+ withdrawalTx.value,
+ withdrawalTx.minGasLimit,
+ withdrawalTx.message,
+ ],
+ output.l2BlockNumber,
+ [
+ proof.outputRootProof.version,
+ proof.outputRootProof.stateRoot,
+ proof.outputRootProof.withdrawerStorageRoot,
+ proof.outputRootProof.latestBlockhash,
+ ],
+ proof.withdrawalProof
+ )
+ } else {
+ // L1CrossDomainMessenger relayMessage is the only method that isn't fully backwards
+ // compatible, so we need to use the legacy interface. When we fully upgrade to Bedrock we
+ // should be able to remove this code.
+ const proof = await this.getMessageProof(resolved)
+ const legacyL1XDM = new ethers.Contract(
+ this.contracts.l1.L1CrossDomainMessenger.address,
+ getContractInterface('L1CrossDomainMessenger'),
+ this.l1SignerOrProvider
+ )
+ return legacyL1XDM.populateTransaction.relayMessage(
+ resolved.target,
+ resolved.sender,
+ resolved.message,
+ resolved.messageNonce,
+ proof,
+ opts?.overrides || {}
+ )
+ }
},
depositETH: async (
diff --git a/packages/sdk/src/interfaces/cross-chain-messenger.ts b/packages/sdk/src/interfaces/cross-chain-messenger.ts
index 6cc1a9942b195..2c598215d149c 100644
--- a/packages/sdk/src/interfaces/cross-chain-messenger.ts
+++ b/packages/sdk/src/interfaces/cross-chain-messenger.ts
@@ -6,8 +6,13 @@ import {
TransactionResponse,
} from '@ethersproject/abstract-provider'
import { Signer } from '@ethersproject/abstract-signer'
+import {
+ BedrockCrossChainMessageProof,
+ BedrockOutputData,
+} from '@eth-optimism/core-utils'
import {
+ CoreCrossChainMessage,
MessageLike,
MessageRequestLike,
TransactionLike,
@@ -91,6 +96,11 @@ export interface ICrossChainMessenger {
*/
l1BlockTimeSeconds: number
+ /**
+ * Whether or not Bedrock compatibility is enabled.
+ */
+ bedrock: boolean
+
/**
* Retrieves all cross chain messages sent within a given transaction.
*
@@ -291,6 +301,16 @@ export interface ICrossChainMessenger {
*/
getChallengePeriodSeconds(): Promise
+ /**
+ * Returns the Bedrock output root that corresponds to the given message.
+ *
+ * @param message Message to get the Bedrock output root for.
+ * @returns Bedrock output root.
+ */
+ getMessageBedrockOutput(
+ message: MessageLike
+ ): Promise
+
/**
* Returns the state root that corresponds to a given message. This is the state root for the
* block in which the transaction was included, as published to the StateCommitmentChain. If the
@@ -342,6 +362,18 @@ export interface ICrossChainMessenger {
*/
getMessageProof(message: MessageLike): Promise
+ /**
+ * Generates the bedrock proof required to finalize an L2 to L1 message.
+ *
+ * @param message Message to generate a proof for.
+ * @returns Proof that can be used to finalize the message.
+ */
+ getBedrockMessageProof(
+ message: MessageLike
+ ): Promise<
+ [BedrockCrossChainMessageProof, BedrockOutputData, CoreCrossChainMessage]
+ >
+
/**
* Sends a given cross chain message. Where the message is sent depends on the direction attached
* to the message itself.
diff --git a/packages/sdk/src/interfaces/types.ts b/packages/sdk/src/interfaces/types.ts
index 93b45a41ce246..a70795b7f79af 100644
--- a/packages/sdk/src/interfaces/types.ts
+++ b/packages/sdk/src/interfaces/types.ts
@@ -17,6 +17,7 @@ export enum L1ChainID {
GOERLI = 5,
KOVAN = 42,
HARDHAT_LOCAL = 31337,
+ BEDROCK_LOCAL_DEVNET = 900,
}
/**
@@ -28,6 +29,7 @@ export enum L2ChainID {
OPTIMISM_KOVAN = 69,
OPTIMISM_HARDHAT_LOCAL = 31337,
OPTIMISM_HARDHAT_DEVNET = 17,
+ OPTIMISM_BEDROCK_LOCAL_DEVNET = 901,
}
/**
@@ -40,6 +42,9 @@ export interface OEL1Contracts {
StateCommitmentChain: Contract
CanonicalTransactionChain: Contract
BondManager: Contract
+ // Bedrock
+ OptimismPortal: Contract
+ L2OutputOracle: Contract
}
/**
@@ -48,6 +53,7 @@ export interface OEL1Contracts {
export interface OEL2Contracts {
L2CrossDomainMessenger: Contract
L2StandardBridge: Contract
+ L2ToL1MessagePasser: Contract
OVM_L1BlockNumber: Contract
OVM_L2ToL1MessagePasser: Contract
OVM_DeployerWhitelist: Contract
@@ -174,7 +180,9 @@ export interface CoreCrossChainMessage {
sender: string
target: string
message: string
- messageNonce: number
+ messageNonce: BigNumber
+ value: BigNumber
+ minGasLimit: BigNumber
}
/**
@@ -183,7 +191,6 @@ export interface CoreCrossChainMessage {
*/
export interface CrossChainMessage extends CoreCrossChainMessage {
direction: MessageDirection
- gasLimit: number
logIndex: number
blockNumber: number
transactionHash: string
diff --git a/packages/sdk/src/utils/chain-constants.ts b/packages/sdk/src/utils/chain-constants.ts
index d7d290aa92a87..73144ab784d14 100644
--- a/packages/sdk/src/utils/chain-constants.ts
+++ b/packages/sdk/src/utils/chain-constants.ts
@@ -8,6 +8,7 @@ export const DEPOSIT_CONFIRMATION_BLOCKS: {
[L2ChainID.OPTIMISM_KOVAN]: 12 as const,
[L2ChainID.OPTIMISM_HARDHAT_LOCAL]: 2 as const,
[L2ChainID.OPTIMISM_HARDHAT_DEVNET]: 2 as const,
+ [L2ChainID.OPTIMISM_BEDROCK_LOCAL_DEVNET]: 2 as const,
}
export const CHAIN_BLOCK_TIMES: {
@@ -17,4 +18,5 @@ export const CHAIN_BLOCK_TIMES: {
[L1ChainID.GOERLI]: 15 as const,
[L1ChainID.KOVAN]: 4 as const,
[L1ChainID.HARDHAT_LOCAL]: 1 as const,
+ [L1ChainID.BEDROCK_LOCAL_DEVNET]: 15 as const,
}
diff --git a/packages/sdk/src/utils/contracts.ts b/packages/sdk/src/utils/contracts.ts
index 3f63917ab3481..2bc4772fd03b8 100644
--- a/packages/sdk/src/utils/contracts.ts
+++ b/packages/sdk/src/utils/contracts.ts
@@ -1,4 +1,5 @@
import { getContractInterface, predeploys } from '@eth-optimism/contracts'
+import { getContractInterface as getContractInterfaceBedrock } from '@eth-optimism/contracts-bedrock'
import { ethers, Contract } from 'ethers'
import { toAddress } from './coercion'
@@ -23,9 +24,11 @@ import {
/**
* Full list of default L2 contract addresses.
+ * TODO(tynes): migrate to predeploys from contracts-bedrock
*/
export const DEFAULT_L2_CONTRACT_ADDRESSES: OEL2ContractsLike = {
L2CrossDomainMessenger: predeploys.L2CrossDomainMessenger,
+ L2ToL1MessagePasser: predeploys.OVM_L2ToL1MessagePasser,
L2StandardBridge: predeploys.L2StandardBridge,
OVM_L1BlockNumber: predeploys.OVM_L1BlockNumber,
OVM_L2ToL1MessagePasser: predeploys.OVM_L2ToL1MessagePasser,
@@ -65,6 +68,8 @@ export const CONTRACT_ADDRESSES: {
CanonicalTransactionChain:
'0x5E4e65926BA27467555EB562121fac00D24E9dD2' as const,
BondManager: '0xcd626E1328b41fCF24737F137BcD4CE0c32bc8d1' as const,
+ OptimismPortal: '0x0000000000000000000000000000000000000000' as const,
+ L2OutputOracle: '0x0000000000000000000000000000000000000000' as const,
},
l2: DEFAULT_L2_CONTRACT_ADDRESSES,
},
@@ -79,6 +84,8 @@ export const CONTRACT_ADDRESSES: {
CanonicalTransactionChain:
'0xf7B88A133202d41Fe5E2Ab22e6309a1A4D50AF74' as const,
BondManager: '0xc5a603d273E28185c18Ba4d26A0024B2d2F42740' as const,
+ OptimismPortal: '0x0000000000000000000000000000000000000000' as const,
+ L2OutputOracle: '0x0000000000000000000000000000000000000000' as const,
},
l2: DEFAULT_L2_CONTRACT_ADDRESSES,
},
@@ -93,6 +100,8 @@ export const CONTRACT_ADDRESSES: {
CanonicalTransactionChain:
'0x607F755149cFEB3a14E1Dc3A4E2450Cde7dfb04D' as const,
BondManager: '0xfC2ab6987C578218f99E85d61Dcf4814A26637Bd' as const,
+ OptimismPortal: '0x0000000000000000000000000000000000000000' as const,
+ L2OutputOracle: '0x0000000000000000000000000000000000000000' as const,
},
l2: DEFAULT_L2_CONTRACT_ADDRESSES,
},
@@ -107,6 +116,8 @@ export const CONTRACT_ADDRESSES: {
CanonicalTransactionChain:
'0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9' as const,
BondManager: '0x5FC8d32690cc91D4c39d9d3abcBD16989F875707' as const,
+ OptimismPortal: '0x0000000000000000000000000000000000000000' as const,
+ L2OutputOracle: '0x0000000000000000000000000000000000000000' as const,
},
l2: DEFAULT_L2_CONTRACT_ADDRESSES,
},
@@ -121,6 +132,24 @@ export const CONTRACT_ADDRESSES: {
CanonicalTransactionChain:
'0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9' as const,
BondManager: '0x5FC8d32690cc91D4c39d9d3abcBD16989F875707' as const,
+ OptimismPortal: '0x0000000000000000000000000000000000000000' as const,
+ L2OutputOracle: '0x0000000000000000000000000000000000000000' as const,
+ },
+ l2: DEFAULT_L2_CONTRACT_ADDRESSES,
+ },
+ [L2ChainID.OPTIMISM_BEDROCK_LOCAL_DEVNET]: {
+ l1: {
+ AddressManager: '0x5FbDB2315678afecb367f032d93F642f64180aa3' as const,
+ L1CrossDomainMessenger:
+ '0x0165878A594ca255338adfa4d48449f69242Eb8F' as const,
+ L1StandardBridge: '0x8A791620dd6260079BF849Dc5567aDC3F2FdC318' as const,
+ StateCommitmentChain:
+ '0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9' as const,
+ CanonicalTransactionChain:
+ '0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9' as const,
+ BondManager: '0x5FC8d32690cc91D4c39d9d3abcBD16989F875707' as const,
+ OptimismPortal: '0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9' as const,
+ L2OutputOracle: '0x5FbDB2315678afecb367f032d93F642f64180aa3' as const,
},
l2: DEFAULT_L2_CONTRACT_ADDRESSES,
},
@@ -145,6 +174,11 @@ export const BRIDGE_ADAPTER_DATA: {
},
},
[L2ChainID.OPTIMISM_KOVAN]: {
+ wstETH: {
+ Adapter: DAIBridgeAdapter,
+ l1Bridge: '0xa88751C0a08623E11ff38c6B70F2BbEe7865C17c' as const,
+ l2Bridge: '0xF9C842dE4381a70eB265d10CF8D43DceFF5bA935' as const,
+ },
BitBTC: {
Adapter: StandardBridgeAdapter,
l1Bridge: '0x0b651A42F32069d62d5ECf4f2a7e5Bd3E9438746' as const,
@@ -191,11 +225,21 @@ export const getOEContract = (
)
}
+ // Bedrock interfaces are backwards compatible. We can prefer Bedrock interfaces over legacy
+ // interfaces if they exist.
+ const name = NAME_REMAPPING[contractName] || contractName
+ let iface: ethers.utils.Interface
+ try {
+ iface = getContractInterfaceBedrock(name)
+ } catch (err) {
+ iface = getContractInterface(name)
+ }
+
return new Contract(
toAddress(
opts.address || addresses.l1[contractName] || addresses.l2[contractName]
),
- getContractInterface(NAME_REMAPPING[contractName] || contractName),
+ iface,
opts.signerOrProvider
)
}
@@ -230,6 +274,8 @@ export const getAllOEContracts = (
StateCommitmentChain: undefined,
CanonicalTransactionChain: undefined,
BondManager: undefined,
+ OptimismPortal: undefined,
+ L2OutputOracle: undefined,
},
l2: DEFAULT_L2_CONTRACT_ADDRESSES,
}
diff --git a/packages/sdk/src/utils/index.ts b/packages/sdk/src/utils/index.ts
index 41dcf3a1375ee..eed51741f042d 100644
--- a/packages/sdk/src/utils/index.ts
+++ b/packages/sdk/src/utils/index.ts
@@ -1,6 +1,5 @@
export * from './coercion'
export * from './contracts'
-export * from './message-encoding'
export * from './type-utils'
export * from './misc-utils'
export * from './merkle-utils'
diff --git a/packages/sdk/src/utils/merkle-utils.ts b/packages/sdk/src/utils/merkle-utils.ts
index 5e47edfcdc0b0..50244328ddffa 100644
--- a/packages/sdk/src/utils/merkle-utils.ts
+++ b/packages/sdk/src/utils/merkle-utils.ts
@@ -1,12 +1,11 @@
/* Imports: External */
-import { ethers } from 'ethers'
+import { ethers, BigNumber } from 'ethers'
import {
fromHexString,
toHexString,
toRpcHexString,
} from '@eth-optimism/core-utils'
import { MerkleTree } from 'merkletreejs'
-import * as rlp from 'rlp'
/**
* Generates a Merkle proof (using the particular scheme we use within Lib_MerkleTree).
@@ -60,8 +59,10 @@ export const makeStateTrieProof = async (
address: string,
slot: string
): Promise<{
- accountProof: string
- storageProof: string
+ accountProof: string[]
+ storageProof: string[]
+ storageValue: BigNumber
+ storageRoot: string
}> => {
const proof = await provider.send('eth_getProof', [
address,
@@ -70,7 +71,9 @@ export const makeStateTrieProof = async (
])
return {
- accountProof: toHexString(rlp.encode(proof.accountProof)),
- storageProof: toHexString(rlp.encode(proof.storageProof[0].proof)),
+ accountProof: proof.accountProof,
+ storageProof: proof.storageProof[0].proof,
+ storageValue: BigNumber.from(proof.storageProof[0].value),
+ storageRoot: proof.storageHash,
}
}
diff --git a/packages/sdk/src/utils/message-encoding.ts b/packages/sdk/src/utils/message-encoding.ts
deleted file mode 100644
index 4915946928517..0000000000000
--- a/packages/sdk/src/utils/message-encoding.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { getContractInterface } from '@eth-optimism/contracts'
-import { ethers } from 'ethers'
-
-import { CoreCrossChainMessage } from '../interfaces'
-
-/**
- * Returns the canonical encoding of a cross chain message. This encoding is used in various
- * locations within the Optimism smart contracts.
- *
- * @param message Cross chain message to encode.
- * @returns Canonical encoding of the message.
- */
-export const encodeCrossChainMessage = (
- message: CoreCrossChainMessage
-): string => {
- return getContractInterface('L2CrossDomainMessenger').encodeFunctionData(
- 'relayMessage',
- [message.target, message.sender, message.message, message.messageNonce]
- )
-}
-
-/**
- * Returns the canonical hash of a cross chain message. This hash is used in various locations
- * within the Optimism smart contracts and is the keccak256 hash of the result of
- * encodeCrossChainMessage.
- *
- * @param message Cross chain message to hash.
- * @returns Canonical hash of the message.
- */
-export const hashCrossChainMessage = (
- message: CoreCrossChainMessage
-): string => {
- return ethers.utils.solidityKeccak256(
- ['bytes'],
- [encodeCrossChainMessage(message)]
- )
-}
diff --git a/packages/sdk/tasks/deposit.ts b/packages/sdk/tasks/deposit.ts
new file mode 100644
index 0000000000000..59dab27efc7d3
--- /dev/null
+++ b/packages/sdk/tasks/deposit.ts
@@ -0,0 +1,214 @@
+import { task, types } from 'hardhat/config'
+import '@nomiclabs/hardhat-ethers'
+import 'hardhat-deploy'
+import {
+ predeploys,
+ getContractInterface,
+} from '@eth-optimism/contracts-bedrock'
+import { Event } from 'ethers'
+
+import {
+ CrossChainMessenger,
+ StandardBridgeAdapter,
+ MessageStatus,
+} from '../src'
+
+// TODO(tynes): this task could be modularized in the future
+// so that it can deposit an arbitrary token. Right now it
+// deploys a WETH9 contract, mints some WETH9 and then
+// deposits that into L2 through the StandardBridge
+task('deposit', 'Deposits WETH9 onto L2.')
+ .addParam(
+ 'l2ProviderUrl',
+ 'L2 provider URL.',
+ 'http://localhost:9545',
+ types.string
+ )
+ .addParam(
+ 'opNodeProviderUrl',
+ 'op-node provider URL',
+ 'http://localhost:7545',
+ types.string
+ )
+ .setAction(async (args, hre) => {
+ const { utils } = hre.ethers
+
+ const signers = await hre.ethers.getSigners()
+ if (signers.length === 0) {
+ throw new Error('No configured signers')
+ }
+ // Use the first configured signer for simplicity
+ const signer = signers[0]
+ const address = await signer.getAddress()
+ console.log(`Using signer ${address}`)
+
+ // Ensure that the signer has a balance before trying to
+ // do anything
+ const balance = await signer.getBalance()
+ if (balance.eq(0)) {
+ throw new Error('Signer has no balance')
+ }
+
+ const l2Provider = new hre.ethers.providers.StaticJsonRpcProvider(
+ args.l2ProviderUrl
+ )
+
+ const Deployment__L2OutputOracleProxy = await hre.deployments.get(
+ 'L2OutputOracleProxy'
+ )
+
+ const l2Signer = new hre.ethers.Wallet(
+ hre.network.config.accounts[0],
+ l2Provider
+ )
+
+ const Artifact__WETH9 = await hre.deployments.getArtifact('WETH9')
+ const Factory__WETH9 = new hre.ethers.ContractFactory(
+ Artifact__WETH9.abi,
+ Artifact__WETH9.bytecode,
+ signer
+ )
+
+ const Deployment__OptimismMintableERC20TokenFactory =
+ await hre.deployments.get('OptimismMintableERC20Factory')
+
+ const Deployment__OptimismPortalProxy = await hre.deployments.get(
+ 'OptimismPortalProxy'
+ )
+
+ const Deployment__L1StandardBridgeProxy = await hre.deployments.get(
+ 'L1StandardBridgeProxy'
+ )
+
+ const Deployment__L1CrossDomainMessengerProxy = await hre.deployments.get(
+ 'L1CrossDomainMessengerProxy'
+ )
+
+ const messenger = new CrossChainMessenger({
+ l1SignerOrProvider: signer,
+ l2SignerOrProvider: l2Signer,
+ l1ChainId: await signer.getChainId(),
+ l2ChainId: await l2Signer.getChainId(),
+ bridges: {
+ Standard: {
+ Adapter: StandardBridgeAdapter,
+ l1Bridge: Deployment__L1StandardBridgeProxy.address,
+ l2Bridge: predeploys.L2StandardBridge,
+ },
+ },
+ contracts: {
+ l1: {
+ L1StandardBridge: Deployment__L1StandardBridgeProxy.address,
+ L1CrossDomainMessenger:
+ Deployment__L1CrossDomainMessengerProxy.address,
+ L2OutputOracle: Deployment__L2OutputOracleProxy.address,
+ OptimismPortal: Deployment__OptimismPortalProxy.address,
+ },
+ },
+ bedrock: true,
+ })
+
+ const OptimismMintableERC20TokenFactory = await hre.ethers.getContractAt(
+ Deployment__OptimismMintableERC20TokenFactory.abi,
+ predeploys.OptimismMintableERC20Factory,
+ l2Signer
+ )
+
+ console.log('Deploying WETH9 to L1')
+ const WETH9 = await Factory__WETH9.deploy()
+ await WETH9.deployTransaction.wait()
+ console.log(`Deployed to ${WETH9.address}`)
+
+ console.log('Creating L2 WETH9')
+ const deployTx =
+ await OptimismMintableERC20TokenFactory.createOptimismMintableERC20(
+ WETH9.address,
+ 'L2 Wrapped Ether',
+ 'L2-WETH9'
+ )
+ const receipt = await deployTx.wait()
+ const event = receipt.events.find(
+ (e: Event) => e.event === 'OptimismMintableERC20Created'
+ )
+ if (!event) {
+ throw new Error('Unable to find OptimismMintableERC20Created event')
+ }
+ // TODO(tynes): may need to be updated based on
+ // https://github.com/ethereum-optimism/optimism/pull/3104
+ const l2WethAddress = event.args.remoteToken
+ console.log(`Deployed to ${l2WethAddress}`)
+
+ console.log('Wrapping ETH')
+ const deposit = await signer.sendTransaction({
+ value: utils.parseEther('1'),
+ to: WETH9.address,
+ })
+ await deposit.wait()
+ console.log('ETH wrapped')
+
+ console.log(`Approving WETH9 for deposit`)
+ const approvalTx = await messenger.approveERC20(
+ WETH9.address,
+ l2WethAddress,
+ hre.ethers.constants.MaxUint256
+ )
+ await approvalTx.wait()
+ console.log('WETH9 approved')
+
+ console.log('Depositing WETH9 to L2')
+ const depositTx = await messenger.depositERC20(
+ WETH9.address,
+ l2WethAddress,
+ utils.parseEther('1')
+ )
+ await depositTx.wait()
+ console.log('ERC20 deposited')
+
+ const messageReceipt = await messenger.waitForMessageReceipt(depositTx)
+ if (messageReceipt.receiptStatus !== 1) {
+ throw new Error('deposit failed')
+ }
+
+ const L2WETH9 = new hre.ethers.Contract(
+ l2WethAddress,
+ getContractInterface('OptimismMintableERC20'),
+ l2Signer
+ )
+
+ const l2Balance = await L2WETH9.balanceOf(await signer.getAddress())
+ if (l2Balance.lt(utils.parseEther('1'))) {
+ throw new Error('bad deposit')
+ }
+ console.log('Deposit success')
+
+ console.log('Starting withdrawal')
+ const preBalance = await WETH9.balanceOf(signer.address)
+ const tx = await messenger.withdrawERC20(
+ WETH9.address,
+ l2WethAddress,
+ utils.parseEther('1')
+ )
+ await tx.wait()
+
+ setInterval(async () => {
+ const currentStatus = await messenger.getMessageStatus(tx)
+ console.log(`Message status: ${MessageStatus[currentStatus]}`)
+ }, 3000)
+
+ const now = Math.floor(Date.now() / 1000)
+
+ console.log('Waiting for message to be able to be relayed')
+ await messenger.waitForMessageStatus(tx, MessageStatus.READY_FOR_RELAY)
+
+ const finalize = await messenger.finalizeMessage(tx)
+ await finalize.wait()
+ console.log(`Took ${Math.floor(Date.now() / 1000) - now} seconds`)
+
+ const postBalance = await WETH9.balanceOf(signer.address)
+
+ const expectedBalance = preBalance.add(utils.parseEther('1'))
+ if (!expectedBalance.eq(postBalance)) {
+ throw new Error('Balance mismatch')
+ }
+ console.log('Withdrawal success')
+ })
diff --git a/packages/sdk/test/contracts/MockBridge.sol b/packages/sdk/test/contracts/MockBridge.sol
index fd46d11537cac..7f3b5155cfb12 100644
--- a/packages/sdk/test/contracts/MockBridge.sol
+++ b/packages/sdk/test/contracts/MockBridge.sol
@@ -80,7 +80,8 @@ contract MockBridge {
address(0),
hex"1234",
1234,
- 12345678
+ 12345678,
+ 0
)
);
}
@@ -101,7 +102,8 @@ contract MockBridge {
address(0),
hex"1234",
1234,
- 12345678
+ 12345678,
+ 0
)
);
}
diff --git a/packages/sdk/test/contracts/MockMessenger.sol b/packages/sdk/test/contracts/MockMessenger.sol
index c23360f427b76..724d90ed6778c 100644
--- a/packages/sdk/test/contracts/MockMessenger.sol
+++ b/packages/sdk/test/contracts/MockMessenger.sol
@@ -48,7 +48,8 @@ contract MockMessenger is ICrossDomainMessenger {
address sender;
bytes message;
uint256 messageNonce;
- uint256 gasLimit;
+ uint256 minGasLimit;
+ uint256 value;
}
function doNothing() public {
@@ -63,7 +64,7 @@ contract MockMessenger is ICrossDomainMessenger {
_params.sender,
_params.message,
_params.messageNonce,
- _params.gasLimit
+ _params.minGasLimit
);
}
diff --git a/packages/sdk/test/cross-chain-messenger.spec.ts b/packages/sdk/test/cross-chain-messenger.spec.ts
index 4b2a78d23c33b..91537431a1fb4 100644
--- a/packages/sdk/test/cross-chain-messenger.spec.ts
+++ b/packages/sdk/test/cross-chain-messenger.spec.ts
@@ -1,5 +1,5 @@
import { Provider } from '@ethersproject/abstract-provider'
-import { expectApprox } from '@eth-optimism/core-utils'
+import { expectApprox, hashCrossDomainMessage } from '@eth-optimism/core-utils'
import { predeploys } from '@eth-optimism/contracts'
import { Contract } from 'ethers'
import { ethers } from 'hardhat'
@@ -8,7 +8,6 @@ import { expect } from './setup'
import {
MessageDirection,
CONTRACT_ADDRESSES,
- hashCrossChainMessage,
omit,
MessageStatus,
CrossChainMessage,
@@ -18,7 +17,7 @@ import {
L1ChainID,
L2ChainID,
} from '../src'
-import { DUMMY_MESSAGE } from './helpers'
+import { DUMMY_MESSAGE, DUMMY_EXTENDED_MESSAGE } from './helpers'
describe('CrossChainMessenger', () => {
let l1Signer: any
@@ -202,6 +201,8 @@ describe('CrossChainMessenger', () => {
StateCommitmentChain: '0x' + '14'.repeat(20),
CanonicalTransactionChain: '0x' + '15'.repeat(20),
BondManager: '0x' + '16'.repeat(20),
+ OptimismPortal: '0x' + '17'.repeat(20),
+ L2OutputOracle: '0x' + '18'.repeat(20),
},
l2: {
L2CrossDomainMessenger: '0x' + '22'.repeat(20),
@@ -318,7 +319,8 @@ describe('CrossChainMessenger', () => {
target: message.target,
message: message.message,
messageNonce: ethers.BigNumber.from(message.messageNonce),
- gasLimit: ethers.BigNumber.from(message.gasLimit),
+ minGasLimit: ethers.BigNumber.from(message.minGasLimit),
+ value: ethers.BigNumber.from(message.value),
logIndex: i,
blockNumber: tx.blockNumber,
transactionHash: tx.hash,
@@ -370,7 +372,8 @@ describe('CrossChainMessenger', () => {
target: message.target,
message: message.message,
messageNonce: ethers.BigNumber.from(message.messageNonce),
- gasLimit: ethers.BigNumber.from(message.gasLimit),
+ minGasLimit: ethers.BigNumber.from(message.minGasLimit),
+ value: ethers.BigNumber.from(message.value),
logIndex: i,
blockNumber: tx.blockNumber,
transactionHash: tx.hash,
@@ -497,15 +500,8 @@ describe('CrossChainMessenger', () => {
describe('when the input is a CrossChainMessage', () => {
it('should return the input', async () => {
const message = {
+ ...DUMMY_EXTENDED_MESSAGE,
direction: MessageDirection.L1_TO_L2,
- target: '0x' + '11'.repeat(20),
- sender: '0x' + '22'.repeat(20),
- message: '0x' + '33'.repeat(64),
- messageNonce: 1234,
- gasLimit: 0,
- logIndex: 0,
- blockNumber: 1234,
- transactionHash: '0x' + '44'.repeat(32),
}
expect(await messenger.toCrossChainMessage(message)).to.deep.equal(
@@ -655,7 +651,14 @@ describe('CrossChainMessenger', () => {
)
await l2Messenger.triggerRelayedMessageEvents([
- hashCrossChainMessage(message),
+ hashCrossDomainMessage(
+ message.messageNonce,
+ message.sender,
+ message.target,
+ message.value,
+ message.minGasLimit,
+ message.message
+ ),
])
expect(await messenger.getMessageStatus(message)).to.equal(
@@ -671,7 +674,14 @@ describe('CrossChainMessenger', () => {
)
await l2Messenger.triggerFailedRelayedMessageEvents([
- hashCrossChainMessage(message),
+ hashCrossDomainMessage(
+ message.messageNonce,
+ message.sender,
+ message.target,
+ message.value,
+ message.minGasLimit,
+ message.message
+ ),
])
expect(await messenger.getMessageStatus(message)).to.equal(
@@ -722,7 +732,14 @@ describe('CrossChainMessenger', () => {
ethers.provider.send('evm_mine', [])
await l1Messenger.triggerRelayedMessageEvents([
- hashCrossChainMessage(message),
+ hashCrossDomainMessage(
+ message.messageNonce,
+ message.sender,
+ message.target,
+ message.value,
+ message.minGasLimit,
+ message.message
+ ),
])
expect(await messenger.getMessageStatus(message)).to.equal(
@@ -744,7 +761,14 @@ describe('CrossChainMessenger', () => {
ethers.provider.send('evm_mine', [])
await l1Messenger.triggerFailedRelayedMessageEvents([
- hashCrossChainMessage(message),
+ hashCrossDomainMessage(
+ message.messageNonce,
+ message.sender,
+ message.target,
+ message.value,
+ message.minGasLimit,
+ message.message
+ ),
])
expect(await messenger.getMessageStatus(message)).to.equal(
@@ -821,19 +845,19 @@ describe('CrossChainMessenger', () => {
describe('when the relay was successful', () => {
it('should return the receipt of the transaction that relayed the message', async () => {
const message = {
+ ...DUMMY_EXTENDED_MESSAGE,
direction: MessageDirection.L1_TO_L2,
- target: '0x' + '11'.repeat(20),
- sender: '0x' + '22'.repeat(20),
- message: '0x' + '33'.repeat(64),
- messageNonce: 1234,
- gasLimit: 0,
- logIndex: 0,
- blockNumber: 1234,
- transactionHash: '0x' + '44'.repeat(32),
}
const tx = await l2Messenger.triggerRelayedMessageEvents([
- hashCrossChainMessage(message),
+ hashCrossDomainMessage(
+ message.messageNonce,
+ message.sender,
+ message.target,
+ message.value,
+ message.minGasLimit,
+ message.message
+ ),
])
const messageReceipt = await messenger.getMessageReceipt(message)
@@ -852,19 +876,19 @@ describe('CrossChainMessenger', () => {
describe('when the relay failed', () => {
it('should return the receipt of the transaction that attempted to relay the message', async () => {
const message = {
+ ...DUMMY_EXTENDED_MESSAGE,
direction: MessageDirection.L1_TO_L2,
- target: '0x' + '11'.repeat(20),
- sender: '0x' + '22'.repeat(20),
- message: '0x' + '33'.repeat(64),
- messageNonce: 1234,
- gasLimit: 0,
- logIndex: 0,
- blockNumber: 1234,
- transactionHash: '0x' + '44'.repeat(32),
}
const tx = await l2Messenger.triggerFailedRelayedMessageEvents([
- hashCrossChainMessage(message),
+ hashCrossDomainMessage(
+ message.messageNonce,
+ message.sender,
+ message.target,
+ message.value,
+ message.minGasLimit,
+ message.message
+ ),
])
const messageReceipt = await messenger.getMessageReceipt(message)
@@ -883,23 +907,30 @@ describe('CrossChainMessenger', () => {
describe('when the relay failed more than once', () => {
it('should return the receipt of the last transaction that attempted to relay the message', async () => {
const message = {
+ ...DUMMY_EXTENDED_MESSAGE,
direction: MessageDirection.L1_TO_L2,
- target: '0x' + '11'.repeat(20),
- sender: '0x' + '22'.repeat(20),
- message: '0x' + '33'.repeat(64),
- messageNonce: 1234,
- gasLimit: 0,
- logIndex: 0,
- blockNumber: 1234,
- transactionHash: '0x' + '44'.repeat(32),
}
await l2Messenger.triggerFailedRelayedMessageEvents([
- hashCrossChainMessage(message),
+ hashCrossDomainMessage(
+ message.messageNonce,
+ message.sender,
+ message.target,
+ message.value,
+ message.minGasLimit,
+ message.message
+ ),
])
const tx = await l2Messenger.triggerFailedRelayedMessageEvents([
- hashCrossChainMessage(message),
+ hashCrossDomainMessage(
+ message.messageNonce,
+ message.sender,
+ message.target,
+ message.value,
+ message.minGasLimit,
+ message.message
+ ),
])
const messageReceipt = await messenger.getMessageReceipt(message)
@@ -919,15 +950,8 @@ describe('CrossChainMessenger', () => {
describe('when the message has not been relayed', () => {
it('should return null', async () => {
const message = {
+ ...DUMMY_EXTENDED_MESSAGE,
direction: MessageDirection.L1_TO_L2,
- target: '0x' + '11'.repeat(20),
- sender: '0x' + '22'.repeat(20),
- message: '0x' + '33'.repeat(64),
- messageNonce: 1234,
- gasLimit: 0,
- logIndex: 0,
- blockNumber: 1234,
- transactionHash: '0x' + '44'.repeat(32),
}
await l2Messenger.doNothing()
@@ -965,19 +989,19 @@ describe('CrossChainMessenger', () => {
describe('when the message receipt already exists', () => {
it('should immediately return the receipt', async () => {
const message = {
+ ...DUMMY_EXTENDED_MESSAGE,
direction: MessageDirection.L1_TO_L2,
- target: '0x' + '11'.repeat(20),
- sender: '0x' + '22'.repeat(20),
- message: '0x' + '33'.repeat(64),
- messageNonce: 1234,
- gasLimit: 0,
- logIndex: 0,
- blockNumber: 1234,
- transactionHash: '0x' + '44'.repeat(32),
}
const tx = await l2Messenger.triggerRelayedMessageEvents([
- hashCrossChainMessage(message),
+ hashCrossDomainMessage(
+ message.messageNonce,
+ message.sender,
+ message.target,
+ message.value,
+ message.minGasLimit,
+ message.message
+ ),
])
const messageReceipt = await messenger.waitForMessageReceipt(message)
@@ -997,20 +1021,20 @@ describe('CrossChainMessenger', () => {
describe('when no extra options are provided', () => {
it('should wait for the receipt to be published', async () => {
const message = {
+ ...DUMMY_EXTENDED_MESSAGE,
direction: MessageDirection.L1_TO_L2,
- target: '0x' + '11'.repeat(20),
- sender: '0x' + '22'.repeat(20),
- message: '0x' + '33'.repeat(64),
- messageNonce: 1234,
- gasLimit: 0,
- logIndex: 0,
- blockNumber: 1234,
- transactionHash: '0x' + '44'.repeat(32),
}
setTimeout(async () => {
await l2Messenger.triggerRelayedMessageEvents([
- hashCrossChainMessage(message),
+ hashCrossDomainMessage(
+ message.messageNonce,
+ message.sender,
+ message.target,
+ message.value,
+ message.minGasLimit,
+ message.message
+ ),
])
}, 5000)
@@ -1030,15 +1054,8 @@ describe('CrossChainMessenger', () => {
describe('when a timeout is provided', () => {
it('should throw an error if the timeout is reached', async () => {
const message = {
+ ...DUMMY_EXTENDED_MESSAGE,
direction: MessageDirection.L1_TO_L2,
- target: '0x' + '11'.repeat(20),
- sender: '0x' + '22'.repeat(20),
- message: '0x' + '33'.repeat(64),
- messageNonce: 1234,
- gasLimit: 0,
- logIndex: 0,
- blockNumber: 1234,
- transactionHash: '0x' + '44'.repeat(32),
}
await expect(
@@ -1222,7 +1239,14 @@ describe('CrossChainMessenger', () => {
await l1Messenger.triggerSentMessageEvents([message])
await l2Messenger.triggerRelayedMessageEvents([
- hashCrossChainMessage(message),
+ hashCrossDomainMessage(
+ message.messageNonce,
+ message.sender,
+ message.target,
+ message.value,
+ message.minGasLimit,
+ message.message
+ ),
])
expect(
@@ -1294,7 +1318,14 @@ describe('CrossChainMessenger', () => {
await l2Messenger.triggerSentMessageEvents([message])
await l1Messenger.triggerRelayedMessageEvents([
- hashCrossChainMessage(message),
+ hashCrossDomainMessage(
+ message.messageNonce,
+ message.sender,
+ message.target,
+ message.value,
+ message.minGasLimit,
+ message.message
+ ),
])
expect(
diff --git a/packages/sdk/test/helpers/constants.ts b/packages/sdk/test/helpers/constants.ts
index eccdf7a848cd0..8a13a005c8086 100644
--- a/packages/sdk/test/helpers/constants.ts
+++ b/packages/sdk/test/helpers/constants.ts
@@ -1,7 +1,17 @@
+import { ethers } from 'ethers'
+
export const DUMMY_MESSAGE = {
target: '0x' + '11'.repeat(20),
sender: '0x' + '22'.repeat(20),
message: '0x' + '33'.repeat(64),
- messageNonce: 1234,
- gasLimit: 100000,
+ messageNonce: ethers.BigNumber.from(1234),
+ value: ethers.BigNumber.from(0),
+ minGasLimit: ethers.BigNumber.from(5678),
+}
+
+export const DUMMY_EXTENDED_MESSAGE = {
+ ...DUMMY_MESSAGE,
+ logIndex: 0,
+ blockNumber: 1234,
+ transactionHash: '0x' + '44'.repeat(32),
}
diff --git a/packages/sdk/test/utils/message-encoding.spec.ts b/packages/sdk/test/utils/message-encoding.spec.ts
deleted file mode 100644
index 232cefb22aafd..0000000000000
--- a/packages/sdk/test/utils/message-encoding.spec.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-import { Contract, Signer } from 'ethers'
-import { ethers } from 'hardhat'
-import { getContractFactory } from '@eth-optimism/contracts'
-
-import { expect } from '../setup'
-import {
- CoreCrossChainMessage,
- encodeCrossChainMessage,
- hashCrossChainMessage,
-} from '../../src'
-
-describe('message encoding utils', () => {
- let signers: Signer[]
- before(async () => {
- signers = (await ethers.getSigners()) as any
- })
-
- describe('encodeCrossChainMessage', () => {
- let Lib_CrossDomainUtils: Contract
- before(async () => {
- Lib_CrossDomainUtils = (await getContractFactory(
- 'TestLib_CrossDomainUtils',
- signers[0]
- ).deploy()) as any
- })
-
- it('should properly encode a message', async () => {
- const message: CoreCrossChainMessage = {
- target: '0x' + '11'.repeat(20),
- sender: '0x' + '22'.repeat(20),
- message: '0x' + '1234'.repeat(32),
- messageNonce: 1234,
- }
-
- const actual = encodeCrossChainMessage(message)
- const expected = await Lib_CrossDomainUtils.encodeXDomainCalldata(
- message.target,
- message.sender,
- message.message,
- message.messageNonce
- )
- expect(actual).to.equal(expected)
- })
- })
-
- describe('hashCrossChainMessage', () => {
- let MessageEncodingHelper: Contract
- before(async () => {
- MessageEncodingHelper = (await (
- await ethers.getContractFactory('MessageEncodingHelper')
- ).deploy()) as any
- })
-
- it('should properly hash a message', async () => {
- const message: CoreCrossChainMessage = {
- target: '0x' + '11'.repeat(20),
- sender: '0x' + '22'.repeat(20),
- message: '0x' + '1234'.repeat(32),
- messageNonce: 1234,
- }
-
- const actual = hashCrossChainMessage(message)
- const expected = await MessageEncodingHelper.hashXDomainCalldata(
- message.target,
- message.sender,
- message.message,
- message.messageNonce
- )
- expect(actual).to.equal(expected)
- })
- })
-})
diff --git a/packages/sdk/tsconfig.json b/packages/sdk/tsconfig.json
index a58b672ec1f60..5cb4fda3c5469 100644
--- a/packages/sdk/tsconfig.json
+++ b/packages/sdk/tsconfig.json
@@ -1,11 +1,9 @@
{
"extends": "../../tsconfig.json",
-
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"
},
-
"include": [
"src/**/*"
]
diff --git a/proxyd/backend.go b/proxyd/backend.go
index 46e52256957d2..80de372bb2a73 100644
--- a/proxyd/backend.go
+++ b/proxyd/backend.go
@@ -74,6 +74,11 @@ var (
Message: "gateway timeout",
HTTPErrorCode: 504,
}
+ ErrOverRateLimit = &RPCErr{
+ Code: JSONRPCErrorInternal - 16,
+ Message: "rate limited",
+ HTTPErrorCode: 429,
+ }
ErrBackendUnexpectedJSONRPC = errors.New("backend returned an unexpected JSON-RPC response")
)
@@ -92,7 +97,7 @@ type Backend struct {
wsURL string
authUsername string
authPassword string
- rateLimiter RateLimiter
+ rateLimiter BackendRateLimiter
client *LimitedHTTPClient
dialer *websocket.Dialer
maxRetries int
@@ -174,7 +179,7 @@ func NewBackend(
name string,
rpcURL string,
wsURL string,
- rateLimiter RateLimiter,
+ rateLimiter BackendRateLimiter,
rpcSemaphore *semaphore.Weighted,
opts ...BackendOpt,
) *Backend {
@@ -349,7 +354,17 @@ func (b *Backend) setOffline() {
}
func (b *Backend) doForward(ctx context.Context, rpcReqs []*RPCReq, isBatch bool) ([]*RPCRes, error) {
- body := mustMarshalJSON(rpcReqs)
+ isSingleElementBatch := len(rpcReqs) == 1
+
+ // Single element batches are unwrapped before being sent
+ // since Alchemy handles single requests better than batches.
+
+ var body []byte
+ if isSingleElementBatch {
+ body = mustMarshalJSON(rpcReqs[0])
+ } else {
+ body = mustMarshalJSON(rpcReqs)
+ }
httpReq, err := http.NewRequestWithContext(ctx, "POST", b.rpcURL, bytes.NewReader(body))
if err != nil {
@@ -362,10 +377,7 @@ func (b *Backend) doForward(ctx context.Context, rpcReqs []*RPCReq, isBatch bool
xForwardedFor := GetXForwardedFor(ctx)
if b.stripTrailingXFF {
- ipList := strings.Split(xForwardedFor, ", ")
- if len(ipList) > 0 {
- xForwardedFor = ipList[0]
- }
+ xForwardedFor = stripXFF(xForwardedFor)
} else if b.proxydIP != "" {
xForwardedFor = fmt.Sprintf("%s, %s", xForwardedFor, b.proxydIP)
}
@@ -402,12 +414,22 @@ func (b *Backend) doForward(ctx context.Context, rpcReqs []*RPCReq, isBatch bool
}
var res []*RPCRes
- if err := json.Unmarshal(resB, &res); err != nil {
- // Infura may return a single JSON-RPC response if, for example, the batch contains a request for an unsupported method
- if responseIsNotBatched(resB) {
- return nil, ErrBackendUnexpectedJSONRPC
+ if isSingleElementBatch {
+ var singleRes RPCRes
+ if err := json.Unmarshal(resB, &singleRes); err != nil {
+ return nil, ErrBackendBadResponse
+ }
+ res = []*RPCRes{
+ &singleRes,
+ }
+ } else {
+ if err := json.Unmarshal(resB, &res); err != nil {
+ // Infura may return a single JSON-RPC response if, for example, the batch contains a request for an unsupported method
+ if responseIsNotBatched(resB) {
+ return nil, ErrBackendUnexpectedJSONRPC
+ }
+ return nil, ErrBackendBadResponse
}
- return nil, ErrBackendBadResponse
}
if len(rpcReqs) != len(res) {
@@ -835,3 +857,8 @@ func RecordBatchRPCForward(ctx context.Context, backendName string, reqs []*RPCR
RecordRPCForward(ctx, backendName, req.Method, source)
}
}
+
+func stripXFF(xff string) string {
+ ipList := strings.Split(xff, ", ")
+ return strings.TrimSpace(ipList[0])
+}
diff --git a/proxyd/config.go b/proxyd/config.go
index 26929d9f6ef66..56eb3cc92690e 100644
--- a/proxyd/config.go
+++ b/proxyd/config.go
@@ -18,6 +18,9 @@ type ServerConfig struct {
TimeoutSeconds int `toml:"timeout_seconds"`
MaxUpstreamBatchSize int `toml:"max_upstream_batch_size"`
+
+ EnableRequestLog bool `toml:"enable_request_log"`
+ MaxRequestBodyLogLen int `toml:"max_request_body_log_len"`
}
type CacheConfig struct {
@@ -36,6 +39,13 @@ type MetricsConfig struct {
Port int `toml:"port"`
}
+type RateLimitConfig struct {
+ RatePerSecond int `toml:"rate_per_second"`
+ ExemptOrigins []string `toml:"exempt_origins"`
+ ExemptUserAgents []string `toml:"exempt_user_agents"`
+ ErrorMessage string `toml:"error_message"`
+}
+
type BackendOptions struct {
ResponseTimeoutSeconds int `toml:"response_timeout_seconds"`
MaxResponseSizeBytes int64 `toml:"max_response_size_bytes"`
@@ -72,6 +82,7 @@ type Config struct {
Cache CacheConfig `toml:"cache"`
Redis RedisConfig `toml:"redis"`
Metrics MetricsConfig `toml:"metrics"`
+ RateLimit RateLimitConfig `toml:"rate_limit"`
BackendOptions BackendOptions `toml:"backend"`
Backends BackendsConfig `toml:"backends"`
Authentication map[string]string `toml:"authentication"`
diff --git a/proxyd/go.mod b/proxyd/go.mod
index 73d7d85ded403..0a866b8883ad5 100644
--- a/proxyd/go.mod
+++ b/proxyd/go.mod
@@ -13,6 +13,7 @@ require (
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d
github.com/prometheus/client_golang v1.11.0
github.com/rs/cors v1.8.2
+ github.com/sethvargo/go-limiter v0.7.2
github.com/stretchr/testify v1.7.0
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
)
@@ -59,7 +60,7 @@ require (
github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/crypto v0.0.0-20220307211146-efcb8507fb70 // indirect
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 // indirect
- golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
+ golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
diff --git a/proxyd/go.sum b/proxyd/go.sum
index d6d5053ae52f3..8e5fd8d164966 100644
--- a/proxyd/go.sum
+++ b/proxyd/go.sum
@@ -451,6 +451,8 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
+github.com/sethvargo/go-limiter v0.7.2 h1:FgC4N7RMpV5gMrUdda15FaFTkQ/L4fEqM7seXMs4oO8=
+github.com/sethvargo/go-limiter v0.7.2/go.mod h1:C0kbSFbiriE5k2FFOe18M1YZbAR2Fiwf72uGu0CXCcU=
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
@@ -701,8 +703,8 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs=
-golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ=
+golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/proxyd/integration_tests/mock_backend_test.go b/proxyd/integration_tests/mock_backend_test.go
index b84b7d7b1c559..aa8f0bad0bc2b 100644
--- a/proxyd/integration_tests/mock_backend_test.go
+++ b/proxyd/integration_tests/mock_backend_test.go
@@ -35,8 +35,12 @@ func SingleResponseHandler(code int, response string) http.HandlerFunc {
}
func BatchedResponseHandler(code int, responses ...string) http.HandlerFunc {
- // all proxyd upstream requests are batched
return func(w http.ResponseWriter, r *http.Request) {
+ if len(responses) == 1 {
+ SingleResponseHandler(code, responses[0])(w, r)
+ return
+ }
+
var body string
body += "["
for i, response := range responses {
diff --git a/proxyd/integration_tests/rate_limit_test.go b/proxyd/integration_tests/rate_limit_test.go
index 409598e535d6c..4648017e997bb 100644
--- a/proxyd/integration_tests/rate_limit_test.go
+++ b/proxyd/integration_tests/rate_limit_test.go
@@ -1,8 +1,11 @@
package integration_tests
import (
+ "fmt"
+ "net/http"
"os"
"testing"
+ "time"
"github.com/ethereum-optimism/optimism/proxyd"
"github.com/stretchr/testify/require"
@@ -13,18 +16,83 @@ type resWithCode struct {
res []byte
}
-func TestMaxRPSLimit(t *testing.T) {
+const frontendOverLimitResponse = `{"error":{"code":-32016,"message":"over rate limit"},"id":null,"jsonrpc":"2.0"}`
+
+func TestBackendMaxRPSLimit(t *testing.T) {
goodBackend := NewMockBackend(BatchedResponseHandler(200, goodResponse))
defer goodBackend.Close()
require.NoError(t, os.Setenv("GOOD_BACKEND_RPC_URL", goodBackend.URL()))
- config := ReadConfig("rate_limit")
+ config := ReadConfig("backend_rate_limit")
client := NewProxydClient("http://127.0.0.1:8545")
shutdown, err := proxyd.Start(config)
require.NoError(t, err)
defer shutdown()
+ limitedRes, codes := spamReqs(t, client, 503)
+ require.Equal(t, 2, codes[200])
+ require.Equal(t, 1, codes[503])
+ RequireEqualJSON(t, []byte(noBackendsResponse), limitedRes)
+}
+
+func TestFrontendMaxRPSLimit(t *testing.T) {
+ goodBackend := NewMockBackend(BatchedResponseHandler(200, goodResponse))
+ defer goodBackend.Close()
+
+ require.NoError(t, os.Setenv("GOOD_BACKEND_RPC_URL", goodBackend.URL()))
+
+ config := ReadConfig("frontend_rate_limit")
+ shutdown, err := proxyd.Start(config)
+ require.NoError(t, err)
+ defer shutdown()
+
+ t.Run("non-exempt over limit", func(t *testing.T) {
+ client := NewProxydClient("http://127.0.0.1:8545")
+ limitedRes, codes := spamReqs(t, client, 429)
+ require.Equal(t, 1, codes[429])
+ require.Equal(t, 2, codes[200])
+ RequireEqualJSON(t, []byte(frontendOverLimitResponse), limitedRes)
+ })
+
+ t.Run("exempt user agent over limit", func(t *testing.T) {
+ h := make(http.Header)
+ h.Set("User-Agent", "exempt_agent")
+ client := NewProxydClientWithHeaders("http://127.0.0.1:8545", h)
+ _, codes := spamReqs(t, client, 429)
+ require.Equal(t, 3, codes[200])
+ })
+
+ t.Run("exempt origin over limit", func(t *testing.T) {
+ h := make(http.Header)
+ h.Set("Origin", "exempt_origin")
+ client := NewProxydClientWithHeaders("http://127.0.0.1:8545", h)
+ _, codes := spamReqs(t, client, 429)
+ fmt.Println(codes)
+ require.Equal(t, 3, codes[200])
+ })
+
+ t.Run("multiple xff", func(t *testing.T) {
+ h1 := make(http.Header)
+ h1.Set("X-Forwarded-For", "0.0.0.0")
+ h2 := make(http.Header)
+ h2.Set("X-Forwarded-For", "1.1.1.1")
+ client1 := NewProxydClientWithHeaders("http://127.0.0.1:8545", h1)
+ client2 := NewProxydClientWithHeaders("http://127.0.0.1:8545", h2)
+ _, codes := spamReqs(t, client1, 429)
+ require.Equal(t, 1, codes[429])
+ require.Equal(t, 2, codes[200])
+ _, code, err := client2.SendRPC("eth_chainId", nil)
+ require.Equal(t, 200, code)
+ require.NoError(t, err)
+ time.Sleep(time.Second)
+ _, code, err = client2.SendRPC("eth_chainId", nil)
+ require.Equal(t, 200, code)
+ require.NoError(t, err)
+ })
+}
+
+func spamReqs(t *testing.T, client *ProxydHTTPClient, limCode int) ([]byte, map[int]int) {
resCh := make(chan *resWithCode)
for i := 0; i < 3; i++ {
go func() {
@@ -48,13 +116,10 @@ func TestMaxRPSLimit(t *testing.T) {
codes[code] += 1
}
- // 503 because there's only one backend available
- if code == 503 {
+ if code == limCode {
limitedRes = res.res
}
}
- require.Equal(t, 2, codes[200])
- require.Equal(t, 1, codes[503])
- RequireEqualJSON(t, []byte(noBackendsResponse), limitedRes)
+ return limitedRes, codes
}
diff --git a/proxyd/integration_tests/testdata/rate_limit.toml b/proxyd/integration_tests/testdata/backend_rate_limit.toml
similarity index 100%
rename from proxyd/integration_tests/testdata/rate_limit.toml
rename to proxyd/integration_tests/testdata/backend_rate_limit.toml
diff --git a/proxyd/integration_tests/testdata/frontend_rate_limit.toml b/proxyd/integration_tests/testdata/frontend_rate_limit.toml
new file mode 100644
index 0000000000000..e838ace4bd26d
--- /dev/null
+++ b/proxyd/integration_tests/testdata/frontend_rate_limit.toml
@@ -0,0 +1,23 @@
+[server]
+rpc_port = 8545
+
+[backend]
+response_timeout_seconds = 1
+
+[backends]
+[backends.good]
+rpc_url = "$GOOD_BACKEND_RPC_URL"
+ws_url = "$GOOD_BACKEND_RPC_URL"
+
+[backend_groups]
+[backend_groups.main]
+backends = ["good"]
+
+[rpc_method_mappings]
+eth_chainId = "main"
+
+[rate_limit]
+rate_per_second = 2
+exempt_origins = ["exempt_origin"]
+exempt_user_agents = ["exempt_agent"]
+error_message = "over rate limit"
diff --git a/proxyd/integration_tests/util_test.go b/proxyd/integration_tests/util_test.go
index c5c15a6156c41..2e443f6f888a8 100644
--- a/proxyd/integration_tests/util_test.go
+++ b/proxyd/integration_tests/util_test.go
@@ -20,11 +20,21 @@ import (
)
type ProxydHTTPClient struct {
- url string
+ url string
+ headers http.Header
}
func NewProxydClient(url string) *ProxydHTTPClient {
- return &ProxydHTTPClient{url: url}
+ return NewProxydClientWithHeaders(url, make(http.Header))
+}
+
+func NewProxydClientWithHeaders(url string, headers http.Header) *ProxydHTTPClient {
+ clonedHeaders := headers.Clone()
+ clonedHeaders.Set("Content-Type", "application/json")
+ return &ProxydHTTPClient{
+ url: url,
+ headers: clonedHeaders,
+ }
}
func (p *ProxydHTTPClient) SendRPC(method string, params []interface{}) ([]byte, int, error) {
@@ -45,7 +55,13 @@ func (p *ProxydHTTPClient) SendBatchRPC(reqs ...*proxyd.RPCReq) ([]byte, int, er
}
func (p *ProxydHTTPClient) SendRequest(body []byte) ([]byte, int, error) {
- res, err := http.Post(p.url, "application/json", bytes.NewReader(body))
+ req, err := http.NewRequest("POST", p.url, bytes.NewReader(body))
+ if err != nil {
+ panic(err)
+ }
+ req.Header = p.headers
+
+ res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, -1, err
}
diff --git a/proxyd/integration_tests/ws_test.go b/proxyd/integration_tests/ws_test.go
index 6a63f719c3c0b..d93d3a7562485 100644
--- a/proxyd/integration_tests/ws_test.go
+++ b/proxyd/integration_tests/ws_test.go
@@ -44,11 +44,14 @@ func TestConcurrentWSPanic(t *testing.T) {
<-readyCh
+ var wg sync.WaitGroup
+ wg.Add(2)
// spam messages
go func() {
for {
select {
case <-quitC:
+ wg.Done()
return
default:
_ = backendToProxyConn.WriteMessage(websocket.TextMessage, []byte("garbage"))
@@ -61,6 +64,7 @@ func TestConcurrentWSPanic(t *testing.T) {
for {
select {
case <-quitC:
+ wg.Done()
return
default:
_ = client.WriteMessage(websocket.TextMessage, []byte("{\"id\": 1, \"method\": \"eth_foo\", \"params\": [\"newHeads\"]}"))
@@ -72,6 +76,7 @@ func TestConcurrentWSPanic(t *testing.T) {
// concurrent write to websocket connection
time.Sleep(time.Second)
close(quitC)
+ wg.Wait()
}
type backendHandler struct {
diff --git a/proxyd/proxyd.go b/proxyd/proxyd.go
index a730a608592e9..e9bbe42fc75f4 100644
--- a/proxyd/proxyd.go
+++ b/proxyd/proxyd.go
@@ -43,11 +43,11 @@ func Start(config *Config) (func(), error) {
redisURL = rURL
}
- var lim RateLimiter
+ var lim BackendRateLimiter
var err error
if redisURL == "" {
log.Warn("redis is not configured, using local rate limiter")
- lim = NewLocalRateLimiter()
+ lim = NewLocalBackendRateLimiter()
} else {
lim, err = NewRedisRateLimiter(redisURL)
if err != nil {
@@ -212,7 +212,7 @@ func Start(config *Config) (func(), error) {
rpcCache = newRPCCache(newCacheWithCompression(cache), blockNumFn, gasPriceFn, config.Cache.NumBlockConfirmations)
}
- srv := NewServer(
+ srv, err := NewServer(
backendGroups,
wsBackendGroup,
NewStringSetFromStrings(config.WSMethodWhitelist),
@@ -222,7 +222,13 @@ func Start(config *Config) (func(), error) {
secondsToDuration(config.Server.TimeoutSeconds),
config.Server.MaxUpstreamBatchSize,
rpcCache,
+ config.RateLimit,
+ config.Server.EnableRequestLog,
+ config.Server.MaxRequestBodyLogLen,
)
+ if err != nil {
+ return nil, fmt.Errorf("error creating server: %w", err)
+ }
if config.Metrics.Enabled {
addr := fmt.Sprintf("%s:%d", config.Metrics.Host, config.Metrics.Port)
diff --git a/proxyd/rate_limiter.go b/proxyd/rate_limiter.go
index 5c4a4d6260387..fe286e63b9f5d 100644
--- a/proxyd/rate_limiter.go
+++ b/proxyd/rate_limiter.go
@@ -41,7 +41,7 @@ end
return false
`
-type RateLimiter interface {
+type BackendRateLimiter interface {
IsBackendOnline(name string) (bool, error)
SetBackendOffline(name string, duration time.Duration) error
IncBackendRPS(name string) (int, error)
@@ -50,14 +50,14 @@ type RateLimiter interface {
FlushBackendWSConns(names []string) error
}
-type RedisRateLimiter struct {
+type RedisBackendRateLimiter struct {
rdb *redis.Client
randID string
touchKeys map[string]time.Duration
tkMtx sync.Mutex
}
-func NewRedisRateLimiter(url string) (RateLimiter, error) {
+func NewRedisRateLimiter(url string) (BackendRateLimiter, error) {
opts, err := redis.ParseURL(url)
if err != nil {
return nil, err
@@ -66,7 +66,7 @@ func NewRedisRateLimiter(url string) (RateLimiter, error) {
if err := rdb.Ping(context.Background()).Err(); err != nil {
return nil, wrapErr(err, "error connecting to redis")
}
- out := &RedisRateLimiter{
+ out := &RedisBackendRateLimiter{
rdb: rdb,
randID: randStr(20),
touchKeys: make(map[string]time.Duration),
@@ -75,7 +75,7 @@ func NewRedisRateLimiter(url string) (RateLimiter, error) {
return out, nil
}
-func (r *RedisRateLimiter) IsBackendOnline(name string) (bool, error) {
+func (r *RedisBackendRateLimiter) IsBackendOnline(name string) (bool, error) {
exists, err := r.rdb.Exists(context.Background(), fmt.Sprintf("backend:%s:offline", name)).Result()
if err != nil {
RecordRedisError("IsBackendOnline")
@@ -85,7 +85,7 @@ func (r *RedisRateLimiter) IsBackendOnline(name string) (bool, error) {
return exists == 0, nil
}
-func (r *RedisRateLimiter) SetBackendOffline(name string, duration time.Duration) error {
+func (r *RedisBackendRateLimiter) SetBackendOffline(name string, duration time.Duration) error {
if duration == 0 {
return nil
}
@@ -102,7 +102,7 @@ func (r *RedisRateLimiter) SetBackendOffline(name string, duration time.Duration
return nil
}
-func (r *RedisRateLimiter) IncBackendRPS(name string) (int, error) {
+func (r *RedisBackendRateLimiter) IncBackendRPS(name string) (int, error) {
cmd := r.rdb.Eval(
context.Background(),
MaxRPSScript,
@@ -116,7 +116,7 @@ func (r *RedisRateLimiter) IncBackendRPS(name string) (int, error) {
return rps, nil
}
-func (r *RedisRateLimiter) IncBackendWSConns(name string, max int) (bool, error) {
+func (r *RedisBackendRateLimiter) IncBackendWSConns(name string, max int) (bool, error) {
connsKey := fmt.Sprintf("proxy:%s:wsconns:%s", r.randID, name)
r.tkMtx.Lock()
r.touchKeys[connsKey] = 5 * time.Minute
@@ -142,7 +142,7 @@ func (r *RedisRateLimiter) IncBackendWSConns(name string, max int) (bool, error)
return incremented, nil
}
-func (r *RedisRateLimiter) DecBackendWSConns(name string) error {
+func (r *RedisBackendRateLimiter) DecBackendWSConns(name string) error {
connsKey := fmt.Sprintf("proxy:%s:wsconns:%s", r.randID, name)
err := r.rdb.Decr(context.Background(), connsKey).Err()
if err != nil {
@@ -152,7 +152,7 @@ func (r *RedisRateLimiter) DecBackendWSConns(name string) error {
return nil
}
-func (r *RedisRateLimiter) FlushBackendWSConns(names []string) error {
+func (r *RedisBackendRateLimiter) FlushBackendWSConns(names []string) error {
ctx := context.Background()
for _, name := range names {
connsKey := fmt.Sprintf("proxy:%s:wsconns:%s", r.randID, name)
@@ -172,7 +172,7 @@ func (r *RedisRateLimiter) FlushBackendWSConns(names []string) error {
return nil
}
-func (r *RedisRateLimiter) touch() {
+func (r *RedisBackendRateLimiter) touch() {
for {
r.tkMtx.Lock()
for key, dur := range r.touchKeys {
@@ -186,15 +186,15 @@ func (r *RedisRateLimiter) touch() {
}
}
-type LocalRateLimiter struct {
+type LocalBackendRateLimiter struct {
deadBackends map[string]time.Time
backendRPS map[string]int
backendWSConns map[string]int
mtx sync.RWMutex
}
-func NewLocalRateLimiter() *LocalRateLimiter {
- out := &LocalRateLimiter{
+func NewLocalBackendRateLimiter() *LocalBackendRateLimiter {
+ out := &LocalBackendRateLimiter{
deadBackends: make(map[string]time.Time),
backendRPS: make(map[string]int),
backendWSConns: make(map[string]int),
@@ -203,27 +203,27 @@ func NewLocalRateLimiter() *LocalRateLimiter {
return out
}
-func (l *LocalRateLimiter) IsBackendOnline(name string) (bool, error) {
+func (l *LocalBackendRateLimiter) IsBackendOnline(name string) (bool, error) {
l.mtx.RLock()
defer l.mtx.RUnlock()
return l.deadBackends[name].Before(time.Now()), nil
}
-func (l *LocalRateLimiter) SetBackendOffline(name string, duration time.Duration) error {
+func (l *LocalBackendRateLimiter) SetBackendOffline(name string, duration time.Duration) error {
l.mtx.Lock()
defer l.mtx.Unlock()
l.deadBackends[name] = time.Now().Add(duration)
return nil
}
-func (l *LocalRateLimiter) IncBackendRPS(name string) (int, error) {
+func (l *LocalBackendRateLimiter) IncBackendRPS(name string) (int, error) {
l.mtx.Lock()
defer l.mtx.Unlock()
l.backendRPS[name] += 1
return l.backendRPS[name], nil
}
-func (l *LocalRateLimiter) IncBackendWSConns(name string, max int) (bool, error) {
+func (l *LocalBackendRateLimiter) IncBackendWSConns(name string, max int) (bool, error) {
l.mtx.Lock()
defer l.mtx.Unlock()
if l.backendWSConns[name] == max {
@@ -233,7 +233,7 @@ func (l *LocalRateLimiter) IncBackendWSConns(name string, max int) (bool, error)
return true, nil
}
-func (l *LocalRateLimiter) DecBackendWSConns(name string) error {
+func (l *LocalBackendRateLimiter) DecBackendWSConns(name string) error {
l.mtx.Lock()
defer l.mtx.Unlock()
if l.backendWSConns[name] == 0 {
@@ -243,11 +243,11 @@ func (l *LocalRateLimiter) DecBackendWSConns(name string) error {
return nil
}
-func (l *LocalRateLimiter) FlushBackendWSConns(names []string) error {
+func (l *LocalBackendRateLimiter) FlushBackendWSConns(names []string) error {
return nil
}
-func (l *LocalRateLimiter) clear() {
+func (l *LocalBackendRateLimiter) clear() {
for {
time.Sleep(time.Second)
l.mtx.Lock()
@@ -263,3 +263,6 @@ func randStr(l int) string {
}
return hex.EncodeToString(b)
}
+
+type ServerRateLimiter struct {
+}
diff --git a/proxyd/rpc.go b/proxyd/rpc.go
index 5f16822a5ac14..ccd7c5f5c8b99 100644
--- a/proxyd/rpc.go
+++ b/proxyd/rpc.go
@@ -65,6 +65,14 @@ func (r *RPCErr) Error() string {
return r.Message
}
+func (r *RPCErr) Clone() *RPCErr {
+ return &RPCErr{
+ Code: r.Code,
+ Message: r.Message,
+ HTTPErrorCode: r.HTTPErrorCode,
+ }
+}
+
func IsValidID(id json.RawMessage) bool {
// handle the case where the ID is a string
if strings.HasPrefix(string(id), "\"") && strings.HasSuffix(string(id), "\"") {
diff --git a/proxyd/server.go b/proxyd/server.go
index f0db53180a510..27f3f0e95bcaa 100644
--- a/proxyd/server.go
+++ b/proxyd/server.go
@@ -14,6 +14,10 @@ import (
"sync"
"time"
+ "github.com/sethvargo/go-limiter"
+ "github.com/sethvargo/go-limiter/memorystore"
+ "github.com/sethvargo/go-limiter/noopstore"
+
"github.com/ethereum/go-ethereum/log"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
@@ -28,7 +32,7 @@ const (
MaxBatchRPCCalls = 100
cacheStatusHdr = "X-Proxyd-Cache-Status"
defaultServerTimeout = time.Second * 10
- maxLogLength = 2000
+ maxRequestBodyLogLen = 2000
defaultMaxUpstreamBatchSize = 10
)
@@ -40,10 +44,16 @@ type Server struct {
wsMethodWhitelist *StringSet
rpcMethodMappings map[string]string
maxBodySize int64
+ enableRequestLog bool
+ maxRequestBodyLogLen int
authenticatedPaths map[string]string
timeout time.Duration
maxUpstreamBatchSize int
upgrader *websocket.Upgrader
+ lim limiter.Store
+ limConfig RateLimitConfig
+ limExemptOrigins map[string]bool
+ limExemptUserAgents map[string]bool
rpcServer *http.Server
wsServer *http.Server
cache RPCCache
@@ -60,7 +70,10 @@ func NewServer(
timeout time.Duration,
maxUpstreamBatchSize int,
cache RPCCache,
-) *Server {
+ rateLimitConfig RateLimitConfig,
+ enableRequestLog bool,
+ maxRequestBodyLogLen int,
+) (*Server, error) {
if cache == nil {
cache = &NoopRPCCache{}
}
@@ -77,6 +90,29 @@ func NewServer(
maxUpstreamBatchSize = defaultMaxUpstreamBatchSize
}
+ var lim limiter.Store
+ limExemptOrigins := make(map[string]bool)
+ limExemptUserAgents := make(map[string]bool)
+ if rateLimitConfig.RatePerSecond > 0 {
+ var err error
+ lim, err = memorystore.New(&memorystore.Config{
+ Tokens: uint64(rateLimitConfig.RatePerSecond),
+ Interval: time.Second,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ for _, origin := range rateLimitConfig.ExemptOrigins {
+ limExemptOrigins[strings.ToLower(origin)] = true
+ }
+ for _, agent := range rateLimitConfig.ExemptUserAgents {
+ limExemptUserAgents[strings.ToLower(agent)] = true
+ }
+ } else {
+ lim, _ = noopstore.New()
+ }
+
return &Server{
backendGroups: backendGroups,
wsBackendGroup: wsBackendGroup,
@@ -87,10 +123,16 @@ func NewServer(
timeout: timeout,
maxUpstreamBatchSize: maxUpstreamBatchSize,
cache: cache,
+ enableRequestLog: enableRequestLog,
+ maxRequestBodyLogLen: maxRequestBodyLogLen,
upgrader: &websocket.Upgrader{
HandshakeTimeout: 5 * time.Second,
},
- }
+ lim: lim,
+ limConfig: rateLimitConfig,
+ limExemptOrigins: limExemptOrigins,
+ limExemptUserAgents: limExemptUserAgents,
+ }, nil
}
func (s *Server) RPCListenAndServe(host string, port int) error {
@@ -154,6 +196,28 @@ func (s *Server) HandleRPC(w http.ResponseWriter, r *http.Request) {
ctx, cancel = context.WithTimeout(ctx, s.timeout)
defer cancel()
+ exemptOrigin := s.limExemptOrigins[strings.ToLower(r.Header.Get("Origin"))]
+ exemptUserAgent := s.limExemptUserAgents[strings.ToLower(r.Header.Get("User-Agent"))]
+ var ok bool
+ if exemptOrigin || exemptUserAgent {
+ ok = true
+ } else {
+ // Use XFF in context since it will automatically be replaced by the remote IP
+ xff := stripXFF(GetXForwardedFor(ctx))
+ if xff == "" {
+ log.Warn("rejecting request without XFF or remote IP")
+ ok = false
+ } else {
+ _, _, _, ok, _ = s.lim.Take(ctx, xff)
+ }
+ }
+ if !ok {
+ rpcErr := ErrOverRateLimit.Clone()
+ rpcErr.Message = s.limConfig.ErrorMessage
+ writeRPCError(ctx, w, nil, rpcErr)
+ return
+ }
+
log.Info(
"received RPC request",
"req_id", GetReqID(ctx),
@@ -169,11 +233,13 @@ func (s *Server) HandleRPC(w http.ResponseWriter, r *http.Request) {
}
RecordRequestPayloadSize(ctx, len(body))
- log.Info("Raw RPC request",
- "body", truncate(string(body)),
- "req_id", GetReqID(ctx),
- "auth", GetAuthCtx(ctx),
- )
+ if s.enableRequestLog {
+ log.Info("Raw RPC request",
+ "body", truncate(string(body), s.maxRequestBodyLogLen),
+ "req_id", GetReqID(ctx),
+ "auth", GetAuthCtx(ctx),
+ )
+ }
if IsBatch(body) {
reqs, err := ParseBatchRPCReq(body)
@@ -382,6 +448,14 @@ func (s *Server) HandleWS(w http.ResponseWriter, r *http.Request) {
func (s *Server) populateContext(w http.ResponseWriter, r *http.Request) context.Context {
vars := mux.Vars(r)
authorization := vars["authorization"]
+ xff := r.Header.Get("X-Forwarded-For")
+ if xff == "" {
+ ipPort := strings.Split(r.RemoteAddr, ":")
+ if len(ipPort) == 2 {
+ xff = ipPort[0]
+ }
+ }
+ ctx := context.WithValue(r.Context(), ContextKeyXForwardedFor, xff) // nolint:staticcheck
if s.authenticatedPaths == nil {
// handle the edge case where auth is disabled
@@ -392,30 +466,17 @@ func (s *Server) populateContext(w http.ResponseWriter, r *http.Request) context
w.WriteHeader(404)
return nil
}
- return context.WithValue(
- r.Context(),
- ContextKeyReqID, // nolint:staticcheck
- randStr(10),
- )
- }
-
- if authorization == "" || s.authenticatedPaths[authorization] == "" {
- log.Info("blocked unauthorized request", "authorization", authorization)
- httpResponseCodesTotal.WithLabelValues("401").Inc()
- w.WriteHeader(401)
- return nil
- }
-
- xff := r.Header.Get("X-Forwarded-For")
- if xff == "" {
- ipPort := strings.Split(r.RemoteAddr, ":")
- if len(ipPort) == 2 {
- xff = ipPort[0]
+ } else {
+ if authorization == "" || s.authenticatedPaths[authorization] == "" {
+ log.Info("blocked unauthorized request", "authorization", authorization)
+ httpResponseCodesTotal.WithLabelValues("401").Inc()
+ w.WriteHeader(401)
+ return nil
}
+
+ ctx = context.WithValue(r.Context(), ContextKeyAuth, s.authenticatedPaths[authorization]) // nolint:staticcheck
}
- ctx := context.WithValue(r.Context(), ContextKeyAuth, s.authenticatedPaths[authorization]) // nolint:staticcheck
- ctx = context.WithValue(ctx, ContextKeyXForwardedFor, xff) // nolint:staticcheck
return context.WithValue(
ctx,
ContextKeyReqID, // nolint:staticcheck
@@ -527,9 +588,13 @@ func (n *NoopRPCCache) PutRPC(context.Context, *RPCReq, *RPCRes) error {
return nil
}
-func truncate(str string) string {
- if len(str) > maxLogLength {
- return str[:maxLogLength] + "..."
+func truncate(str string, maxLen int) string {
+ if maxLen == 0 {
+ maxLen = maxRequestBodyLogLen
+ }
+
+ if len(str) > maxLen {
+ return str[:maxLen] + "..."
} else {
return str
}
diff --git a/specs/README.md b/specs/README.md
index 0e29e5dca1c9a..13fd45658dcb0 100644
--- a/specs/README.md
+++ b/specs/README.md
@@ -1,7 +1,7 @@
# Optimism Bedrock specs
-This directory contains the plain english specs for Optimism, an minimal optimistic rollup protocol
+This directory contains the plain english specs for Optimism, a minimal optimistic rollup protocol
that maintains 1:1 compatibility with Ethereum.
## Specification Contents
diff --git a/specs/batcher.md b/specs/batcher.md
new file mode 100644
index 0000000000000..2ce1970922334
--- /dev/null
+++ b/specs/batcher.md
@@ -0,0 +1,25 @@
+
+# Batch Submitter
+
+The batch submitter, also referred to as the batcher, is the entity submitting the L2 sequencer data to L1,
+to make it available for verifiers.
+
+[derivation-spec]: ./derivation.md
+
+The format of the data transactions is defined in the [derivation spec]: the data is constructed from L2 blocks
+in the reverse order as it is derived from data into L2 blocks.
+
+The timing, operation and transaction signing is implementation-specific: any data can be submitted at any time,
+but only the data that matches the [derivation spec] rules will be valid from the verifier perspective.
+
+The most minimal batcher implementation can be defined as a loop of the following operations:
+
+1. See if the `unsafe` L2 block number is past the `safe` block number: `unsafe` data needs to be submitted.
+2. Iterate over all unsafe L2 blocks, skip any that were previously submitted.
+3. Open a channel, buffer all the L2 block data to be submitted,
+ while applying the encoding and compression as defined in the [derivation spec].
+4. Pull frames from the channel to fill data transactions with, until the channel is empty.
+5. Submit the data transactions to L1
+
+The L2 view of safe/unsafe does not instantly update after data is submitted, nor when it gets confirmed on L1,
+so special care may have to be taken to not duplicate data submissions.
diff --git a/specs/deposits.md b/specs/deposits.md
index f86d02b6df4d9..f8a7297c155a8 100644
--- a/specs/deposits.md
+++ b/specs/deposits.md
@@ -36,7 +36,7 @@ with the authorization and validation conditions on L2.
- [User-Deposited Transactions](#user-deposited-transactions)
- [Deposit Contract](#deposit-contract)
- [Address Aliasing](#address-aliasing)
- - [Deposit Feed Contract: Reference Implementation](#deposit-feed-contract-reference-implementation)
+ - [Deposit Contract Implementation: Optimism Portal](#deposit-contract-implementation-optimism-portal)
@@ -148,6 +148,9 @@ the gas pool on L2. Gas usage exactly matches other transaction types (including
If a deposit runs out of gas or has some other failure, the mint will succeed and the nonce of the
account will be increased, but no other state transition will occur.
+If `isSystemTransaction` in the deposit is set to `true`, the gas used by the deposit is unmetered.
+It must not be subtracted from the gas pool and the `usedGas` field of the receipt must be set to 0.
+
#### Nonce Handling
Despite the lack of signature validation, we still increment the nonce of the `from` account when a
@@ -173,8 +176,9 @@ This transaction MUST have the following values:
contract][predeploy]).
3. `mint` is `0`
4. `value` is `0`
-5. `gasLimit` is set to 75,000.
-6. `data` is an [ABI] encoded call to the [L1 attributes predeployed contract][predeploy]'s
+5. `gasLimit` is set to 150,000,000.
+6. `isSystemTransaction` is set to `true`.
+7. `data` is an [ABI] encoded call to the [L1 attributes predeployed contract][predeploy]'s
`setL1BlockValues()` function with correct values associated with the corresponding L1 block (cf.
[reference implementation][l1-attr-ref-implem]).
@@ -221,7 +225,7 @@ The contract has the following solidity interface, and can be interacted with ac
A reference implementation of the L1 Attributes predeploy contract can be found in [L1Block.sol].
-[L1Block.sol]: ../packages/contracts/contracts/L2/L1Block.sol
+[L1Block.sol]: ../packages/contracts-bedrock/contracts/L2/L1Block.sol
After running `yarn build` in the `packages/contracts` directory, the bytecode to add to the genesis
file will be located in the `deployedBytecode` field of the build artifacts file at
@@ -233,8 +237,8 @@ file will be located in the `deployedBytecode` field of the build artifacts file
[User-deposited transactions][g-user-deposited] are [deposited transactions][deposited-tx-type]
generated by the [L2 Chain Derivation][g-derivation] process. The content of each user-deposited
-transaction are determined by the corresponding `TransactionDeposited` event emitted by the [deposit
-feed contract][deposit-feed-contract] on L1.
+transaction are determined by the corresponding `TransactionDeposited` event emitted by the
+[deposit contract][deposit-contract] on L1.
1. `from` is unchanged from the emitted value (though it may have been transformed to an alias in
the deposit feed contract).
@@ -246,6 +250,8 @@ feed contract][deposit-feed-contract] on L1.
6. `isCreation` is set to `true` if the transaction is a contract creation, `false` otherwise.
7. `data` is unchanged from the emitted value. Depending on the value of `isCreation` it is handled
as either calldata or contract initialization code.
+8. `isSystemTransaction` is set by the rollup node for certain transactions that have unmetered execution.
+ It is `false` for user deposited transactions
### Deposit Contract
@@ -275,8 +281,8 @@ contract on L1 has the same address as a contract on L2 but doesn't have the sam
for EOAs because they're guaranteed to have the same "code" (i.e. no code at all). This also makes
it possible for users to interact with contracts on L2 even when the Sequencer is down.
-#### Deposit Feed Contract: Reference Implementation
+#### Deposit Contract Implementation: Optimism Portal
-A reference implementation of the Deposit Feed contract can be found in [DepositFeed.sol].
+A reference implementation of the deposit contract can be found in [OptimismPortal.sol].
-[DepositFeed.sol]: ../packages/contracts/contracts/L1/abstracts/DepositFeed.sol
+[OptimismPortal.sol]: ../packages/contracts-bedrock/contracts/L1/OptimismPortal.sol
diff --git a/specs/derivation.md b/specs/derivation.md
index 7128679339d21..db7105e17f059 100644
--- a/specs/derivation.md
+++ b/specs/derivation.md
@@ -28,7 +28,7 @@
[g-avail-provider]: glossary.md#data-availability-provider
[g-batcher]: glossary.md#batcher
[g-l2-output]: glossary.md#l2-output
-[g-fault-proof]: glosary.md#fault-proof
+[g-fault-proof]: glossary.md#fault-proof
[g-channel]: glossary.md#channel
[g-channel-frame]: glossary.md#channel-frame
[g-rollup-node]: glossary.md#rollup-node
@@ -181,7 +181,7 @@ by a correct output root **for the existing sequencer batches.**
Refer to the [Batch Submission specification][batcher-spec] for more information.
-[batcher-spec]: batching.md
+[batcher-spec]: batcher.md
> **TODO** rewrite the batch submission specification
>
@@ -303,7 +303,7 @@ where:
> can influence things down the line!!
[sqlite-uvarint]: https://www.sqlite.org/src4/doc/trunk/www/varint.wiki
-[batcher-spec]: batching.md
+[batcher-spec]: batcher.md
### Channel Format
diff --git a/specs/glossary.md b/specs/glossary.md
index 92ae1a4d98f15..4934d3402c30c 100644
--- a/specs/glossary.md
+++ b/specs/glossary.md
@@ -531,7 +531,7 @@ L2 derivation inputs include:
This term refers to an object that can be derived from [L2 chain derivation inputs][deriv-inputs] found on L1, which are
then passed to the [execution engine][execution-engine] to construct L2 blocks.
-The payload attributes object essentially essentially encodes a [a block without output properties][block].
+The payload attributes object essentially encodes [a block without output properties][block].
Payload attributes are originally specified in the [Ethereum Engine API specification][engine-api], which we expand in
the [Execution Engine Specification](exec-engine.md).
diff --git a/specs/introduction.md b/specs/introduction.md
index 83f77c8205ac8..0a0399def66f4 100644
--- a/specs/introduction.md
+++ b/specs/introduction.md
@@ -138,7 +138,7 @@ Links to components mentioned in this diagram:
- [Execution Engine](./exec-engine.md)
- Sequencer Batch Submitter (WIP)
- [L2 Output Oracle](./proposals.md#l2-output-oracle-smart-contract)
-- [L2 Output Submitter](./proposals#proposing-l2-output-commitments)
+- [L2 Output Submitter](./proposals.md#proposing-l2-output-commitments)
- Fault Proof VM (WIP)
### Withdrawing
diff --git a/specs/meta/devnet.md b/specs/meta/devnet.md
index 00a6ba88f93d3..4b749e1ca67d6 100644
--- a/specs/meta/devnet.md
+++ b/specs/meta/devnet.md
@@ -1,3 +1,4 @@
+
# Bedrock Local Devnet Setup
diff --git a/specs/meta/linting.md b/specs/meta/linting.md
index f6e317db15420..dd4d5ecb749b8 100644
--- a/specs/meta/linting.md
+++ b/specs/meta/linting.md
@@ -24,10 +24,13 @@ Justification for linting rules in [.markdownlint.json](/.markdownlint.json):
- *no-emphasis-as-heading*: enable emphasized paragraphs
```shell
-yarn # Install dependencies
-yarn lint # Run linter
-yarn lint:links # Check links
-yarn lint:toc # Update TOC docs
+yarn # Install dependencies
+yarn lint:specs:check # Run linter
+yarn lint:specs:fix # Fix lint issues
+yarn lint:specs:toc # Update TOC docs
+
+# Check links
+docker run --init -it -v `pwd`:/input lycheeverse/lychee --verbose --no-progress --exclude-loopback --exclude twitter.com --exclude-mail /input/README.md "/input/specs/**/*.md"
```
To check links, you'll need to install [lychee]. The [version ran in CI][lychee-ci] is 0.8.1, but
diff --git a/specs/meta/markdown-style.md b/specs/meta/markdown-style.md
index ccc4ae6ced0b5..b837efbf573a2 100644
--- a/specs/meta/markdown-style.md
+++ b/specs/meta/markdown-style.md
@@ -43,7 +43,7 @@ In general:
- e.g. `[g-block]: glossary.md#block`
- Example: [Rollup Node Specification source][rollup-node]
-[glossary]: ../specs/glossary.md
+[glossary]: ../glossary.md
[rollup-node]: https://raw.githubusercontent.com/ethereum-optimism/optimistic-specs/main/specs/rollup-node.md
## Internal (In-File) Links
diff --git a/specs/overview.md b/specs/overview.md
index 5db2acce08267..e09ffbdf40985 100644
--- a/specs/overview.md
+++ b/specs/overview.md
@@ -85,7 +85,7 @@ and fault proofs.
**Spec links:**
-- [Execution Engine](specs/exec-engine.md)
+- [Execution Engine](./exec-engine.md)
Since the EE uses Geth under the hood, Optimism uses Geth's built-in peer-to-peer network and transaction pool to
propagate transactions. The same network can also be used to propagate submitted blocks and support snap-sync.
diff --git a/specs/predeploys.md b/specs/predeploys.md
index 11c92c55499f6..38db3e1c3ec47 100644
--- a/specs/predeploys.md
+++ b/specs/predeploys.md
@@ -333,9 +333,9 @@ Reserved for future use.
## L1Block
-[l1-block-predeploy]: glossary.md#l1-block-predeployed-contract
+[l1-block-predeploy]: glossary.md#l1-attributes-predeployed-contract
-The [L1Block](l1-block-predeploy) was introduced in Bedrock and is responsible for
+The [L1Block][l1-block-predeploy] was introduced in Bedrock and is responsible for
maintaining L1 context in L2. This allows for L1 state to be accessed in L2.
```solidity
@@ -370,10 +370,11 @@ interface L1Block {
* @dev sets the latest L1 block attributes
*/
function setL1BlockValues(
- uint256 _number,
- uint256 _timestamp,
+ uint64 _number,
+ uint64 _timestamp,
uint256 _basefee,
- bytes32 _hash
+ bytes32 _hash,
+ uint64 _sequenceNumber
) external;
}
```
diff --git a/specs/rollup-node-p2p.md b/specs/rollup-node-p2p.md
index e453783b9df4c..d26c676eb8ed1 100644
--- a/specs/rollup-node-p2p.md
+++ b/specs/rollup-node-p2p.md
@@ -171,7 +171,7 @@ For async communication over different channels over the same connection, multip
#### GossipSub
-[GossipSub 1.1](gossipsub) (`/meshsub/1.1.0`, i.e. with peer-scoring extension) is a pubsub protocol for mesh-networks,
+[GossipSub 1.1][gossipsub] (`/meshsub/1.1.0`, i.e. with peer-scoring extension) is a pubsub protocol for mesh-networks,
deployed on L1 consensus (Eth2) and other protocols such as Filecoin, offering lots of customization options.
##### Content-based message identification
diff --git a/specs/rollup-node.md b/specs/rollup-node.md
index 82e176ae9f2f1..9116db564f483 100644
--- a/specs/rollup-node.md
+++ b/specs/rollup-node.md
@@ -24,7 +24,6 @@ currently only concerned with the specification of the rollup driver.
- [Derivation](#derivation)
- [L2 Output RPC method](#l2-output-rpc-method)
- [Output Method API](#output-method-api)
-- [L2 Batch creation RPC method](#l2-batch-creation-rpc-method)
@@ -74,7 +73,3 @@ The input and return types here are as defined by the [engine API specs][engine-
- returns:
1. `version`: `DATA`, 32 Bytes - the output root version number, beginning with 0.
1. `l2OutputRoot`: `DATA`, 32 Bytes - the output root
-
-## L2 Batch creation RPC method
-
-See [Batch derivation](./batching.md) for an RPC specification for batch data submission.
diff --git a/specs/withdrawals.md b/specs/withdrawals.md
index 5f0aa254517e1..daba781aafb9d 100644
--- a/specs/withdrawals.md
+++ b/specs/withdrawals.md
@@ -87,6 +87,8 @@ interface L2ToL1MessagePasser {
bytes data
);
+ event WithdrawalInitiatedExtension1(bytes32 indexed hash);
+
event WithdrawerBalanceBurnt(uint256 indexed amount);
function burn() external;
@@ -100,6 +102,14 @@ interface L2ToL1MessagePasser {
```
+The `WithdrawalInitiated` event includes all of the data that is hashed and
+stored in the `sentMessages` mapping. The `WithdrawalInitiatedExtension1` emits
+the hash that was computed and used as part of the storage proof used to
+finalize the withdrawal on L1.
+
+The events are separate as to preserve backwards compatibility. The hashing
+scheme could be upgraded in the future through a contract upgrade.
+
### Addresses are not Aliased on Withdrawals
[address-aliasing]: #no-address-aliasing
diff --git a/yarn.lock b/yarn.lock
index 42db9ca2b55e1..4ee5847351cdb 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1636,10 +1636,10 @@
command-exists "^1.2.9"
ts-interface-checker "^0.1.9"
-"@foundry-rs/hardhat-forge@^0.1.12":
- version "0.1.12"
- resolved "https://registry.yarnpkg.com/@foundry-rs/hardhat-forge/-/hardhat-forge-0.1.12.tgz#0557909762b86033e4699b9dc8e4cb58ddfc3fff"
- integrity sha512-y05JYP+uvBaWKZZPuMkzc7cWS0gPTb4JzwrBA++9cIe1Aae+atz340cREBsCV9joEUpcK0UMRMURBns3A5nhhQ==
+"@foundry-rs/hardhat-forge@^0.1.16":
+ version "0.1.16"
+ resolved "https://registry.yarnpkg.com/@foundry-rs/hardhat-forge/-/hardhat-forge-0.1.16.tgz#73a637b51ac50e95fbcfe4a522efc782f9a078a4"
+ integrity sha512-C0Xz7fnGAg7hOJG7hC90iUjJTQxl+xq20Rbxee3cIIY+w59NzjmCaW4ikNeKidHJVPWiYXq6BNBTFBrSfL/d4Q==
dependencies:
"@foundry-rs/easy-foundryup" "^0.1.3"
"@nomiclabs/hardhat-ethers" "^2.0.0"
@@ -2816,7 +2816,7 @@
dependencies:
"@octokit/openapi-types" "^9.5.0"
-"@openzeppelin/contracts-upgradeable@4.7.1", "@openzeppelin/contracts-upgradeable@^4.3.2", "@openzeppelin/contracts-upgradeable@^4.5.2":
+"@openzeppelin/contracts-upgradeable@4.7.1", "@openzeppelin/contracts-upgradeable@^4.3.2":
version "4.7.1"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.7.1.tgz#f63fc384255d6ac139e0a2561aa207fd7c14183c"
integrity sha512-5EFiZld3DYFd8aTL8eeMnhnaWh1/oXLXFNuFMrgF3b1DNPshF3LCyO7VR6lc+gac2URJ0BlVcZoCfkk/3MoEfg==
@@ -2836,7 +2836,7 @@
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.5.0.tgz#3fd75d57de172b3743cdfc1206883f56430409cc"
integrity sha512-fdkzKPYMjrRiPK6K4y64e6GzULR7R7RwxSigHS8DDp7aWDeoReqsQI+cxHV1UuhAqX69L1lAaWDxenfP+xiqzA==
-"@openzeppelin/contracts@4.6.0", "@openzeppelin/contracts@^4.5.0":
+"@openzeppelin/contracts@4.6.0":
version "4.6.0"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.6.0.tgz#c91cf64bc27f573836dba4122758b4743418c1b3"
integrity sha512-8vi4d50NNya/bQqCmaVzvHNmwHvS0OBKb7HNtuNwEE3scXWrP31fKQoGxNMT+KbzmrNZzatE3QK5p2gFONI/hg==
@@ -3106,23 +3106,24 @@
dependencies:
defer-to-connect "^1.0.1"
-"@textlint/ast-node-types@^4.2.5":
- version "4.4.3"
- resolved "https://registry.yarnpkg.com/@textlint/ast-node-types/-/ast-node-types-4.4.3.tgz#fdba16e8126cddc50f45433ce7f6c55e7829566c"
- integrity sha512-qi2jjgO6Tn3KNPGnm6B7p6QTEPvY95NFsIAaJuwbulur8iJUEenp1OnoUfiDaC/g2WPPEFkcfXpmnu8XEMFo2A==
+"@textlint/ast-node-types@^12.2.1":
+ version "12.2.1"
+ resolved "https://registry.yarnpkg.com/@textlint/ast-node-types/-/ast-node-types-12.2.1.tgz#bec1e4b02e97ff1167d057c71feeee1a80015aef"
+ integrity sha512-NXYza6aG1+LdZ4g83gjRhDht+gdrTjJYkdcQhpvzNCtTar/sVpaykkauRcAKLhkIWrQpfb311pfMlU6qNDW76Q==
-"@textlint/markdown-to-ast@~6.1.7":
- version "6.1.7"
- resolved "https://registry.yarnpkg.com/@textlint/markdown-to-ast/-/markdown-to-ast-6.1.7.tgz#7ed9561b577bcd5307c8ef82660bc568ce31647e"
- integrity sha512-B0QtokeQR4a9+4q0NQr8T9l7A1fFihTN5Ze57tVgqW+3ymzXEouh8DvPHeNQ4T6jEkAThvdjk95mxAMpGRJ79w==
+"@textlint/markdown-to-ast@^12.1.1":
+ version "12.2.1"
+ resolved "https://registry.yarnpkg.com/@textlint/markdown-to-ast/-/markdown-to-ast-12.2.1.tgz#e9ec19be71e4513d882986d14ab9a993dec74511"
+ integrity sha512-p+LlVcrgHnSNEWWflYU412uu+v4Cejs6hmI4SgZCheNg4u7Ik78aKgpe4jT5BhjLSBZ/KP6IrJxtCUOoJIUWmQ==
dependencies:
- "@textlint/ast-node-types" "^4.2.5"
- debug "^4.1.1"
- remark-frontmatter "^1.2.0"
- remark-parse "^5.0.0"
- structured-source "^3.0.2"
+ "@textlint/ast-node-types" "^12.2.1"
+ debug "^4.3.4"
+ remark-footnotes "^3.0.0"
+ remark-frontmatter "^3.0.0"
+ remark-gfm "^1.0.0"
+ remark-parse "^9.0.0"
traverse "^0.6.6"
- unified "^6.1.6"
+ unified "^9.2.2"
"@tootallnate/once@1":
version "1.1.2"
@@ -3343,6 +3344,13 @@
resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef"
integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==
+"@types/mdast@^3.0.0":
+ version "3.0.10"
+ resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.10.tgz#4724244a82a4598884cbbe9bcfd73dff927ee8af"
+ integrity sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==
+ dependencies:
+ "@types/unist" "*"
+
"@types/mime@^1":
version "1.3.2"
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a"
@@ -3555,6 +3563,11 @@
resolved "https://registry.yarnpkg.com/@types/underscore/-/underscore-1.11.3.tgz#d6734f3741ce41b2630018c6b61c6745f6188c07"
integrity sha512-Fl1TX1dapfXyDqFg2ic9M+vlXRktcPJrc4PR7sRc7sdVrjavg/JHlbUXBt8qWWqhJrmSqg3RNAkAPRiOYw6Ahw==
+"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2":
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
+ integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==
+
"@types/web3@1.0.19":
version "1.0.19"
resolved "https://registry.yarnpkg.com/@types/web3/-/web3-1.0.19.tgz#46b85d91d398ded9ab7c85a5dd57cb33ac558924"
@@ -4075,10 +4088,10 @@ amdefine@>=0.0.4:
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=
-anchor-markdown-header@~0.5.7:
+anchor-markdown-header@^0.5.7:
version "0.5.7"
resolved "https://registry.yarnpkg.com/anchor-markdown-header/-/anchor-markdown-header-0.5.7.tgz#045063d76e6a1f9cd327a57a0126aa0fdec371a7"
- integrity sha1-BFBj125qH5zTJ6V6ASaqD97Dcac=
+ integrity sha512-AmikqcK15r3q99hPvTa1na9n3eLkW0uE+RL9BZMSgwYalQeDnNXbYrN06BIcBPfGlmsGIE2jvkuvl/x0hyPF5Q==
dependencies:
emoji-regex "~6.1.0"
@@ -4316,6 +4329,11 @@ array-union@^2.1.0:
resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
+array-union@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/array-union/-/array-union-3.0.1.tgz#da52630d327f8b88cfbfb57728e2af5cd9b6b975"
+ integrity sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==
+
array-uniq@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
@@ -5259,11 +5277,6 @@ body-parser@^1.20.0:
type-is "~1.6.18"
unpipe "1.0.0"
-boundary@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/boundary/-/boundary-1.0.1.tgz#4d67dc2602c0cc16dd9bce7ebf87e948290f5812"
- integrity sha1-TWfcJgLAzBbdm85+v4fpSCkPWBI=
-
boxen@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b"
@@ -5308,7 +5321,7 @@ braces@^2.3.1:
split-string "^3.0.2"
to-regex "^3.0.1"
-braces@^3.0.1, braces@^3.0.2, braces@~3.0.2:
+braces@^3.0.1, braces@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
@@ -5717,6 +5730,11 @@ cbor@^5.0.2:
bignumber.js "^9.0.1"
nofilter "^1.0.4"
+ccount@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043"
+ integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==
+
chai-as-promised@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0"
@@ -6102,11 +6120,6 @@ code-point-at@^1.0.0:
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
-collapse-white-space@^1.0.2:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287"
- integrity sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==
-
collection-visit@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
@@ -6724,7 +6737,7 @@ debug@4.3.3, debug@^4.3.3:
dependencies:
ms "2.1.2"
-debug@4.3.4, debug@^4.2.0, debug@^4.3.4:
+debug@4.3.4, debug@^4.0.0, debug@^4.2.0, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@@ -7054,17 +7067,17 @@ directory-tree@^2.2.7:
resolved "https://registry.yarnpkg.com/directory-tree/-/directory-tree-2.3.1.tgz#78b8aa84878eb84dd29a51dcd664ded4cd0247c7"
integrity sha512-hxolIHCtQ/a56CUywaLzGD/V78zPwFihI+UK/4ZjOp7GoV4Mptmtv95yavOn/RlnTi7cCMjszvfcNrwCoWLH+Q==
-doctoc@2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/doctoc/-/doctoc-2.1.0.tgz#e7cbcd1f9e65519c295461423b2e7195d9e0d7ab"
- integrity sha512-0darEVEuWKLyIlpGOzE5cILf/pgUu25qUs6YwCqLqfxb8+3b9Cl4iakA8vwYrBQOkJ5SwpHKEPVMu2KOMrTA7A==
+doctoc@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/doctoc/-/doctoc-2.2.0.tgz#27f23eb75d109d29722d449efbcde3854cb0eabf"
+ integrity sha512-PtiyaS+S3kcMbpx6x2V0S+PeDKisxmjEFnZsuYkkj4Lh3ObozJuuYh9dM4+sX02Ouuty8RF2LOCnIbpu/hWy/A==
dependencies:
- "@textlint/markdown-to-ast" "~6.1.7"
- anchor-markdown-header "~0.5.7"
- htmlparser2 "~4.1.0"
- minimist "~1.2.5"
- underscore "~1.12.1"
- update-section "~0.3.3"
+ "@textlint/markdown-to-ast" "^12.1.1"
+ anchor-markdown-header "^0.5.7"
+ htmlparser2 "^7.2.0"
+ minimist "^1.2.6"
+ underscore "^1.13.2"
+ update-section "^0.3.3"
doctrine@^2.1.0:
version "2.1.0"
@@ -7099,21 +7112,14 @@ domelementtype@^2.0.1, domelementtype@^2.2.0:
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
-domhandler@^3.0.0:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-3.3.0.tgz#6db7ea46e4617eb15cf875df68b2b8524ce0037a"
- integrity sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==
- dependencies:
- domelementtype "^2.0.1"
-
-domhandler@^4.2.0:
+domhandler@^4.2.0, domhandler@^4.2.2:
version "4.3.1"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c"
integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==
dependencies:
domelementtype "^2.2.0"
-domutils@^2.0.0:
+domutils@^2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
@@ -7304,6 +7310,11 @@ entities@^2.0.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
+entities@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4"
+ integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==
+
entities@~2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5"
@@ -8529,9 +8540,9 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
md5.js "^1.3.4"
safe-buffer "^5.1.1"
-"excessively-safe-call@https://github.com/nomad-xyz/ExcessivelySafeCall.git#4fcdfd3593d21381f696c790fa6180b8ef559c1e":
+"excessively-safe-call@https://github.com/nomad-xyz/ExcessivelySafeCall.git#81cd99ce3e69117d665d7601c330ea03b97acce0":
version "0.0.1-rc.1"
- resolved "https://github.com/nomad-xyz/ExcessivelySafeCall.git#4fcdfd3593d21381f696c790fa6180b8ef559c1e"
+ resolved "https://github.com/nomad-xyz/ExcessivelySafeCall.git#81cd99ce3e69117d665d7601c330ea03b97acce0"
execa@^0.7.0:
version "0.7.0"
@@ -8734,7 +8745,7 @@ fast-glob@^3.0.3, fast-glob@^3.1.1:
merge2 "^1.3.0"
micromatch "^4.0.4"
-fast-glob@^3.2.9:
+fast-glob@^3.2.7, fast-glob@^3.2.9:
version "3.2.11"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9"
integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==
@@ -8777,7 +8788,7 @@ fastq@^1.6.0:
dependencies:
reusify "^1.0.4"
-fault@^1.0.1:
+fault@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13"
integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==
@@ -9603,6 +9614,18 @@ globals@^9.18.0:
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==
+globby@12.1.0:
+ version "12.1.0"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-12.1.0.tgz#471757d6d9d25651b655b1da3eae1e25209f86a5"
+ integrity sha512-YULDaNwsoUZkRy9TWSY/M7Obh0abamTKoKzTfOI3uU+hfpX2FZqOq8LFDxsjYheF1RH7ITdArgbQnsNBFgcdBA==
+ dependencies:
+ array-union "^3.0.1"
+ dir-glob "^3.0.1"
+ fast-glob "^3.2.7"
+ ignore "^5.1.9"
+ merge2 "^1.4.1"
+ slash "^4.0.0"
+
globby@^10.0.1:
version "10.0.2"
resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543"
@@ -9617,7 +9640,7 @@ globby@^10.0.1:
merge2 "^1.2.3"
slash "^3.0.0"
-globby@^11.0.0, globby@^11.0.2, globby@^11.0.3, globby@~11.0.4:
+globby@^11.0.0, globby@^11.0.2, globby@^11.0.3:
version "11.0.4"
resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5"
integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==
@@ -10025,15 +10048,15 @@ html-escaper@^2.0.0:
resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453"
integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==
-htmlparser2@~4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-4.1.0.tgz#9a4ef161f2e4625ebf7dfbe6c0a2f52d18a59e78"
- integrity sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==
+htmlparser2@^7.2.0:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-7.2.0.tgz#8817cdea38bbc324392a90b1990908e81a65f5a5"
+ integrity sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==
dependencies:
domelementtype "^2.0.1"
- domhandler "^3.0.0"
- domutils "^2.0.0"
- entities "^2.0.0"
+ domhandler "^4.2.2"
+ domutils "^2.8.0"
+ entities "^3.0.1"
http-basic@^8.1.1:
version "8.1.3"
@@ -10186,7 +10209,7 @@ ignore@^5.1.1, ignore@^5.1.4:
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
-ignore@^5.1.8, ignore@^5.2.0:
+ignore@^5.1.8, ignore@^5.1.9, ignore@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
@@ -10263,7 +10286,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
-inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4:
+inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@@ -10445,12 +10468,12 @@ is-boolean-object@^1.1.0:
call-bind "^1.0.2"
has-tostringtag "^1.0.0"
-is-buffer@^1.1.4, is-buffer@^1.1.5:
+is-buffer@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
-is-buffer@^2.0.5, is-buffer@~2.0.3:
+is-buffer@^2.0.0, is-buffer@^2.0.5, is-buffer@~2.0.3:
version "2.0.5"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191"
integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==
@@ -10801,21 +10824,11 @@ is-weakref@^1.0.2:
dependencies:
call-bind "^1.0.2"
-is-whitespace-character@^1.0.0:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7"
- integrity sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==
-
is-windows@^1.0.0, is-windows@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==
-is-word-character@^1.0.0:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.4.tgz#ce0e73216f98599060592f62ff31354ddbeb0230"
- integrity sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==
-
is-wsl@^2.1.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
@@ -11838,6 +11851,11 @@ logform@^2.3.2, logform@^2.4.0:
safe-stable-stringify "^2.3.1"
triple-beam "^1.3.0"
+longest-streak@^2.0.0:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4"
+ integrity sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==
+
looper@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/looper/-/looper-2.0.0.tgz#66cd0c774af3d4fedac53794f742db56da8f09ec"
@@ -12025,11 +12043,6 @@ map-visit@^1.0.0:
dependencies:
object-visit "^1.0.0"
-markdown-escapes@^1.0.0:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535"
- integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==
-
markdown-it@12.2.0:
version "12.2.0"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.2.0.tgz#091f720fd5db206f80de7a8d1f1a7035fd0d38db"
@@ -12041,35 +12054,60 @@ markdown-it@12.2.0:
mdurl "^1.0.1"
uc.micro "^1.0.5"
+markdown-it@12.3.2:
+ version "12.3.2"
+ resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90"
+ integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==
+ dependencies:
+ argparse "^2.0.1"
+ entities "~2.1.0"
+ linkify-it "^3.0.1"
+ mdurl "^1.0.1"
+ uc.micro "^1.0.5"
+
markdown-table@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.3.tgz#9fcb69bcfdb8717bfd0398c6ec2d93036ef8de60"
integrity sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==
-markdownlint-cli2-formatter-default@^0.0.2:
- version "0.0.2"
- resolved "https://registry.yarnpkg.com/markdownlint-cli2-formatter-default/-/markdownlint-cli2-formatter-default-0.0.2.tgz#76f1a064d70966178dfe3bb489af9423d830ca79"
- integrity sha512-jIz1X3SIC8sX4NDFqQFUXL+JEtfnDoN4i+xocEu+etcxGX455pHb6sx86f/yVk4mKJ2o7aNe2ydSx9an22BfBg==
+markdown-table@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-2.0.0.tgz#194a90ced26d31fe753d8b9434430214c011865b"
+ integrity sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==
+ dependencies:
+ repeat-string "^1.0.0"
-markdownlint-cli2@^0.3.2:
- version "0.3.2"
- resolved "https://registry.yarnpkg.com/markdownlint-cli2/-/markdownlint-cli2-0.3.2.tgz#328774b5ab981997fdd6fa8f72ea7feaed84722b"
- integrity sha512-Wj4iQy2J49m9CVkWkLTdFxMTPDqD3AyL3NbLQgz/nUnTu8LnDguFCbQtFhdzQPvncHVjrKT2vYqg7DifzVP4tA==
- dependencies:
- globby "~11.0.4"
- markdownlint "~0.24.0"
- markdownlint-cli2-formatter-default "^0.0.2"
- markdownlint-rule-helpers "~0.15.0"
- micromatch "~4.0.4"
- strip-json-comments "~3.1.1"
- yaml "~1.10.2"
-
-markdownlint-rule-helpers@~0.15.0:
- version "0.15.0"
- resolved "https://registry.yarnpkg.com/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.15.0.tgz#11434c573649b9235ae70b967314f5711f7d8fa8"
- integrity sha512-A+9mswc3m/kkqpJCqntmte/1VKhDJ+tjZsERLz5L4h/Qr7ht2/BkGkgY5E7/wsxIhcpl+ctIfz+oS3PQrMOB2w==
+markdownlint-cli2-formatter-default@0.0.3:
+ version "0.0.3"
+ resolved "https://registry.yarnpkg.com/markdownlint-cli2-formatter-default/-/markdownlint-cli2-formatter-default-0.0.3.tgz#5aecd6e576ad18801b76e58bbbaf0e916c583ab8"
+ integrity sha512-QEAJitT5eqX1SNboOD+SO/LNBpu4P4je8JlR02ug2cLQAqmIhh8IJnSK7AcaHBHhNADqdGydnPpQOpsNcEEqCw==
-markdownlint@^0.24.0, markdownlint@~0.24.0:
+markdownlint-cli2@0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/markdownlint-cli2/-/markdownlint-cli2-0.4.0.tgz#9e29150278fd3f1fe31a05fc46bd95d2370e8758"
+ integrity sha512-EcwP5tAbyzzL3ACI0L16LqbNctmh8wNX56T+aVvIxWyTAkwbYNx2V7IheRkXS3mE7R/pnaApZ/RSXcXuzRVPjg==
+ dependencies:
+ globby "12.1.0"
+ markdownlint "0.25.1"
+ markdownlint-cli2-formatter-default "0.0.3"
+ markdownlint-rule-helpers "0.16.0"
+ micromatch "4.0.4"
+ strip-json-comments "4.0.0"
+ yaml "1.10.2"
+
+markdownlint-rule-helpers@0.16.0:
+ version "0.16.0"
+ resolved "https://registry.yarnpkg.com/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.16.0.tgz#c327f72782bd2b9475127a240508231f0413a25e"
+ integrity sha512-oEacRUVeTJ5D5hW1UYd2qExYI0oELdYK72k1TKGvIeYJIbqQWAz476NAc7LNixSySUhcNl++d02DvX0ccDk9/w==
+
+markdownlint@0.25.1:
+ version "0.25.1"
+ resolved "https://registry.yarnpkg.com/markdownlint/-/markdownlint-0.25.1.tgz#df04536607ebeeda5ccd5e4f38138823ed623788"
+ integrity sha512-AG7UkLzNa1fxiOv5B+owPsPhtM4D6DoODhsJgiaNg1xowXovrYgOnLqAgOOFQpWOlHFVQUzjMY5ypNNTeov92g==
+ dependencies:
+ markdown-it "12.3.2"
+
+markdownlint@^0.24.0:
version "0.24.0"
resolved "https://registry.yarnpkg.com/markdownlint/-/markdownlint-0.24.0.tgz#224b53f671367a237d40c8be1745c7be9a322671"
integrity sha512-OJIGsGFV/rC9irI5E1FMy6v9hdACSwaa+EN3224Y5KG8zj2EYzdHOw0pOJovIYmjNfEZ9BtxUY4P7uYHTSNnbQ==
@@ -12119,6 +12157,100 @@ md5.js@^1.3.4:
inherits "^2.0.1"
safe-buffer "^5.1.2"
+mdast-util-find-and-replace@^1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/mdast-util-find-and-replace/-/mdast-util-find-and-replace-1.1.1.tgz#b7db1e873f96f66588c321f1363069abf607d1b5"
+ integrity sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA==
+ dependencies:
+ escape-string-regexp "^4.0.0"
+ unist-util-is "^4.0.0"
+ unist-util-visit-parents "^3.0.0"
+
+mdast-util-footnote@^0.1.0:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/mdast-util-footnote/-/mdast-util-footnote-0.1.7.tgz#4b226caeab4613a3362c144c94af0fdd6f7e0ef0"
+ integrity sha512-QxNdO8qSxqbO2e3m09KwDKfWiLgqyCurdWTQ198NpbZ2hxntdc+VKS4fDJCmNWbAroUdYnSthu+XbZ8ovh8C3w==
+ dependencies:
+ mdast-util-to-markdown "^0.6.0"
+ micromark "~2.11.0"
+
+mdast-util-from-markdown@^0.8.0:
+ version "0.8.5"
+ resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz#d1ef2ca42bc377ecb0463a987910dae89bd9a28c"
+ integrity sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==
+ dependencies:
+ "@types/mdast" "^3.0.0"
+ mdast-util-to-string "^2.0.0"
+ micromark "~2.11.0"
+ parse-entities "^2.0.0"
+ unist-util-stringify-position "^2.0.0"
+
+mdast-util-frontmatter@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/mdast-util-frontmatter/-/mdast-util-frontmatter-0.2.0.tgz#8bd5cd55e236c03e204a036f7372ebe9e6748240"
+ integrity sha512-FHKL4w4S5fdt1KjJCwB0178WJ0evnyyQr5kXTM3wrOVpytD0hrkvd+AOOjU9Td8onOejCkmZ+HQRT3CZ3coHHQ==
+ dependencies:
+ micromark-extension-frontmatter "^0.2.0"
+
+mdast-util-gfm-autolink-literal@^0.1.0:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-0.1.3.tgz#9c4ff399c5ddd2ece40bd3b13e5447d84e385fb7"
+ integrity sha512-GjmLjWrXg1wqMIO9+ZsRik/s7PLwTaeCHVB7vRxUwLntZc8mzmTsLVr6HW1yLokcnhfURsn5zmSVdi3/xWWu1A==
+ dependencies:
+ ccount "^1.0.0"
+ mdast-util-find-and-replace "^1.1.0"
+ micromark "^2.11.3"
+
+mdast-util-gfm-strikethrough@^0.2.0:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-0.2.3.tgz#45eea337b7fff0755a291844fbea79996c322890"
+ integrity sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA==
+ dependencies:
+ mdast-util-to-markdown "^0.6.0"
+
+mdast-util-gfm-table@^0.1.0:
+ version "0.1.6"
+ resolved "https://registry.yarnpkg.com/mdast-util-gfm-table/-/mdast-util-gfm-table-0.1.6.tgz#af05aeadc8e5ee004eeddfb324b2ad8c029b6ecf"
+ integrity sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ==
+ dependencies:
+ markdown-table "^2.0.0"
+ mdast-util-to-markdown "~0.6.0"
+
+mdast-util-gfm-task-list-item@^0.1.0:
+ version "0.1.6"
+ resolved "https://registry.yarnpkg.com/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-0.1.6.tgz#70c885e6b9f543ddd7e6b41f9703ee55b084af10"
+ integrity sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A==
+ dependencies:
+ mdast-util-to-markdown "~0.6.0"
+
+mdast-util-gfm@^0.1.0:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/mdast-util-gfm/-/mdast-util-gfm-0.1.2.tgz#8ecddafe57d266540f6881f5c57ff19725bd351c"
+ integrity sha512-NNkhDx/qYcuOWB7xHUGWZYVXvjPFFd6afg6/e2g+SV4r9q5XUcCbV4Wfa3DLYIiD+xAEZc6K4MGaE/m0KDcPwQ==
+ dependencies:
+ mdast-util-gfm-autolink-literal "^0.1.0"
+ mdast-util-gfm-strikethrough "^0.2.0"
+ mdast-util-gfm-table "^0.1.0"
+ mdast-util-gfm-task-list-item "^0.1.0"
+ mdast-util-to-markdown "^0.6.1"
+
+mdast-util-to-markdown@^0.6.0, mdast-util-to-markdown@^0.6.1, mdast-util-to-markdown@~0.6.0:
+ version "0.6.5"
+ resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz#b33f67ca820d69e6cc527a93d4039249b504bebe"
+ integrity sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==
+ dependencies:
+ "@types/unist" "^2.0.0"
+ longest-streak "^2.0.0"
+ mdast-util-to-string "^2.0.0"
+ parse-entities "^2.0.0"
+ repeat-string "^1.0.0"
+ zwitch "^1.0.0"
+
+mdast-util-to-string@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz#b8cfe6a713e1091cb5b728fc48885a4767f8b97b"
+ integrity sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==
+
mdurl@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
@@ -12345,6 +12477,81 @@ methods@^1.1.2, methods@~1.1.2:
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
+micromark-extension-footnote@^0.3.0:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/micromark-extension-footnote/-/micromark-extension-footnote-0.3.2.tgz#129b74ef4920ce96719b2c06102ee7abb2b88a20"
+ integrity sha512-gr/BeIxbIWQoUm02cIfK7mdMZ/fbroRpLsck4kvFtjbzP4yi+OPVbnukTc/zy0i7spC2xYE/dbX1Sur8BEDJsQ==
+ dependencies:
+ micromark "~2.11.0"
+
+micromark-extension-frontmatter@^0.2.0:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/micromark-extension-frontmatter/-/micromark-extension-frontmatter-0.2.2.tgz#61b8e92e9213e1d3c13f5a59e7862f5ca98dfa53"
+ integrity sha512-q6nPLFCMTLtfsctAuS0Xh4vaolxSFUWUWR6PZSrXXiRy+SANGllpcqdXFv2z07l0Xz/6Hl40hK0ffNCJPH2n1A==
+ dependencies:
+ fault "^1.0.0"
+
+micromark-extension-gfm-autolink-literal@~0.5.0:
+ version "0.5.7"
+ resolved "https://registry.yarnpkg.com/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-0.5.7.tgz#53866c1f0c7ef940ae7ca1f72c6faef8fed9f204"
+ integrity sha512-ePiDGH0/lhcngCe8FtH4ARFoxKTUelMp4L7Gg2pujYD5CSMb9PbblnyL+AAMud/SNMyusbS2XDSiPIRcQoNFAw==
+ dependencies:
+ micromark "~2.11.3"
+
+micromark-extension-gfm-strikethrough@~0.6.5:
+ version "0.6.5"
+ resolved "https://registry.yarnpkg.com/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-0.6.5.tgz#96cb83356ff87bf31670eefb7ad7bba73e6514d1"
+ integrity sha512-PpOKlgokpQRwUesRwWEp+fHjGGkZEejj83k9gU5iXCbDG+XBA92BqnRKYJdfqfkrRcZRgGuPuXb7DaK/DmxOhw==
+ dependencies:
+ micromark "~2.11.0"
+
+micromark-extension-gfm-table@~0.4.0:
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/micromark-extension-gfm-table/-/micromark-extension-gfm-table-0.4.3.tgz#4d49f1ce0ca84996c853880b9446698947f1802b"
+ integrity sha512-hVGvESPq0fk6ALWtomcwmgLvH8ZSVpcPjzi0AjPclB9FsVRgMtGZkUcpE0zgjOCFAznKepF4z3hX8z6e3HODdA==
+ dependencies:
+ micromark "~2.11.0"
+
+micromark-extension-gfm-tagfilter@~0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-0.3.0.tgz#d9f26a65adee984c9ccdd7e182220493562841ad"
+ integrity sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q==
+
+micromark-extension-gfm-task-list-item@~0.3.0:
+ version "0.3.3"
+ resolved "https://registry.yarnpkg.com/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-0.3.3.tgz#d90c755f2533ed55a718129cee11257f136283b8"
+ integrity sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ==
+ dependencies:
+ micromark "~2.11.0"
+
+micromark-extension-gfm@^0.3.0:
+ version "0.3.3"
+ resolved "https://registry.yarnpkg.com/micromark-extension-gfm/-/micromark-extension-gfm-0.3.3.tgz#36d1a4c089ca8bdfd978c9bd2bf1a0cb24e2acfe"
+ integrity sha512-oVN4zv5/tAIA+l3GbMi7lWeYpJ14oQyJ3uEim20ktYFAcfX1x3LNlFGGlmrZHt7u9YlKExmyJdDGaTt6cMSR/A==
+ dependencies:
+ micromark "~2.11.0"
+ micromark-extension-gfm-autolink-literal "~0.5.0"
+ micromark-extension-gfm-strikethrough "~0.6.5"
+ micromark-extension-gfm-table "~0.4.0"
+ micromark-extension-gfm-tagfilter "~0.3.0"
+ micromark-extension-gfm-task-list-item "~0.3.0"
+
+micromark@^2.11.3, micromark@~2.11.0, micromark@~2.11.3:
+ version "2.11.4"
+ resolved "https://registry.yarnpkg.com/micromark/-/micromark-2.11.4.tgz#d13436138eea826383e822449c9a5c50ee44665a"
+ integrity sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==
+ dependencies:
+ debug "^4.0.0"
+ parse-entities "^2.0.0"
+
+micromatch@4.0.4, micromatch@^4.0.2, micromatch@^4.0.4:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
+ integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
+ dependencies:
+ braces "^3.0.1"
+ picomatch "^2.2.3"
+
micromatch@^3.1.4:
version "3.1.10"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
@@ -12364,22 +12571,6 @@ micromatch@^3.1.4:
snapdragon "^0.8.1"
to-regex "^3.0.2"
-micromatch@^4.0.2, micromatch@^4.0.4:
- version "4.0.4"
- resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
- integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
- dependencies:
- braces "^3.0.1"
- picomatch "^2.2.3"
-
-micromatch@~4.0.4:
- version "4.0.5"
- resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
- integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
- dependencies:
- braces "^3.0.2"
- picomatch "^2.3.1"
-
miller-rabin@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
@@ -13779,10 +13970,10 @@ parse-cache-control@^1.0.1:
resolved "https://registry.yarnpkg.com/parse-cache-control/-/parse-cache-control-1.0.1.tgz#8eeab3e54fa56920fe16ba38f77fa21aacc2d74e"
integrity sha1-juqz5U+laSD+Fro493+iGqzC104=
-parse-entities@^1.1.0:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.2.2.tgz#c31bf0f653b6661354f8973559cb86dd1d5edf50"
- integrity sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==
+parse-entities@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8"
+ integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==
dependencies:
character-entities "^1.0.0"
character-entities-legacy "^1.0.0"
@@ -13992,11 +14183,6 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
-picomatch@^2.3.1:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
- integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
-
pify@^2.0.0, pify@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
@@ -14940,44 +15126,46 @@ release-zalgo@^1.0.0:
dependencies:
es6-error "^4.0.1"
-remark-frontmatter@^1.2.0:
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/remark-frontmatter/-/remark-frontmatter-1.3.3.tgz#67ec63c89da5a84bb793ecec166e11b4eb47af10"
- integrity sha512-fM5eZPBvu2pVNoq3ZPW22q+5Ativ1oLozq2qYt9I2oNyxiUd/tDl0iLLntEVAegpZIslPWg1brhcP1VsaSVUag==
+remark-footnotes@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/remark-footnotes/-/remark-footnotes-3.0.0.tgz#5756b56f8464fa7ed80dbba0c966136305d8cb8d"
+ integrity sha512-ZssAvH9FjGYlJ/PBVKdSmfyPc3Cz4rTWgZLI4iE/SX8Nt5l3o3oEjv3wwG5VD7xOjktzdwp5coac+kJV9l4jgg==
dependencies:
- fault "^1.0.1"
- xtend "^4.0.1"
+ mdast-util-footnote "^0.1.0"
+ micromark-extension-footnote "^0.3.0"
-remark-parse@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-5.0.0.tgz#4c077f9e499044d1d5c13f80d7a98cf7b9285d95"
- integrity sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==
+remark-frontmatter@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/remark-frontmatter/-/remark-frontmatter-3.0.0.tgz#ca5d996361765c859bd944505f377d6b186a6ec6"
+ integrity sha512-mSuDd3svCHs+2PyO29h7iijIZx4plX0fheacJcAoYAASfgzgVIcXGYSq9GFyYocFLftQs8IOmmkgtOovs6d4oA==
dependencies:
- collapse-white-space "^1.0.2"
- is-alphabetical "^1.0.0"
- is-decimal "^1.0.0"
- is-whitespace-character "^1.0.0"
- is-word-character "^1.0.0"
- markdown-escapes "^1.0.0"
- parse-entities "^1.1.0"
- repeat-string "^1.5.4"
- state-toggle "^1.0.0"
- trim "0.0.1"
- trim-trailing-lines "^1.0.0"
- unherit "^1.0.4"
- unist-util-remove-position "^1.0.0"
- vfile-location "^2.0.0"
- xtend "^4.0.1"
+ mdast-util-frontmatter "^0.2.0"
+ micromark-extension-frontmatter "^0.2.0"
+
+remark-gfm@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/remark-gfm/-/remark-gfm-1.0.0.tgz#9213643001be3f277da6256464d56fd28c3b3c0d"
+ integrity sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==
+ dependencies:
+ mdast-util-gfm "^0.1.0"
+ micromark-extension-gfm "^0.3.0"
+
+remark-parse@^9.0.0:
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-9.0.0.tgz#4d20a299665880e4f4af5d90b7c7b8a935853640"
+ integrity sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==
+ dependencies:
+ mdast-util-from-markdown "^0.8.0"
repeat-element@^1.1.2:
version "1.1.4"
resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9"
integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==
-repeat-string@^1.5.4, repeat-string@^1.6.1:
+repeat-string@^1.0.0, repeat-string@^1.6.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
- integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc=
+ integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==
repeating@^2.0.0:
version "2.0.1"
@@ -14986,11 +15174,6 @@ repeating@^2.0.0:
dependencies:
is-finite "^1.0.0"
-replace-ext@1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb"
- integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=
-
req-cwd@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/req-cwd/-/req-cwd-2.0.0.tgz#d4082b4d44598036640fb73ddea01ed53db49ebc"
@@ -15676,6 +15859,11 @@ slash@^3.0.0:
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
+slash@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7"
+ integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==
+
slice-ansi@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636"
@@ -16114,11 +16302,6 @@ stacktrace-parser@^0.1.10:
dependencies:
type-fest "^0.7.1"
-state-toggle@^1.0.0:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe"
- integrity sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==
-
static-extend@^0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6"
@@ -16392,11 +16575,16 @@ strip-json-comments@2.0.1, strip-json-comments@^2.0.1, strip-json-comments@~2.0.
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
-strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1, strip-json-comments@~3.1.1:
+strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
+strip-json-comments@4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-4.0.0.tgz#6fd3a79f1b956905483769b0bf66598b8f87da50"
+ integrity sha512-LzWcbfMbAsEDTRmhjWIioe8GcDRl0fa35YMXFoJKDdiD/quGFmjJjdgPjFJJNwCMaLyQqFIDqCdHD2V4HfLgYA==
+
strong-log-transformer@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz#0f5ed78d325e0421ac6f90f7f10e691d6ae3ae10"
@@ -16406,13 +16594,6 @@ strong-log-transformer@^2.1.0:
minimist "^1.2.0"
through "^2.3.4"
-structured-source@^3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/structured-source/-/structured-source-3.0.2.tgz#dd802425e0f53dc4a6e7aca3752901a1ccda7af5"
- integrity sha1-3YAkJeD1PcSm56yjdSkBoczaevU=
- dependencies:
- boundary "^1.0.1"
-
superagent@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/superagent/-/superagent-6.1.0.tgz#09f08807bc41108ef164cfb4be293cebd480f4a6"
@@ -16876,16 +17057,6 @@ trim-right@^1.0.1:
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=
-trim-trailing-lines@^1.0.0:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0"
- integrity sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==
-
-trim@0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd"
- integrity sha1-WFhUf2spB1fulczMZm+1AITEYN0=
-
triple-beam@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9"
@@ -17362,35 +17533,27 @@ underscore@1.9.1:
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961"
integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==
-underscore@~1.12.1:
- version "1.12.1"
- resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.12.1.tgz#7bb8cc9b3d397e201cf8553336d262544ead829e"
- integrity sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==
+underscore@^1.13.2:
+ version "1.13.4"
+ resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.4.tgz#7886b46bbdf07f768e0052f1828e1dcab40c0dee"
+ integrity sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ==
undici@^4.14.1:
version "4.15.0"
resolved "https://registry.yarnpkg.com/undici/-/undici-4.15.0.tgz#507ec94bce46bec5c76e934938c50b825eda8258"
integrity sha512-kHppwh/y49FLEXl/zYCCbGB0D3nrcWNBczNYCsDdNYzWPs80aQgfKic1PVkJEIc2YlR7m0Lf5i559zbr0AA7FQ==
-unherit@^1.0.4:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.3.tgz#6c9b503f2b41b262330c80e91c8614abdaa69c22"
- integrity sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==
- dependencies:
- inherits "^2.0.0"
- xtend "^4.0.0"
-
-unified@^6.1.6:
- version "6.2.0"
- resolved "https://registry.yarnpkg.com/unified/-/unified-6.2.0.tgz#7fbd630f719126d67d40c644b7e3f617035f6dba"
- integrity sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==
+unified@^9.2.2:
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.2.tgz#67649a1abfc3ab85d2969502902775eb03146975"
+ integrity sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==
dependencies:
bail "^1.0.0"
extend "^3.0.0"
- is-plain-obj "^1.1.0"
+ is-buffer "^2.0.0"
+ is-plain-obj "^2.0.0"
trough "^1.0.0"
- vfile "^2.0.0"
- x-is-string "^0.1.0"
+ vfile "^4.0.0"
union-value@^1.0.0:
version "1.0.1"
@@ -17416,36 +17579,25 @@ unique-slug@^2.0.0:
dependencies:
imurmurhash "^0.1.4"
-unist-util-is@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-3.0.0.tgz#d9e84381c2468e82629e4a5be9d7d05a2dd324cd"
- integrity sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==
-
-unist-util-remove-position@^1.0.0:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz#ec037348b6102c897703eee6d0294ca4755a2020"
- integrity sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==
- dependencies:
- unist-util-visit "^1.1.0"
-
-unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz#3f37fcf351279dcbca7480ab5889bb8a832ee1c6"
- integrity sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==
+unist-util-is@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797"
+ integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==
-unist-util-visit-parents@^2.0.0:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz#25e43e55312166f3348cae6743588781d112c1e9"
- integrity sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==
+unist-util-stringify-position@^2.0.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da"
+ integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==
dependencies:
- unist-util-is "^3.0.0"
+ "@types/unist" "^2.0.2"
-unist-util-visit@^1.1.0:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.4.1.tgz#4724aaa8486e6ee6e26d7ff3c8685960d560b1e3"
- integrity sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==
+unist-util-visit-parents@^3.0.0:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz#65a6ce698f78a6b0f56aa0e88f13801886cdaef6"
+ integrity sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==
dependencies:
- unist-util-visit-parents "^2.0.0"
+ "@types/unist" "^2.0.0"
+ unist-util-is "^4.0.0"
uniswap-v3-deploy-plugin@^0.1.0:
version "0.1.0"
@@ -17499,10 +17651,10 @@ upath@^2.0.1:
resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b"
integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==
-update-section@~0.3.3:
+update-section@^0.3.3:
version "0.3.3"
resolved "https://registry.yarnpkg.com/update-section/-/update-section-0.3.3.tgz#458f17820d37820dc60e20b86d94391b00123158"
- integrity sha1-RY8Xgg03gg3GDiC4bZQ5GwASMVg=
+ integrity sha512-BpRZMZpgXLuTiKeiu7kK0nIPwGdyrqrs6EDSaXtjD/aQ2T+qVo9a5hRC3HN3iJjCMxNT/VxoLGQ7E/OzE5ucnw==
uri-js@^4.2.2:
version "4.4.1"
@@ -17688,27 +17840,23 @@ verror@1.10.0:
core-util-is "1.0.2"
extsprintf "^1.2.0"
-vfile-location@^2.0.0:
- version "2.0.6"
- resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.6.tgz#8a274f39411b8719ea5728802e10d9e0dff1519e"
- integrity sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==
-
-vfile-message@^1.0.0:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-1.1.1.tgz#5833ae078a1dfa2d96e9647886cd32993ab313e1"
- integrity sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==
+vfile-message@^2.0.0:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a"
+ integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==
dependencies:
- unist-util-stringify-position "^1.1.1"
+ "@types/unist" "^2.0.0"
+ unist-util-stringify-position "^2.0.0"
-vfile@^2.0.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/vfile/-/vfile-2.3.0.tgz#e62d8e72b20e83c324bc6c67278ee272488bf84a"
- integrity sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==
+vfile@^4.0.0:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624"
+ integrity sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==
dependencies:
- is-buffer "^1.1.4"
- replace-ext "1.0.0"
- unist-util-stringify-position "^1.0.0"
- vfile-message "^1.0.0"
+ "@types/unist" "^2.0.0"
+ is-buffer "^2.0.0"
+ unist-util-stringify-position "^2.0.0"
+ vfile-message "^2.0.0"
vscode-oniguruma@^1.6.1:
version "1.6.2"
@@ -18539,11 +18687,6 @@ ws@^7.4.6:
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74"
integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==
-x-is-string@^0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82"
- integrity sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=
-
xhr-request-promise@^0.1.2:
version "0.1.3"
resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz#2d5f4b16d8c6c893be97f1a62b0ed4cf3ca5f96c"
@@ -18633,7 +18776,7 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
-yaml@^1.10.0, yaml@~1.10.2:
+yaml@1.10.2, yaml@^1.10.0:
version "1.10.2"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
@@ -18793,3 +18936,8 @@ zksync-web3@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/zksync-web3/-/zksync-web3-0.4.0.tgz#9ab3e8648a6ab11d42b649b3458a0383d6c41bab"
integrity sha512-LmrjkQlg2YSR+P0J1NQKtkraCN2ESKfVoMxole3NxesrASQTsk6fR5+ph/8Vucq/Xh8EoAafp07+Q6TavP/TTw==
+
+zwitch@^1.0.0:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920"
+ integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==