Commit cb21d3fa authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

Merge pull request #3170 from ethereum-optimism/develop

Develop -> Master
parents 907ef2ee b6f4bfcf
---
'@eth-optimism/contracts-bedrock': patch
---
Fix slither script
---
'@eth-optimism/contracts-bedrock': patch
---
Update genesis-l2 task to set immutables in the bytecode
---
'@eth-optimism/contracts-bedrock': patch
---
Fix build for smaller package
---
'@eth-optimism/contracts-bedrock': patch
---
Use the same initializable across codebase
---
'@eth-optimism/contracts-bedrock': patch
---
Update @foundry-rs/hardhat-forge@0.1.16
---
'@eth-optimism/contracts-bedrock': patch
---
Fix build on latest foundry
---
'@eth-optimism/core-utils': patch
---
Implement basic OpNodeProvider
---
'@eth-optimism/hardhat-deploy-config': patch
---
Support JSON-formatted deploy configs
---
'@eth-optimism/proxyd': minor
---
Add frontend rate limiting
---
'@eth-optimism/contracts-bedrock': patch
---
Emit an extra event when withdrawals are initiated to make chainops easier
---
'@eth-optimism/proxyd': patch
---
Unwrap single RPC batches
---
'@eth-optimism/contracts-bedrock': patch
---
Fix portal deployment to have L2OutputOracle proxy address
---
'@eth-optimism/contracts-bedrock': patch
---
Add watch task
---
'@eth-optimism/contracts-bedrock': patch
---
Add harhdat forge contract verification support
---
'@eth-optimism/proxyd': patch
---
Parameterize full RPC request logging
---
'@eth-optimism/contracts-bedrock': patch
---
Update hardhat-forge dep, remove dead deps
---
'@eth-optimism/contracts-bedrock': patch
---
bedrock-goerli-96f44f79 deployment
---
'@eth-optimism/foundry': patch
---
Update to 64fe4acc97e6d76551cea7598c201f05ecd65639
---
'@eth-optimism/contracts-bedrock': patch
'@eth-optimism/core-utils': patch
---
Update deposit transaction type
---
'@eth-optimism/integration-tests': patch
---
Modularize the itests away from depending on api of messenger
---
'@eth-optimism/contracts-bedrock': patch
---
Fix typechain exports
---
'@eth-optimism/sdk': minor
---
Add wstETH to sdk
---
'@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.
......@@ -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
......
......@@ -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
......@@ -58,7 +58,7 @@ root
├── <a href="./teleportr">teleportr</a>: Bridge for teleporting ETH between L1 and L2 at low cost
~~ BEDROCK upgrade - Not production-ready yet, part of next major upgrade ~~
├── <a href="./contracts-bedrock">contracts-bedrock</a>: Bedrock smart contracts. To be merged with ./packages/contracts.
├── <a href="./packages/contracts-bedrock">packages/contracts-bedrock</a>: Bedrock smart contracts. To be merged with ./packages/contracts.
├── <a href="./op-bindings">op-bindings</a>: Go bindings for Bedrock smart contracts.
├── <a href="./op-batcher">op-batcher</a>: L2-Batch Submitter, submits bundles of batches to L1
├── <a href="./op-e2e">op-e2e</a>: End-to-End testing of all bedrock components in Go
......
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
......@@ -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
......@@ -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=
......
......@@ -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()
......
......@@ -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)
......
......@@ -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),
}
}
......@@ -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.
......
......@@ -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
......@@ -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=
......
......@@ -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
......
......@@ -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.
......
......@@ -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
......
......@@ -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"
......@@ -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.
......
......@@ -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"
......@@ -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}
......
......@@ -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
......@@ -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=
......
......@@ -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
......@@ -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=
......
......@@ -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,
......
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
},
},
}
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)
})
}
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
}
......@@ -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) {
......
......@@ -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
......@@ -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=
......
......@@ -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 {
......
......@@ -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)
......
......@@ -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
}
......
......@@ -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 &eth.PayloadAttributes{
Timestamp: hexutil.Uint64(l2Parent.Time + cfg.BlockTime),
Timestamp: hexutil.Uint64(timestamp),
PrevRandao: eth.Bytes32(l1Info.MixDigest()),
SuggestedFeeRecipient: cfg.FeeRecipientAddress,
Transactions: txs,
......
......@@ -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)
......
......@@ -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")},
}}
......
......@@ -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)
......
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
}
}
}
......
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
}
......@@ -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
}
}
......
......@@ -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 {
......
......@@ -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
}
......
......@@ -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}
}
......
......@@ -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
......
......@@ -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
}
......
......@@ -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,
}
......
......@@ -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
}
......
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
......
......@@ -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),
}
}
......@@ -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.
......
......@@ -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
......@@ -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=
......
......@@ -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)
......
......@@ -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
......
......@@ -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:
......
......@@ -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 \
......
......@@ -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",
......
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)
// 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"
......
// 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";
......
......@@ -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;
}
......
......@@ -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));
}
......
......@@ -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;
......
......@@ -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,
......
......@@ -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
);
}
}
......@@ -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
......
......@@ -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),
......
......@@ -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
);
}
......
......@@ -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
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
......@@ -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,
......
......@@ -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()
......
......@@ -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,
......
{
"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",
......
{
"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",
......
{
"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",
......
{
"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",
......
[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
......@@ -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: [
......
......@@ -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",
......
......@@ -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]
......
#!/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
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}`
)
}
})
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))
})
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<boolean> => {
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}`)
}
}
})
......@@ -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')
}
......
......@@ -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<string> => {
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,
......
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'
......@@ -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,
......
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)
})
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": ".",
"rootDir": "./src",
"outDir": "./dist"
},
"exclude": ["hardhat.config.ts", "deploy", "tasks", "test"],
"include": ["src/**/*", "scripts/**/*"]
"include": ["src/**/*"]
}
[default]
[profile.default]
# The source directory
src = 'contracts/universal'
# The test directory
......
# AddressUpgradeable
*Collection of functions related to the address type*
......@@ -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 |
......@@ -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&#39;t have a constructor, it&#39;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&#39;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 &quot;step&quot; 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(&quot;MyToken&quot;, &quot;MTK&quot;); } } contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { function initializeV2() reinitializer(2) public { __ERC20Permit_init(&quot;MyToken&quot;); } } ``` 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 |
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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 |
......@@ -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"
......
......@@ -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
......
......@@ -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.
*
......
......@@ -10,3 +10,4 @@ export * from './op-node'
export * from './deposit-transaction'
export * from './encoding'
export * from './hashing'
export * from './op-provider'
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<SyncStatusResponse> {
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<any>): Promise<any> {
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
}
}
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}`
......
[default]
[profile.default]
src = 'contracts'
out = 'forge-artifacts'
optimizer = true
......
......@@ -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
......@@ -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"
......
......@@ -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,
}
)
}
},
......
......@@ -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
)
......
......@@ -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<OEContractsLike>
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<L2OutputOracleParameters> {
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<MessageReceipt> {
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<number> {
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<BedrockOutputData | null> {
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<StateRoot | null> {
......@@ -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 (
......
......@@ -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<number>
/**
* 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<BedrockOutputData | null>
/**
* 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<CrossChainMessageProof>
/**
* 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.
......
......@@ -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
......
......@@ -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,
}
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,
}
......
export * from './coercion'
export * from './contracts'
export * from './message-encoding'
export * from './type-utils'
export * from './misc-utils'
export * from './merkle-utils'
......
/* 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,
}
}
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)]
)
}
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')
})
......@@ -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
)
);
}
......
......@@ -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
);
}
......
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(
......
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),
}
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)
})
})
})
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"
},
"include": [
"src/**/*"
]
......
......@@ -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])
}
......@@ -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"`
......
......@@ -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
......
......@@ -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=
......
......@@ -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 {
......
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
}
[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"
......@@ -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
}
......
......@@ -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 {
......
......@@ -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)
......
......@@ -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 {
}
......@@ -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), "\"") {
......
......@@ -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
}
......
<!-- DOCTOC SKIP -->
# 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
......
<!-- DOCTOC SKIP -->
# 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.
......@@ -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)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
......@@ -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
......@@ -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
......
......@@ -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).
......
......@@ -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
......
<!-- DOCTOC SKIP -->
# Bedrock Local Devnet Setup
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
......
......@@ -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
......
......@@ -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
......
......@@ -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.
......
......@@ -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;
}
```
......@@ -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
......
......@@ -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)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
......@@ -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.
......@@ -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
......
......@@ -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==
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment