Commit 8af6d151 authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

Merge pull request #3602 from ethereum-optimism/develop

Develop -> Master
parents ac43b2fe 7b5fb40d
---
'@eth-optimism/integration-tests': patch
'@eth-optimism/contracts-periphery': patch
---
Removes NFT refund logic if withdrawals fail.
---
'@eth-optimism/common-ts': patch
---
Minor update to BaseServiceV2 to keep the raw body around when requests are made.
---
'@eth-optimism/contracts-bedrock': patch
---
Fixes a small bug in the constructor of the L2OutputOracle contract
---
'@eth-optimism/proxyd': patch
---
Add customizable whitelist error
---
'@eth-optimism/contracts': patch
---
Add prefunded accounts to L2 genesis when doing local network
---
'@eth-optimism/contracts-bedrock': minor
---
No refunds!
---
'@eth-optimism/contracts-bedrock': patch
---
Updates README to include versioning rules.
---
'@eth-optimism/contracts': patch
---
Expose the deployments in the deployer image
---
'@eth-optimism/contracts-periphery': patch
---
Adds input validation to the ERC721Bridge constructor, fixes a typo in the L1ERC721Bridge, and removes the ERC721Refunded event declaration.
---
'@eth-optimism/data-transport-layer': patch
---
Adds consistency checks for transaction entries in L1 syncing nodes
---
'@eth-optimism/proxyd': patch
---
Batch metrics and max batch size
---
'@eth-optimism/contracts-bedrock': patch
---
Fuzz L2ToL1MessagePasser
---
'@eth-optimism/contracts-periphery': patch
---
Remove ownable upgradable from erc721 factory
---
'@eth-optimism/contracts-bedrock': patch
---
Modifies the StandardBridge to move a value check deeper down the call stack to be more defensive.
---
'@eth-optimism/contracts-periphery': patch
---
Increased solc version on drip checks to 0.8.16.
---
'@eth-optimism/hardhat-deploy-config': patch
---
Allow `paths` to be unset in hardhat config
......@@ -8,56 +8,38 @@ jobs:
- image: ethereumoptimism/ci-builder:latest
resource_class: xlarge
steps:
- restore_cache:
keys:
- v2-cache-source-{{ .Branch }}-{{ .Revision }}
- v2-cache-source-{{ .Branch }}
- checkout
- run:
name: Check if we should run
command: |
shopt -s inherit_errexit
CHANGED=$(check-changed "(op-bindings|op-chain-ops|packages/)")
CHANGED=$(check-changed "(op-bindings|op-chain-ops|packages/)" || echo "TRUE")
if [[ "$CHANGED" = "FALSE" ]]; then
circleci step halt
fi
- save_cache:
key: v2-cache-source-{{ .Branch }}-{{ .Revision }}
paths:
- ".git"
- restore_cache:
keys:
- v2-cache-yarn-install-{{ checksum "yarn.lock" }}
- v2-cache-yarn-install
- run:
name: Install dependencies
command: yarn --frozen-lockfile
- run:
name: print forge version
command: forge --version
- save_cache:
key: v2-cache-yarn-install-{{ checksum "yarn.lock" }}
paths:
- node_modules
- packages/common-ts/node_modules
- packages/contracts/node_modules
- packages/contracts-bedrock/node_modules
- packages/contracts-periphery/node_modules
- packages/core-utils/node_modules
- packages/data-transport-layer/node_modules
- packages/drippie-mon/node_modules
- packages/fault-detector/node_modules
- packages/message-relayer/node_modules
- packages/replica-healthcheck/node_modules
- packages/sdk/node_modules
- integration-tests/node_modules
- run:
name: Build monorepo
command: yarn build
- save_cache:
key: v2-cache-yarn-build-{{ .Revision }}
- persist_to_workspace:
root: "."
paths:
- "."
- "node_modules"
- "packages/*/node_modules"
- "packages/*/dist"
- "packages/*/artifacts"
- "packages/contracts/src/contract-artifacts.ts"
- "packages/contracts/src/contract-deployed-artifacts.ts"
- "packages/contracts/chugsplash"
- "packages/contracts/L1"
- "packages/contracts/L2"
- "packages/contracts/libraries"
- "packages/contracts/standards"
docker-publish:
......@@ -85,6 +67,13 @@ jobs:
image: ubuntu-2204:2022.07.1
resource_class: xlarge
steps:
# Below is CircleCI recommended way of specifying nameservers on an Ubuntu box:
# https://support.circleci.com/hc/en-us/articles/7323511028251-How-to-set-custom-DNS-on-Ubuntu-based-images-using-netplan
- run: sudo sed -i '13 i \ \ \ \ \ \ \ \ \ \ \ \ nameservers:' /etc/netplan/50-cloud-init.yaml
- run: sudo sed -i '14 i \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ addresses:' /etc/netplan/50-cloud-init.yaml
- run: sudo sed -i "s/addresses:/ addresses":" [8.8.8.8, 8.8.4.4] /g" /etc/netplan/50-cloud-init.yaml
- run: cat /etc/netplan/50-cloud-init.yaml
- run: sudo netplan apply
- checkout
- when:
condition: <<parameters.target>>
......@@ -92,6 +81,7 @@ jobs:
- run:
name: Build with context
command: |
echo "$DOCKER_HUB_READ_ONLY_TOKEN" | docker login -u "$DOCKER_HUB_READ_ONLY_USER" --password-stdin
docker build \
$(echo -ne "<< parameters.docker_tags >>" | sed "s/,/\n/g" | sed -e 's/^/-t /' | tr '\n' ' ') \
-f <<parameters.docker_file>> \
......@@ -103,6 +93,7 @@ jobs:
- run:
name: Build
command: |
echo "$DOCKER_HUB_READ_ONLY_TOKEN" | docker login -u "$DOCKER_HUB_READ_ONLY_USER" --password-stdin
docker build \
$(echo -ne "<< parameters.docker_tags >>" | sed "s/,/\n/g" | sed -e 's/^/-t /' | tr '\n' ' ') \
-f <<parameters.docker_file>> \
......@@ -118,15 +109,13 @@ jobs:
- image: ethereumoptimism/ci-builder:latest
resource_class: large
steps:
- restore_cache:
keys:
- v2-cache-yarn-build-{{ .Revision }}
- checkout
- attach_workspace: {at: "."}
- run:
name: Check if we should run
command: |
shopt -s inherit_errexit
CHANGED=$(check-changed "(contracts-bedrock|hardhat-deploy-config)")
CHANGED=$(check-changed "(contracts-bedrock|hardhat-deploy-config)" || echo "TRUE")
if [[ "$CHANGED" = "FALSE" ]]; then
circleci step halt
fi
......@@ -134,6 +123,10 @@ jobs:
name: lint
command: yarn lint:check
working_directory: packages/contracts-bedrock
- run:
name: validate spacers
command: yarn validate-spacers
working_directory: packages/contracts-bedrock
- run:
name: slither
command: |
......@@ -152,8 +145,7 @@ jobs:
working_directory: packages/contracts-bedrock
- run:
name: upload coverage
command: |
codecov --verbose || exit 0
command: codecov --verbose --clean --flag contracts-bedrock-forge
environment:
FOUNDRY_PROFILE: ci
- run:
......@@ -174,15 +166,13 @@ jobs:
- image: ethereumoptimism/ci-builder:latest
resource_class: medium
steps:
- restore_cache:
keys:
- v2-cache-yarn-build-{{ .Revision }}
- checkout
- attach_workspace: {at: "."}
- run:
name: Check if we should run
command: |
shopt -s inherit_errexit
CHANGED=$(check-changed "(contracts-bedrock|op-bindings)")
CHANGED=$(check-changed "(contracts-bedrock|op-bindings)" || echo "TRUE")
if [[ "$CHANGED" = "FALSE" ]]; then
circleci step halt
fi
......@@ -204,15 +194,13 @@ jobs:
- image: ethereumoptimism/ci-builder:latest
resource_class: large
steps:
- restore_cache:
keys:
- v2-cache-yarn-build-{{ .Revision }}
- checkout
- attach_workspace: {at: "."}
- run:
name: Check if we should run
command: |
shopt -s inherit_errexit
CHANGED=$(check-changed "(packages/<<parameters.package_name>>|packages/<<parameters.dependencies>>)")
CHANGED=$(check-changed "(packages/<<parameters.package_name>>|packages/<<parameters.dependencies>>)" || echo "TRUE")
if [[ "$CHANGED" = "FALSE" ]]; then
circleci step halt
fi
......@@ -224,6 +212,11 @@ jobs:
name: Test
command: yarn test:coverage
working_directory: packages/<<parameters.package_name>>
- run:
name: Upload coverage
command: |
echo <<parameters.package_name>> # TEMP for debugging
codecov --verbose --clean --flag <<parameters.package_name>>
bedrock-go-tests:
docker:
......@@ -235,7 +228,7 @@ jobs:
name: Check if we should run
command: |
shopt -s inherit_errexit
CHANGED=$(check-changed "op-(batcher|bindings|e2e|node|proposer|chain-ops)")
CHANGED=$(check-changed "op-(batcher|bindings|e2e|node|proposer|chain-ops)" || echo "TRUE")
if [[ "$CHANGED" = "FALSE" ]]; then
circleci step halt
fi
......@@ -308,9 +301,8 @@ jobs:
gotestsum --junitfile /test-results/op-chain-ops.xml -- -coverpkg=github.com/ethereum-optimism/optimism/... -coverprofile=coverage.out -covermode=atomic ./...
working_directory: op-chain-ops
- run:
name: Upload coverage reports to CodeCov
command: |
codecov --verbose || exit 0
name: upload coverage
command: codecov --verbose --clean --flag bedrock-go-tests
- store_test_results:
path: /test-results
- run:
......@@ -344,7 +336,7 @@ jobs:
name: Check if we should run
command: |
shopt -s inherit_errexit
CHANGED=$(check-changed "op-node")
CHANGED=$(check-changed "op-node" || echo "TRUE")
if [[ "$CHANGED" = "FALSE" ]]; then
circleci step halt
fi
......@@ -357,15 +349,13 @@ jobs:
docker:
- image: ethereumoptimism/ci-builder:latest
steps:
- restore_cache:
keys:
- v2-cache-yarn-build-{{ .Revision }}
- checkout
- attach_workspace: {at: "."}
- run:
name: Check if we should run
command: |
shopt -s inherit_errexit
CHANGED=$(check-changed "packages/")
CHANGED=$(check-changed "packages/" || echo "TRUE")
if [[ "$CHANGED" = "FALSE" ]]; then
circleci step halt
fi
......@@ -421,7 +411,7 @@ jobs:
name: Check if we should run
command: |
shopt -s inherit_errexit
CHANGED=$(check-changed "(<<parameters.working_directory>>|<<parameters.dependencies>>)")
CHANGED=$(check-changed "(<<parameters.working_directory>>|<<parameters.dependencies>>)" || echo "TRUE")
echo $CHANGED
if [[ "$CHANGED" = "FALSE" ]]; then
circleci step halt
......@@ -447,27 +437,6 @@ jobs:
command: make <<parameters.binary_name>>
working_directory: <<parameters.working_directory>>
op-chain-ops-tests:
docker:
- image: ethereumoptimism/ci-builder:latest
steps:
- restore_cache:
keys:
- v2-cache-yarn-build-{{ .Revision }}
- checkout
- run:
name: Check if we should run
command: |
CHANGED=$(bash ./ops/docker/ci-builder/check-changed.sh "op-chain-ops")
if [[ "$CHANGED" = "FALSE" ]]; then
circleci step halt
fi
- run:
name: Test
command: |
gotestsum --junitfile /test-results/op-chain-ops.xml -- -coverpkg=github.com/ethereum-optimism/optimism/... -coverprofile=coverage.out -covermode=atomic ./...
working_directory: op-chain-ops
geth-tests:
docker:
- image: ethereumoptimism/ci-builder:latest
......@@ -477,7 +446,7 @@ jobs:
name: Check if we should run
command: |
shopt -s inherit_errexit
CHANGED=$(check-changed "l2geth")
CHANGED=$(check-changed "l2geth" || echo "TRUE")
if [[ "$CHANGED" = "FALSE" ]]; then
circleci step halt
fi
......@@ -497,7 +466,7 @@ jobs:
- run:
name: Check if we should run
command: |
CHANGED=$(bash ./ops/docker/ci-builder/check-changed.sh "(contracts-bedrock|op-bindings|op-batcher|op-node|op-proposer|ops-bedrock|sdk)/")
CHANGED=$(bash ./ops/docker/ci-builder/check-changed.sh "(contracts-bedrock|op-bindings|op-batcher|op-node|op-proposer|ops-bedrock|sdk)/" || echo "TRUE")
if [[ "$CHANGED" = "FALSE" ]]; then
circleci step halt
fi
......@@ -551,7 +520,7 @@ jobs:
name: Check if we should run
command: |
shopt -s inherit_errexit
CHANGED=$(bash ./ops/docker/ci-builder/check-changed.sh "(l2geth|common-ts|contracts|core-utils|message-relayer|data-transport-layer|replica-healthcheck|sdk|batch-submitter|gas-oracle|bss-core|integration-tests)/")
CHANGED=$(bash ./ops/docker/ci-builder/check-changed.sh "(l2geth|common-ts|contracts|core-utils|message-relayer|data-transport-layer|replica-healthcheck|sdk|batch-submitter|gas-oracle|bss-core|integration-tests)/" || echo "TRUE")
if [[ "$CHANGED" = "FALSE" ]]; then
circleci step halt
fi
......@@ -646,7 +615,7 @@ jobs:
-sim=<<parameters.sim>> \
-sim.loglevel=5 \
-docker.pull=true \
-client=go-ethereum,op-geth_optimism-history,op-proposer_<<parameters.version>>,op-batcher_<<parameters.version>>,op-node_<<parameters.version>> |& tee /tmp/hive.log
-client=go-ethereum,op-geth_optimism-history,op-proposer_<<parameters.version>>,op-batcher_<<parameters.version>>,op-node_<<parameters.version>> |& tee /tmp/hive.log || echo "failed."
- run:
command: |
tar -cvf /tmp/workspace.tgz -C /home/circleci/project /home/circleci/project/workspace
......@@ -772,10 +741,6 @@ workflows:
binary_name: bss-core
working_directory: bss-core
build: false
- op-chain-ops-tests:
name: op-chain-ops-tests
requires:
- yarn-monorepo
- geth-tests
- integration-tests
- semgrep-scan
......@@ -788,9 +753,6 @@ workflows:
repo: us-central1-docker.pkg.dev
context:
- gcr
requires:
- bedrock-go-tests
- op-bindings-build
- docker-publish:
name: op-batcher-publish-dev
docker_file: op-batcher/Dockerfile
......@@ -799,9 +761,6 @@ workflows:
repo: us-central1-docker.pkg.dev
context:
- gcr
requires:
- bedrock-go-tests
- op-bindings-build
- docker-publish:
name: op-proposer-publish-dev
docker_file: op-proposer/Dockerfile
......@@ -810,31 +769,6 @@ workflows:
repo: us-central1-docker.pkg.dev
context:
- gcr
requires:
- bedrock-go-tests
- op-bindings-build
- docker-publish:
name: deployer-bedrock-publish-dev
docker_file: ops/docker/Dockerfile.packages
docker_tags: us-central1-docker.pkg.dev/bedrock-goerli-development/images/deployer-bedrock:<<pipeline.git.revision>>
target: deployer-bedrock
docker_context: .
repo: us-central1-docker.pkg.dev
context:
- gcr
requires:
- contracts-bedrock-tests
- docker-publish:
name: contract-artifacts-bedrock-publish-dev
docker_file: ops/docker/Dockerfile.packages
docker_tags: us-central1-docker.pkg.dev/bedrock-goerli-development/images/contract-artifacts-bedrock:<<pipeline.git.revision>>
target: contract-artifacts-bedrock
docker_context: .
repo: us-central1-docker.pkg.dev
context:
- gcr
requires:
- contracts-bedrock-tests
- hive-test:
name: hive-test-rpc
version: <<pipeline.git.revision>>
......@@ -843,7 +777,6 @@ workflows:
- op-node-publish-dev
- op-batcher-publish-dev
- op-proposer-publish-dev
- deployer-bedrock-publish-dev
- hive-test:
name: hive-test-p2p
version: <<pipeline.git.revision>>
......@@ -852,7 +785,6 @@ workflows:
- op-node-publish-dev
- op-batcher-publish-dev
- op-proposer-publish-dev
- deployer-bedrock-publish-dev
- hive-test:
name: hive-test-l1ops
version: <<pipeline.git.revision>>
......@@ -861,4 +793,3 @@ workflows:
- op-node-publish-dev
- op-batcher-publish-dev
- op-proposer-publish-dev
- deployer-bedrock-publish-dev
comment: false
ignore:
- "l2geth"
- "**/*.t.sol"
- "op-bindings/bindings/*.go"
......@@ -19,7 +19,7 @@ use (
./teleportr
)
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd
// For local debugging:
//replace github.com/ethereum/go-ethereum v1.10.23 => ../go-ethereum
......@@ -43,19 +43,3 @@ func FilterDepositFinalizedWithRetry(ctx context.Context, filterer *bindings.L2S
time.Sleep(clientRetryInterval)
}
}
// FilterDepositFailedWithRetry retries the given func until it succeeds,
// waiting for clientRetryInterval duration after every call.
func FilterDepositFailedWithRetry(ctx context.Context, filterer *bindings.L2StandardBridgeFilterer, opts *bind.FilterOpts) (*bindings.L2StandardBridgeDepositFailedIterator, error) {
for {
ctxt, cancel := context.WithTimeout(ctx, DefaultConnectionTimeout)
opts.Context = ctxt
res, err := filterer.FilterDepositFailed(opts, nil, nil, nil)
cancel()
if err == nil {
return res, nil
}
logger.Error("Error fetching filter", "err", err)
time.Sleep(clientRetryInterval)
}
}
......@@ -3,7 +3,6 @@ import { Contract, ContractFactory, utils, Wallet } from 'ethers'
import { ethers } from 'hardhat'
import { getChainId } from '@eth-optimism/core-utils'
import { predeploys } from '@eth-optimism/contracts'
import { MessageLike } from '@eth-optimism/sdk'
import Artifact__TestERC721 from '@eth-optimism/contracts-periphery/artifacts/contracts/testing/helpers/TestERC721.sol/TestERC721.json'
import Artifact__L1ERC721Bridge from '@eth-optimism/contracts-periphery/artifacts/contracts/L1/L1ERC721Bridge.sol/L1ERC721Bridge.json'
import Artifact__L2ERC721Bridge from '@eth-optimism/contracts-periphery/artifacts/contracts/L2/L2ERC721Bridge.sol/L2ERC721Bridge.json'
......@@ -18,9 +17,6 @@ import { withdrawalTest } from './shared/utils'
const TOKEN_ID: number = 1
const FINALIZATION_GAS: number = 600_000
const NON_NULL_BYTES: string = '0x1111'
const DUMMY_L1ERC721_ADDRESS: string = ethers.utils.getAddress(
'0x' + 'acdc'.repeat(10)
)
describe('ERC721 Bridge', () => {
let env: OptimismEnv
......@@ -313,61 +309,4 @@ describe('ERC721 Bridge', () => {
expect(await L1ERC721.ownerOf(TOKEN_ID)).to.equal(L1ERC721Bridge.address)
}
)
withdrawalTest(
'should refund an L2 NFT that fails to be finalized on l1',
async () => {
// Deploy an L2 native NFT, which:
// - Mimics the interface of an OptimismMintableERC721.
// - Allows anyone to mint tokens.
// - Has a `remoteToken` state variable that returns the address of a non-existent L1 ERC721.
// This will cause the bridge to fail on L1, triggering a refund on L2.
const L2NativeNFT = await (
await ethers.getContractFactory(
'FakeOptimismMintableERC721',
aliceWalletL2
)
).deploy(
L2ERC721Bridge.address,
DUMMY_L1ERC721_ADDRESS,
await getChainId(env.l1Wallet.provider)
)
await L2NativeNFT.deployed()
// Alice mints an NFT from the L2 native ERC721 contract
const tx = await L2NativeNFT.safeMint(aliceAddress, TOKEN_ID)
await tx.wait()
// Check that Alice owns the L2 NFT
expect(await L2NativeNFT.ownerOf(TOKEN_ID)).to.equal(aliceAddress)
// Alice bridges her L2 native NFT to L1, which burns the L2 NFT.
const withdrawalTx = await L2ERC721Bridge.connect(
aliceWalletL2
).bridgeERC721(
L2NativeNFT.address,
DUMMY_L1ERC721_ADDRESS,
TOKEN_ID,
FINALIZATION_GAS,
NON_NULL_BYTES
)
await withdrawalTx.wait()
// Check that the token was burnt on L2 (pre-refund).
await expect(L2NativeNFT.ownerOf(TOKEN_ID)).to.be.revertedWith(
'ERC721: owner query for nonexistent token'
)
// Relay the cross-domain transaction to L1, which initiates an L1 -> L2 message to refund
// Alice her L2 NFT.
await env.relayXDomainMessages(withdrawalTx)
// Wait for the L1 -> L2 message to finalize on L2
const txPair = await env.waitForXDomainTransaction(withdrawalTx)
await env.messenger.waitForMessageReceipt(txPair.remoteTx as MessageLike)
// Check that the L2 NFT has been refunded to Alice.
expect(await L2NativeNFT.ownerOf(TOKEN_ID)).to.equal(aliceAddress)
}
)
})
......@@ -3,9 +3,9 @@ module github.com/ethereum-optimism/optimism/op-batcher
go 1.18
require (
github.com/ethereum-optimism/optimism/op-node v0.8.6
github.com/ethereum-optimism/optimism/op-proposer v0.8.6
github.com/ethereum-optimism/optimism/op-service v0.8.6
github.com/ethereum-optimism/optimism/op-node v0.8.8
github.com/ethereum-optimism/optimism/op-proposer v0.8.8
github.com/ethereum-optimism/optimism/op-service v0.8.8
github.com/ethereum/go-ethereum v1.10.23
github.com/miguelmota/go-ethereum-hdwallet v0.1.1
github.com/urfave/cli v1.22.9
......@@ -22,7 +22,7 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/deckarep/golang-set v1.8.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/ethereum-optimism/optimism/op-bindings v0.8.6 // indirect
github.com/ethereum-optimism/optimism/op-bindings v0.8.8 // indirect
github.com/fjl/memsize v0.0.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-stack/stack v1.8.1 // indirect
......@@ -70,4 +70,4 @@ require (
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
)
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd
......@@ -147,16 +147,16 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73 h1:eXnnByFF0QiN1Qrq0wYmvI5lbDM8QQM0pv6AHx2FLnk=
github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo=
github.com/ethereum-optimism/optimism/op-bindings v0.8.6 h1:jJYhmygt7hqGzYa+8sme9SdnKt1c3Y6EbWgIrRONoxw=
github.com/ethereum-optimism/optimism/op-bindings v0.8.6/go.mod h1:gUX5317IAvRMjB4GftayM87JVln3DTqukfirwJpEWnE=
github.com/ethereum-optimism/optimism/op-node v0.8.6 h1:xNwN+Q/Rt17vSKawhBeG9qTcqcyh8JU8PGjK1iuGkF4=
github.com/ethereum-optimism/optimism/op-node v0.8.6/go.mod h1:gkyzgVHV3+tIhLZ8GhT+bL9GrrmouQCW4mKYukS0SHg=
github.com/ethereum-optimism/optimism/op-proposer v0.8.6 h1:iy8XAtkvrURBy3TT2Lf540cbWztxit7K4+BghZ4IsMI=
github.com/ethereum-optimism/optimism/op-proposer v0.8.6/go.mod h1:tuCLnXcO4MrtVyis1Yfo7wtL8EQta1u6zFdzHHj+RAc=
github.com/ethereum-optimism/optimism/op-service v0.8.6 h1:ruZp/BxL8TGn1y9EJmygypPTeVAFlAA0A/h8LsCoV+M=
github.com/ethereum-optimism/optimism/op-service v0.8.6/go.mod h1:gm8YNzERrL/CHBPWx3+01mR/NOVpLLw4GEUSnnTdyFU=
github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd h1:NchOnosWOkH9wlix8QevGHE+6vuRa+OMGvDNsczv2kQ=
github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo=
github.com/ethereum-optimism/optimism/op-bindings v0.8.8 h1:HN625JI2VsRsli+U6GAXipg7lAKx8EOmGIovN79Az+I=
github.com/ethereum-optimism/optimism/op-bindings v0.8.8/go.mod h1:pyTCbh2o/SY+5/AL2Qo5GgAao3Gtt9Ff6tfK9Pa9emM=
github.com/ethereum-optimism/optimism/op-node v0.8.8 h1:WuZF1RsZnB+u/wwWToVaC1lZWfGfgncLusUssA3Hm+o=
github.com/ethereum-optimism/optimism/op-node v0.8.8/go.mod h1:O5nXPCx8vn9c/CHgBC7vP5utcanIQ4uhWKkJ3pAaaSQ=
github.com/ethereum-optimism/optimism/op-proposer v0.8.8 h1:IV0P64q7RJ52yvLMBLAKyqeDOxdQPGHbhmIXGkMKG/8=
github.com/ethereum-optimism/optimism/op-proposer v0.8.8/go.mod h1:PSNjVKZQxjlkDTcXnoCt3Aeo6N6nY0Ma+R+ZHOTsXU8=
github.com/ethereum-optimism/optimism/op-service v0.8.8 h1:k5E78Zr2cGU0SwjoHpFXuC1eyfXhu3oKEOnDDaFi57I=
github.com/ethereum-optimism/optimism/op-service v0.8.8/go.mod h1:K0uybOhICTc2yfhrRj0cD1m7aPkOf5C9e6bUmvf4rGA=
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=
......
......@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const DeployerWhitelistStorageLayoutJSON = "{\"storage\":[{\"astId\":2900,\"contract\":\"contracts/legacy/DeployerWhitelist.sol:DeployerWhitelist\",\"label\":\"owner\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":2905,\"contract\":\"contracts/legacy/DeployerWhitelist.sol:DeployerWhitelist\",\"label\":\"whitelist\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_address,t_bool)\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_mapping(t_address,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_bool\"}}}"
const DeployerWhitelistStorageLayoutJSON = "{\"storage\":[{\"astId\":2853,\"contract\":\"contracts/legacy/DeployerWhitelist.sol:DeployerWhitelist\",\"label\":\"owner\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":2858,\"contract\":\"contracts/legacy/DeployerWhitelist.sol:DeployerWhitelist\",\"label\":\"whitelist\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_address,t_bool)\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_mapping(t_address,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_bool\"}}}"
var DeployerWhitelistStorageLayout = new(solc.StorageLayout)
......
......@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const GasPriceOracleStorageLayoutJSON = "{\"storage\":[{\"astId\":27915,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":1754,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"spacer_1_0_32\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"},{\"astId\":1757,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"spacer_2_0_32\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":1760,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"overhead\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_uint256\"},{\"astId\":1763,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"scalar\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_uint256\"},{\"astId\":1766,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"decimals\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_uint256\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
const GasPriceOracleStorageLayoutJSON = "{\"storage\":[{\"astId\":27735,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":1754,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"spacer_1_0_32\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"},{\"astId\":1757,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"spacer_2_0_32\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":1760,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"overhead\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_uint256\"},{\"astId\":1763,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"scalar\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_uint256\"},{\"astId\":1766,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"decimals\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_uint256\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
var GasPriceOracleStorageLayout = new(solc.StorageLayout)
......
......@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const GovernanceTokenStorageLayoutJSON = "{\"storage\":[{\"astId\":28114,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_balances\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_address,t_uint256)\"},{\"astId\":28120,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_allowances\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":28122,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_totalSupply\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":28124,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_name\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_string_storage\"},{\"astId\":28126,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_symbol\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_string_storage\"},{\"astId\":29491,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_nonces\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_mapping(t_address,t_struct(Counter)30280_storage)\"},{\"astId\":29499,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_PERMIT_TYPEHASH_DEPRECATED_SLOT\",\"offset\":0,\"slot\":\"6\",\"type\":\"t_bytes32\"},{\"astId\":28832,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_delegates\",\"offset\":0,\"slot\":\"7\",\"type\":\"t_mapping(t_address,t_address)\"},{\"astId\":28838,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_checkpoints\",\"offset\":0,\"slot\":\"8\",\"type\":\"t_mapping(t_address,t_array(t_struct(Checkpoint)28823_storage)dyn_storage)\"},{\"astId\":28842,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_totalSupplyCheckpoints\",\"offset\":0,\"slot\":\"9\",\"type\":\"t_array(t_struct(Checkpoint)28823_storage)dyn_storage\"},{\"astId\":27915,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"10\",\"type\":\"t_address\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_struct(Checkpoint)28823_storage)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"struct ERC20Votes.Checkpoint[]\",\"numberOfBytes\":\"32\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_address,t_address)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e address)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_address\"},\"t_mapping(t_address,t_array(t_struct(Checkpoint)28823_storage)dyn_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e struct ERC20Votes.Checkpoint[])\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_array(t_struct(Checkpoint)28823_storage)dyn_storage\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_struct(Counter)30280_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e struct Counters.Counter)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_struct(Counter)30280_storage\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_string_storage\":{\"encoding\":\"bytes\",\"label\":\"string\",\"numberOfBytes\":\"32\"},\"t_struct(Checkpoint)28823_storage\":{\"encoding\":\"inplace\",\"label\":\"struct ERC20Votes.Checkpoint\",\"numberOfBytes\":\"32\"},\"t_struct(Counter)30280_storage\":{\"encoding\":\"inplace\",\"label\":\"struct Counters.Counter\",\"numberOfBytes\":\"32\"},\"t_uint224\":{\"encoding\":\"inplace\",\"label\":\"uint224\",\"numberOfBytes\":\"28\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint32\":{\"encoding\":\"inplace\",\"label\":\"uint32\",\"numberOfBytes\":\"4\"}}}"
const GovernanceTokenStorageLayoutJSON = "{\"storage\":[{\"astId\":27934,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_balances\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_address,t_uint256)\"},{\"astId\":27940,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_allowances\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":27942,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_totalSupply\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":27944,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_name\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_string_storage\"},{\"astId\":27946,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_symbol\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_string_storage\"},{\"astId\":29311,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_nonces\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_mapping(t_address,t_struct(Counter)30100_storage)\"},{\"astId\":29319,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_PERMIT_TYPEHASH_DEPRECATED_SLOT\",\"offset\":0,\"slot\":\"6\",\"type\":\"t_bytes32\"},{\"astId\":28652,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_delegates\",\"offset\":0,\"slot\":\"7\",\"type\":\"t_mapping(t_address,t_address)\"},{\"astId\":28658,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_checkpoints\",\"offset\":0,\"slot\":\"8\",\"type\":\"t_mapping(t_address,t_array(t_struct(Checkpoint)28643_storage)dyn_storage)\"},{\"astId\":28662,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_totalSupplyCheckpoints\",\"offset\":0,\"slot\":\"9\",\"type\":\"t_array(t_struct(Checkpoint)28643_storage)dyn_storage\"},{\"astId\":27735,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"10\",\"type\":\"t_address\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_struct(Checkpoint)28643_storage)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"struct ERC20Votes.Checkpoint[]\",\"numberOfBytes\":\"32\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_address,t_address)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e address)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_address\"},\"t_mapping(t_address,t_array(t_struct(Checkpoint)28643_storage)dyn_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e struct ERC20Votes.Checkpoint[])\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_array(t_struct(Checkpoint)28643_storage)dyn_storage\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_struct(Counter)30100_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e struct Counters.Counter)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_struct(Counter)30100_storage\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_string_storage\":{\"encoding\":\"bytes\",\"label\":\"string\",\"numberOfBytes\":\"32\"},\"t_struct(Checkpoint)28643_storage\":{\"encoding\":\"inplace\",\"label\":\"struct ERC20Votes.Checkpoint\",\"numberOfBytes\":\"32\"},\"t_struct(Counter)30100_storage\":{\"encoding\":\"inplace\",\"label\":\"struct Counters.Counter\",\"numberOfBytes\":\"32\"},\"t_uint224\":{\"encoding\":\"inplace\",\"label\":\"uint224\",\"numberOfBytes\":\"28\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint32\":{\"encoding\":\"inplace\",\"label\":\"uint32\",\"numberOfBytes\":\"4\"}}}"
var GovernanceTokenStorageLayout = new(solc.StorageLayout)
......
......@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const L1CrossDomainMessengerStorageLayoutJSON = "{\"storage\":[{\"astId\":24801,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":27292,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_initialized\",\"offset\":20,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":27295,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_initializing\",\"offset\":21,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":27906,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":27164,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":27284,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":27457,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_paused\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_bool\"},{\"astId\":27562,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":27577,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_status\",\"offset\":0,\"slot\":\"151\",\"type\":\"t_uint256\"},{\"astId\":27621,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"152\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":24853,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_201_0_32\",\"offset\":0,\"slot\":\"201\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24858,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_202_0_32\",\"offset\":0,\"slot\":\"202\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24863,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"successfulMessages\",\"offset\":0,\"slot\":\"203\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24866,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"xDomainMsgSender\",\"offset\":0,\"slot\":\"204\",\"type\":\"t_address\"},{\"astId\":24869,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"msgNonce\",\"offset\":0,\"slot\":\"205\",\"type\":\"t_uint240\"},{\"astId\":24874,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"receivedMessages\",\"offset\":0,\"slot\":\"206\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24879,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"207\",\"type\":\"t_array(t_uint256)42_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)42_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[42]\",\"numberOfBytes\":\"1344\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint240\":{\"encoding\":\"inplace\",\"label\":\"uint240\",\"numberOfBytes\":\"30\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}"
const L1CrossDomainMessengerStorageLayoutJSON = "{\"storage\":[{\"astId\":24726,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":27112,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_initialized\",\"offset\":20,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":27115,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_initializing\",\"offset\":21,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":27726,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":26984,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":27104,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":27277,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_paused\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_bool\"},{\"astId\":27382,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":27397,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_status\",\"offset\":0,\"slot\":\"151\",\"type\":\"t_uint256\"},{\"astId\":27441,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"152\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":24778,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_201_0_32\",\"offset\":0,\"slot\":\"201\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24783,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_202_0_32\",\"offset\":0,\"slot\":\"202\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24788,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"successfulMessages\",\"offset\":0,\"slot\":\"203\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24791,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"xDomainMsgSender\",\"offset\":0,\"slot\":\"204\",\"type\":\"t_address\"},{\"astId\":24794,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"msgNonce\",\"offset\":0,\"slot\":\"205\",\"type\":\"t_uint240\"},{\"astId\":24799,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"receivedMessages\",\"offset\":0,\"slot\":\"206\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24804,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"207\",\"type\":\"t_array(t_uint256)42_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)42_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[42]\",\"numberOfBytes\":\"1344\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint240\":{\"encoding\":\"inplace\",\"label\":\"uint240\",\"numberOfBytes\":\"30\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}"
var L1CrossDomainMessengerStorageLayout = new(solc.StorageLayout)
......
......@@ -30,8 +30,8 @@ var (
// L1StandardBridgeMetaData contains all meta data concerning the L1StandardBridge contract.
var L1StandardBridgeMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_messenger\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20DepositInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20WithdrawalFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHBridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHBridgeInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHDepositInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHWithdrawalFinalized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC20To\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeETHTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"completeOutboundTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"depositERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"depositERC20To\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"depositETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"depositETHTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeERC20\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeERC20Withdrawal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeETHWithdrawal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2TokenBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"contractCrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"otherBridge\",\"outputs\":[{\"internalType\":\"contractStandardBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
Bin: "0x6101206040523480156200001257600080fd5b5060405162002fe938038062002fe983398101604081905262000035916200006f565b6001600160a01b031660805273420000000000000000000000000000000000001060a052600060c081905260e052600261010052620000a1565b6000602082840312156200008257600080fd5b81516001600160a01b03811681146200009a57600080fd5b9392505050565b60805160a05160c05160e05161010051612e8c6200015d60003960006111730152600061114a015260006111210152600081816103aa01528181610446015281816105210152818161066f01528181610ad501528181610d220152818161136001526119b301526000818161026c015281816104e401528181610645015281816106a601528181610aab01528181610b0c01528181610cf801528181610d59015281816113360152818161139701526119770152612e8c6000f3fe60806040526004361061012d5760003560e01c806387087623116100a5578063a9f9e67511610074578063b1a1a88211610059578063b1a1a88214610421578063c89701a214610434578063e11013dd1461046857600080fd5b8063a9f9e675146103e1578063af565a131461040157600080fd5b806387087623146103355780638f601f661461035557806391c49bf81461039b5780639a2ac6d5146103ce57600080fd5b80633cb747bf116100fc57806354fd4d50116100e157806354fd4d50146102d357806358a997f6146102f5578063838b25201461031557600080fd5b80633cb747bf1461025a578063540abf73146102b357600080fd5b80630166a07a146101ec57806309fc8843146102215780631532ec34146102345780631635f5fd1461024757600080fd5b366101e757333b156101c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b6101e533333462030d406040518060200160405280600081525061047b565b005b600080fd5b3480156101f857600080fd5b5061020c6102073660046126d6565b61062b565b60405190151581526020015b60405180910390f35b6101e561022f366004612787565b6109bc565b6101e56102423660046127da565b610a93565b6101e56102553660046127da565b610ce0565b34801561026657600080fd5b5061028e7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610218565b3480156102bf57600080fd5b506101e56102ce36600461284d565b611101565b3480156102df57600080fd5b506102e861111a565b604051610218919061293a565b34801561030157600080fd5b506101e561031036600461294d565b6111bd565b34801561032157600080fd5b506101e561033036600461284d565b61125c565b34801561034157600080fd5b506101e561035036600461294d565b61126c565b34801561036157600080fd5b5061038d6103703660046129d0565b600260209081526000928352604080842090915290825290205481565b604051908152602001610218565b3480156103a757600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061028e565b6101e56103dc366004612a09565b61130b565b3480156103ed57600080fd5b506101e56103fc3660046126d6565b61131e565b34801561040d57600080fd5b506101e561041c366004612a6c565b611589565b6101e561042f366004612787565b611896565b34801561044057600080fd5b5061028e7f000000000000000000000000000000000000000000000000000000000000000081565b6101e5610476366004612a09565b611932565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af585846040516104da929190612abd565b60405180910390a37f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b847f0000000000000000000000000000000000000000000000000000000000000000631635f5fd60e01b8989898860405160240161055f9493929190612ad6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b90921682526105f292918890600401612b1f565b6000604051808303818588803b15801561060b57600080fd5b505af115801561061f573d6000803e3d6000fd5b50505050505050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561074b57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa15801561070f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107339190612b64565b73ffffffffffffffffffffffffffffffffffffffff16145b6107fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101bd565b6040517faf565a1300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808a16600483015280891660248301528616604482015260648101859052309063af565a1390608401600060405180830381600087803b15801561087b57600080fd5b505af192505050801561088c575060015b61092b576108a1888887898860008989611975565b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f2755817676249910615f0a6a240ad225abe5343df8d527f7294c4af36a92009a8888888860405161091b9493929190612bca565b60405180910390a45060006109b1565b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd888888886040516109a59493929190612bca565b60405180910390a45060015b979650505050505050565b333b15610a4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101bd565b610a8e3333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061047b92505050565b505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015610bb157507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b999190612b64565b73ffffffffffffffffffffffffffffffffffffffff16145b610c63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101bd565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e631858585604051610cc493929190612c00565b60405180910390a3610cd98585858585610ce0565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015610dfe57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de69190612b64565b73ffffffffffffffffffffffffffffffffffffffff16145b610eb0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101bd565b823414610f3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e7420726571756972656400000000000060648201526084016101bd565b3073ffffffffffffffffffffffffffffffffffffffff851603610fe4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c66000000000000000000000000000000000000000000000000000000000060648201526084016101bd565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d85858560405161104593929190612c00565b60405180910390a3600061106a855a8660405180602001604052806000815250611b48565b9050806110f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526084016101bd565b505050505050565b6111118787338888888888611b62565b50505050505050565b60606111457f0000000000000000000000000000000000000000000000000000000000000000611e02565b61116e7f0000000000000000000000000000000000000000000000000000000000000000611e02565b6111977f0000000000000000000000000000000000000000000000000000000000000000611e02565b6040516020016111a993929190612c23565b604051602081830303815290604052905090565b333b1561124c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101bd565b6110f98686333388888888611f3f565b6111118787338888888888611f3f565b333b156112fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101bd565b6110f98686333388888888611b62565b6113183385858585611fd1565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561143c57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015611400573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114249190612b64565b73ffffffffffffffffffffffffffffffffffffffff16145b6114ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101bd565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b3878787876040516115689493929190612bca565b60405180910390a461157f8787878787878761062b565b5050505050505050565b333014611618576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642062792073656c660000000000000000000000000060648201526084016101bd565b3073ffffffffffffffffffffffffffffffffffffffff8516036116bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5374616e646172644272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c660000000000000000000000000000000000000000000060648201526084016101bd565b6116c68461207d565b15611814576116d584846120df565b611787576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101bd565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390528516906340c10f1990604401600060405180830381600087803b1580156117f757600080fd5b505af115801561180b573d6000803e3d6000fd5b50505050611318565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260026020908152604080832093871683529290522054611852908290612cc8565b73ffffffffffffffffffffffffffffffffffffffff808616600081815260026020908152604080832094891683529390529190912091909155611318908383612186565b333b15611925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101bd565b610a8e3333858585611fd1565b6113183385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061047b92505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b7f0000000000000000000000000000000000000000000000000000000000000000630166a07a60e01b8a8c8b8b8b8a8a6040516024016119f79796959493929190612cdf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611a8a92918890600401612b1f565b600060405180830381600087803b158015611aa457600080fd5b505af1158015611ab8573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf88888787604051611b369493929190612bca565b60405180910390a45050505050505050565b600080600080845160208601878a8af19695505050505050565b3073ffffffffffffffffffffffffffffffffffffffff891603611c07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5374616e646172644272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c660000000000000000000000000000000000000000000060648201526084016101bd565b611c108861207d565b15611d5e57611c1f88886120df565b611cd1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101bd565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015260248201869052891690639dc29fac90604401600060405180830381600087803b158015611d4157600080fd5b505af1158015611d55573d6000803e3d6000fd5b50505050611df2565b611d8073ffffffffffffffffffffffffffffffffffffffff891687308761225a565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b1683529290522054611dbe908590612d3c565b73ffffffffffffffffffffffffffffffffffffffff808a166000908152600260209081526040808320938c16835292905220555b61157f8888888888888888611975565b606081600003611e4557505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611e6f5780611e5981612d54565b9150611e689050600a83612dbb565b9150611e49565b60008167ffffffffffffffff811115611e8a57611e8a612dcf565b6040519080825280601f01601f191660200182016040528015611eb4576020820181803683370190505b5090505b8415611f3757611ec9600183612cc8565b9150611ed6600a86612dfe565b611ee1906030612d3c565b60f81b818381518110611ef657611ef6612e12565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611f30600a86612dbb565b9450611eb8565b949350505050565b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039688888787604051611fb99493929190612bca565b60405180910390a461157f8888888888888888611b62565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f2334858560405161203293929190612c00565b60405180910390a3610cd98585348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061047b92505050565b60006120a9827f1d1d8b63000000000000000000000000000000000000000000000000000000006122b8565b806120d957506120d9827fec4fc8e3000000000000000000000000000000000000000000000000000000006122b8565b92915050565b60008273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561212c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121509190612b64565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905092915050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a8e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526122db565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526113189085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016121d8565b60006122c3836123e7565b80156122d457506122d4838361244b565b9392505050565b600061233d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166125169092919063ffffffff16565b805190915015610a8e578080602001905181019061235b9190612e41565b610a8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101bd565b6000612413827f01ffc9a70000000000000000000000000000000000000000000000000000000061244b565b80156120d95750612444827fffffffff0000000000000000000000000000000000000000000000000000000061244b565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015612503575060208210155b80156109b1575015159695505050505050565b6060611f3784846000858573ffffffffffffffffffffffffffffffffffffffff85163b61259f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101bd565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125c89190612e63565b60006040518083038185875af1925050503d8060008114612605576040519150601f19603f3d011682016040523d82523d6000602084013e61260a565b606091505b50915091506109b1828286606083156126245750816122d4565b8251156126345782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101bd919061293a565b73ffffffffffffffffffffffffffffffffffffffff8116811461268a57600080fd5b50565b60008083601f84011261269f57600080fd5b50813567ffffffffffffffff8111156126b757600080fd5b6020830191508360208285010111156126cf57600080fd5b9250929050565b600080600080600080600060c0888a0312156126f157600080fd5b87356126fc81612668565b9650602088013561270c81612668565b9550604088013561271c81612668565b9450606088013561272c81612668565b93506080880135925060a088013567ffffffffffffffff81111561274f57600080fd5b61275b8a828b0161268d565b989b979a50959850939692959293505050565b803563ffffffff8116811461278257600080fd5b919050565b60008060006040848603121561279c57600080fd5b6127a58461276e565b9250602084013567ffffffffffffffff8111156127c157600080fd5b6127cd8682870161268d565b9497909650939450505050565b6000806000806000608086880312156127f257600080fd5b85356127fd81612668565b9450602086013561280d81612668565b935060408601359250606086013567ffffffffffffffff81111561283057600080fd5b61283c8882890161268d565b969995985093965092949392505050565b600080600080600080600060c0888a03121561286857600080fd5b873561287381612668565b9650602088013561288381612668565b9550604088013561289381612668565b9450606088013593506128a86080890161276e565b925060a088013567ffffffffffffffff81111561274f57600080fd5b60005b838110156128df5781810151838201526020016128c7565b838111156113185750506000910152565b600081518084526129088160208601602086016128c4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006122d460208301846128f0565b60008060008060008060a0878903121561296657600080fd5b863561297181612668565b9550602087013561298181612668565b9450604087013593506129966060880161276e565b9250608087013567ffffffffffffffff8111156129b257600080fd5b6129be89828a0161268d565b979a9699509497509295939492505050565b600080604083850312156129e357600080fd5b82356129ee81612668565b915060208301356129fe81612668565b809150509250929050565b60008060008060608587031215612a1f57600080fd5b8435612a2a81612668565b9350612a386020860161276e565b9250604085013567ffffffffffffffff811115612a5457600080fd5b612a608782880161268d565b95989497509550505050565b60008060008060808587031215612a8257600080fd5b8435612a8d81612668565b93506020850135612a9d81612668565b92506040850135612aad81612668565b9396929550929360600135925050565b828152604060208201526000611f3760408301846128f0565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152612b1560808301846128f0565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84168152606060208201526000612b4e60608301856128f0565b905063ffffffff83166040830152949350505050565b600060208284031215612b7657600080fd5b81516122d481612668565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152606060408201526000612b15606083018486612b81565b838152604060208201526000612c1a604083018486612b81565b95945050505050565b60008451612c358184602089016128c4565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551612c71816001850160208a016128c4565b60019201918201528351612c8c8160028401602088016128c4565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612cda57612cda612c99565b500390565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a0830152612d2f60c083018486612b81565b9998505050505050505050565b60008219821115612d4f57612d4f612c99565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612d8557612d85612c99565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082612dca57612dca612d8c565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082612e0d57612e0d612d8c565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215612e5357600080fd5b815180151581146122d457600080fd5b60008251612e758184602087016128c4565b919091019291505056fea164736f6c634300080f000a",
ABI: "[{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_messenger\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20DepositInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20WithdrawalFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHBridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHBridgeInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHDepositInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHWithdrawalFinalized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC20To\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeETHTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"depositERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"depositERC20To\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"depositETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"depositETHTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeERC20Withdrawal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeETHWithdrawal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2TokenBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"contractCrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"otherBridge\",\"outputs\":[{\"internalType\":\"contractStandardBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
Bin: "0x6101206040523480156200001257600080fd5b5060405162002da338038062002da383398101604081905262000035916200006f565b6001600160a01b031660805273420000000000000000000000000000000000001060a052600060c081905260e052600261010052620000a1565b6000602082840312156200008257600080fd5b81516001600160a01b03811681146200009a57600080fd5b9392505050565b60805160a05160c05160e05161010051612c3f6200016460003960006113350152600061130c015260006112e301526000818161037f015281816103fb01528181610565015281816106b101528181610bbc01528181610e09015281816115220152611cc201526000818161023c0152818161052801528181610687015281816106e801528181610b9201528181610bf301528181610ddf01528181610e40015281816110cd015281816114f8015281816115590152611c860152612c3f6000f3fe6080604052600436106101125760003560e01c8063838b2520116100a55780639a2ac6d511610074578063b1a1a88211610059578063b1a1a882146103d6578063c89701a2146103e9578063e11013dd1461041d57600080fd5b80639a2ac6d5146103a3578063a9f9e675146103b657600080fd5b8063838b2520146102ea578063870876231461030a5780638f601f661461032a57806391c49bf81461037057600080fd5b80633cb747bf116100e15780633cb747bf1461022a578063540abf731461028857806354fd4d50146102a857806358a997f6146102ca57600080fd5b80630166a07a146101d157806309fc8843146101f15780631532ec34146102045780631635f5fd1461021757600080fd5b366101cc57333b156101ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b6101ca33333462030d4060405180602001604052806000815250610430565b005b600080fd5b3480156101dd57600080fd5b506101ca6101ec3660046124da565b61066f565b6101ca6101ff36600461258b565b610aa3565b6101ca6102123660046125de565b610b7a565b6101ca6102253660046125de565b610dc7565b34801561023657600080fd5b5061025e7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561029457600080fd5b506101ca6102a3366004612651565b6112c3565b3480156102b457600080fd5b506102bd6112dc565b60405161027f919061273e565b3480156102d657600080fd5b506101ca6102e5366004612751565b61137f565b3480156102f657600080fd5b506101ca610305366004612651565b61141e565b34801561031657600080fd5b506101ca610325366004612751565b61142e565b34801561033657600080fd5b506103626103453660046127d4565b600260209081526000928352604080842090915290825290205481565b60405190815260200161027f565b34801561037c57600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061025e565b6101ca6103b136600461280d565b6114cd565b3480156103c257600080fd5b506101ca6103d13660046124da565b6114e0565b6101ca6103e436600461258b565b611741565b3480156103f557600080fd5b5061025e7f000000000000000000000000000000000000000000000000000000000000000081565b6101ca61042b36600461280d565b6117dd565b8234146104bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c7565000060648201526084016101a2565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5858460405161051e929190612870565b60405180910390a37f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b847f0000000000000000000000000000000000000000000000000000000000000000631635f5fd60e01b898989886040516024016105a39493929190612889565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b9092168252610636929188906004016128d2565b6000604051808303818588803b15801561064f57600080fd5b505af1158015610663573d6000803e3d6000fd5b50505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561078d57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610751573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107759190612917565b73ffffffffffffffffffffffffffffffffffffffff16145b61083f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101a2565b61084887611820565b15610996576108578787611882565b610909576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101a2565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b15801561097957600080fd5b505af115801561098d573d6000803e3d6000fd5b50505050610a18565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a16835292905220546109d4908490612963565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c1683529390529190912091909155610a18908585611929565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd87878787604051610a9294939291906129c3565b60405180910390a450505050505050565b333b15610b32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101a2565b610b753333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061043092505050565b505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015610c9857507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c809190612917565b73ffffffffffffffffffffffffffffffffffffffff16145b610d4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101a2565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e631858585604051610dab939291906129f9565b60405180910390a3610dc08585858585610dc7565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015610ee557507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ea9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecd9190612917565b73ffffffffffffffffffffffffffffffffffffffff16145b610f97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101a2565b823414611026576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e7420726571756972656400000000000060648201526084016101a2565b3073ffffffffffffffffffffffffffffffffffffffff8516036110cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c66000000000000000000000000000000000000000000000000000000000060648201526084016101a2565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036111a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e67657200000000000000000000000000000000000000000000000060648201526084016101a2565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d858585604051611207939291906129f9565b60405180910390a3600061122c855a86604051806020016040528060008152506119fd565b9050806112bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526084016101a2565b505050505050565b6112d38787338888888888611a17565b50505050505050565b60606113077f0000000000000000000000000000000000000000000000000000000000000000611dd5565b6113307f0000000000000000000000000000000000000000000000000000000000000000611dd5565b6113597f0000000000000000000000000000000000000000000000000000000000000000611dd5565b60405160200161136b93929190612a1c565b604051602081830303815290604052905090565b333b1561140e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101a2565b6112bb8686333388888888611f12565b6112d38787338888888888611f12565b333b156114bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101a2565b6112bb8686333388888888611a17565b6114da3385858585611fae565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156115fe57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e69190612917565b73ffffffffffffffffffffffffffffffffffffffff16145b6116b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101a2565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b38787878760405161172a94939291906129c3565b60405180910390a46112d38787878787878761066f565b333b156117d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101a2565b610b753333858585611fae565b6114da3385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061043092505050565b600061184c827f1d1d8b630000000000000000000000000000000000000000000000000000000061205a565b8061187c575061187c827fec4fc8e30000000000000000000000000000000000000000000000000000000061205a565b92915050565b60008273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118f39190612917565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905092915050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610b759084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261207d565b600080600080845160208601878a8af19695505050505050565b611a2088611820565b15611b6e57611a2f8888611882565b611ae1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101a2565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015260248201869052891690639dc29fac90604401600060405180830381600087803b158015611b5157600080fd5b505af1158015611b65573d6000803e3d6000fd5b50505050611c02565b611b9073ffffffffffffffffffffffffffffffffffffffff8916873087612189565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b1683529290522054611bce908590612a92565b73ffffffffffffffffffffffffffffffffffffffff808a166000908152600260209081526040808320938c16835292905220555b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf88888787604051611c7c94939291906129c3565b60405180910390a47f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b7f0000000000000000000000000000000000000000000000000000000000000000630166a07a60e01b8a8c8b8b8b8a8a604051602401611d069796959493929190612aaa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611d99929188906004016128d2565b600060405180830381600087803b158015611db357600080fd5b505af1158015611dc7573d6000803e3d6000fd5b505050505050505050505050565b606081600003611e1857505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611e425780611e2c81612b07565b9150611e3b9050600a83612b6e565b9150611e1c565b60008167ffffffffffffffff811115611e5d57611e5d612b82565b6040519080825280601f01601f191660200182016040528015611e87576020820181803683370190505b5090505b8415611f0a57611e9c600183612963565b9150611ea9600a86612bb1565b611eb4906030612a92565b60f81b818381518110611ec957611ec9612bc5565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611f03600a86612b6e565b9450611e8b565b949350505050565b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039688888787604051611f8c94939291906129c3565b60405180910390a4611fa48888888888888888611a17565b5050505050505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f2334858560405161200f939291906129f9565b60405180910390a3610dc08585348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061043092505050565b6000612065836121e7565b80156120765750612076838361224b565b9392505050565b60006120df826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661231a9092919063ffffffff16565b805190915015610b7557808060200190518101906120fd9190612bf4565b610b75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101a2565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526114da9085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161197b565b6000612213827f01ffc9a70000000000000000000000000000000000000000000000000000000061224b565b801561187c5750612244827fffffffff0000000000000000000000000000000000000000000000000000000061224b565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015612303575060208210155b801561230f5750600081115b979650505050505050565b6060611f0a84846000858573ffffffffffffffffffffffffffffffffffffffff85163b6123a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101a2565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516123cc9190612c16565b60006040518083038185875af1925050503d8060008114612409576040519150601f19603f3d011682016040523d82523d6000602084013e61240e565b606091505b509150915061230f82828660608315612428575081612076565b8251156124385782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a2919061273e565b73ffffffffffffffffffffffffffffffffffffffff8116811461248e57600080fd5b50565b60008083601f8401126124a357600080fd5b50813567ffffffffffffffff8111156124bb57600080fd5b6020830191508360208285010111156124d357600080fd5b9250929050565b600080600080600080600060c0888a0312156124f557600080fd5b87356125008161246c565b965060208801356125108161246c565b955060408801356125208161246c565b945060608801356125308161246c565b93506080880135925060a088013567ffffffffffffffff81111561255357600080fd5b61255f8a828b01612491565b989b979a50959850939692959293505050565b803563ffffffff8116811461258657600080fd5b919050565b6000806000604084860312156125a057600080fd5b6125a984612572565b9250602084013567ffffffffffffffff8111156125c557600080fd5b6125d186828701612491565b9497909650939450505050565b6000806000806000608086880312156125f657600080fd5b85356126018161246c565b945060208601356126118161246c565b935060408601359250606086013567ffffffffffffffff81111561263457600080fd5b61264088828901612491565b969995985093965092949392505050565b600080600080600080600060c0888a03121561266c57600080fd5b87356126778161246c565b965060208801356126878161246c565b955060408801356126978161246c565b9450606088013593506126ac60808901612572565b925060a088013567ffffffffffffffff81111561255357600080fd5b60005b838110156126e35781810151838201526020016126cb565b838111156114da5750506000910152565b6000815180845261270c8160208601602086016126c8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061207660208301846126f4565b60008060008060008060a0878903121561276a57600080fd5b86356127758161246c565b955060208701356127858161246c565b94506040870135935061279a60608801612572565b9250608087013567ffffffffffffffff8111156127b657600080fd5b6127c289828a01612491565b979a9699509497509295939492505050565b600080604083850312156127e757600080fd5b82356127f28161246c565b915060208301356128028161246c565b809150509250929050565b6000806000806060858703121561282357600080fd5b843561282e8161246c565b935061283c60208601612572565b9250604085013567ffffffffffffffff81111561285857600080fd5b61286487828801612491565b95989497509550505050565b828152604060208201526000611f0a60408301846126f4565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526128c860808301846126f4565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061290160608301856126f4565b905063ffffffff83166040830152949350505050565b60006020828403121561292957600080fd5b81516120768161246c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561297557612975612934565b500390565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006128c860608301848661297a565b838152604060208201526000612a1360408301848661297a565b95945050505050565b60008451612a2e8184602089016126c8565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551612a6a816001850160208a016126c8565b60019201918201528351612a858160028401602088016126c8565b0160020195945050505050565b60008219821115612aa557612aa5612934565b500190565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a0830152612afa60c08301848661297a565b9998505050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612b3857612b38612934565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082612b7d57612b7d612b3f565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082612bc057612bc0612b3f565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215612c0657600080fd5b8151801515811461207657600080fd5b60008251612c288184602087016126c8565b919091019291505056fea164736f6c634300080f000a",
}
// L1StandardBridgeABI is the input ABI used to generate the binding from.
......@@ -440,27 +440,6 @@ func (_L1StandardBridge *L1StandardBridgeTransactorSession) BridgeETHTo(_to comm
return _L1StandardBridge.Contract.BridgeETHTo(&_L1StandardBridge.TransactOpts, _to, _minGasLimit, _extraData)
}
// CompleteOutboundTransfer is a paid mutator transaction binding the contract method 0xaf565a13.
//
// Solidity: function completeOutboundTransfer(address _localToken, address _remoteToken, address _to, uint256 _amount) returns()
func (_L1StandardBridge *L1StandardBridgeTransactor) CompleteOutboundTransfer(opts *bind.TransactOpts, _localToken common.Address, _remoteToken common.Address, _to common.Address, _amount *big.Int) (*types.Transaction, error) {
return _L1StandardBridge.contract.Transact(opts, "completeOutboundTransfer", _localToken, _remoteToken, _to, _amount)
}
// CompleteOutboundTransfer is a paid mutator transaction binding the contract method 0xaf565a13.
//
// Solidity: function completeOutboundTransfer(address _localToken, address _remoteToken, address _to, uint256 _amount) returns()
func (_L1StandardBridge *L1StandardBridgeSession) CompleteOutboundTransfer(_localToken common.Address, _remoteToken common.Address, _to common.Address, _amount *big.Int) (*types.Transaction, error) {
return _L1StandardBridge.Contract.CompleteOutboundTransfer(&_L1StandardBridge.TransactOpts, _localToken, _remoteToken, _to, _amount)
}
// CompleteOutboundTransfer is a paid mutator transaction binding the contract method 0xaf565a13.
//
// Solidity: function completeOutboundTransfer(address _localToken, address _remoteToken, address _to, uint256 _amount) returns()
func (_L1StandardBridge *L1StandardBridgeTransactorSession) CompleteOutboundTransfer(_localToken common.Address, _remoteToken common.Address, _to common.Address, _amount *big.Int) (*types.Transaction, error) {
return _L1StandardBridge.Contract.CompleteOutboundTransfer(&_L1StandardBridge.TransactOpts, _localToken, _remoteToken, _to, _amount)
}
// DepositERC20 is a paid mutator transaction binding the contract method 0x58a997f6.
//
// Solidity: function depositERC20(address _l1Token, address _l2Token, uint256 _amount, uint32 _minGasLimit, bytes _extraData) returns()
......@@ -547,21 +526,21 @@ func (_L1StandardBridge *L1StandardBridgeTransactorSession) DepositETHTo(_to com
// FinalizeBridgeERC20 is a paid mutator transaction binding the contract method 0x0166a07a.
//
// Solidity: function finalizeBridgeERC20(address _localToken, address _remoteToken, address _from, address _to, uint256 _amount, bytes _extraData) returns(bool)
// Solidity: function finalizeBridgeERC20(address _localToken, address _remoteToken, address _from, address _to, uint256 _amount, bytes _extraData) returns()
func (_L1StandardBridge *L1StandardBridgeTransactor) FinalizeBridgeERC20(opts *bind.TransactOpts, _localToken common.Address, _remoteToken common.Address, _from common.Address, _to common.Address, _amount *big.Int, _extraData []byte) (*types.Transaction, error) {
return _L1StandardBridge.contract.Transact(opts, "finalizeBridgeERC20", _localToken, _remoteToken, _from, _to, _amount, _extraData)
}
// FinalizeBridgeERC20 is a paid mutator transaction binding the contract method 0x0166a07a.
//
// Solidity: function finalizeBridgeERC20(address _localToken, address _remoteToken, address _from, address _to, uint256 _amount, bytes _extraData) returns(bool)
// Solidity: function finalizeBridgeERC20(address _localToken, address _remoteToken, address _from, address _to, uint256 _amount, bytes _extraData) returns()
func (_L1StandardBridge *L1StandardBridgeSession) FinalizeBridgeERC20(_localToken common.Address, _remoteToken common.Address, _from common.Address, _to common.Address, _amount *big.Int, _extraData []byte) (*types.Transaction, error) {
return _L1StandardBridge.Contract.FinalizeBridgeERC20(&_L1StandardBridge.TransactOpts, _localToken, _remoteToken, _from, _to, _amount, _extraData)
}
// FinalizeBridgeERC20 is a paid mutator transaction binding the contract method 0x0166a07a.
//
// Solidity: function finalizeBridgeERC20(address _localToken, address _remoteToken, address _from, address _to, uint256 _amount, bytes _extraData) returns(bool)
// Solidity: function finalizeBridgeERC20(address _localToken, address _remoteToken, address _from, address _to, uint256 _amount, bytes _extraData) returns()
func (_L1StandardBridge *L1StandardBridgeTransactorSession) FinalizeBridgeERC20(_localToken common.Address, _remoteToken common.Address, _from common.Address, _to common.Address, _amount *big.Int, _extraData []byte) (*types.Transaction, error) {
return _L1StandardBridge.Contract.FinalizeBridgeERC20(&_L1StandardBridge.TransactOpts, _localToken, _remoteToken, _from, _to, _amount, _extraData)
}
......@@ -650,171 +629,6 @@ func (_L1StandardBridge *L1StandardBridgeTransactorSession) Receive() (*types.Tr
return _L1StandardBridge.Contract.Receive(&_L1StandardBridge.TransactOpts)
}
// L1StandardBridgeERC20BridgeFailedIterator is returned from FilterERC20BridgeFailed and is used to iterate over the raw logs and unpacked data for ERC20BridgeFailed events raised by the L1StandardBridge contract.
type L1StandardBridgeERC20BridgeFailedIterator struct {
Event *L1StandardBridgeERC20BridgeFailed // 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 *L1StandardBridgeERC20BridgeFailedIterator) 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(L1StandardBridgeERC20BridgeFailed)
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(L1StandardBridgeERC20BridgeFailed)
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 *L1StandardBridgeERC20BridgeFailedIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *L1StandardBridgeERC20BridgeFailedIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// L1StandardBridgeERC20BridgeFailed represents a ERC20BridgeFailed event raised by the L1StandardBridge contract.
type L1StandardBridgeERC20BridgeFailed struct {
LocalToken common.Address
RemoteToken common.Address
From common.Address
To common.Address
Amount *big.Int
ExtraData []byte
Raw types.Log // Blockchain specific contextual infos
}
// FilterERC20BridgeFailed is a free log retrieval operation binding the contract event 0x2755817676249910615f0a6a240ad225abe5343df8d527f7294c4af36a92009a.
//
// Solidity: event ERC20BridgeFailed(address indexed localToken, address indexed remoteToken, address indexed from, address to, uint256 amount, bytes extraData)
func (_L1StandardBridge *L1StandardBridgeFilterer) FilterERC20BridgeFailed(opts *bind.FilterOpts, localToken []common.Address, remoteToken []common.Address, from []common.Address) (*L1StandardBridgeERC20BridgeFailedIterator, error) {
var localTokenRule []interface{}
for _, localTokenItem := range localToken {
localTokenRule = append(localTokenRule, localTokenItem)
}
var remoteTokenRule []interface{}
for _, remoteTokenItem := range remoteToken {
remoteTokenRule = append(remoteTokenRule, remoteTokenItem)
}
var fromRule []interface{}
for _, fromItem := range from {
fromRule = append(fromRule, fromItem)
}
logs, sub, err := _L1StandardBridge.contract.FilterLogs(opts, "ERC20BridgeFailed", localTokenRule, remoteTokenRule, fromRule)
if err != nil {
return nil, err
}
return &L1StandardBridgeERC20BridgeFailedIterator{contract: _L1StandardBridge.contract, event: "ERC20BridgeFailed", logs: logs, sub: sub}, nil
}
// WatchERC20BridgeFailed is a free log subscription operation binding the contract event 0x2755817676249910615f0a6a240ad225abe5343df8d527f7294c4af36a92009a.
//
// Solidity: event ERC20BridgeFailed(address indexed localToken, address indexed remoteToken, address indexed from, address to, uint256 amount, bytes extraData)
func (_L1StandardBridge *L1StandardBridgeFilterer) WatchERC20BridgeFailed(opts *bind.WatchOpts, sink chan<- *L1StandardBridgeERC20BridgeFailed, localToken []common.Address, remoteToken []common.Address, from []common.Address) (event.Subscription, error) {
var localTokenRule []interface{}
for _, localTokenItem := range localToken {
localTokenRule = append(localTokenRule, localTokenItem)
}
var remoteTokenRule []interface{}
for _, remoteTokenItem := range remoteToken {
remoteTokenRule = append(remoteTokenRule, remoteTokenItem)
}
var fromRule []interface{}
for _, fromItem := range from {
fromRule = append(fromRule, fromItem)
}
logs, sub, err := _L1StandardBridge.contract.WatchLogs(opts, "ERC20BridgeFailed", localTokenRule, remoteTokenRule, fromRule)
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(L1StandardBridgeERC20BridgeFailed)
if err := _L1StandardBridge.contract.UnpackLog(event, "ERC20BridgeFailed", 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
}
// ParseERC20BridgeFailed is a log parse operation binding the contract event 0x2755817676249910615f0a6a240ad225abe5343df8d527f7294c4af36a92009a.
//
// Solidity: event ERC20BridgeFailed(address indexed localToken, address indexed remoteToken, address indexed from, address to, uint256 amount, bytes extraData)
func (_L1StandardBridge *L1StandardBridgeFilterer) ParseERC20BridgeFailed(log types.Log) (*L1StandardBridgeERC20BridgeFailed, error) {
event := new(L1StandardBridgeERC20BridgeFailed)
if err := _L1StandardBridge.contract.UnpackLog(event, "ERC20BridgeFailed", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// L1StandardBridgeERC20BridgeFinalizedIterator is returned from FilterERC20BridgeFinalized and is used to iterate over the raw logs and unpacked data for ERC20BridgeFinalized events raised by the L1StandardBridge contract.
type L1StandardBridgeERC20BridgeFinalizedIterator struct {
Event *L1StandardBridgeERC20BridgeFinalized // Event containing the contract specifics and raw log
......
......@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const L2CrossDomainMessengerStorageLayoutJSON = "{\"storage\":[{\"astId\":24801,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":27292,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_initialized\",\"offset\":20,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":27295,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_initializing\",\"offset\":21,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":27906,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":27164,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":27284,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":27457,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_paused\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_bool\"},{\"astId\":27562,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":27577,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_status\",\"offset\":0,\"slot\":\"151\",\"type\":\"t_uint256\"},{\"astId\":27621,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"152\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":24853,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_201_0_32\",\"offset\":0,\"slot\":\"201\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24858,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_202_0_32\",\"offset\":0,\"slot\":\"202\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24863,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"successfulMessages\",\"offset\":0,\"slot\":\"203\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24866,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"xDomainMsgSender\",\"offset\":0,\"slot\":\"204\",\"type\":\"t_address\"},{\"astId\":24869,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"msgNonce\",\"offset\":0,\"slot\":\"205\",\"type\":\"t_uint240\"},{\"astId\":24874,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"receivedMessages\",\"offset\":0,\"slot\":\"206\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24879,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"207\",\"type\":\"t_array(t_uint256)42_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)42_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[42]\",\"numberOfBytes\":\"1344\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint240\":{\"encoding\":\"inplace\",\"label\":\"uint240\",\"numberOfBytes\":\"30\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}"
const L2CrossDomainMessengerStorageLayoutJSON = "{\"storage\":[{\"astId\":24726,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":27112,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_initialized\",\"offset\":20,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":27115,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_initializing\",\"offset\":21,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":27726,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":26984,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":27104,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":27277,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_paused\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_bool\"},{\"astId\":27382,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":27397,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_status\",\"offset\":0,\"slot\":\"151\",\"type\":\"t_uint256\"},{\"astId\":27441,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"152\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":24778,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_201_0_32\",\"offset\":0,\"slot\":\"201\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24783,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_202_0_32\",\"offset\":0,\"slot\":\"202\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24788,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"successfulMessages\",\"offset\":0,\"slot\":\"203\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24791,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"xDomainMsgSender\",\"offset\":0,\"slot\":\"204\",\"type\":\"t_address\"},{\"astId\":24794,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"msgNonce\",\"offset\":0,\"slot\":\"205\",\"type\":\"t_uint240\"},{\"astId\":24799,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"receivedMessages\",\"offset\":0,\"slot\":\"206\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24804,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"207\",\"type\":\"t_array(t_uint256)42_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)42_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[42]\",\"numberOfBytes\":\"1344\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint240\":{\"encoding\":\"inplace\",\"label\":\"uint240\",\"numberOfBytes\":\"30\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}"
var L2CrossDomainMessengerStorageLayout = new(solc.StorageLayout)
......
......@@ -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: "0x6101806040523480156200001257600080fd5b506040516200235c3803806200235c83398101604081905262000035916200060a565b6000608081905260a052600160c052428310620000cd5760405162461bcd60e51b8152602060048201526044602482018190527f4c324f75747075744f7261636c653a20696e697469616c204c3220626c6f636b908201527f2074696d65206d757374206265206c657373207468616e2063757272656e742060648201526374696d6560e01b608482015260a4015b60405180910390fd5b60e0889052610100869052610120859052610140849052610160839052620000f88786848462000106565b50505050505050506200067c565b600054610100900460ff1615808015620001275750600054600160ff909116105b806200015757506200014430620002fa60201b620013da1760201c565b15801562000157575060005460ff166001145b620001bc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000c4565b6000805460ff191660011790558015620001e0576000805461ff0019166101001790555b816001600160a01b0316836001600160a01b031603620002585760405162461bcd60e51b815260206004820152603860248201526000805160206200233c83398151915260448201527f6265207468652073616d6520617320746865206f776e657200000000000000006064820152608401620000c4565b604080518082018252868152426020808301918252600088815260679091529290922090518155905160019091015560668490556200029662000309565b620002a18362000371565b620002ac82620004d8565b8015620002f3576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b6001600160a01b03163b151590565b600054610100900460ff16620003655760405162461bcd60e51b815260206004820152602b60248201526000805160206200231c83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000c4565b6200036f6200052a565b565b6200037b62000591565b6001600160a01b038116620003f95760405162461bcd60e51b815260206004820152603760248201527f4c324f75747075744f7261636c653a206e65772070726f706f7365722063616e60448201527f6e6f7420626520746865207a65726f20616464726573730000000000000000006064820152608401620000c4565b6033546001600160a01b03166001600160a01b0316816001600160a01b0316036200047c5760405162461bcd60e51b815260206004820152603860248201526000805160206200233c83398151915260448201527f6265207468652073616d6520617320746865206f776e657200000000000000006064820152608401620000c4565b6065546040516001600160a01b038084169216907f3d7728dc2838bb794606bd89f5a37930830b32060f69ee929bbfc59b669024dd90600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16620005865760405162461bcd60e51b815260206004820152602b60248201526000805160206200231c83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000c4565b6200036f33620004d8565b6033546001600160a01b031633146200036f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620000c4565b80516001600160a01b03811681146200060557600080fd5b919050565b600080600080600080600080610100898b0312156200062857600080fd5b885197506020890151965060408901519550606089015194506080890151935060a089015192506200065d60c08a01620005ed565b91506200066d60e08a01620005ed565b90509295985092959890939650565b60805160a05160c05160e05161010051610120516101405161016051611bf4620007286000396000818161013f0152610fcc0152600081816101a801526110250152600081816101f201528181610cbe01528181610dba01528181610ef60152610ff00152600061034b0152600081816102260152818161061001528181610d9601528181610df901526112ea015260006106950152600061066c015260006106430152611bf46000f3fe6080604052600436106101285760003560e01c80638da5cb5b116100a5578063a8e4fb9011610074578063d20b1a5111610059578063d20b1a51146103ba578063dcec3348146103da578063f2fde38b146103ef57600080fd5b8063a8e4fb901461036d578063d1de856c1461039a57600080fd5b80638da5cb5b1461029f5780639aaab648146102eb578063a25ae557146102fe578063a4771aad1461033957600080fd5b80634ab65d73116100fc57806354fd4d50116100e157806354fd4d5014610248578063715018a61461026a57806372d5fe211461027f57600080fd5b80634ab65d73146101e0578063529933df1461021457600080fd5b80622134cc1461012d578063093b3d901461017457806320e9fcd4146101965780634599c788146101ca575b600080fd5b34801561013957600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561018057600080fd5b5061019461018f366004611845565b61040f565b005b3480156101a257600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b3480156101d657600080fd5b5061016160665481565b3480156101ec57600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b34801561022057600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b34801561025457600080fd5b5061025d61063c565b60405161016b91906118eb565b34801561027657600080fd5b506101946106df565b34801561028b57600080fd5b5061019461029a366004611965565b6106f3565b3480156102ab57600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161016b565b6101946102f9366004611987565b6108ff565b34801561030a57600080fd5b5061031e6103193660046119b9565b610ca8565b6040805182518152602092830151928101929092520161016b565b34801561034557600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b34801561037957600080fd5b506065546102c69073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a657600080fd5b506101616103b53660046119b9565b610ef2565b3480156103c657600080fd5b506101946103d53660046119d2565b61104f565b3480156103e657600080fd5b506101616112e6565b3480156103fb57600080fd5b5061019461040a366004611965565b61131b565b6104176113f6565b6066546000908152606760209081526040918290208251808401909352805480845260019091015491830191909152825114610500576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604f60248201527f4c324f75747075744f7261636c653a206f757470757420726f6f7420746f206460448201527f656c65746520646f6573206e6f74206d6174636820746865206c61746573742060648201527f6f75747075742070726f706f73616c0000000000000000000000000000000000608482015260a4015b60405180910390fd5b80602001518260200151146105bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f4c324f75747075744f7261636c653a2074696d657374616d7020746f2064656c60448201527f65746520646f6573206e6f74206d6174636820746865206c6174657374206f7560648201527f747075742070726f706f73616c00000000000000000000000000000000000000608482015260a4016104f7565b606654602082015182516040517f11e942315215fbc11bf574b22ca610d001e704d870a2307833c188d31600b5c690600090a46066805460009081526067602052604081208181556001015554610635907f000000000000000000000000000000000000000000000000000000000000000090611a47565b6066555050565b60606106677f0000000000000000000000000000000000000000000000000000000000000000611477565b6106907f0000000000000000000000000000000000000000000000000000000000000000611477565b6106b97f0000000000000000000000000000000000000000000000000000000000000000611477565b6040516020016106cb93929190611a5e565b604051602081830303815290604052905090565b6106e76113f6565b6106f160006115ac565b565b6106fb6113f6565b73ffffffffffffffffffffffffffffffffffffffff811661079e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c324f75747075744f7261636c653a206e65772070726f706f7365722063616e60448201527f6e6f7420626520746865207a65726f206164647265737300000000000000000060648201526084016104f7565b60335473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610871576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c324f75747075744f7261636c653a2070726f706f7365722063616e6e6f742060448201527f6265207468652073616d6520617320746865206f776e6572000000000000000060648201526084016104f7565b60655460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f3d7728dc2838bb794606bd89f5a37930830b32060f69ee929bbfc59b669024dd90600090a3606580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60655473ffffffffffffffffffffffffffffffffffffffff1633146109a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c324f75747075744f7261636c653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642062792070726f706f73657200000000000000000060648201526084016104f7565b6109ae6112e6565b8314610a62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a4016104f7565b42610a6c84610ef2565b10610af9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e20746865206675747572650000000000000000000060648201526084016104f7565b83610b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f206861736800000000000060648201526084016104f7565b8115610c425781814014610c42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b6861736820646f6573206e60448201527f6f74206d6174636820746865206861736820617420746865206578706563746560648201527f6420686569676874000000000000000000000000000000000000000000000000608482015260a4016104f7565b6040805180820182528581524260208083018281526000888152606790925284822093518455516001909301929092556066869055915185929187917fc120f5e881491e6e212befa39e36b8f57d5eca31915f2e5d60a420f418caa6df9190a450505050565b60408051808201909152600080825260208201527f0000000000000000000000000000000000000000000000000000000000000000821015610d92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d6265722063616e60448201527f6e6f74206265206c657373207468616e20746865207374617274696e6720626c60648201527f6f636b206e756d6265722e000000000000000000000000000000000000000000608482015260a4016104f7565b60007f0000000000000000000000000000000000000000000000000000000000000000610ddf7f000000000000000000000000000000000000000000000000000000000000000085611a47565b610de99190611b03565b905060008115610e2c57610e1d827f0000000000000000000000000000000000000000000000000000000000000000611a47565b610e279085611b17565b610e2e565b835b600081815260676020908152604091829020825180840190935280548084526001909101549183019190915291925090610eea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a204e6f206f757470757420666f756e642060448201527f666f72207468617420626c6f636b206e756d6265722e0000000000000000000060648201526084016104f7565b949350505050565b60007f0000000000000000000000000000000000000000000000000000000000000000821015610fca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605360248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f742062652067726561746572207468616e206f7220657175616c20746f20737460648201527f617274696e6720626c6f636b206e756d62657200000000000000000000000000608482015260a4016104f7565b7f00000000000000000000000000000000000000000000000000000000000000006110157f000000000000000000000000000000000000000000000000000000000000000084611a47565b61101f9190611b2f565b611049907f0000000000000000000000000000000000000000000000000000000000000000611b17565b92915050565b600054610100900460ff161580801561106f5750600054600160ff909116105b806110895750303b158015611089575060005460ff166001145b611115576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104f7565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561117357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361122e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c324f75747075744f7261636c653a2070726f706f7365722063616e6e6f742060448201527f6265207468652073616d6520617320746865206f776e6572000000000000000060648201526084016104f7565b6040805180820182528681524260208083019182526000888152606790915292909220905181559051600190910155606684905561126a611623565b611273836106f3565b61127c826115ac565b80156112df57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006066546113169190611b17565b905090565b6113236113f6565b60655473ffffffffffffffffffffffffffffffffffffffff908116908216036113ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c324f75747075744f7261636c653a206f776e65722063616e6e6f742062652060448201527f7468652073616d65206173207468652070726f706f736572000000000000000060648201526084016104f7565b6113d7816116c2565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104f7565b6060816000036114ba57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156114e457806114ce81611b6c565b91506114dd9050600a83611ba4565b91506114be565b60008167ffffffffffffffff8111156114ff576114ff611816565b6040519080825280601f01601f191660200182016040528015611529576020820181803683370190505b5090505b8415610eea5761153e600183611a47565b915061154b600a86611b03565b611556906030611b17565b60f81b81838151811061156b5761156b611bb8565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506115a5600a86611ba4565b945061152d565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166116ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104f7565b6106f1611776565b6116ca6113f6565b73ffffffffffffffffffffffffffffffffffffffff811661176d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104f7565b6113d7816115ac565b600054610100900460ff1661180d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104f7565b6106f1336115ac565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006040828403121561185757600080fd5b6040516040810181811067ffffffffffffffff821117156118a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052823581526020928301359281019290925250919050565b60005b838110156118d65781810151838201526020016118be565b838111156118e5576000848401525b50505050565b602081526000825180602084015261190a8160408501602087016118bb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461196057600080fd5b919050565b60006020828403121561197757600080fd5b6119808261193c565b9392505050565b6000806000806080858703121561199d57600080fd5b5050823594602084013594506040840135936060013592509050565b6000602082840312156119cb57600080fd5b5035919050565b600080600080608085870312156119e857600080fd5b84359350602085013592506119ff6040860161193c565b9150611a0d6060860161193c565b905092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611a5957611a59611a18565b500390565b60008451611a708184602089016118bb565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611aac816001850160208a016118bb565b60019201918201528351611ac78160028401602088016118bb565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611b1257611b12611ad4565b500690565b60008219821115611b2a57611b2a611a18565b500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611b6757611b67611a18565b500290565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611b9d57611b9d611a18565b5060010190565b600082611bb357611bb3611ad4565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420694c324f75747075744f7261636c653a2070726f706f7365722063616e6e6f7420",
Bin: "0x6101806040523480156200001257600080fd5b506040516200235d3803806200235d83398101604081905262000035916200060b565b6000608081905260a052600160c05242841115620000ce5760405162461bcd60e51b8152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201526374696d6560e01b608482015260a4015b60405180910390fd5b60e0889052610100869052610120859052610140849052610160839052620000f98786848462000107565b50505050505050506200067d565b600054610100900460ff1615808015620001285750600054600160ff909116105b806200015857506200014530620002fb60201b620013da1760201c565b15801562000158575060005460ff166001145b620001bd5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000c5565b6000805460ff191660011790558015620001e1576000805461ff0019166101001790555b816001600160a01b0316836001600160a01b031603620002595760405162461bcd60e51b815260206004820152603860248201526000805160206200233d83398151915260448201527f6265207468652073616d6520617320746865206f776e657200000000000000006064820152608401620000c5565b60408051808201825286815242602080830191825260008881526067909152929092209051815590516001909101556066849055620002976200030a565b620002a28362000372565b620002ad82620004d9565b8015620002f4576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b6001600160a01b03163b151590565b600054610100900460ff16620003665760405162461bcd60e51b815260206004820152602b60248201526000805160206200231d83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000c5565b620003706200052b565b565b6200037c62000592565b6001600160a01b038116620003fa5760405162461bcd60e51b815260206004820152603760248201527f4c324f75747075744f7261636c653a206e65772070726f706f7365722063616e60448201527f6e6f7420626520746865207a65726f20616464726573730000000000000000006064820152608401620000c5565b6033546001600160a01b03166001600160a01b0316816001600160a01b0316036200047d5760405162461bcd60e51b815260206004820152603860248201526000805160206200233d83398151915260448201527f6265207468652073616d6520617320746865206f776e657200000000000000006064820152608401620000c5565b6065546040516001600160a01b038084169216907f3d7728dc2838bb794606bd89f5a37930830b32060f69ee929bbfc59b669024dd90600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16620005875760405162461bcd60e51b815260206004820152602b60248201526000805160206200231d83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000c5565b6200037033620004d9565b6033546001600160a01b03163314620003705760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620000c5565b80516001600160a01b03811681146200060657600080fd5b919050565b600080600080600080600080610100898b0312156200062957600080fd5b885197506020890151965060408901519550606089015194506080890151935060a089015192506200065e60c08a01620005ee565b91506200066e60e08a01620005ee565b90509295985092959890939650565b60805160a05160c05160e05161010051610120516101405161016051611bf4620007296000396000818161013f0152610fcc0152600081816101a801526110250152600081816101f201528181610cbe01528181610dba01528181610ef60152610ff00152600061034b0152600081816102260152818161061001528181610d9601528181610df901526112ea015260006106950152600061066c015260006106430152611bf46000f3fe6080604052600436106101285760003560e01c80638da5cb5b116100a5578063a8e4fb9011610074578063d20b1a5111610059578063d20b1a51146103ba578063dcec3348146103da578063f2fde38b146103ef57600080fd5b8063a8e4fb901461036d578063d1de856c1461039a57600080fd5b80638da5cb5b1461029f5780639aaab648146102eb578063a25ae557146102fe578063a4771aad1461033957600080fd5b80634ab65d73116100fc57806354fd4d50116100e157806354fd4d5014610248578063715018a61461026a57806372d5fe211461027f57600080fd5b80634ab65d73146101e0578063529933df1461021457600080fd5b80622134cc1461012d578063093b3d901461017457806320e9fcd4146101965780634599c788146101ca575b600080fd5b34801561013957600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561018057600080fd5b5061019461018f366004611845565b61040f565b005b3480156101a257600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b3480156101d657600080fd5b5061016160665481565b3480156101ec57600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b34801561022057600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b34801561025457600080fd5b5061025d61063c565b60405161016b91906118eb565b34801561027657600080fd5b506101946106df565b34801561028b57600080fd5b5061019461029a366004611965565b6106f3565b3480156102ab57600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161016b565b6101946102f9366004611987565b6108ff565b34801561030a57600080fd5b5061031e6103193660046119b9565b610ca8565b6040805182518152602092830151928101929092520161016b565b34801561034557600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b34801561037957600080fd5b506065546102c69073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103a657600080fd5b506101616103b53660046119b9565b610ef2565b3480156103c657600080fd5b506101946103d53660046119d2565b61104f565b3480156103e657600080fd5b506101616112e6565b3480156103fb57600080fd5b5061019461040a366004611965565b61131b565b6104176113f6565b6066546000908152606760209081526040918290208251808401909352805480845260019091015491830191909152825114610500576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604f60248201527f4c324f75747075744f7261636c653a206f757470757420726f6f7420746f206460448201527f656c65746520646f6573206e6f74206d6174636820746865206c61746573742060648201527f6f75747075742070726f706f73616c0000000000000000000000000000000000608482015260a4015b60405180910390fd5b80602001518260200151146105bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f4c324f75747075744f7261636c653a2074696d657374616d7020746f2064656c60448201527f65746520646f6573206e6f74206d6174636820746865206c6174657374206f7560648201527f747075742070726f706f73616c00000000000000000000000000000000000000608482015260a4016104f7565b606654602082015182516040517f11e942315215fbc11bf574b22ca610d001e704d870a2307833c188d31600b5c690600090a46066805460009081526067602052604081208181556001015554610635907f000000000000000000000000000000000000000000000000000000000000000090611a47565b6066555050565b60606106677f0000000000000000000000000000000000000000000000000000000000000000611477565b6106907f0000000000000000000000000000000000000000000000000000000000000000611477565b6106b97f0000000000000000000000000000000000000000000000000000000000000000611477565b6040516020016106cb93929190611a5e565b604051602081830303815290604052905090565b6106e76113f6565b6106f160006115ac565b565b6106fb6113f6565b73ffffffffffffffffffffffffffffffffffffffff811661079e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c324f75747075744f7261636c653a206e65772070726f706f7365722063616e60448201527f6e6f7420626520746865207a65726f206164647265737300000000000000000060648201526084016104f7565b60335473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610871576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c324f75747075744f7261636c653a2070726f706f7365722063616e6e6f742060448201527f6265207468652073616d6520617320746865206f776e6572000000000000000060648201526084016104f7565b60655460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f3d7728dc2838bb794606bd89f5a37930830b32060f69ee929bbfc59b669024dd90600090a3606580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60655473ffffffffffffffffffffffffffffffffffffffff1633146109a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c324f75747075744f7261636c653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642062792070726f706f73657200000000000000000060648201526084016104f7565b6109ae6112e6565b8314610a62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f7420626520657175616c20746f206e65787420657870656374656420626c6f6360648201527f6b206e756d626572000000000000000000000000000000000000000000000000608482015260a4016104f7565b42610a6c84610ef2565b10610af9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527f32206f757470757420696e20746865206675747572650000000000000000000060648201526084016104f7565b83610b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f206861736800000000000060648201526084016104f7565b8115610c425781814014610c42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f4c324f75747075744f7261636c653a20626c6f636b6861736820646f6573206e60448201527f6f74206d6174636820746865206861736820617420746865206578706563746560648201527f6420686569676874000000000000000000000000000000000000000000000000608482015260a4016104f7565b6040805180820182528581524260208083018281526000888152606790925284822093518455516001909301929092556066869055915185929187917fc120f5e881491e6e212befa39e36b8f57d5eca31915f2e5d60a420f418caa6df9190a450505050565b60408051808201909152600080825260208201527f0000000000000000000000000000000000000000000000000000000000000000821015610d92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d6265722063616e60448201527f6e6f74206265206c657373207468616e20746865207374617274696e6720626c60648201527f6f636b206e756d6265722e000000000000000000000000000000000000000000608482015260a4016104f7565b60007f0000000000000000000000000000000000000000000000000000000000000000610ddf7f000000000000000000000000000000000000000000000000000000000000000085611a47565b610de99190611b03565b905060008115610e2c57610e1d827f0000000000000000000000000000000000000000000000000000000000000000611a47565b610e279085611b17565b610e2e565b835b600081815260676020908152604091829020825180840190935280548084526001909101549183019190915291925090610eea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c324f75747075744f7261636c653a204e6f206f757470757420666f756e642060448201527f666f72207468617420626c6f636b206e756d6265722e0000000000000000000060648201526084016104f7565b949350505050565b60007f0000000000000000000000000000000000000000000000000000000000000000821015610fca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605360248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f742062652067726561746572207468616e206f7220657175616c20746f20737460648201527f617274696e6720626c6f636b206e756d62657200000000000000000000000000608482015260a4016104f7565b7f00000000000000000000000000000000000000000000000000000000000000006110157f000000000000000000000000000000000000000000000000000000000000000084611a47565b61101f9190611b2f565b611049907f0000000000000000000000000000000000000000000000000000000000000000611b17565b92915050565b600054610100900460ff161580801561106f5750600054600160ff909116105b806110895750303b158015611089575060005460ff166001145b611115576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104f7565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561117357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361122e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c324f75747075744f7261636c653a2070726f706f7365722063616e6e6f742060448201527f6265207468652073616d6520617320746865206f776e6572000000000000000060648201526084016104f7565b6040805180820182528681524260208083019182526000888152606790915292909220905181559051600190910155606684905561126a611623565b611273836106f3565b61127c826115ac565b80156112df57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006066546113169190611b17565b905090565b6113236113f6565b60655473ffffffffffffffffffffffffffffffffffffffff908116908216036113ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c324f75747075744f7261636c653a206f776e65722063616e6e6f742062652060448201527f7468652073616d65206173207468652070726f706f736572000000000000000060648201526084016104f7565b6113d7816116c2565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104f7565b6060816000036114ba57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156114e457806114ce81611b6c565b91506114dd9050600a83611ba4565b91506114be565b60008167ffffffffffffffff8111156114ff576114ff611816565b6040519080825280601f01601f191660200182016040528015611529576020820181803683370190505b5090505b8415610eea5761153e600183611a47565b915061154b600a86611b03565b611556906030611b17565b60f81b81838151811061156b5761156b611bb8565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506115a5600a86611ba4565b945061152d565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166116ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104f7565b6106f1611776565b6116ca6113f6565b73ffffffffffffffffffffffffffffffffffffffff811661176d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104f7565b6113d7816115ac565b600054610100900460ff1661180d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104f7565b6106f1336115ac565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006040828403121561185757600080fd5b6040516040810181811067ffffffffffffffff821117156118a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052823581526020928301359281019290925250919050565b60005b838110156118d65781810151838201526020016118be565b838111156118e5576000848401525b50505050565b602081526000825180602084015261190a8160408501602087016118bb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461196057600080fd5b919050565b60006020828403121561197757600080fd5b6119808261193c565b9392505050565b6000806000806080858703121561199d57600080fd5b5050823594602084013594506040840135936060013592509050565b6000602082840312156119cb57600080fd5b5035919050565b600080600080608085870312156119e857600080fd5b84359350602085013592506119ff6040860161193c565b9150611a0d6060860161193c565b905092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611a5957611a59611a18565b500390565b60008451611a708184602089016118bb565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611aac816001850160208a016118bb565b60019201918201528351611ac78160028401602088016118bb565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611b1257611b12611ad4565b500690565b60008219821115611b2a57611b2a611a18565b500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611b6757611b67611a18565b500290565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611b9d57611b9d611a18565b5060010190565b600082611bb357611bb3611ad4565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420694c324f75747075744f7261636c653a2070726f706f7365722063616e6e6f7420",
}
// L2OutputOracleABI is the input ABI used to generate the binding from.
......
......@@ -30,8 +30,8 @@ var (
// L2StandardBridgeMetaData contains all meta data concerning the L2StandardBridge contract.
var L2StandardBridgeMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_otherBridge\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"DepositFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"DepositFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHBridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHBridgeInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"WithdrawalInitiated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC20To\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeETHTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"completeOutboundTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeERC20\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeDeposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"contractCrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"otherBridge\",\"outputs\":[{\"internalType\":\"contractStandardBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"withdrawTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
Bin: "0x6101206040523480156200001257600080fd5b5060405162002ccb38038062002ccb83398101604081905262000035916200006f565b7342000000000000000000000000000000000000076080526001600160a01b031660a052600060c081905260e052600261010052620000a1565b6000602082840312156200008257600080fd5b81516001600160a01b03811681146200009a57600080fd5b9392505050565b60805160a05160c05160e05161010051612b9f6200012c6000396000610eec01526000610ec301526000610e9a0152600081816103670152818161044201528181610590015281816109f6015261158b0152600081816102200152818161040501528181610566015281816105c7015281816109cc01528181610a2d015261154f0152612b9f6000f3fe6080604052600436106100e15760003560e01c8063662a633a1161007f578063a3a7954811610059578063a3a7954814610322578063af565a1314610335578063c89701a214610355578063e11013dd1461038957600080fd5b8063662a633a146102a957806387087623146102bc5780638f601f66146102dc57600080fd5b806332b7006d116100bb57806332b7006d146101fb5780633cb747bf1461020e578063540abf731461026757806354fd4d501461028757600080fd5b80630166a07a146101a057806309fc8843146101d55780631635f5fd146101e857600080fd5b3661019b57333b1561017a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61019933333462030d406040518060200160405280600081525061039c565b005b600080fd5b3480156101ac57600080fd5b506101c06101bb366004612395565b61054c565b60405190151581526020015b60405180910390f35b6101996101e3366004612446565b6108dd565b6101996101f6366004612499565b6109b4565b61019961020936600461250c565b610dd5565b34801561021a57600080fd5b506102427f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cc565b34801561027357600080fd5b50610199610282366004612560565b610e7a565b34801561029357600080fd5b5061029c610e93565b6040516101cc919061264d565b6101996102b7366004612395565b610f36565b3480156102c857600080fd5b506101996102d7366004612660565b611149565b3480156102e857600080fd5b506103146102f73660046126e3565b600260209081526000928352604080842090915290825290205481565b6040519081526020016101cc565b610199610330366004612660565b6111e8565b34801561034157600080fd5b5061019961035036600461271c565b6111f7565b34801561036157600080fd5b506102427f000000000000000000000000000000000000000000000000000000000000000081565b61019961039736600461276d565b61150a565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af585846040516103fb9291906127d0565b60405180910390a37f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b847f0000000000000000000000000000000000000000000000000000000000000000631635f5fd60e01b8989898860405160240161048094939291906127e9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261051392918890600401612832565b6000604051808303818588803b15801561052c57600080fd5b505af1158015610540573d6000803e3d6000fd5b50505050505050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561066c57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610630573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106549190612877565b73ffffffffffffffffffffffffffffffffffffffff16145b61071e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610171565b6040517faf565a1300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808a16600483015280891660248301528616604482015260648101859052309063af565a1390608401600060405180830381600087803b15801561079c57600080fd5b505af19250505080156107ad575060015b61084c576107c288888789886000898961154d565b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f2755817676249910615f0a6a240ad225abe5343df8d527f7294c4af36a92009a8888888860405161083c94939291906128dd565b60405180910390a45060006108d2565b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd888888886040516108c694939291906128dd565b60405180910390a45060015b979650505050505050565b333b1561096c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610171565b6109af3333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061039c92505050565b505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015610ad257507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aba9190612877565b73ffffffffffffffffffffffffffffffffffffffff16145b610b84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610171565b823414610c13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e742072657175697265640000000000006064820152608401610171565b3073ffffffffffffffffffffffffffffffffffffffff851603610cb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c6600000000000000000000000000000000000000000000000000000000006064820152608401610171565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d858585604051610d1993929190612913565b60405180910390a36000610d3e855a866040518060200160405280600081525061170e565b905080610dcd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c656400000000000000000000000000000000000000000000000000000000006064820152608401610171565b505050505050565b333b15610e64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610171565b610e7385333387878787611728565b5050505050565b610e8a878733888888888861195f565b50505050505050565b6060610ebe7f0000000000000000000000000000000000000000000000000000000000000000611bff565b610ee77f0000000000000000000000000000000000000000000000000000000000000000611bff565b610f107f0000000000000000000000000000000000000000000000000000000000000000611bff565b604051602001610f2293929190612936565b604051602081830303815290604052905090565b73ffffffffffffffffffffffffffffffffffffffff8716158015610f83575073ffffffffffffffffffffffffffffffffffffffff861673deaddeaddeaddeaddeaddeaddeaddeaddead0000145b1561101c57610f9585858585856109b4565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd898787878760405161100f94939291906128dd565b60405180910390a4610e8a565b600061102d8789888888888861054c565b905080156110bc578573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89888888886040516110af94939291906128dd565b60405180910390a461113f565b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f7ea89a4591614515571c2b51f5ea06494056f261c10ab1ed8c03c7590d87bce08888888860405161113694939291906128dd565b60405180910390a45b5050505050505050565b333b156111d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610171565b610dcd868633338888888861195f565b610dcd86338787878787611728565b333014611286576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642062792073656c66000000000000000000000000006064820152608401610171565b3073ffffffffffffffffffffffffffffffffffffffff85160361132b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5374616e646172644272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c66000000000000000000000000000000000000000000006064820152608401610171565b61133484611d3c565b15611482576113438484611d9e565b6113f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610171565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390528516906340c10f1990604401600060405180830381600087803b15801561146557600080fd5b505af1158015611479573d6000803e3d6000fd5b50505050611504565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600260209081526040808320938716835292905220546114c09082906129db565b73ffffffffffffffffffffffffffffffffffffffff808616600081815260026020908152604080832094891683529390529190912091909155611504908383611e45565b50505050565b6115043385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061039c92505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b7f0000000000000000000000000000000000000000000000000000000000000000630166a07a60e01b8a8c8b8b8b8a8a6040516024016115cf97969594939291906129f2565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b909216825261166292918890600401612832565b600060405180830381600087803b15801561167c57600080fd5b505af1158015611690573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf8888878760405161113694939291906128dd565b600080600080845160208601878a8af19695505050505050565b60008773ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611775573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117999190612877565b90507fffffffffffffffffffffffff215221522152215221522152215221522153000073ffffffffffffffffffffffffffffffffffffffff8916016118d55784341461188d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c325374616e646172644272696467653a20455448207769746864726177616c60448201527f73206d75737420696e636c7564652073756666696369656e742045544820766160648201527f6c75650000000000000000000000000000000000000000000000000000000000608482015260a401610171565b6118d08787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061039c92505050565b6118e5565b6118e5888289898989898961195f565b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e8989888860405161113694939291906128dd565b3073ffffffffffffffffffffffffffffffffffffffff891603611a04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5374616e646172644272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c66000000000000000000000000000000000000000000006064820152608401610171565b611a0d88611d3c565b15611b5b57611a1c8888611d9e565b611ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610171565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015260248201869052891690639dc29fac90604401600060405180830381600087803b158015611b3e57600080fd5b505af1158015611b52573d6000803e3d6000fd5b50505050611bef565b611b7d73ffffffffffffffffffffffffffffffffffffffff8916873087611f19565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b1683529290522054611bbb908590612a4f565b73ffffffffffffffffffffffffffffffffffffffff808a166000908152600260209081526040808320938c16835292905220555b61113f888888888888888861154d565b606081600003611c4257505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611c6c5780611c5681612a67565b9150611c659050600a83612ace565b9150611c46565b60008167ffffffffffffffff811115611c8757611c87612ae2565b6040519080825280601f01601f191660200182016040528015611cb1576020820181803683370190505b5090505b8415611d3457611cc66001836129db565b9150611cd3600a86612b11565b611cde906030612a4f565b60f81b818381518110611cf357611cf3612b25565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611d2d600a86612ace565b9450611cb5565b949350505050565b6000611d68827f1d1d8b6300000000000000000000000000000000000000000000000000000000611f77565b80611d985750611d98827fec4fc8e300000000000000000000000000000000000000000000000000000000611f77565b92915050565b60008273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611deb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0f9190612877565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905092915050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109af9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611f9a565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526115049085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611e97565b6000611f82836120a6565b8015611f935750611f93838361210a565b9392505050565b6000611ffc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121d59092919063ffffffff16565b8051909150156109af578080602001905181019061201a9190612b54565b6109af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610171565b60006120d2827f01ffc9a70000000000000000000000000000000000000000000000000000000061210a565b8015611d985750612103827fffffffff0000000000000000000000000000000000000000000000000000000061210a565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156121c2575060208210155b80156108d2575015159695505050505050565b6060611d3484846000858573ffffffffffffffffffffffffffffffffffffffff85163b61225e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610171565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516122879190612b76565b60006040518083038185875af1925050503d80600081146122c4576040519150601f19603f3d011682016040523d82523d6000602084013e6122c9565b606091505b50915091506108d2828286606083156122e3575081611f93565b8251156122f35782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610171919061264d565b73ffffffffffffffffffffffffffffffffffffffff8116811461234957600080fd5b50565b60008083601f84011261235e57600080fd5b50813567ffffffffffffffff81111561237657600080fd5b60208301915083602082850101111561238e57600080fd5b9250929050565b600080600080600080600060c0888a0312156123b057600080fd5b87356123bb81612327565b965060208801356123cb81612327565b955060408801356123db81612327565b945060608801356123eb81612327565b93506080880135925060a088013567ffffffffffffffff81111561240e57600080fd5b61241a8a828b0161234c565b989b979a50959850939692959293505050565b803563ffffffff8116811461244157600080fd5b919050565b60008060006040848603121561245b57600080fd5b6124648461242d565b9250602084013567ffffffffffffffff81111561248057600080fd5b61248c8682870161234c565b9497909650939450505050565b6000806000806000608086880312156124b157600080fd5b85356124bc81612327565b945060208601356124cc81612327565b935060408601359250606086013567ffffffffffffffff8111156124ef57600080fd5b6124fb8882890161234c565b969995985093965092949392505050565b60008060008060006080868803121561252457600080fd5b853561252f81612327565b9450602086013593506125446040870161242d565b9250606086013567ffffffffffffffff8111156124ef57600080fd5b600080600080600080600060c0888a03121561257b57600080fd5b873561258681612327565b9650602088013561259681612327565b955060408801356125a681612327565b9450606088013593506125bb6080890161242d565b925060a088013567ffffffffffffffff81111561240e57600080fd5b60005b838110156125f25781810151838201526020016125da565b838111156115045750506000910152565b6000815180845261261b8160208601602086016125d7565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611f936020830184612603565b60008060008060008060a0878903121561267957600080fd5b863561268481612327565b9550602087013561269481612327565b9450604087013593506126a96060880161242d565b9250608087013567ffffffffffffffff8111156126c557600080fd5b6126d189828a0161234c565b979a9699509497509295939492505050565b600080604083850312156126f657600080fd5b823561270181612327565b9150602083013561271181612327565b809150509250929050565b6000806000806080858703121561273257600080fd5b843561273d81612327565b9350602085013561274d81612327565b9250604085013561275d81612327565b9396929550929360600135925050565b6000806000806060858703121561278357600080fd5b843561278e81612327565b935061279c6020860161242d565b9250604085013567ffffffffffffffff8111156127b857600080fd5b6127c48782880161234c565b95989497509550505050565b828152604060208201526000611d346040830184612603565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526128286080830184612603565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006128616060830185612603565b905063ffffffff83166040830152949350505050565b60006020828403121561288957600080fd5b8151611f9381612327565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152606060408201526000612828606083018486612894565b83815260406020820152600061292d604083018486612894565b95945050505050565b600084516129488184602089016125d7565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551612984816001850160208a016125d7565b6001920191820152835161299f8160028401602088016125d7565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156129ed576129ed6129ac565b500390565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a0830152612a4260c083018486612894565b9998505050505050505050565b60008219821115612a6257612a626129ac565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612a9857612a986129ac565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082612add57612add612a9f565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082612b2057612b20612a9f565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215612b6657600080fd5b81518015158114611f9357600080fd5b60008251612b888184602087016125d7565b919091019291505056fea164736f6c634300080f000a",
ABI: "[{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_otherBridge\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"DepositFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ERC20BridgeInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHBridgeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"ETHBridgeInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"WithdrawalInitiated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeERC20To\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"bridgeETHTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_localToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeBridgeETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"finalizeDeposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"contractCrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"otherBridge\",\"outputs\":[{\"internalType\":\"contractStandardBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_minGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"withdrawTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
Bin: "0x6101206040523480156200001257600080fd5b50604051620028de380380620028de83398101604081905262000035916200006f565b7342000000000000000000000000000000000000076080526001600160a01b031660a052600060c081905260e052600261010052620000a1565b6000602082840312156200008257600080fd5b81516001600160a01b03811681146200009a57600080fd5b9392505050565b60805160a05160c05160e051610100516127ab6200013360003960006110be015260006110950152600061106c01526000818161032c01528181610496015281816105e201528181610aed015261192201526000818161020001528181610459015281816105b80152818161061901528181610ac301528181610b2401528181610db101526118e601526127ab6000f3fe6080604052600436106100d65760003560e01c806354fd4d501161007f5780638f601f66116100595780638f601f66146102c1578063a3a7954814610307578063c89701a21461031a578063e11013dd1461034e57600080fd5b806354fd4d501461026c578063662a633a1461028e57806387087623146102a157600080fd5b806332b7006d116100b057806332b7006d146101db5780633cb747bf146101ee578063540abf731461024c57600080fd5b80630166a07a1461019557806309fc8843146101b55780631635f5fd146101c857600080fd5b3661019057333b1561016f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61018e33333462030d4060405180602001604052806000815250610361565b005b600080fd5b3480156101a157600080fd5b5061018e6101b0366004611ff2565b6105a0565b61018e6101c33660046120a3565b6109d4565b61018e6101d63660046120f6565b610aab565b61018e6101e9366004612169565b610fa7565b3480156101fa57600080fd5b506102227f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561025857600080fd5b5061018e6102673660046121bd565b61104c565b34801561027857600080fd5b50610281611065565b60405161024391906122aa565b61018e61029c366004611ff2565b611108565b3480156102ad57600080fd5b5061018e6102bc3660046122bd565b6111f5565b3480156102cd57600080fd5b506102f96102dc366004612340565b600260209081526000928352604080842090915290825290205481565b604051908152602001610243565b61018e6103153660046122bd565b611294565b34801561032657600080fd5b506102227f000000000000000000000000000000000000000000000000000000000000000081565b61018e61035c366004612379565b6112a3565b8234146103f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c756500006064820152608401610166565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5858460405161044f9291906123dc565b60405180910390a37f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b847f0000000000000000000000000000000000000000000000000000000000000000631635f5fd60e01b898989886040516024016104d494939291906123f5565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b90921682526105679291889060040161243e565b6000604051808303818588803b15801561058057600080fd5b505af1158015610594573d6000803e3d6000fd5b50505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156106be57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610682573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a69190612483565b73ffffffffffffffffffffffffffffffffffffffff16145b610770576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610166565b610779876112ec565b156108c757610788878761134e565b61083a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610166565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156108aa57600080fd5b505af11580156108be573d6000803e3d6000fd5b50505050610949565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a16835292905220546109059084906124cf565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c16835293905291909120919091556109499085856113f5565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd878787876040516109c3949392919061252f565b60405180910390a450505050505050565b333b15610a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610166565b610aa63333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061036192505050565b505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015610bc957507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb19190612483565b73ffffffffffffffffffffffffffffffffffffffff16145b610c7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610166565b823414610d0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e742072657175697265640000000000006064820152608401610166565b3073ffffffffffffffffffffffffffffffffffffffff851603610daf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c6600000000000000000000000000000000000000000000000000000000006064820152608401610166565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610e8a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e6765720000000000000000000000000000000000000000000000006064820152608401610166565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d858585604051610eeb93929190612565565b60405180910390a36000610f10855a86604051806020016040528060008152506114c9565b905080610f9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c656400000000000000000000000000000000000000000000000000000000006064820152608401610166565b505050505050565b333b15611036576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610166565b611045853333878787876114e3565b5050505050565b61105c8787338888888888611677565b50505050505050565b60606110907f0000000000000000000000000000000000000000000000000000000000000000611a35565b6110b97f0000000000000000000000000000000000000000000000000000000000000000611a35565b6110e27f0000000000000000000000000000000000000000000000000000000000000000611a35565b6040516020016110f493929190612588565b604051602081830303815290604052905090565b73ffffffffffffffffffffffffffffffffffffffff8716158015611155575073ffffffffffffffffffffffffffffffffffffffff861673deaddeaddeaddeaddeaddeaddeaddeaddead0000145b1561116c576111678585858585610aab565b61117b565b61117b868887878787876105a0565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89878787876040516109c3949392919061252f565b333b15611284576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610166565b610f9f8686333388888888611677565b610f9f863387878787876114e3565b6112e63385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061036192505050565b50505050565b6000611318827f1d1d8b6300000000000000000000000000000000000000000000000000000000611b72565b806113485750611348827fec4fc8e300000000000000000000000000000000000000000000000000000000611b72565b92915050565b60008273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561139b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113bf9190612483565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905092915050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610aa69084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611b95565b600080600080845160208601878a8af19695505050505050565b60008773ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611530573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115549190612483565b90507fffffffffffffffffffffffff215221522152215221522152215221522153000073ffffffffffffffffffffffffffffffffffffffff8916016115db576115d68787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061036192505050565b6115eb565b6115eb8882898989898989611677565b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e89898888604051611665949392919061252f565b60405180910390a45050505050505050565b611680886112ec565b156117ce5761168f888861134e565b611741576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610166565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015260248201869052891690639dc29fac90604401600060405180830381600087803b1580156117b157600080fd5b505af11580156117c5573d6000803e3d6000fd5b50505050611862565b6117f073ffffffffffffffffffffffffffffffffffffffff8916873087611ca1565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b168352929052205461182e9085906125fe565b73ffffffffffffffffffffffffffffffffffffffff808a166000908152600260209081526040808320938c16835292905220555b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf888887876040516118dc949392919061252f565b60405180910390a47f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b7f0000000000000000000000000000000000000000000000000000000000000000630166a07a60e01b8a8c8b8b8b8a8a6040516024016119669796959493929190612616565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b90921682526119f99291889060040161243e565b600060405180830381600087803b158015611a1357600080fd5b505af1158015611a27573d6000803e3d6000fd5b505050505050505050505050565b606081600003611a7857505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611aa25780611a8c81612673565b9150611a9b9050600a836126da565b9150611a7c565b60008167ffffffffffffffff811115611abd57611abd6126ee565b6040519080825280601f01601f191660200182016040528015611ae7576020820181803683370190505b5090505b8415611b6a57611afc6001836124cf565b9150611b09600a8661271d565b611b149060306125fe565b60f81b818381518110611b2957611b29612731565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611b63600a866126da565b9450611aeb565b949350505050565b6000611b7d83611cff565b8015611b8e5750611b8e8383611d63565b9392505050565b6000611bf7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611e329092919063ffffffff16565b805190915015610aa65780806020019051810190611c159190612760565b610aa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610166565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112e69085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611447565b6000611d2b827f01ffc9a700000000000000000000000000000000000000000000000000000000611d63565b80156113485750611d5c827fffffffff00000000000000000000000000000000000000000000000000000000611d63565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015611e1b575060208210155b8015611e275750600081115b979650505050505050565b6060611b6a84846000858573ffffffffffffffffffffffffffffffffffffffff85163b611ebb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610166565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ee49190612782565b60006040518083038185875af1925050503d8060008114611f21576040519150601f19603f3d011682016040523d82523d6000602084013e611f26565b606091505b5091509150611e2782828660608315611f40575081611b8e565b825115611f505782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161016691906122aa565b73ffffffffffffffffffffffffffffffffffffffff81168114611fa657600080fd5b50565b60008083601f840112611fbb57600080fd5b50813567ffffffffffffffff811115611fd357600080fd5b602083019150836020828501011115611feb57600080fd5b9250929050565b600080600080600080600060c0888a03121561200d57600080fd5b873561201881611f84565b9650602088013561202881611f84565b9550604088013561203881611f84565b9450606088013561204881611f84565b93506080880135925060a088013567ffffffffffffffff81111561206b57600080fd5b6120778a828b01611fa9565b989b979a50959850939692959293505050565b803563ffffffff8116811461209e57600080fd5b919050565b6000806000604084860312156120b857600080fd5b6120c18461208a565b9250602084013567ffffffffffffffff8111156120dd57600080fd5b6120e986828701611fa9565b9497909650939450505050565b60008060008060006080868803121561210e57600080fd5b853561211981611f84565b9450602086013561212981611f84565b935060408601359250606086013567ffffffffffffffff81111561214c57600080fd5b61215888828901611fa9565b969995985093965092949392505050565b60008060008060006080868803121561218157600080fd5b853561218c81611f84565b9450602086013593506121a16040870161208a565b9250606086013567ffffffffffffffff81111561214c57600080fd5b600080600080600080600060c0888a0312156121d857600080fd5b87356121e381611f84565b965060208801356121f381611f84565b9550604088013561220381611f84565b9450606088013593506122186080890161208a565b925060a088013567ffffffffffffffff81111561206b57600080fd5b60005b8381101561224f578181015183820152602001612237565b838111156112e65750506000910152565b60008151808452612278816020860160208601612234565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611b8e6020830184612260565b60008060008060008060a087890312156122d657600080fd5b86356122e181611f84565b955060208701356122f181611f84565b9450604087013593506123066060880161208a565b9250608087013567ffffffffffffffff81111561232257600080fd5b61232e89828a01611fa9565b979a9699509497509295939492505050565b6000806040838503121561235357600080fd5b823561235e81611f84565b9150602083013561236e81611f84565b809150509250929050565b6000806000806060858703121561238f57600080fd5b843561239a81611f84565b93506123a86020860161208a565b9250604085013567ffffffffffffffff8111156123c457600080fd5b6123d087828801611fa9565b95989497509550505050565b828152604060208201526000611b6a6040830184612260565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526124346080830184612260565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061246d6060830185612260565b905063ffffffff83166040830152949350505050565b60006020828403121561249557600080fd5b8151611b8e81611f84565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156124e1576124e16124a0565b500390565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006124346060830184866124e6565b83815260406020820152600061257f6040830184866124e6565b95945050505050565b6000845161259a818460208901612234565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516125d6816001850160208a01612234565b600192019182015283516125f1816002840160208801612234565b0160020195945050505050565b60008219821115612611576126116124a0565b500190565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261266660c0830184866124e6565b9998505050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036126a4576126a46124a0565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826126e9576126e96126ab565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008261272c5761272c6126ab565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561277257600080fd5b81518015158114611b8e57600080fd5b60008251612794818460208701612234565b919091019291505056fea164736f6c634300080f000a",
}
// L2StandardBridgeABI is the input ABI used to generate the binding from.
......@@ -409,44 +409,23 @@ func (_L2StandardBridge *L2StandardBridgeTransactorSession) BridgeETHTo(_to comm
return _L2StandardBridge.Contract.BridgeETHTo(&_L2StandardBridge.TransactOpts, _to, _minGasLimit, _extraData)
}
// CompleteOutboundTransfer is a paid mutator transaction binding the contract method 0xaf565a13.
//
// Solidity: function completeOutboundTransfer(address _localToken, address _remoteToken, address _to, uint256 _amount) returns()
func (_L2StandardBridge *L2StandardBridgeTransactor) CompleteOutboundTransfer(opts *bind.TransactOpts, _localToken common.Address, _remoteToken common.Address, _to common.Address, _amount *big.Int) (*types.Transaction, error) {
return _L2StandardBridge.contract.Transact(opts, "completeOutboundTransfer", _localToken, _remoteToken, _to, _amount)
}
// CompleteOutboundTransfer is a paid mutator transaction binding the contract method 0xaf565a13.
//
// Solidity: function completeOutboundTransfer(address _localToken, address _remoteToken, address _to, uint256 _amount) returns()
func (_L2StandardBridge *L2StandardBridgeSession) CompleteOutboundTransfer(_localToken common.Address, _remoteToken common.Address, _to common.Address, _amount *big.Int) (*types.Transaction, error) {
return _L2StandardBridge.Contract.CompleteOutboundTransfer(&_L2StandardBridge.TransactOpts, _localToken, _remoteToken, _to, _amount)
}
// CompleteOutboundTransfer is a paid mutator transaction binding the contract method 0xaf565a13.
//
// Solidity: function completeOutboundTransfer(address _localToken, address _remoteToken, address _to, uint256 _amount) returns()
func (_L2StandardBridge *L2StandardBridgeTransactorSession) CompleteOutboundTransfer(_localToken common.Address, _remoteToken common.Address, _to common.Address, _amount *big.Int) (*types.Transaction, error) {
return _L2StandardBridge.Contract.CompleteOutboundTransfer(&_L2StandardBridge.TransactOpts, _localToken, _remoteToken, _to, _amount)
}
// FinalizeBridgeERC20 is a paid mutator transaction binding the contract method 0x0166a07a.
//
// Solidity: function finalizeBridgeERC20(address _localToken, address _remoteToken, address _from, address _to, uint256 _amount, bytes _extraData) returns(bool)
// Solidity: function finalizeBridgeERC20(address _localToken, address _remoteToken, address _from, address _to, uint256 _amount, bytes _extraData) returns()
func (_L2StandardBridge *L2StandardBridgeTransactor) FinalizeBridgeERC20(opts *bind.TransactOpts, _localToken common.Address, _remoteToken common.Address, _from common.Address, _to common.Address, _amount *big.Int, _extraData []byte) (*types.Transaction, error) {
return _L2StandardBridge.contract.Transact(opts, "finalizeBridgeERC20", _localToken, _remoteToken, _from, _to, _amount, _extraData)
}
// FinalizeBridgeERC20 is a paid mutator transaction binding the contract method 0x0166a07a.
//
// Solidity: function finalizeBridgeERC20(address _localToken, address _remoteToken, address _from, address _to, uint256 _amount, bytes _extraData) returns(bool)
// Solidity: function finalizeBridgeERC20(address _localToken, address _remoteToken, address _from, address _to, uint256 _amount, bytes _extraData) returns()
func (_L2StandardBridge *L2StandardBridgeSession) FinalizeBridgeERC20(_localToken common.Address, _remoteToken common.Address, _from common.Address, _to common.Address, _amount *big.Int, _extraData []byte) (*types.Transaction, error) {
return _L2StandardBridge.Contract.FinalizeBridgeERC20(&_L2StandardBridge.TransactOpts, _localToken, _remoteToken, _from, _to, _amount, _extraData)
}
// FinalizeBridgeERC20 is a paid mutator transaction binding the contract method 0x0166a07a.
//
// Solidity: function finalizeBridgeERC20(address _localToken, address _remoteToken, address _from, address _to, uint256 _amount, bytes _extraData) returns(bool)
// Solidity: function finalizeBridgeERC20(address _localToken, address _remoteToken, address _from, address _to, uint256 _amount, bytes _extraData) returns()
func (_L2StandardBridge *L2StandardBridgeTransactorSession) FinalizeBridgeERC20(_localToken common.Address, _remoteToken common.Address, _from common.Address, _to common.Address, _amount *big.Int, _extraData []byte) (*types.Transaction, error) {
return _L2StandardBridge.Contract.FinalizeBridgeERC20(&_L2StandardBridge.TransactOpts, _localToken, _remoteToken, _from, _to, _amount, _extraData)
}
......@@ -556,171 +535,6 @@ func (_L2StandardBridge *L2StandardBridgeTransactorSession) Receive() (*types.Tr
return _L2StandardBridge.Contract.Receive(&_L2StandardBridge.TransactOpts)
}
// L2StandardBridgeDepositFailedIterator is returned from FilterDepositFailed and is used to iterate over the raw logs and unpacked data for DepositFailed events raised by the L2StandardBridge contract.
type L2StandardBridgeDepositFailedIterator struct {
Event *L2StandardBridgeDepositFailed // 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 *L2StandardBridgeDepositFailedIterator) 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(L2StandardBridgeDepositFailed)
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(L2StandardBridgeDepositFailed)
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 *L2StandardBridgeDepositFailedIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *L2StandardBridgeDepositFailedIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// L2StandardBridgeDepositFailed represents a DepositFailed event raised by the L2StandardBridge contract.
type L2StandardBridgeDepositFailed struct {
L1Token common.Address
L2Token common.Address
From common.Address
To common.Address
Amount *big.Int
ExtraData []byte
Raw types.Log // Blockchain specific contextual infos
}
// FilterDepositFailed is a free log retrieval operation binding the contract event 0x7ea89a4591614515571c2b51f5ea06494056f261c10ab1ed8c03c7590d87bce0.
//
// Solidity: event DepositFailed(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes extraData)
func (_L2StandardBridge *L2StandardBridgeFilterer) FilterDepositFailed(opts *bind.FilterOpts, l1Token []common.Address, l2Token []common.Address, from []common.Address) (*L2StandardBridgeDepositFailedIterator, error) {
var l1TokenRule []interface{}
for _, l1TokenItem := range l1Token {
l1TokenRule = append(l1TokenRule, l1TokenItem)
}
var l2TokenRule []interface{}
for _, l2TokenItem := range l2Token {
l2TokenRule = append(l2TokenRule, l2TokenItem)
}
var fromRule []interface{}
for _, fromItem := range from {
fromRule = append(fromRule, fromItem)
}
logs, sub, err := _L2StandardBridge.contract.FilterLogs(opts, "DepositFailed", l1TokenRule, l2TokenRule, fromRule)
if err != nil {
return nil, err
}
return &L2StandardBridgeDepositFailedIterator{contract: _L2StandardBridge.contract, event: "DepositFailed", logs: logs, sub: sub}, nil
}
// WatchDepositFailed is a free log subscription operation binding the contract event 0x7ea89a4591614515571c2b51f5ea06494056f261c10ab1ed8c03c7590d87bce0.
//
// Solidity: event DepositFailed(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes extraData)
func (_L2StandardBridge *L2StandardBridgeFilterer) WatchDepositFailed(opts *bind.WatchOpts, sink chan<- *L2StandardBridgeDepositFailed, l1Token []common.Address, l2Token []common.Address, from []common.Address) (event.Subscription, error) {
var l1TokenRule []interface{}
for _, l1TokenItem := range l1Token {
l1TokenRule = append(l1TokenRule, l1TokenItem)
}
var l2TokenRule []interface{}
for _, l2TokenItem := range l2Token {
l2TokenRule = append(l2TokenRule, l2TokenItem)
}
var fromRule []interface{}
for _, fromItem := range from {
fromRule = append(fromRule, fromItem)
}
logs, sub, err := _L2StandardBridge.contract.WatchLogs(opts, "DepositFailed", l1TokenRule, l2TokenRule, fromRule)
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(L2StandardBridgeDepositFailed)
if err := _L2StandardBridge.contract.UnpackLog(event, "DepositFailed", 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
}
// ParseDepositFailed is a log parse operation binding the contract event 0x7ea89a4591614515571c2b51f5ea06494056f261c10ab1ed8c03c7590d87bce0.
//
// Solidity: event DepositFailed(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes extraData)
func (_L2StandardBridge *L2StandardBridgeFilterer) ParseDepositFailed(log types.Log) (*L2StandardBridgeDepositFailed, error) {
event := new(L2StandardBridgeDepositFailed)
if err := _L2StandardBridge.contract.UnpackLog(event, "DepositFailed", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// L2StandardBridgeDepositFinalizedIterator is returned from FilterDepositFinalized and is used to iterate over the raw logs and unpacked data for DepositFinalized events raised by the L2StandardBridge contract.
type L2StandardBridgeDepositFinalizedIterator struct {
Event *L2StandardBridgeDepositFinalized // Event containing the contract specifics and raw log
......@@ -886,171 +700,6 @@ func (_L2StandardBridge *L2StandardBridgeFilterer) ParseDepositFinalized(log typ
return event, nil
}
// L2StandardBridgeERC20BridgeFailedIterator is returned from FilterERC20BridgeFailed and is used to iterate over the raw logs and unpacked data for ERC20BridgeFailed events raised by the L2StandardBridge contract.
type L2StandardBridgeERC20BridgeFailedIterator struct {
Event *L2StandardBridgeERC20BridgeFailed // 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 *L2StandardBridgeERC20BridgeFailedIterator) 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(L2StandardBridgeERC20BridgeFailed)
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(L2StandardBridgeERC20BridgeFailed)
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 *L2StandardBridgeERC20BridgeFailedIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *L2StandardBridgeERC20BridgeFailedIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// L2StandardBridgeERC20BridgeFailed represents a ERC20BridgeFailed event raised by the L2StandardBridge contract.
type L2StandardBridgeERC20BridgeFailed struct {
LocalToken common.Address
RemoteToken common.Address
From common.Address
To common.Address
Amount *big.Int
ExtraData []byte
Raw types.Log // Blockchain specific contextual infos
}
// FilterERC20BridgeFailed is a free log retrieval operation binding the contract event 0x2755817676249910615f0a6a240ad225abe5343df8d527f7294c4af36a92009a.
//
// Solidity: event ERC20BridgeFailed(address indexed localToken, address indexed remoteToken, address indexed from, address to, uint256 amount, bytes extraData)
func (_L2StandardBridge *L2StandardBridgeFilterer) FilterERC20BridgeFailed(opts *bind.FilterOpts, localToken []common.Address, remoteToken []common.Address, from []common.Address) (*L2StandardBridgeERC20BridgeFailedIterator, error) {
var localTokenRule []interface{}
for _, localTokenItem := range localToken {
localTokenRule = append(localTokenRule, localTokenItem)
}
var remoteTokenRule []interface{}
for _, remoteTokenItem := range remoteToken {
remoteTokenRule = append(remoteTokenRule, remoteTokenItem)
}
var fromRule []interface{}
for _, fromItem := range from {
fromRule = append(fromRule, fromItem)
}
logs, sub, err := _L2StandardBridge.contract.FilterLogs(opts, "ERC20BridgeFailed", localTokenRule, remoteTokenRule, fromRule)
if err != nil {
return nil, err
}
return &L2StandardBridgeERC20BridgeFailedIterator{contract: _L2StandardBridge.contract, event: "ERC20BridgeFailed", logs: logs, sub: sub}, nil
}
// WatchERC20BridgeFailed is a free log subscription operation binding the contract event 0x2755817676249910615f0a6a240ad225abe5343df8d527f7294c4af36a92009a.
//
// Solidity: event ERC20BridgeFailed(address indexed localToken, address indexed remoteToken, address indexed from, address to, uint256 amount, bytes extraData)
func (_L2StandardBridge *L2StandardBridgeFilterer) WatchERC20BridgeFailed(opts *bind.WatchOpts, sink chan<- *L2StandardBridgeERC20BridgeFailed, localToken []common.Address, remoteToken []common.Address, from []common.Address) (event.Subscription, error) {
var localTokenRule []interface{}
for _, localTokenItem := range localToken {
localTokenRule = append(localTokenRule, localTokenItem)
}
var remoteTokenRule []interface{}
for _, remoteTokenItem := range remoteToken {
remoteTokenRule = append(remoteTokenRule, remoteTokenItem)
}
var fromRule []interface{}
for _, fromItem := range from {
fromRule = append(fromRule, fromItem)
}
logs, sub, err := _L2StandardBridge.contract.WatchLogs(opts, "ERC20BridgeFailed", localTokenRule, remoteTokenRule, fromRule)
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(L2StandardBridgeERC20BridgeFailed)
if err := _L2StandardBridge.contract.UnpackLog(event, "ERC20BridgeFailed", 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
}
// ParseERC20BridgeFailed is a log parse operation binding the contract event 0x2755817676249910615f0a6a240ad225abe5343df8d527f7294c4af36a92009a.
//
// Solidity: event ERC20BridgeFailed(address indexed localToken, address indexed remoteToken, address indexed from, address to, uint256 amount, bytes extraData)
func (_L2StandardBridge *L2StandardBridgeFilterer) ParseERC20BridgeFailed(log types.Log) (*L2StandardBridgeERC20BridgeFailed, error) {
event := new(L2StandardBridgeERC20BridgeFailed)
if err := _L2StandardBridge.contract.UnpackLog(event, "ERC20BridgeFailed", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// L2StandardBridgeERC20BridgeFinalizedIterator is returned from FilterERC20BridgeFinalized and is used to iterate over the raw logs and unpacked data for ERC20BridgeFinalized events raised by the L2StandardBridge contract.
type L2StandardBridgeERC20BridgeFinalizedIterator struct {
Event *L2StandardBridgeERC20BridgeFinalized // Event containing the contract specifics and raw log
......
......@@ -9,11 +9,11 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const L2StandardBridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":26351,\"contract\":\"contracts/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":26354,\"contract\":\"contracts/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"spacer_1_0_20\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_address\"},{\"astId\":26361,\"contract\":\"contracts/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"deposits\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":26366,\"contract\":\"contracts/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_array(t_uint256)47_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)47_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[47]\",\"numberOfBytes\":\"1504\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
const L2StandardBridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":26285,\"contract\":\"contracts/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":26288,\"contract\":\"contracts/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"spacer_1_0_20\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_address\"},{\"astId\":26295,\"contract\":\"contracts/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"deposits\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":26300,\"contract\":\"contracts/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_array(t_uint256)47_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)47_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[47]\",\"numberOfBytes\":\"1504\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
var L2StandardBridgeStorageLayout = new(solc.StorageLayout)
var L2StandardBridgeDeployedBin = "0x6080604052600436106100e15760003560e01c8063662a633a1161007f578063a3a7954811610059578063a3a7954814610322578063af565a1314610335578063c89701a214610355578063e11013dd1461038957600080fd5b8063662a633a146102a957806387087623146102bc5780638f601f66146102dc57600080fd5b806332b7006d116100bb57806332b7006d146101fb5780633cb747bf1461020e578063540abf731461026757806354fd4d501461028757600080fd5b80630166a07a146101a057806309fc8843146101d55780631635f5fd146101e857600080fd5b3661019b57333b1561017a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61019933333462030d406040518060200160405280600081525061039c565b005b600080fd5b3480156101ac57600080fd5b506101c06101bb366004612395565b61054c565b60405190151581526020015b60405180910390f35b6101996101e3366004612446565b6108dd565b6101996101f6366004612499565b6109b4565b61019961020936600461250c565b610dd5565b34801561021a57600080fd5b506102427f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cc565b34801561027357600080fd5b50610199610282366004612560565b610e7a565b34801561029357600080fd5b5061029c610e93565b6040516101cc919061264d565b6101996102b7366004612395565b610f36565b3480156102c857600080fd5b506101996102d7366004612660565b611149565b3480156102e857600080fd5b506103146102f73660046126e3565b600260209081526000928352604080842090915290825290205481565b6040519081526020016101cc565b610199610330366004612660565b6111e8565b34801561034157600080fd5b5061019961035036600461271c565b6111f7565b34801561036157600080fd5b506102427f000000000000000000000000000000000000000000000000000000000000000081565b61019961039736600461276d565b61150a565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af585846040516103fb9291906127d0565b60405180910390a37f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b847f0000000000000000000000000000000000000000000000000000000000000000631635f5fd60e01b8989898860405160240161048094939291906127e9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261051392918890600401612832565b6000604051808303818588803b15801561052c57600080fd5b505af1158015610540573d6000803e3d6000fd5b50505050505050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614801561066c57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610630573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106549190612877565b73ffffffffffffffffffffffffffffffffffffffff16145b61071e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610171565b6040517faf565a1300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808a16600483015280891660248301528616604482015260648101859052309063af565a1390608401600060405180830381600087803b15801561079c57600080fd5b505af19250505080156107ad575060015b61084c576107c288888789886000898961154d565b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f2755817676249910615f0a6a240ad225abe5343df8d527f7294c4af36a92009a8888888860405161083c94939291906128dd565b60405180910390a45060006108d2565b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd888888886040516108c694939291906128dd565b60405180910390a45060015b979650505050505050565b333b1561096c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610171565b6109af3333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061039c92505050565b505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015610ad257507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aba9190612877565b73ffffffffffffffffffffffffffffffffffffffff16145b610b84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610171565b823414610c13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e742072657175697265640000000000006064820152608401610171565b3073ffffffffffffffffffffffffffffffffffffffff851603610cb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c6600000000000000000000000000000000000000000000000000000000006064820152608401610171565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d858585604051610d1993929190612913565b60405180910390a36000610d3e855a866040518060200160405280600081525061170e565b905080610dcd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c656400000000000000000000000000000000000000000000000000000000006064820152608401610171565b505050505050565b333b15610e64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610171565b610e7385333387878787611728565b5050505050565b610e8a878733888888888861195f565b50505050505050565b6060610ebe7f0000000000000000000000000000000000000000000000000000000000000000611bff565b610ee77f0000000000000000000000000000000000000000000000000000000000000000611bff565b610f107f0000000000000000000000000000000000000000000000000000000000000000611bff565b604051602001610f2293929190612936565b604051602081830303815290604052905090565b73ffffffffffffffffffffffffffffffffffffffff8716158015610f83575073ffffffffffffffffffffffffffffffffffffffff861673deaddeaddeaddeaddeaddeaddeaddeaddead0000145b1561101c57610f9585858585856109b4565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd898787878760405161100f94939291906128dd565b60405180910390a4610e8a565b600061102d8789888888888861054c565b905080156110bc578573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89888888886040516110af94939291906128dd565b60405180910390a461113f565b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f7ea89a4591614515571c2b51f5ea06494056f261c10ab1ed8c03c7590d87bce08888888860405161113694939291906128dd565b60405180910390a45b5050505050505050565b333b156111d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610171565b610dcd868633338888888861195f565b610dcd86338787878787611728565b333014611286576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642062792073656c66000000000000000000000000006064820152608401610171565b3073ffffffffffffffffffffffffffffffffffffffff85160361132b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5374616e646172644272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c66000000000000000000000000000000000000000000006064820152608401610171565b61133484611d3c565b15611482576113438484611d9e565b6113f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610171565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390528516906340c10f1990604401600060405180830381600087803b15801561146557600080fd5b505af1158015611479573d6000803e3d6000fd5b50505050611504565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600260209081526040808320938716835292905220546114c09082906129db565b73ffffffffffffffffffffffffffffffffffffffff808616600081815260026020908152604080832094891683529390529190912091909155611504908383611e45565b50505050565b6115043385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061039c92505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b7f0000000000000000000000000000000000000000000000000000000000000000630166a07a60e01b8a8c8b8b8b8a8a6040516024016115cf97969594939291906129f2565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b909216825261166292918890600401612832565b600060405180830381600087803b15801561167c57600080fd5b505af1158015611690573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf8888878760405161113694939291906128dd565b600080600080845160208601878a8af19695505050505050565b60008773ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611775573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117999190612877565b90507fffffffffffffffffffffffff215221522152215221522152215221522153000073ffffffffffffffffffffffffffffffffffffffff8916016118d55784341461188d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4c325374616e646172644272696467653a20455448207769746864726177616c60448201527f73206d75737420696e636c7564652073756666696369656e742045544820766160648201527f6c75650000000000000000000000000000000000000000000000000000000000608482015260a401610171565b6118d08787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061039c92505050565b6118e5565b6118e5888289898989898961195f565b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e8989888860405161113694939291906128dd565b3073ffffffffffffffffffffffffffffffffffffffff891603611a04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5374616e646172644272696467653a206c6f63616c20746f6b656e2063616e6e60448201527f6f742062652073656c66000000000000000000000000000000000000000000006064820152608401610171565b611a0d88611d3c565b15611b5b57611a1c8888611d9e565b611ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610171565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015260248201869052891690639dc29fac90604401600060405180830381600087803b158015611b3e57600080fd5b505af1158015611b52573d6000803e3d6000fd5b50505050611bef565b611b7d73ffffffffffffffffffffffffffffffffffffffff8916873087611f19565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b1683529290522054611bbb908590612a4f565b73ffffffffffffffffffffffffffffffffffffffff808a166000908152600260209081526040808320938c16835292905220555b61113f888888888888888861154d565b606081600003611c4257505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611c6c5780611c5681612a67565b9150611c659050600a83612ace565b9150611c46565b60008167ffffffffffffffff811115611c8757611c87612ae2565b6040519080825280601f01601f191660200182016040528015611cb1576020820181803683370190505b5090505b8415611d3457611cc66001836129db565b9150611cd3600a86612b11565b611cde906030612a4f565b60f81b818381518110611cf357611cf3612b25565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611d2d600a86612ace565b9450611cb5565b949350505050565b6000611d68827f1d1d8b6300000000000000000000000000000000000000000000000000000000611f77565b80611d985750611d98827fec4fc8e300000000000000000000000000000000000000000000000000000000611f77565b92915050565b60008273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611deb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0f9190612877565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905092915050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109af9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611f9a565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526115049085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611e97565b6000611f82836120a6565b8015611f935750611f93838361210a565b9392505050565b6000611ffc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121d59092919063ffffffff16565b8051909150156109af578080602001905181019061201a9190612b54565b6109af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610171565b60006120d2827f01ffc9a70000000000000000000000000000000000000000000000000000000061210a565b8015611d985750612103827fffffffff0000000000000000000000000000000000000000000000000000000061210a565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156121c2575060208210155b80156108d2575015159695505050505050565b6060611d3484846000858573ffffffffffffffffffffffffffffffffffffffff85163b61225e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610171565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516122879190612b76565b60006040518083038185875af1925050503d80600081146122c4576040519150601f19603f3d011682016040523d82523d6000602084013e6122c9565b606091505b50915091506108d2828286606083156122e3575081611f93565b8251156122f35782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610171919061264d565b73ffffffffffffffffffffffffffffffffffffffff8116811461234957600080fd5b50565b60008083601f84011261235e57600080fd5b50813567ffffffffffffffff81111561237657600080fd5b60208301915083602082850101111561238e57600080fd5b9250929050565b600080600080600080600060c0888a0312156123b057600080fd5b87356123bb81612327565b965060208801356123cb81612327565b955060408801356123db81612327565b945060608801356123eb81612327565b93506080880135925060a088013567ffffffffffffffff81111561240e57600080fd5b61241a8a828b0161234c565b989b979a50959850939692959293505050565b803563ffffffff8116811461244157600080fd5b919050565b60008060006040848603121561245b57600080fd5b6124648461242d565b9250602084013567ffffffffffffffff81111561248057600080fd5b61248c8682870161234c565b9497909650939450505050565b6000806000806000608086880312156124b157600080fd5b85356124bc81612327565b945060208601356124cc81612327565b935060408601359250606086013567ffffffffffffffff8111156124ef57600080fd5b6124fb8882890161234c565b969995985093965092949392505050565b60008060008060006080868803121561252457600080fd5b853561252f81612327565b9450602086013593506125446040870161242d565b9250606086013567ffffffffffffffff8111156124ef57600080fd5b600080600080600080600060c0888a03121561257b57600080fd5b873561258681612327565b9650602088013561259681612327565b955060408801356125a681612327565b9450606088013593506125bb6080890161242d565b925060a088013567ffffffffffffffff81111561240e57600080fd5b60005b838110156125f25781810151838201526020016125da565b838111156115045750506000910152565b6000815180845261261b8160208601602086016125d7565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611f936020830184612603565b60008060008060008060a0878903121561267957600080fd5b863561268481612327565b9550602087013561269481612327565b9450604087013593506126a96060880161242d565b9250608087013567ffffffffffffffff8111156126c557600080fd5b6126d189828a0161234c565b979a9699509497509295939492505050565b600080604083850312156126f657600080fd5b823561270181612327565b9150602083013561271181612327565b809150509250929050565b6000806000806080858703121561273257600080fd5b843561273d81612327565b9350602085013561274d81612327565b9250604085013561275d81612327565b9396929550929360600135925050565b6000806000806060858703121561278357600080fd5b843561278e81612327565b935061279c6020860161242d565b9250604085013567ffffffffffffffff8111156127b857600080fd5b6127c48782880161234c565b95989497509550505050565b828152604060208201526000611d346040830184612603565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526128286080830184612603565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006128616060830185612603565b905063ffffffff83166040830152949350505050565b60006020828403121561288957600080fd5b8151611f9381612327565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152606060408201526000612828606083018486612894565b83815260406020820152600061292d604083018486612894565b95945050505050565b600084516129488184602089016125d7565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551612984816001850160208a016125d7565b6001920191820152835161299f8160028401602088016125d7565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156129ed576129ed6129ac565b500390565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a0830152612a4260c083018486612894565b9998505050505050505050565b60008219821115612a6257612a626129ac565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612a9857612a986129ac565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082612add57612add612a9f565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082612b2057612b20612a9f565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215612b6657600080fd5b81518015158114611f9357600080fd5b60008251612b888184602087016125d7565b919091019291505056fea164736f6c634300080f000a"
var L2StandardBridgeDeployedBin = "0x6080604052600436106100d65760003560e01c806354fd4d501161007f5780638f601f66116100595780638f601f66146102c1578063a3a7954814610307578063c89701a21461031a578063e11013dd1461034e57600080fd5b806354fd4d501461026c578063662a633a1461028e57806387087623146102a157600080fd5b806332b7006d116100b057806332b7006d146101db5780633cb747bf146101ee578063540abf731461024c57600080fd5b80630166a07a1461019557806309fc8843146101b55780631635f5fd146101c857600080fd5b3661019057333b1561016f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b61018e33333462030d4060405180602001604052806000815250610361565b005b600080fd5b3480156101a157600080fd5b5061018e6101b0366004611ff2565b6105a0565b61018e6101c33660046120a3565b6109d4565b61018e6101d63660046120f6565b610aab565b61018e6101e9366004612169565b610fa7565b3480156101fa57600080fd5b506102227f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561025857600080fd5b5061018e6102673660046121bd565b61104c565b34801561027857600080fd5b50610281611065565b60405161024391906122aa565b61018e61029c366004611ff2565b611108565b3480156102ad57600080fd5b5061018e6102bc3660046122bd565b6111f5565b3480156102cd57600080fd5b506102f96102dc366004612340565b600260209081526000928352604080842090915290825290205481565b604051908152602001610243565b61018e6103153660046122bd565b611294565b34801561032657600080fd5b506102227f000000000000000000000000000000000000000000000000000000000000000081565b61018e61035c366004612379565b6112a3565b8234146103f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c756500006064820152608401610166565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5858460405161044f9291906123dc565b60405180910390a37f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b847f0000000000000000000000000000000000000000000000000000000000000000631635f5fd60e01b898989886040516024016104d494939291906123f5565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b90921682526105679291889060040161243e565b6000604051808303818588803b15801561058057600080fd5b505af1158015610594573d6000803e3d6000fd5b50505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156106be57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610682573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a69190612483565b73ffffffffffffffffffffffffffffffffffffffff16145b610770576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610166565b610779876112ec565b156108c757610788878761134e565b61083a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610166565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156108aa57600080fd5b505af11580156108be573d6000803e3d6000fd5b50505050610949565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a16835292905220546109059084906124cf565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c16835293905291909120919091556109499085856113f5565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd878787876040516109c3949392919061252f565b60405180910390a450505050505050565b333b15610a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610166565b610aa63333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061036192505050565b505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015610bc957507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb19190612483565b73ffffffffffffffffffffffffffffffffffffffff16145b610c7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a401610166565b823414610d0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e742072657175697265640000000000006064820152608401610166565b3073ffffffffffffffffffffffffffffffffffffffff851603610daf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c6600000000000000000000000000000000000000000000000000000000006064820152608401610166565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610e8a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e6765720000000000000000000000000000000000000000000000006064820152608401610166565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d858585604051610eeb93929190612565565b60405180910390a36000610f10855a86604051806020016040528060008152506114c9565b905080610f9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c656400000000000000000000000000000000000000000000000000000000006064820152608401610166565b505050505050565b333b15611036576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610166565b611045853333878787876114e3565b5050505050565b61105c8787338888888888611677565b50505050505050565b60606110907f0000000000000000000000000000000000000000000000000000000000000000611a35565b6110b97f0000000000000000000000000000000000000000000000000000000000000000611a35565b6110e27f0000000000000000000000000000000000000000000000000000000000000000611a35565b6040516020016110f493929190612588565b604051602081830303815290604052905090565b73ffffffffffffffffffffffffffffffffffffffff8716158015611155575073ffffffffffffffffffffffffffffffffffffffff861673deaddeaddeaddeaddeaddeaddeaddeaddead0000145b1561116c576111678585858585610aab565b61117b565b61117b868887878787876105a0565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89878787876040516109c3949392919061252f565b333b15611284576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f410000000000000000006064820152608401610166565b610f9f8686333388888888611677565b610f9f863387878787876114e3565b6112e63385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061036192505050565b50505050565b6000611318827f1d1d8b6300000000000000000000000000000000000000000000000000000000611b72565b806113485750611348827fec4fc8e300000000000000000000000000000000000000000000000000000000611b72565b92915050565b60008273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561139b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113bf9190612483565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905092915050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610aa69084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611b95565b600080600080845160208601878a8af19695505050505050565b60008773ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611530573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115549190612483565b90507fffffffffffffffffffffffff215221522152215221522152215221522153000073ffffffffffffffffffffffffffffffffffffffff8916016115db576115d68787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061036192505050565b6115eb565b6115eb8882898989898989611677565b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e89898888604051611665949392919061252f565b60405180910390a45050505050505050565b611680886112ec565b156117ce5761168f888861134e565b611741576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a401610166565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015260248201869052891690639dc29fac90604401600060405180830381600087803b1580156117b157600080fd5b505af11580156117c5573d6000803e3d6000fd5b50505050611862565b6117f073ffffffffffffffffffffffffffffffffffffffff8916873087611ca1565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b168352929052205461182e9085906125fe565b73ffffffffffffffffffffffffffffffffffffffff808a166000908152600260209081526040808320938c16835292905220555b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf888887876040516118dc949392919061252f565b60405180910390a47f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b7f0000000000000000000000000000000000000000000000000000000000000000630166a07a60e01b8a8c8b8b8b8a8a6040516024016119669796959493929190612616565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b90921682526119f99291889060040161243e565b600060405180830381600087803b158015611a1357600080fd5b505af1158015611a27573d6000803e3d6000fd5b505050505050505050505050565b606081600003611a7857505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611aa25780611a8c81612673565b9150611a9b9050600a836126da565b9150611a7c565b60008167ffffffffffffffff811115611abd57611abd6126ee565b6040519080825280601f01601f191660200182016040528015611ae7576020820181803683370190505b5090505b8415611b6a57611afc6001836124cf565b9150611b09600a8661271d565b611b149060306125fe565b60f81b818381518110611b2957611b29612731565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611b63600a866126da565b9450611aeb565b949350505050565b6000611b7d83611cff565b8015611b8e5750611b8e8383611d63565b9392505050565b6000611bf7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611e329092919063ffffffff16565b805190915015610aa65780806020019051810190611c159190612760565b610aa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610166565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112e69085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611447565b6000611d2b827f01ffc9a700000000000000000000000000000000000000000000000000000000611d63565b80156113485750611d5c827fffffffff00000000000000000000000000000000000000000000000000000000611d63565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015611e1b575060208210155b8015611e275750600081115b979650505050505050565b6060611b6a84846000858573ffffffffffffffffffffffffffffffffffffffff85163b611ebb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610166565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ee49190612782565b60006040518083038185875af1925050503d8060008114611f21576040519150601f19603f3d011682016040523d82523d6000602084013e611f26565b606091505b5091509150611e2782828660608315611f40575081611b8e565b825115611f505782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161016691906122aa565b73ffffffffffffffffffffffffffffffffffffffff81168114611fa657600080fd5b50565b60008083601f840112611fbb57600080fd5b50813567ffffffffffffffff811115611fd357600080fd5b602083019150836020828501011115611feb57600080fd5b9250929050565b600080600080600080600060c0888a03121561200d57600080fd5b873561201881611f84565b9650602088013561202881611f84565b9550604088013561203881611f84565b9450606088013561204881611f84565b93506080880135925060a088013567ffffffffffffffff81111561206b57600080fd5b6120778a828b01611fa9565b989b979a50959850939692959293505050565b803563ffffffff8116811461209e57600080fd5b919050565b6000806000604084860312156120b857600080fd5b6120c18461208a565b9250602084013567ffffffffffffffff8111156120dd57600080fd5b6120e986828701611fa9565b9497909650939450505050565b60008060008060006080868803121561210e57600080fd5b853561211981611f84565b9450602086013561212981611f84565b935060408601359250606086013567ffffffffffffffff81111561214c57600080fd5b61215888828901611fa9565b969995985093965092949392505050565b60008060008060006080868803121561218157600080fd5b853561218c81611f84565b9450602086013593506121a16040870161208a565b9250606086013567ffffffffffffffff81111561214c57600080fd5b600080600080600080600060c0888a0312156121d857600080fd5b87356121e381611f84565b965060208801356121f381611f84565b9550604088013561220381611f84565b9450606088013593506122186080890161208a565b925060a088013567ffffffffffffffff81111561206b57600080fd5b60005b8381101561224f578181015183820152602001612237565b838111156112e65750506000910152565b60008151808452612278816020860160208601612234565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611b8e6020830184612260565b60008060008060008060a087890312156122d657600080fd5b86356122e181611f84565b955060208701356122f181611f84565b9450604087013593506123066060880161208a565b9250608087013567ffffffffffffffff81111561232257600080fd5b61232e89828a01611fa9565b979a9699509497509295939492505050565b6000806040838503121561235357600080fd5b823561235e81611f84565b9150602083013561236e81611f84565b809150509250929050565b6000806000806060858703121561238f57600080fd5b843561239a81611f84565b93506123a86020860161208a565b9250604085013567ffffffffffffffff8111156123c457600080fd5b6123d087828801611fa9565b95989497509550505050565b828152604060208201526000611b6a6040830184612260565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526124346080830184612260565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061246d6060830185612260565b905063ffffffff83166040830152949350505050565b60006020828403121561249557600080fd5b8151611b8e81611f84565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156124e1576124e16124a0565b500390565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006124346060830184866124e6565b83815260406020820152600061257f6040830184866124e6565b95945050505050565b6000845161259a818460208901612234565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516125d6816001850160208a01612234565b600192019182015283516125f1816002840160208801612234565b0160020195945050505050565b60008219821115612611576126116124a0565b500190565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261266660c0830184866124e6565b9998505050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036126a4576126a46124a0565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826126e9576126e96126ab565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008261272c5761272c6126ab565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561277257600080fd5b81518015158114611b8e57600080fd5b60008251612794818460208701612234565b919091019291505056fea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(L2StandardBridgeStorageLayoutJSON), L2StandardBridgeStorageLayout); err != nil {
......
......@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const L2ToL1MessagePasserStorageLayoutJSON = "{\"storage\":[{\"astId\":2593,\"contract\":\"contracts/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser\",\"label\":\"sentMessages\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":2596,\"contract\":\"contracts/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser\",\"label\":\"nonce\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"}],\"types\":{\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
const L2ToL1MessagePasserStorageLayoutJSON = "{\"storage\":[{\"astId\":2546,\"contract\":\"contracts/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser\",\"label\":\"sentMessages\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":2549,\"contract\":\"contracts/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser\",\"label\":\"nonce\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"}],\"types\":{\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
var L2ToL1MessagePasserStorageLayout = new(solc.StorageLayout)
......
......@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const LegacyERC20ETHStorageLayoutJSON = "{\"storage\":[{\"astId\":28114,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_balances\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_address,t_uint256)\"},{\"astId\":28120,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_allowances\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":28122,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_totalSupply\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":28124,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_name\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_string_storage\"},{\"astId\":28126,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_symbol\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_string_storage\"},{\"astId\":25273,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"remoteToken\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_address\"},{\"astId\":25276,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"bridge\",\"offset\":0,\"slot\":\"6\",\"type\":\"t_address\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_string_storage\":{\"encoding\":\"bytes\",\"label\":\"string\",\"numberOfBytes\":\"32\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
const LegacyERC20ETHStorageLayoutJSON = "{\"storage\":[{\"astId\":27934,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_balances\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_address,t_uint256)\"},{\"astId\":27940,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_allowances\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":27942,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_totalSupply\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":27944,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_name\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_string_storage\"},{\"astId\":27946,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_symbol\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_string_storage\"},{\"astId\":25198,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"remoteToken\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_address\"},{\"astId\":25201,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"bridge\",\"offset\":0,\"slot\":\"6\",\"type\":\"t_address\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_string_storage\":{\"encoding\":\"bytes\",\"label\":\"string\",\"numberOfBytes\":\"32\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
var LegacyERC20ETHStorageLayout = new(solc.StorageLayout)
......
......@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const LegacyMessagePasserStorageLayoutJSON = "{\"storage\":[{\"astId\":3543,\"contract\":\"contracts/legacy/LegacyMessagePasser.sol:LegacyMessagePasser\",\"label\":\"sentMessages\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_bytes32,t_bool)\"}],\"types\":{\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"}}}"
const LegacyMessagePasserStorageLayoutJSON = "{\"storage\":[{\"astId\":3496,\"contract\":\"contracts/legacy/LegacyMessagePasser.sol:LegacyMessagePasser\",\"label\":\"sentMessages\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_bytes32,t_bool)\"}],\"types\":{\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"}}}"
var LegacyMessagePasserStorageLayout = new(solc.StorageLayout)
......
......@@ -30,8 +30,8 @@ var (
// OptimismMintableERC20FactoryMetaData contains all meta data concerning the OptimismMintableERC20Factory contract.
var OptimismMintableERC20FactoryMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\"}],\"name\":\"OptimismMintableERC20Created\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"StandardL2TokenCreated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"createOptimismMintableERC20\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"createStandardL2Token\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
Bin: "0x60a060405234801561001057600080fd5b50604051611baa380380611baa83398101604081905261002f91610040565b6001600160a01b0316608052610070565b60006020828403121561005257600080fd5b81516001600160a01b038116811461006957600080fd5b9392505050565b608051611b1961009160003960008181609a015261017e0152611b196000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063896f93d114610046578063ce5ac90f14610082578063e78cea9214610095575b600080fd5b610059610054366004610371565b6100bc565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b610059610090366004610371565b6100d1565b6100597f000000000000000000000000000000000000000000000000000000000000000081565b60006100c98484846100d1565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff841661017a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e206164647265737300606482015260840160405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000008585856040516101ac9061028a565b6101b9949392919061046b565b604051809103906000f0801580156101d5573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80871691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a3949350505050565b61164b806104c283390190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126102d757600080fd5b813567ffffffffffffffff808211156102f2576102f2610297565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561033857610338610297565b8160405283815286602085880101111561035157600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561038657600080fd5b833573ffffffffffffffffffffffffffffffffffffffff811681146103aa57600080fd5b9250602084013567ffffffffffffffff808211156103c757600080fd5b6103d3878388016102c6565b935060408601359150808211156103e957600080fd5b506103f6868287016102c6565b9150509250925092565b6000815180845260005b818110156104265760208185018101518683018201520161040a565b81811115610438576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250608060408301526104a46080830185610400565b82810360608401526104b68185610400565b97965050505050505056fe60806040523480156200001157600080fd5b506040516200164b3803806200164b833981016040819052620000349162000179565b8181600362000044838262000298565b50600462000053828262000298565b5050600580546001600160a01b039586166001600160a01b03199182161790915560068054969095169516949094179092555062000364915050565b80516001600160a01b0381168114620000a757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000d457600080fd5b81516001600160401b0380821115620000f157620000f1620000ac565b604051601f8301601f19908116603f011681019082821181831017156200011c576200011c620000ac565b816040528381526020925086838588010111156200013957600080fd5b600091505b838210156200015d57858201830151818301840152908201906200013e565b838211156200016f5760008385830101525b9695505050505050565b600080600080608085870312156200019057600080fd5b6200019b856200008f565b9350620001ab602086016200008f565b60408601519093506001600160401b0380821115620001c957600080fd5b620001d788838901620000c2565b93506060870151915080821115620001ee57600080fd5b50620001fd87828801620000c2565b91505092959194509250565b600181811c908216806200021e57607f821691505b6020821081036200023f57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029357600081815260208120601f850160051c810160208610156200026e5750805b601f850160051c820191505b818110156200028f578281556001016200027a565b5050505b505050565b81516001600160401b03811115620002b457620002b4620000ac565b620002cc81620002c5845462000209565b8462000245565b602080601f831160018114620003045760008415620002eb5750858301515b600019600386901b1c1916600185901b1785556200028f565b600085815260208120601f198616915b82811015620003355788860151825594840194600190910190840162000314565b5085821015620003545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6112d780620003746000396000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c806395d89b41116100b2578063ae1f6aaf11610081578063d6c0b2c411610066578063d6c0b2c4146102bb578063dd62ed3e146102db578063e78cea921461032157600080fd5b8063ae1f6aaf1461025e578063c01e1bd61461029d57600080fd5b806395d89b411461021d5780639dc29fac14610225578063a457c2d714610238578063a9059cbb1461024b57600080fd5b806323b872dd1161010957806339509351116100ee57806339509351146101bf57806340c10f19146101d257806370a08231146101e757600080fd5b806323b872dd1461019d578063313ce567146101b057600080fd5b806301ffc9a71461013b57806306fdde0314610163578063095ea7b31461017857806318160ddd1461018b575b600080fd5b61014e610149366004611080565b610341565b60405190151581526020015b60405180910390f35b61016b610432565b60405161015a91906110c9565b61014e610186366004611165565b6104c4565b6002545b60405190815260200161015a565b61014e6101ab36600461118f565b6104dc565b6040516012815260200161015a565b61014e6101cd366004611165565b610500565b6101e56101e0366004611165565b61054c565b005b61018f6101f53660046111cb565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61016b610656565b6101e5610233366004611165565b610665565b61014e610246366004611165565b61075e565b61014e610259366004611165565b61082f565b60065473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161015a565b60055473ffffffffffffffffffffffffffffffffffffffff16610278565b6005546102789073ffffffffffffffffffffffffffffffffffffffff1681565b61018f6102e93660046111e6565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6006546102789073ffffffffffffffffffffffffffffffffffffffff1681565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806103fa57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b8061042957507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461044190611219565b80601f016020809104026020016040519081016040528092919081815260200182805461046d90611219565b80156104ba5780601f1061048f576101008083540402835291602001916104ba565b820191906000526020600020905b81548152906001019060200180831161049d57829003601f168201915b5050505050905090565b6000336104d281858561083d565b5060019392505050565b6000336104ea8582856109f1565b6104f5858585610ac8565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104d2908290869061054790879061129b565b61083d565b60065473ffffffffffffffffffffffffffffffffffffffff1633146105f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106028282610d7b565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161064a91815260200190565b60405180910390a25050565b60606004805461044190611219565b60065473ffffffffffffffffffffffffffffffffffffffff16331461070c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016105ef565b6107168282610e9b565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161064a91815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016105ef565b6104f5828686840361083d565b6000336104d2818585610ac8565b73ffffffffffffffffffffffffffffffffffffffff83166108df576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff8216610982576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610ac25781811015610ab5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016105ef565b610ac2848484840361083d565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610b6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff8216610c0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610cc4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610d0890849061129b565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610d6e91815260200190565b60405180910390a3610ac2565b73ffffffffffffffffffffffffffffffffffffffff8216610df8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016105ef565b8060026000828254610e0a919061129b565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610e4490849061129b565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8216610f3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610ff4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906110309084906112b3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020016109e4565b60006020828403121561109257600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146110c257600080fd5b9392505050565b600060208083528351808285015260005b818110156110f6578581018301518582016040015282016110da565b81811115611108576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461116057600080fd5b919050565b6000806040838503121561117857600080fd5b6111818361113c565b946020939093013593505050565b6000806000606084860312156111a457600080fd5b6111ad8461113c565b92506111bb6020850161113c565b9150604084013590509250925092565b6000602082840312156111dd57600080fd5b6110c28261113c565b600080604083850312156111f957600080fd5b6112028361113c565b91506112106020840161113c565b90509250929050565b600181811c9082168061122d57607f821691505b602082108103611266577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156112ae576112ae61126c565b500190565b6000828210156112c5576112c561126c565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a",
ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\"}],\"name\":\"OptimismMintableERC20Created\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"StandardL2TokenCreated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"createOptimismMintableERC20\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"createStandardL2Token\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
Bin: "0x61010060405234801561001157600080fd5b50604051611ffc380380611ffc83398101604081905261003091610050565b6000608081905260a052600160c0526001600160a01b031660e052610080565b60006020828403121561006257600080fd5b81516001600160a01b038116811461007957600080fd5b9392505050565b60805160a05160c05160e051611f3e6100be6000396000818160d3015261026501526000610153015260006101280152600060fd0152611f3e6000f3fe60806040523480156200001157600080fd5b5060043610620000525760003560e01c806354fd4d501462000057578063896f93d11462000079578063ce5ac90f14620000b6578063e78cea9214620000cd575b600080fd5b62000061620000f5565b60405162000070919062000550565b60405180910390f35b620000906200008a3660046200064e565b620001a0565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200162000070565b62000090620000c73660046200064e565b620001b7565b620000907f000000000000000000000000000000000000000000000000000000000000000081565b6060620001227f000000000000000000000000000000000000000000000000000000000000000062000376565b6200014d7f000000000000000000000000000000000000000000000000000000000000000062000376565b620001787f000000000000000000000000000000000000000000000000000000000000000062000376565b6040516020016200018c93929190620006e5565b604051602081830303815290604052905090565b6000620001af848484620001b7565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff841662000261576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e206164647265737300606482015260840160405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000008585856040516200029590620004c3565b620002a4949392919062000761565b604051809103906000f080158015620002c1573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80871691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a3949350505050565b606081600003620003ba57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115620003ea5780620003d181620007ea565b9150620003e29050600a8362000854565b9150620003be565b60008167ffffffffffffffff8111156200040857620004086200056c565b6040519080825280601f01601f19166020018201604052801562000433576020820181803683370190505b5090505b8415620001af576200044b6001836200086b565b91506200045a600a8662000885565b620004679060306200089c565b60f81b8183815181106200047f576200047f620008b7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350620004bb600a8662000854565b945062000437565b61164b80620008e783390190565b60005b83811015620004ee578181015183820152602001620004d4565b83811115620004fe576000848401525b50505050565b600081518084526200051e816020860160208601620004d1565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600062000565602083018462000504565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112620005ad57600080fd5b813567ffffffffffffffff80821115620005cb57620005cb6200056c565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156200061457620006146200056c565b816040528381528660208588010111156200062e57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200066457600080fd5b833573ffffffffffffffffffffffffffffffffffffffff811681146200068957600080fd5b9250602084013567ffffffffffffffff80821115620006a757600080fd5b620006b5878388016200059b565b93506040860135915080821115620006cc57600080fd5b50620006db868287016200059b565b9150509250925092565b60008451620006f9818460208901620004d1565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855162000737816001850160208a01620004d1565b6001920191820152835162000754816002840160208801620004d1565b0160020195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250608060408301526200079c608083018562000504565b8281036060840152620007b0818562000504565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036200081e576200081e620007bb565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008262000866576200086662000825565b500490565b600082821015620008805762000880620007bb565b500390565b60008262000897576200089762000825565b500690565b60008219821115620008b257620008b2620007bb565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfe60806040523480156200001157600080fd5b506040516200164b3803806200164b833981016040819052620000349162000179565b8181600362000044838262000298565b50600462000053828262000298565b5050600580546001600160a01b039586166001600160a01b03199182161790915560068054969095169516949094179092555062000364915050565b80516001600160a01b0381168114620000a757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000d457600080fd5b81516001600160401b0380821115620000f157620000f1620000ac565b604051601f8301601f19908116603f011681019082821181831017156200011c576200011c620000ac565b816040528381526020925086838588010111156200013957600080fd5b600091505b838210156200015d57858201830151818301840152908201906200013e565b838211156200016f5760008385830101525b9695505050505050565b600080600080608085870312156200019057600080fd5b6200019b856200008f565b9350620001ab602086016200008f565b60408601519093506001600160401b0380821115620001c957600080fd5b620001d788838901620000c2565b93506060870151915080821115620001ee57600080fd5b50620001fd87828801620000c2565b91505092959194509250565b600181811c908216806200021e57607f821691505b6020821081036200023f57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029357600081815260208120601f850160051c810160208610156200026e5750805b601f850160051c820191505b818110156200028f578281556001016200027a565b5050505b505050565b81516001600160401b03811115620002b457620002b4620000ac565b620002cc81620002c5845462000209565b8462000245565b602080601f831160018114620003045760008415620002eb5750858301515b600019600386901b1c1916600185901b1785556200028f565b600085815260208120601f198616915b82811015620003355788860151825594840194600190910190840162000314565b5085821015620003545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6112d780620003746000396000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c806395d89b41116100b2578063ae1f6aaf11610081578063d6c0b2c411610066578063d6c0b2c4146102bb578063dd62ed3e146102db578063e78cea921461032157600080fd5b8063ae1f6aaf1461025e578063c01e1bd61461029d57600080fd5b806395d89b411461021d5780639dc29fac14610225578063a457c2d714610238578063a9059cbb1461024b57600080fd5b806323b872dd1161010957806339509351116100ee57806339509351146101bf57806340c10f19146101d257806370a08231146101e757600080fd5b806323b872dd1461019d578063313ce567146101b057600080fd5b806301ffc9a71461013b57806306fdde0314610163578063095ea7b31461017857806318160ddd1461018b575b600080fd5b61014e610149366004611080565b610341565b60405190151581526020015b60405180910390f35b61016b610432565b60405161015a91906110c9565b61014e610186366004611165565b6104c4565b6002545b60405190815260200161015a565b61014e6101ab36600461118f565b6104dc565b6040516012815260200161015a565b61014e6101cd366004611165565b610500565b6101e56101e0366004611165565b61054c565b005b61018f6101f53660046111cb565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61016b610656565b6101e5610233366004611165565b610665565b61014e610246366004611165565b61075e565b61014e610259366004611165565b61082f565b60065473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161015a565b60055473ffffffffffffffffffffffffffffffffffffffff16610278565b6005546102789073ffffffffffffffffffffffffffffffffffffffff1681565b61018f6102e93660046111e6565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6006546102789073ffffffffffffffffffffffffffffffffffffffff1681565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806103fa57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b8061042957507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461044190611219565b80601f016020809104026020016040519081016040528092919081815260200182805461046d90611219565b80156104ba5780601f1061048f576101008083540402835291602001916104ba565b820191906000526020600020905b81548152906001019060200180831161049d57829003601f168201915b5050505050905090565b6000336104d281858561083d565b5060019392505050565b6000336104ea8582856109f1565b6104f5858585610ac8565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104d2908290869061054790879061129b565b61083d565b60065473ffffffffffffffffffffffffffffffffffffffff1633146105f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106028282610d7b565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161064a91815260200190565b60405180910390a25050565b60606004805461044190611219565b60065473ffffffffffffffffffffffffffffffffffffffff16331461070c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016105ef565b6107168282610e9b565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161064a91815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016105ef565b6104f5828686840361083d565b6000336104d2818585610ac8565b73ffffffffffffffffffffffffffffffffffffffff83166108df576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff8216610982576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610ac25781811015610ab5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016105ef565b610ac2848484840361083d565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610b6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff8216610c0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610cc4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610d0890849061129b565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610d6e91815260200190565b60405180910390a3610ac2565b73ffffffffffffffffffffffffffffffffffffffff8216610df8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016105ef565b8060026000828254610e0a919061129b565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610e4490849061129b565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8216610f3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610ff4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906110309084906112b3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020016109e4565b60006020828403121561109257600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146110c257600080fd5b9392505050565b600060208083528351808285015260005b818110156110f6578581018301518582016040015282016110da565b81811115611108576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461116057600080fd5b919050565b6000806040838503121561117857600080fd5b6111818361113c565b946020939093013593505050565b6000806000606084860312156111a457600080fd5b6111ad8461113c565b92506111bb6020850161113c565b9150604084013590509250925092565b6000602082840312156111dd57600080fd5b6110c28261113c565b600080604083850312156111f957600080fd5b6112028361113c565b91506112106020840161113c565b90509250929050565b600181811c9082168061122d57607f821691505b602082108103611266577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156112ae576112ae61126c565b500190565b6000828210156112c5576112c561126c565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a",
}
// OptimismMintableERC20FactoryABI is the input ABI used to generate the binding from.
......@@ -232,6 +232,37 @@ func (_OptimismMintableERC20Factory *OptimismMintableERC20FactoryCallerSession)
return _OptimismMintableERC20Factory.Contract.Bridge(&_OptimismMintableERC20Factory.CallOpts)
}
// Version is a free data retrieval call binding the contract method 0x54fd4d50.
//
// Solidity: function version() view returns(string)
func (_OptimismMintableERC20Factory *OptimismMintableERC20FactoryCaller) Version(opts *bind.CallOpts) (string, error) {
var out []interface{}
err := _OptimismMintableERC20Factory.contract.Call(opts, &out, "version")
if err != nil {
return *new(string), err
}
out0 := *abi.ConvertType(out[0], new(string)).(*string)
return out0, err
}
// Version is a free data retrieval call binding the contract method 0x54fd4d50.
//
// Solidity: function version() view returns(string)
func (_OptimismMintableERC20Factory *OptimismMintableERC20FactorySession) Version() (string, error) {
return _OptimismMintableERC20Factory.Contract.Version(&_OptimismMintableERC20Factory.CallOpts)
}
// Version is a free data retrieval call binding the contract method 0x54fd4d50.
//
// Solidity: function version() view returns(string)
func (_OptimismMintableERC20Factory *OptimismMintableERC20FactoryCallerSession) Version() (string, error) {
return _OptimismMintableERC20Factory.Contract.Version(&_OptimismMintableERC20Factory.CallOpts)
}
// CreateOptimismMintableERC20 is a paid mutator transaction binding the contract method 0xce5ac90f.
//
// Solidity: function createOptimismMintableERC20(address _remoteToken, string _name, string _symbol) returns(address)
......
......@@ -13,7 +13,7 @@ const OptimismMintableERC20FactoryStorageLayoutJSON = "{\"storage\":null,\"types
var OptimismMintableERC20FactoryStorageLayout = new(solc.StorageLayout)
var OptimismMintableERC20FactoryDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063896f93d114610046578063ce5ac90f14610082578063e78cea9214610095575b600080fd5b610059610054366004610371565b6100bc565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b610059610090366004610371565b6100d1565b6100597f000000000000000000000000000000000000000000000000000000000000000081565b60006100c98484846100d1565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff841661017a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e206164647265737300606482015260840160405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000008585856040516101ac9061028a565b6101b9949392919061046b565b604051809103906000f0801580156101d5573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80871691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a3949350505050565b61164b806104c283390190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126102d757600080fd5b813567ffffffffffffffff808211156102f2576102f2610297565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561033857610338610297565b8160405283815286602085880101111561035157600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561038657600080fd5b833573ffffffffffffffffffffffffffffffffffffffff811681146103aa57600080fd5b9250602084013567ffffffffffffffff808211156103c757600080fd5b6103d3878388016102c6565b935060408601359150808211156103e957600080fd5b506103f6868287016102c6565b9150509250925092565b6000815180845260005b818110156104265760208185018101518683018201520161040a565b81811115610438576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250608060408301526104a46080830185610400565b82810360608401526104b68185610400565b97965050505050505056fe60806040523480156200001157600080fd5b506040516200164b3803806200164b833981016040819052620000349162000179565b8181600362000044838262000298565b50600462000053828262000298565b5050600580546001600160a01b039586166001600160a01b03199182161790915560068054969095169516949094179092555062000364915050565b80516001600160a01b0381168114620000a757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000d457600080fd5b81516001600160401b0380821115620000f157620000f1620000ac565b604051601f8301601f19908116603f011681019082821181831017156200011c576200011c620000ac565b816040528381526020925086838588010111156200013957600080fd5b600091505b838210156200015d57858201830151818301840152908201906200013e565b838211156200016f5760008385830101525b9695505050505050565b600080600080608085870312156200019057600080fd5b6200019b856200008f565b9350620001ab602086016200008f565b60408601519093506001600160401b0380821115620001c957600080fd5b620001d788838901620000c2565b93506060870151915080821115620001ee57600080fd5b50620001fd87828801620000c2565b91505092959194509250565b600181811c908216806200021e57607f821691505b6020821081036200023f57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029357600081815260208120601f850160051c810160208610156200026e5750805b601f850160051c820191505b818110156200028f578281556001016200027a565b5050505b505050565b81516001600160401b03811115620002b457620002b4620000ac565b620002cc81620002c5845462000209565b8462000245565b602080601f831160018114620003045760008415620002eb5750858301515b600019600386901b1c1916600185901b1785556200028f565b600085815260208120601f198616915b82811015620003355788860151825594840194600190910190840162000314565b5085821015620003545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6112d780620003746000396000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c806395d89b41116100b2578063ae1f6aaf11610081578063d6c0b2c411610066578063d6c0b2c4146102bb578063dd62ed3e146102db578063e78cea921461032157600080fd5b8063ae1f6aaf1461025e578063c01e1bd61461029d57600080fd5b806395d89b411461021d5780639dc29fac14610225578063a457c2d714610238578063a9059cbb1461024b57600080fd5b806323b872dd1161010957806339509351116100ee57806339509351146101bf57806340c10f19146101d257806370a08231146101e757600080fd5b806323b872dd1461019d578063313ce567146101b057600080fd5b806301ffc9a71461013b57806306fdde0314610163578063095ea7b31461017857806318160ddd1461018b575b600080fd5b61014e610149366004611080565b610341565b60405190151581526020015b60405180910390f35b61016b610432565b60405161015a91906110c9565b61014e610186366004611165565b6104c4565b6002545b60405190815260200161015a565b61014e6101ab36600461118f565b6104dc565b6040516012815260200161015a565b61014e6101cd366004611165565b610500565b6101e56101e0366004611165565b61054c565b005b61018f6101f53660046111cb565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61016b610656565b6101e5610233366004611165565b610665565b61014e610246366004611165565b61075e565b61014e610259366004611165565b61082f565b60065473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161015a565b60055473ffffffffffffffffffffffffffffffffffffffff16610278565b6005546102789073ffffffffffffffffffffffffffffffffffffffff1681565b61018f6102e93660046111e6565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6006546102789073ffffffffffffffffffffffffffffffffffffffff1681565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806103fa57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b8061042957507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461044190611219565b80601f016020809104026020016040519081016040528092919081815260200182805461046d90611219565b80156104ba5780601f1061048f576101008083540402835291602001916104ba565b820191906000526020600020905b81548152906001019060200180831161049d57829003601f168201915b5050505050905090565b6000336104d281858561083d565b5060019392505050565b6000336104ea8582856109f1565b6104f5858585610ac8565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104d2908290869061054790879061129b565b61083d565b60065473ffffffffffffffffffffffffffffffffffffffff1633146105f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106028282610d7b565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161064a91815260200190565b60405180910390a25050565b60606004805461044190611219565b60065473ffffffffffffffffffffffffffffffffffffffff16331461070c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016105ef565b6107168282610e9b565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161064a91815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016105ef565b6104f5828686840361083d565b6000336104d2818585610ac8565b73ffffffffffffffffffffffffffffffffffffffff83166108df576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff8216610982576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610ac25781811015610ab5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016105ef565b610ac2848484840361083d565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610b6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff8216610c0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610cc4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610d0890849061129b565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610d6e91815260200190565b60405180910390a3610ac2565b73ffffffffffffffffffffffffffffffffffffffff8216610df8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016105ef565b8060026000828254610e0a919061129b565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610e4490849061129b565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8216610f3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610ff4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906110309084906112b3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020016109e4565b60006020828403121561109257600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146110c257600080fd5b9392505050565b600060208083528351808285015260005b818110156110f6578581018301518582016040015282016110da565b81811115611108576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461116057600080fd5b919050565b6000806040838503121561117857600080fd5b6111818361113c565b946020939093013593505050565b6000806000606084860312156111a457600080fd5b6111ad8461113c565b92506111bb6020850161113c565b9150604084013590509250925092565b6000602082840312156111dd57600080fd5b6110c28261113c565b600080604083850312156111f957600080fd5b6112028361113c565b91506112106020840161113c565b90509250929050565b600181811c9082168061122d57607f821691505b602082108103611266577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156112ae576112ae61126c565b500190565b6000828210156112c5576112c561126c565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a"
var OptimismMintableERC20FactoryDeployedBin = "0x60806040523480156200001157600080fd5b5060043610620000525760003560e01c806354fd4d501462000057578063896f93d11462000079578063ce5ac90f14620000b6578063e78cea9214620000cd575b600080fd5b62000061620000f5565b60405162000070919062000550565b60405180910390f35b620000906200008a3660046200064e565b620001a0565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200162000070565b62000090620000c73660046200064e565b620001b7565b620000907f000000000000000000000000000000000000000000000000000000000000000081565b6060620001227f000000000000000000000000000000000000000000000000000000000000000062000376565b6200014d7f000000000000000000000000000000000000000000000000000000000000000062000376565b620001787f000000000000000000000000000000000000000000000000000000000000000062000376565b6040516020016200018c93929190620006e5565b604051602081830303815290604052905090565b6000620001af848484620001b7565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff841662000261576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e206164647265737300606482015260840160405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000008585856040516200029590620004c3565b620002a4949392919062000761565b604051809103906000f080158015620002c1573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80871691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a3949350505050565b606081600003620003ba57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115620003ea5780620003d181620007ea565b9150620003e29050600a8362000854565b9150620003be565b60008167ffffffffffffffff8111156200040857620004086200056c565b6040519080825280601f01601f19166020018201604052801562000433576020820181803683370190505b5090505b8415620001af576200044b6001836200086b565b91506200045a600a8662000885565b620004679060306200089c565b60f81b8183815181106200047f576200047f620008b7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350620004bb600a8662000854565b945062000437565b61164b80620008e783390190565b60005b83811015620004ee578181015183820152602001620004d4565b83811115620004fe576000848401525b50505050565b600081518084526200051e816020860160208601620004d1565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600062000565602083018462000504565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112620005ad57600080fd5b813567ffffffffffffffff80821115620005cb57620005cb6200056c565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156200061457620006146200056c565b816040528381528660208588010111156200062e57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200066457600080fd5b833573ffffffffffffffffffffffffffffffffffffffff811681146200068957600080fd5b9250602084013567ffffffffffffffff80821115620006a757600080fd5b620006b5878388016200059b565b93506040860135915080821115620006cc57600080fd5b50620006db868287016200059b565b9150509250925092565b60008451620006f9818460208901620004d1565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855162000737816001850160208a01620004d1565b6001920191820152835162000754816002840160208801620004d1565b0160020195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250608060408301526200079c608083018562000504565b8281036060840152620007b0818562000504565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036200081e576200081e620007bb565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008262000866576200086662000825565b500490565b600082821015620008805762000880620007bb565b500390565b60008262000897576200089762000825565b500690565b60008219821115620008b257620008b2620007bb565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfe60806040523480156200001157600080fd5b506040516200164b3803806200164b833981016040819052620000349162000179565b8181600362000044838262000298565b50600462000053828262000298565b5050600580546001600160a01b039586166001600160a01b03199182161790915560068054969095169516949094179092555062000364915050565b80516001600160a01b0381168114620000a757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000d457600080fd5b81516001600160401b0380821115620000f157620000f1620000ac565b604051601f8301601f19908116603f011681019082821181831017156200011c576200011c620000ac565b816040528381526020925086838588010111156200013957600080fd5b600091505b838210156200015d57858201830151818301840152908201906200013e565b838211156200016f5760008385830101525b9695505050505050565b600080600080608085870312156200019057600080fd5b6200019b856200008f565b9350620001ab602086016200008f565b60408601519093506001600160401b0380821115620001c957600080fd5b620001d788838901620000c2565b93506060870151915080821115620001ee57600080fd5b50620001fd87828801620000c2565b91505092959194509250565b600181811c908216806200021e57607f821691505b6020821081036200023f57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029357600081815260208120601f850160051c810160208610156200026e5750805b601f850160051c820191505b818110156200028f578281556001016200027a565b5050505b505050565b81516001600160401b03811115620002b457620002b4620000ac565b620002cc81620002c5845462000209565b8462000245565b602080601f831160018114620003045760008415620002eb5750858301515b600019600386901b1c1916600185901b1785556200028f565b600085815260208120601f198616915b82811015620003355788860151825594840194600190910190840162000314565b5085821015620003545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6112d780620003746000396000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c806395d89b41116100b2578063ae1f6aaf11610081578063d6c0b2c411610066578063d6c0b2c4146102bb578063dd62ed3e146102db578063e78cea921461032157600080fd5b8063ae1f6aaf1461025e578063c01e1bd61461029d57600080fd5b806395d89b411461021d5780639dc29fac14610225578063a457c2d714610238578063a9059cbb1461024b57600080fd5b806323b872dd1161010957806339509351116100ee57806339509351146101bf57806340c10f19146101d257806370a08231146101e757600080fd5b806323b872dd1461019d578063313ce567146101b057600080fd5b806301ffc9a71461013b57806306fdde0314610163578063095ea7b31461017857806318160ddd1461018b575b600080fd5b61014e610149366004611080565b610341565b60405190151581526020015b60405180910390f35b61016b610432565b60405161015a91906110c9565b61014e610186366004611165565b6104c4565b6002545b60405190815260200161015a565b61014e6101ab36600461118f565b6104dc565b6040516012815260200161015a565b61014e6101cd366004611165565b610500565b6101e56101e0366004611165565b61054c565b005b61018f6101f53660046111cb565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61016b610656565b6101e5610233366004611165565b610665565b61014e610246366004611165565b61075e565b61014e610259366004611165565b61082f565b60065473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161015a565b60055473ffffffffffffffffffffffffffffffffffffffff16610278565b6005546102789073ffffffffffffffffffffffffffffffffffffffff1681565b61018f6102e93660046111e6565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6006546102789073ffffffffffffffffffffffffffffffffffffffff1681565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806103fa57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b8061042957507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461044190611219565b80601f016020809104026020016040519081016040528092919081815260200182805461046d90611219565b80156104ba5780601f1061048f576101008083540402835291602001916104ba565b820191906000526020600020905b81548152906001019060200180831161049d57829003601f168201915b5050505050905090565b6000336104d281858561083d565b5060019392505050565b6000336104ea8582856109f1565b6104f5858585610ac8565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104d2908290869061054790879061129b565b61083d565b60065473ffffffffffffffffffffffffffffffffffffffff1633146105f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106028282610d7b565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161064a91815260200190565b60405180910390a25050565b60606004805461044190611219565b60065473ffffffffffffffffffffffffffffffffffffffff16331461070c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016105ef565b6107168282610e9b565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161064a91815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016105ef565b6104f5828686840361083d565b6000336104d2818585610ac8565b73ffffffffffffffffffffffffffffffffffffffff83166108df576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff8216610982576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610ac25781811015610ab5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016105ef565b610ac2848484840361083d565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610b6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff8216610c0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610cc4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610d0890849061129b565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610d6e91815260200190565b60405180910390a3610ac2565b73ffffffffffffffffffffffffffffffffffffffff8216610df8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016105ef565b8060026000828254610e0a919061129b565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610e4490849061129b565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8216610f3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610ff4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016105ef565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906110309084906112b3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020016109e4565b60006020828403121561109257600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146110c257600080fd5b9392505050565b600060208083528351808285015260005b818110156110f6578581018301518582016040015282016110da565b81811115611108576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461116057600080fd5b919050565b6000806040838503121561117857600080fd5b6111818361113c565b946020939093013593505050565b6000806000606084860312156111a457600080fd5b6111ad8461113c565b92506111bb6020850161113c565b9150604084013590509250925092565b6000602082840312156111dd57600080fd5b6110c28261113c565b600080604083850312156111f957600080fd5b6112028361113c565b91506112106020840161113c565b90509250929050565b600181811c9082168061122d57607f821691505b602082108103611266577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156112ae576112ae61126c565b500190565b6000828210156112c5576112c561126c565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(OptimismMintableERC20FactoryStorageLayoutJSON), OptimismMintableERC20FactoryStorageLayout); err != nil {
......
......@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const OptimismPortalStorageLayoutJSON = "{\"storage\":[{\"astId\":27292,\"contract\":\"contracts/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":27295,\"contract\":\"contracts/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1404,\"contract\":\"contracts/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"params\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_struct(ResourceParams)1374_storage\"},{\"astId\":1409,\"contract\":\"contracts/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":982,\"contract\":\"contracts/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"l2Sender\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":995,\"contract\":\"contracts/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"finalizedWithdrawals\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_mapping(t_bytes32,t_bool)\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_struct(ResourceParams)1374_storage\":{\"encoding\":\"inplace\",\"label\":\"struct ResourceMetering.ResourceParams\",\"numberOfBytes\":\"32\"},\"t_uint128\":{\"encoding\":\"inplace\",\"label\":\"uint128\",\"numberOfBytes\":\"16\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint64\":{\"encoding\":\"inplace\",\"label\":\"uint64\",\"numberOfBytes\":\"8\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}"
const OptimismPortalStorageLayoutJSON = "{\"storage\":[{\"astId\":27112,\"contract\":\"contracts/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":27115,\"contract\":\"contracts/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1404,\"contract\":\"contracts/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"params\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_struct(ResourceParams)1374_storage\"},{\"astId\":1409,\"contract\":\"contracts/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":982,\"contract\":\"contracts/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"l2Sender\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":995,\"contract\":\"contracts/L1/OptimismPortal.sol:OptimismPortal\",\"label\":\"finalizedWithdrawals\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_mapping(t_bytes32,t_bool)\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_struct(ResourceParams)1374_storage\":{\"encoding\":\"inplace\",\"label\":\"struct ResourceMetering.ResourceParams\",\"numberOfBytes\":\"32\"},\"t_uint128\":{\"encoding\":\"inplace\",\"label\":\"uint128\",\"numberOfBytes\":\"16\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint64\":{\"encoding\":\"inplace\",\"label\":\"uint64\",\"numberOfBytes\":\"8\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}"
var OptimismPortalStorageLayout = new(solc.StorageLayout)
......
......@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const SequencerFeeVaultStorageLayoutJSON = "{\"storage\":[{\"astId\":2741,\"contract\":\"contracts/L2/SequencerFeeVault.sol:SequencerFeeVault\",\"label\":\"l1FeeWallet\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"}}}"
const SequencerFeeVaultStorageLayoutJSON = "{\"storage\":[{\"astId\":2694,\"contract\":\"contracts/L2/SequencerFeeVault.sol:SequencerFeeVault\",\"label\":\"l1FeeWallet\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"}}}"
var SequencerFeeVaultStorageLayout = new(solc.StorageLayout)
......
......@@ -40,6 +40,6 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd
// github.com/ethereum-optimism/op-geth v0.0.0-20220909213840-e6575c0168f1
......@@ -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/op-geth v0.0.0-20220921202220-511148385c73 h1:eXnnByFF0QiN1Qrq0wYmvI5lbDM8QQM0pv6AHx2FLnk=
github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo=
github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd h1:NchOnosWOkH9wlix8QevGHE+6vuRa+OMGvDNsczv2kQ=
github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo=
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=
......
package crossdomain
import (
"github.com/holiman/uint256"
"github.com/ethereum/go-ethereum/common"
)
var (
uint160Max, _ = uint256.FromHex("0xffffffffffffffffffffffffffffffffffffffff")
offset = new(uint256.Int).SetBytes(common.HexToAddress("0x1111000000000000000000000000000000001111").Bytes())
)
// ApplyL1ToL2Alias will apply the alias applied to L1 to L2 messages when it
// originates from a contract address
func ApplyL1ToL2Alias(address *common.Address) *common.Address {
input := new(uint256.Int).SetBytes(address.Bytes())
output := new(uint256.Int).AddMod(input, offset, uint160Max)
if output.Cmp(input) < 0 {
output = output.Sub(output, new(uint256.Int).SetUint64(1))
}
addr := common.BigToAddress(output.ToBig())
return &addr
}
// UndoL1ToL2Alias will remove the alias applied to L1 to L2 messages when it
// originates from a contract address
func UndoL1ToL2Alias(address *common.Address) *common.Address {
input := new(uint256.Int).SetBytes(address.Bytes())
output := new(uint256.Int).Sub(input, offset)
addr := common.BigToAddress(output.ToBig())
return &addr
}
package crossdomain_test
import (
"fmt"
"testing"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
func FuzzAliasing(f *testing.F) {
f.Fuzz(func(t *testing.T, address []byte) {
addr := common.BytesToAddress(address)
aliased := crossdomain.ApplyL1ToL2Alias(&addr)
unaliased := crossdomain.UndoL1ToL2Alias(aliased)
require.Equal(t, addr, *unaliased)
})
}
func TestAliasing(t *testing.T) {
cases := []struct {
Input common.Address
Output common.Address
}{
{
Input: common.HexToAddress("0x24eb0f74a434b2f4f07744652630ce90367aab71"),
Output: common.HexToAddress("0x35fc0f74a434b2f4f07744652630ce90367abc82"),
},
{
Input: common.HexToAddress("0xd3f11e293c353bd07ce8fd89e911180e12a7eb77"),
Output: common.HexToAddress("0xe5021e293c353bd07ce8fd89e911180e12a7fc88"),
},
{
Input: common.HexToAddress("0xa900b52694dfa5de7255e9b0b6161ec3cc522fed"),
Output: common.HexToAddress("0xba11b52694dfa5de7255e9b0b6161ec3cc5240fe"),
},
{
Input: common.HexToAddress("0xffffffffffffffffffffffffffffffffffffffff"),
Output: common.HexToAddress("0x1111000000000000000000000000000000001110"),
},
{
Input: common.HexToAddress("0x0000000000000000000000000000000000000041"),
Output: common.HexToAddress("0x1111000000000000000000000000000000001152"),
},
{
Input: common.HexToAddress("0x4c0aa49c57716406043f97c087a72fe96397959b"),
Output: common.HexToAddress("0x5d1ba49c57716406043f97c087a72fe96397a6ac"),
},
}
for i, test := range cases {
t.Run(fmt.Sprintf("test%d", i), func(t *testing.T) {
aliased := crossdomain.ApplyL1ToL2Alias(&test.Input)
require.Equal(t, test.Output, *aliased)
unaliased := crossdomain.UndoL1ToL2Alias(aliased)
require.Equal(t, test.Input, *unaliased)
})
}
}
package crossdomain
import (
"bytes"
"errors"
"fmt"
"math/big"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
// LegacyWithdrawal represents a pre bedrock upgrade withdrawal.
type LegacyWithdrawal struct {
Target *common.Address
Sender *common.Address
Data []byte
Nonce *big.Int
}
var _ WithdrawalMessage = (*LegacyWithdrawal)(nil)
// NewLegacyWithdrawal will construct a LegacyWithdrawal
func NewLegacyWithdrawal(target, sender *common.Address, data []byte, nonce *big.Int) *LegacyWithdrawal {
return &LegacyWithdrawal{
Target: target,
Sender: sender,
Data: data,
Nonce: nonce,
}
}
// Encode will serialze the Withdrawal in the legacy format so that it
// is suitable for hashing. This assumes that the message is being withdrawn
// through the standard optimism cross domain messaging system by hashing in
// the L2CrossDomainMessenger address.
func (w *LegacyWithdrawal) Encode() ([]byte, error) {
enc, err := EncodeCrossDomainMessageV0(w.Target, w.Sender, w.Data, w.Nonce)
if err != nil {
return nil, err
}
out := make([]byte, len(enc)+len(predeploys.L2CrossDomainMessengerAddr.Bytes()))
copy(out, enc)
copy(out[len(enc):], predeploys.L2CrossDomainMessengerAddr.Bytes())
return out, nil
}
// Decode will decode a serialized LegacyWithdrawal
func (w *LegacyWithdrawal) Decode(data []byte) error {
if len(data) < len(predeploys.L2CrossDomainMessengerAddr)+4 {
return fmt.Errorf("withdrawal data too short: %d", len(data))
}
selector := crypto.Keccak256([]byte("relayMessage(address,address,bytes,uint256)"))[0:4]
if !bytes.Equal(data[0:4], selector) {
return fmt.Errorf("invalid selector: 0x%x", data[0:4])
}
msgSender := data[len(data)-len(predeploys.L2CrossDomainMessengerAddr):]
if !bytes.Equal(msgSender, predeploys.L2CrossDomainMessengerAddr.Bytes()) {
return errors.New("invalid msg.sender")
}
raw := data[4 : len(data)-len(predeploys.L2CrossDomainMessengerAddr)]
args := abi.Arguments{
{Name: "target", Type: AddressType},
{Name: "sender", Type: AddressType},
{Name: "data", Type: BytesType},
{Name: "nonce", Type: Uint256Type},
}
decoded, err := args.Unpack(raw)
if err != nil {
return err
}
target, ok := decoded[0].(common.Address)
if !ok {
return errors.New("cannot abi decode target")
}
sender, ok := decoded[1].(common.Address)
if !ok {
return errors.New("cannot abi decode sender")
}
msgData, ok := decoded[2].([]byte)
if !ok {
return errors.New("cannot abi decode data")
}
nonce, ok := decoded[3].(*big.Int)
if !ok {
return errors.New("cannot abi decode nonce")
}
w.Target = &target
w.Sender = &sender
w.Data = msgData
w.Nonce = nonce
return nil
}
// Hash will compute the legacy style hash that is computed in the
// OVM_L2ToL1MessagePasser.
func (w *LegacyWithdrawal) Hash() (common.Hash, error) {
encoded, err := w.Encode()
if err != nil {
return common.Hash{}, nil
}
hash := crypto.Keccak256(encoded)
return common.BytesToHash(hash), nil
}
// StorageSlot will compute the storage slot that is set
// to true in the legacy L2ToL1MessagePasser.
func (w *LegacyWithdrawal) StorageSlot() (common.Hash, error) {
hash, err := w.Hash()
if err != nil {
return common.Hash{}, err
}
preimage := make([]byte, 64)
copy(preimage, hash.Bytes())
slot := crypto.Keccak256(preimage)
return common.BytesToHash(slot), nil
}
package crossdomain_test
import (
"encoding/json"
"fmt"
"math/big"
"os"
"path/filepath"
"strings"
"testing"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/stretchr/testify/require"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
)
// callFrame represents the response returned from geth's
// `debug_traceTransaction` callTracer
type callFrame struct {
Type string `json:"type"`
From string `json:"from"`
To string `json:"to,omitempty"`
Value string `json:"value,omitempty"`
Gas string `json:"gas"`
GasUsed string `json:"gasUsed"`
Input string `json:"input"`
Output string `json:"output,omitempty"`
Error string `json:"error,omitempty"`
Calls []callFrame `json:"calls,omitempty"`
}
// stateDiff represents the response returned from geth's
// `debug_traceTransaction` preStateTracer
type stateDiff map[common.Address]stateDiffAccount
// stateDiffAccount represents a single account in the preStateTracer
type stateDiffAccount struct {
Balance hexutil.Big `json:"balance"`
Code hexutil.Bytes `json:"code"`
Nonce uint64 `json:"nonce"`
Storage map[common.Hash]common.Hash
}
var (
// traces represents a prepopulated map of call traces
traces map[string]*callFrame
// receipts represents a prepopulated map of receipts
receipts map[string]*types.Receipt
// stateDiffs represents a prepopulated map of state diffs
stateDiffs map[string]stateDiff
// passMessageABI is a JSON representation of the legacy L2ToL1MessagePasser ABI
passMessageABI = "[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"passMessageToL1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"
// passMessage represents an initialized L2ToL1MessagePasser ABI
passMessage abi.ABI
// base represents
base = "testdata"
// callTracesPath represents
callTracesPath = filepath.Join(base, "call-traces")
// receiptsPath represents
receiptsPath = filepath.Join(base, "receipts")
// stateDiffsPath represents
stateDiffsPath = filepath.Join(base, "state-diffs")
)
func init() {
traces = make(map[string]*callFrame)
receipts = make(map[string]*types.Receipt)
stateDiffs = make(map[string]stateDiff)
// Read all of the receipt test vectors into memory
if err := readReceipts(); err != nil {
panic(err)
}
// Read all of the transaction trace vectors into memory
if err := readTraces(); err != nil {
panic(err)
}
// Read all of the state diff vectors into memory
if err := readStateDiffs(); err != nil {
panic(err)
}
// Initialze the message passer ABI
var err error
passMessage, err = abi.JSON(strings.NewReader(passMessageABI))
if err != nil {
panic(err)
}
}
// TestWithdrawalLegacyStorageSlot will test that the computation
// of the legacy storage slot is correct. It is done so using real
// test vectors generated from mainnet.
func TestWithdrawalLegacyStorageSlot(t *testing.T) {
for hash, trace := range traces {
t.Run(hash, func(t *testing.T) {
// Given a callTrace, find the call that corresponds
// to L2ToL1MessagePasser.passMessageToL1
call := findPassMessage(trace)
require.NotNil(t, call)
receipt, ok := receipts[hash]
require.True(t, ok)
// Given a receipt, parse the cross domain message
// from its logs
msg, err := findCrossDomainMessage(receipt)
require.Nil(t, err)
// Ensure that it is a version 0 cross domain message
require.Equal(t, uint64(0), msg.Version())
// Encode the cross domain message
encoded, err := msg.Encode()
require.Nil(t, err)
// ABI encode the serialized cross domain message
packed, err := passMessage.Pack("passMessageToL1", encoded)
require.Nil(t, err)
// Decode the calldata where the L2CrossDomainMessenger is calling
// L2ToL1MessagePasser.passMessageToL1 from the callTrace
calldata := hexutil.MustDecode(call.Input)
// If these values are the same, we know for a fact that the
// cross domain message was correctly parsed from the logs.
require.Equal(t, calldata, packed)
// Cast the cross domain message to a withdrawal. Note that
// this only works for legacy style messages
withdrawal, err := msg.ToWithdrawal()
require.Nil(t, err)
// Compute the legacy storage slot for the withdrawal
slot, err := withdrawal.StorageSlot()
require.Nil(t, err)
// Get the state diff that corresponds to this transaction
diff, ok := stateDiffs[hash]
require.True(t, ok)
// Get the account out of the state diff that corresponds
// to the L2ToL1MessagePasser
messagePasser, ok := diff[predeploys.LegacyMessagePasserAddr]
require.True(t, ok)
// The computed storage slot must be in the state diff. Note
// that the built-in preStateTracer includes the storage slots
// that were altered by the transaction but the values are
// the values before any modifications to state by the transaction
_, ok = messagePasser.Storage[slot]
require.True(t, ok)
})
}
}
func FuzzEncodeDecodeLegacyWithdrawal(f *testing.F) {
f.Fuzz(func(t *testing.T, _target, _sender, _nonce, data []byte) {
target := common.BytesToAddress(_target)
sender := common.BytesToAddress(_sender)
nonce := new(big.Int).SetBytes(_nonce)
withdrawal := crossdomain.NewLegacyWithdrawal(&target, &sender, data, nonce)
encoded, err := withdrawal.Encode()
require.Nil(t, err)
var w crossdomain.LegacyWithdrawal
err = w.Decode(encoded)
require.Nil(t, err)
require.Equal(t, withdrawal.Nonce.Uint64(), w.Nonce.Uint64())
require.Equal(t, withdrawal.Sender, w.Sender)
require.Equal(t, withdrawal.Target, w.Target)
require.Equal(t, withdrawal.Data, w.Data)
})
}
// findPassMessage pulls the call from the L2CrossDomainMessenger to the
// L2ToL1MessagePasser out of the call trace. This call is used to assert
// against the calldata
func findPassMessage(trace *callFrame) *callFrame {
isCall := trace.Type == "CALL"
isTarget := trace.To == predeploys.LegacyMessagePasser
isFrom := trace.From == predeploys.L2CrossDomainMessenger
if isCall && isTarget && isFrom {
return trace
}
for _, subcall := range trace.Calls {
if call := findPassMessage(&subcall); call != nil {
return call
}
}
return nil
}
// findCrossDomainMessage will parse a CrossDomainMessage from a receipt
func findCrossDomainMessage(receipt *types.Receipt) (*crossdomain.CrossDomainMessage, error) {
backend := backends.NewSimulatedBackend(nil, 15000000)
l2xdm, err := bindings.NewL2CrossDomainMessenger(predeploys.L2CrossDomainMessengerAddr, backend)
if err != nil {
return nil, err
}
abi, _ := bindings.L2CrossDomainMessengerMetaData.GetAbi()
var msg crossdomain.CrossDomainMessage
seen := false
// Assume there is only 1 deposit per transaction
for _, log := range receipt.Logs {
event, _ := abi.EventByID(log.Topics[0])
// Not the event we are looking for
if event == nil {
continue
}
// Parse the legacy event
if event.Name == "SentMessage" {
e, _ := l2xdm.ParseSentMessage(*log)
msg.Target = &e.Target
msg.Sender = &e.Sender
msg.Data = e.Message
msg.Nonce = e.MessageNonce
msg.GasLimit = e.GasLimit
// Set seen to true to ensure that this event
// was observed
seen = true
}
// Parse the new extension event
if event.Name == "SentMessageExtension1" {
e, _ := l2xdm.ParseSentMessageExtension1(*log)
msg.Value = e.Value
}
}
if seen {
return &msg, nil
} else {
return nil, fmt.Errorf("cannot find receipt for %s", receipt.TxHash)
}
}
// readTraces will read all traces into memory
func readTraces() error {
entries, err := os.ReadDir(callTracesPath)
if err != nil {
return err
}
for _, entry := range entries {
name := entry.Name()
trace, err := readTrace(name)
if err != nil {
return err
}
traces[name] = trace
}
return nil
}
// readReceipts will read all receipts into memory
func readReceipts() error {
entries, err := os.ReadDir(receiptsPath)
if err != nil {
return err
}
for _, entry := range entries {
name := entry.Name()
trace, err := readReceipt(name)
if err != nil {
return err
}
receipts[name] = trace
}
return nil
}
// readStateDiffs will read all state diffs into memory
func readStateDiffs() error {
entries, err := os.ReadDir(stateDiffsPath)
if err != nil {
return err
}
for _, entry := range entries {
name := entry.Name()
diff, err := readStateDiff(name)
if err != nil {
return err
}
stateDiffs[name] = diff
}
return nil
}
// readTrace will read the transaction trace by hash from disk
func readTrace(hash string) (*callFrame, error) {
vector := filepath.Join(callTracesPath, hash)
file, err := os.ReadFile(vector)
if err != nil {
return nil, err
}
var trace callFrame
if err := json.Unmarshal(file, &trace); err != nil {
return nil, err
}
return &trace, nil
}
// readReceipt will read the receipt by hash from disk
func readReceipt(hash string) (*types.Receipt, error) {
vector := filepath.Join(receiptsPath, hash)
file, err := os.ReadFile(vector)
if err != nil {
return nil, err
}
var receipt types.Receipt
if err := json.Unmarshal(file, &receipt); err != nil {
return nil, err
}
return &receipt, nil
}
// readStateDiff will read the state diff by hash from disk
func readStateDiff(hash string) (stateDiff, error) {
vector := filepath.Join(stateDiffsPath, hash)
file, err := os.ReadFile(vector)
if err != nil {
return nil, err
}
var diff stateDiff
if err := json.Unmarshal(file, &diff); err != nil {
return nil, err
}
return diff, nil
}
package crossdomain
import (
"errors"
"fmt"
"math/big"
......@@ -54,7 +55,7 @@ func (c *CrossDomainMessage) Encode() ([]byte, error) {
case 1:
return EncodeCrossDomainMessageV1(c.Nonce, c.Sender, c.Target, c.Value, c.GasLimit, c.Data)
default:
return nil, fmt.Errorf("unknown nonce version %d", version)
return nil, fmt.Errorf("unknown version %d", version)
}
}
......@@ -67,6 +68,26 @@ func (c *CrossDomainMessage) Hash() (common.Hash, error) {
case 1:
return HashCrossDomainMessageV1(c.Nonce, c.Sender, c.Target, c.Value, c.GasLimit, c.Data)
default:
return common.Hash{}, fmt.Errorf("unknown nonce version %d", version)
return common.Hash{}, fmt.Errorf("unknown version %d", version)
}
}
// ToWithdrawal will turn a CrossDomainMessage into a Withdrawal.
// This only works for version 0 CrossDomainMessages as not all of
// the data is present for version 1 CrossDomainMessages to be turned
// into Withdrawals.
func (c *CrossDomainMessage) ToWithdrawal() (WithdrawalMessage, error) {
version := c.Version()
switch version {
case 0:
if c.Value != nil && c.Value.Cmp(common.Big0) != 0 {
return nil, errors.New("version 0 messages must have 0 value")
}
w := NewLegacyWithdrawal(c.Target, c.Sender, c.Data, c.Nonce)
return w, nil
case 1:
return nil, errors.New("version 1 messages cannot be turned into withdrawals")
default:
return nil, fmt.Errorf("unknown version %d", version)
}
}
# crossdomain/testdata
Real world test data is used to generate test vectors for the withdrawal
hashing. The `trace.sh` script will generate artifacts used as part of the
tests. It accepts a single argument, being the transaction hash to fetch
artifacts for. It will fetch a receipt, a call trace and a state diff.
The tests require that a file named after the transaction hash exists
in each of the directories `call-traces`, `receipts` and `state-diffs`.
The `trace.sh` script will ensure that the files are created correctly.
{
"calls": [
{
"from": "0x4200000000000000000000000000000000000010",
"gas": "0x1647d",
"gasUsed": "0x341b",
"input": "0x9dc29fac0000000000000000000000009c8f005ab27adb94f3d49020a15722db2fcd9f2700000000000000000000000000000000000000000000000000232bff5f46c000",
"output": "0x",
"to": "0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000",
"type": "CALL",
"value": "0x0"
},
{
"from": "0x4200000000000000000000000000000000000010",
"gas": "0x12fe8",
"gasUsed": "0x94b",
"input": "0xc01e1bd6",
"output": "0x0000000000000000000000000000000000000000000000000000000000000000",
"to": "0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000",
"type": "CALL",
"value": "0x0"
},
{
"calls": [
{
"from": "0x4200000000000000000000000000000000000007",
"gas": "0x8ea6",
"gasUsed": "0x5e1e",
"input": "0xcafa81dc00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000164cbd4ece900000000000000000000000099c9fc46f92e8a1c0dec1b1747d010903e884be100000000000000000000000042000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000001b04d00000000000000000000000000000000000000000000000000000000000000a41532ec340000000000000000000000009c8f005ab27adb94f3d49020a15722db2fcd9f270000000000000000000000009c8f005ab27adb94f3d49020a15722db2fcd9f2700000000000000000000000000000000000000000000000000232bff5f46c000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"output": "0x",
"to": "0x4200000000000000000000000000000000000000",
"type": "CALL",
"value": "0x0"
}
],
"from": "0x4200000000000000000000000000000000000010",
"gas": "0x10644",
"gasUsed": "0xf29d",
"input": "0x3dbb202b00000000000000000000000099c9fc46f92e8a1c0dec1b1747d010903e884be10000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a41532ec340000000000000000000000009c8f005ab27adb94f3d49020a15722db2fcd9f270000000000000000000000009c8f005ab27adb94f3d49020a15722db2fcd9f2700000000000000000000000000000000000000000000000000232bff5f46c0000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"output": "0x",
"to": "0x4200000000000000000000000000000000000007",
"type": "CALL",
"value": "0x0"
}
],
"from": "0x9c8f005ab27adb94f3d49020a15722db2fcd9f27",
"gas": "0x177d2",
"gasUsed": "0x16ce2",
"input": "0x32b7006d000000000000000000000000deaddeaddeaddeaddeaddeaddeaddeaddead000000000000000000000000000000000000000000000000000000232bff5f46c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
"output": "0x",
"time": "112.522948ms",
"to": "0x4200000000000000000000000000000000000010",
"type": "CALL",
"value": "0x0"
}
{
"calls": [
{
"from": "0x4200000000000000000000000000000000000010",
"gas": "0x318ce",
"gasUsed": "0x427b",
"input": "0x9dc29fac0000000000000000000000003178490d60b5cceaa5a79fd4d9050c7405bab80c0000000000000000000000000000000000000000000000a3b61828488b117259",
"output": "0x",
"to": "0x76fb31fb4af56892a25e32cfc43de717950c9278",
"type": "CALL",
"value": "0x0"
},
{
"from": "0x4200000000000000000000000000000000000010",
"gas": "0x2d612",
"gasUsed": "0xa14",
"input": "0xc01e1bd6",
"output": "0x0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae9",
"to": "0x76fb31fb4af56892a25e32cfc43de717950c9278",
"type": "CALL",
"value": "0x0"
},
{
"calls": [
{
"from": "0x4200000000000000000000000000000000000007",
"gas": "0x22b8c",
"gasUsed": "0x5ecf",
"input": "0xcafa81dc000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001a4cbd4ece900000000000000000000000099c9fc46f92e8a1c0dec1b1747d010903e884be100000000000000000000000042000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000001b04f00000000000000000000000000000000000000000000000000000000000000e4a9f9e6750000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae900000000000000000000000076fb31fb4af56892a25e32cfc43de717950c92780000000000000000000000003178490d60b5cceaa5a79fd4d9050c7405bab80c0000000000000000000000003178490d60b5cceaa5a79fd4d9050c7405bab80c0000000000000000000000000000000000000000000000a3b61828488b11725900000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"output": "0x",
"to": "0x4200000000000000000000000000000000000000",
"type": "CALL",
"value": "0x0"
}
],
"from": "0x4200000000000000000000000000000000000010",
"gas": "0x2aae9",
"gasUsed": "0xf705",
"input": "0x3dbb202b00000000000000000000000099c9fc46f92e8a1c0dec1b1747d010903e884be10000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e4a9f9e6750000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae900000000000000000000000076fb31fb4af56892a25e32cfc43de717950c92780000000000000000000000003178490d60b5cceaa5a79fd4d9050c7405bab80c0000000000000000000000003178490d60b5cceaa5a79fd4d9050c7405bab80c0000000000000000000000000000000000000000000000a3b61828488b11725900000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"output": "0x",
"to": "0x4200000000000000000000000000000000000007",
"type": "CALL",
"value": "0x0"
}
],
"from": "0x3178490d60b5cceaa5a79fd4d9050c7405bab80c",
"gas": "0x33310",
"gasUsed": "0x18136",
"input": "0x32b7006d00000000000000000000000076fb31fb4af56892a25e32cfc43de717950c92780000000000000000000000000000000000000000000000a3b61828488b117259000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
"output": "0x",
"time": "40.447524ms",
"to": "0x4200000000000000000000000000000000000010",
"type": "CALL",
"value": "0x0"
}
{
"calls": [
{
"from": "0x467194771dae2967aef3ecbedd3bf9a310c76c65",
"gas": "0x150b9",
"gasUsed": "0x395f",
"input": "0x9dc29fac0000000000000000000000006659612eb0e2464ccadf7a5e851bcd12873f6e040000000000000000000000000000000000000000000211654585005212800000",
"output": "0x",
"to": "0xda10009cbd5d07dd0cecc66161fc93d7c9000da1",
"type": "CALL",
"value": "0x0"
},
{
"calls": [
{
"from": "0x4200000000000000000000000000000000000007",
"gas": "0x86e2",
"gasUsed": "0x5ecf",
"input": "0xcafa81dc000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001a4cbd4ece900000000000000000000000010e6593cdda8c58a1d0f14c5164b376352a55f2f000000000000000000000000467194771dae2967aef3ecbedd3bf9a310c76c650000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000001b05e00000000000000000000000000000000000000000000000000000000000000e4a9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000006659612eb0e2464ccadf7a5e851bcd12873f6e040000000000000000000000006659612eb0e2464ccadf7a5e851bcd12873f6e04000000000000000000000000000000000000000000021165458500521280000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"output": "0x",
"to": "0x4200000000000000000000000000000000000000",
"type": "CALL",
"value": "0x0"
}
],
"from": "0x467194771dae2967aef3ecbedd3bf9a310c76c65",
"gas": "0xff92",
"gasUsed": "0xf705",
"input": "0x3dbb202b00000000000000000000000010e6593cdda8c58a1d0f14c5164b376352a55f2f0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e4a9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000006659612eb0e2464ccadf7a5e851bcd12873f6e040000000000000000000000006659612eb0e2464ccadf7a5e851bcd12873f6e04000000000000000000000000000000000000000000021165458500521280000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"output": "0x",
"to": "0x4200000000000000000000000000000000000007",
"type": "CALL",
"value": "0x0"
}
],
"from": "0x6659612eb0e2464ccadf7a5e851bcd12873f6e04",
"gas": "0x16bb3",
"gasUsed": "0x16bb3",
"input": "0x32b7006d000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000000000000000000000000211654585005212800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
"output": "0x",
"time": "30.357952ms",
"to": "0x467194771dae2967aef3ecbedd3bf9a310c76c65",
"type": "CALL",
"value": "0x0"
}
{
"calls": [
{
"calls": [
{
"from": "0xfe8e48bf36ccc3254081ec8c65965d1c8b2e744d",
"gas": "0x2d816",
"gasUsed": "0x9bb",
"input": "0x70a0823100000000000000000000000090f1cb932dbf94385434c40d53df3727f00e50b1",
"output": "0x0000000000000000000000000000000000000000000001c9f23e7ccc897c65e5",
"to": "0xb9c6ca25452e7f6d0d3340ce1e9b573421afc2ee",
"type": "STATICCALL"
},
{
"calls": [
{
"from": "0x01da457aa57abc0dba3fc26d6c350899f04e8417",
"gas": "0x29fdd",
"gasUsed": "0xa27",
"input": "0x70a0823100000000000000000000000090f1cb932dbf94385434c40d53df3727f00e50b1",
"output": "0x0000000000000000000000000000000000000000000000000000000000000000",
"to": "0x45c55bf488d3cb8640f12f63cbedc027e8261e79",
"type": "STATICCALL"
},
{
"calls": [
{
"from": "0x37aafb2ee35f1250a001202c660b13c301d2130b",
"gas": "0x258ad",
"gasUsed": "0x1cf2",
"input": "0xfeaf968c",
"output": "0x0000000000000000000000000000000000000000000000000000000000003a1600000000000000000000000000000000000000000082e0fab52217072028a796000000000000000000000000000000000000000000000000000000006327dde9000000000000000000000000000000000000000000000000000000006327dde90000000000000000000000000000000000000000000000000000000000003a16",
"to": "0x22f04bc4162d63730dcde051fdfd97b4f55ff63b",
"type": "STATICCALL"
}
],
"from": "0x01da457aa57abc0dba3fc26d6c350899f04e8417",
"gas": "0x27fba",
"gasUsed": "0x3d1b",
"input": "0xfeaf968c",
"output": "0x0000000000000000000000000000000000000000000000010000000000003a1600000000000000000000000000000000000000000082e0fab52217072028a796000000000000000000000000000000000000000000000000000000006327dde9000000000000000000000000000000000000000000000000000000006327dde90000000000000000000000000000000000000000000000010000000000003a16",
"to": "0x37aafb2ee35f1250a001202c660b13c301d2130b",
"type": "STATICCALL"
},
{
"calls": [
{
"from": "0x94a178f2c480d14f8cdda908d173d7a73f779cb7",
"gas": "0x20589",
"gasUsed": "0x1cf2",
"input": "0xfeaf968c",
"output": "0x00000000000000000000000000000000000000000000000000000000000039e1000000000000000000000000000000000000000003eed3c5c4dd1b5d426c4280000000000000000000000000000000000000000000000000000000006327dfb7000000000000000000000000000000000000000000000000000000006327dfb700000000000000000000000000000000000000000000000000000000000039e1",
"to": "0x0d5642c6329adb3246c13d78b429a9fb1965a0d8",
"type": "STATICCALL"
}
],
"from": "0x01da457aa57abc0dba3fc26d6c350899f04e8417",
"gas": "0x22b44",
"gasUsed": "0x3d1b",
"input": "0xfeaf968c",
"output": "0x00000000000000000000000000000000000000000000000100000000000039e1000000000000000000000000000000000000000003eed3c5c4dd1b5d426c4280000000000000000000000000000000000000000000000000000000006327dfb7000000000000000000000000000000000000000000000000000000006327dfb700000000000000000000000000000000000000000000000100000000000039e1",
"to": "0x94a178f2c480d14f8cdda908d173d7a73f779cb7",
"type": "STATICCALL"
},
{
"from": "0x01da457aa57abc0dba3fc26d6c350899f04e8417",
"gas": "0x1d414",
"gasUsed": "0x12a0",
"input": "0x23257c2b53797374656d53657474696e6773000000000000000000000000000000000000726174655374616c65506572696f640000000000000000000000000000000000",
"output": "0x0000000000000000000000000000000000000000000000000000000000001518",
"to": "0x47649022380d182da8010ae5d257fea4227b21ff",
"type": "STATICCALL"
},
{
"from": "0x01da457aa57abc0dba3fc26d6c350899f04e8417",
"gas": "0x1bbf0",
"gasUsed": "0x300",
"input": "0x23257c2b53797374656d53657474696e6773000000000000000000000000000000000000726174655374616c65506572696f640000000000000000000000000000000000",
"output": "0x0000000000000000000000000000000000000000000000000000000000001518",
"to": "0x47649022380d182da8010ae5d257fea4227b21ff",
"type": "STATICCALL"
},
{
"from": "0x01da457aa57abc0dba3fc26d6c350899f04e8417",
"gas": "0x1b330",
"gasUsed": "0x300",
"input": "0x23257c2b53797374656d53657474696e6773000000000000000000000000000000000000726174655374616c65506572696f640000000000000000000000000000000000",
"output": "0x0000000000000000000000000000000000000000000000000000000000001518",
"to": "0x47649022380d182da8010ae5d257fea4227b21ff",
"type": "STATICCALL"
},
{
"from": "0x01da457aa57abc0dba3fc26d6c350899f04e8417",
"gas": "0x1a9f6",
"gasUsed": "0xad0",
"input": "0x23257c2b53797374656d53657474696e677300000000000000000000000000000000000069737375616e6365526174696f00000000000000000000000000000000000000",
"output": "0x00000000000000000000000000000000000000000000000003f70fa11c48cc00",
"to": "0x47649022380d182da8010ae5d257fea4227b21ff",
"type": "STATICCALL"
}
],
"from": "0xfe8e48bf36ccc3254081ec8c65965d1c8b2e744d",
"gas": "0x2c32d",
"gasUsed": "0x12144",
"input": "0x6bed041500000000000000000000000090f1cb932dbf94385434c40d53df3727f00e50b10000000000000000000000000000000000000000000001c9f23e7ccc897c65e5",
"output": "0x0000000000000000000000000000000000000000000001c9f23e7ccc897c65e50000000000000000000000000000000000000000000000000000000000000000",
"to": "0x01da457aa57abc0dba3fc26d6c350899f04e8417",
"type": "STATICCALL"
}
],
"from": "0x136b1ec699c62b0606854056f02dc7bb80482d63",
"gas": "0x301cc",
"gasUsed": "0x1552d",
"input": "0x6ac0bf9c00000000000000000000000090f1cb932dbf94385434c40d53df3727f00e50b1",
"output": "0x0000000000000000000000000000000000000000000001c9f23e7ccc897c65e5",
"to": "0xfe8e48bf36ccc3254081ec8c65965d1c8b2e744d",
"type": "STATICCALL"
},
{
"calls": [
{
"from": "0xfe8e48bf36ccc3254081ec8c65965d1c8b2e744d",
"gas": "0x18618",
"gasUsed": "0x9c8",
"input": "0x086dabd1",
"output": "0x",
"to": "0xe8c41be1a167314abaf2423b72bf8da826943ffd",
"type": "STATICCALL"
},
{
"from": "0xfe8e48bf36ccc3254081ec8c65965d1c8b2e744d",
"gas": "0x17a5c",
"gasUsed": "0x1eb",
"input": "0x70a0823100000000000000000000000090f1cb932dbf94385434c40d53df3727f00e50b1",
"output": "0x0000000000000000000000000000000000000000000001c9f23e7ccc897c65e5",
"to": "0xb9c6ca25452e7f6d0d3340ce1e9b573421afc2ee",
"type": "STATICCALL"
},
{
"from": "0xfe8e48bf36ccc3254081ec8c65965d1c8b2e744d",
"gas": "0x17682",
"gasUsed": "0x1514",
"input": "0xb46310f600000000000000000000000090f1cb932dbf94385434c40d53df3727f00e50b10000000000000000000000000000000000000000000000000000000000000000",
"output": "0x",
"to": "0xb9c6ca25452e7f6d0d3340ce1e9b573421afc2ee",
"type": "CALL",
"value": "0x0"
},
{
"from": "0xfe8e48bf36ccc3254081ec8c65965d1c8b2e744d",
"gas": "0x14c2b",
"gasUsed": "0x1277",
"input": "0x907dff9700000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000003ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef00000000000000000000000090f1cb932dbf94385434c40d53df3727f00e50b10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000001c9f23e7ccc897c65e5",
"output": "0x",
"to": "0x8700daec35af8ff88c16bdf0418774cb3d7599b4",
"type": "CALL",
"value": "0x0"
}
],
"from": "0x136b1ec699c62b0606854056f02dc7bb80482d63",
"gas": "0x1abd5",
"gasUsed": "0x80f1",
"input": "0xedef719a00000000000000000000000090f1cb932dbf94385434c40d53df3727f00e50b10000000000000000000000000000000000000000000001c9f23e7ccc897c65e5",
"output": "0x",
"to": "0xfe8e48bf36ccc3254081ec8c65965d1c8b2e744d",
"type": "CALL",
"value": "0x0"
},
{
"from": "0x136b1ec699c62b0606854056f02dc7bb80482d63",
"gas": "0x109c6",
"gasUsed": "0xad0",
"input": "0x23257c2b53797374656d53657474696e677300000000000000000000000000000000000063726f7373446f6d61696e5769746864726177616c4761734c696d6974000000",
"output": "0x00000000000000000000000000000000000000000000000000000000002dc6c0",
"to": "0x47649022380d182da8010ae5d257fea4227b21ff",
"type": "STATICCALL"
},
{
"calls": [
{
"from": "0x4200000000000000000000000000000000000007",
"gas": "0x7a8c",
"gasUsed": "0x5d16",
"input": "0xcafa81dc00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000104cbd4ece900000000000000000000000039ea01a0298c315d149a490e34b59dbf2ec7e48f000000000000000000000000136b1ec699c62b0606854056f02dc7bb80482d630000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000001b04c0000000000000000000000000000000000000000000000000000000000000044f4f7b41a00000000000000000000000090f1cb932dbf94385434c40d53df3727f00e50b10000000000000000000000000000000000000000000001c9f23e7ccc897c65e50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"output": "0x",
"to": "0x4200000000000000000000000000000000000000",
"type": "CALL",
"value": "0x0"
}
],
"from": "0x136b1ec699c62b0606854056f02dc7bb80482d63",
"gas": "0xf00f",
"gasUsed": "0xec03",
"input": "0x3dbb202b00000000000000000000000039ea01a0298c315d149a490e34b59dbf2ec7e48f000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000002dc6c00000000000000000000000000000000000000000000000000000000000000044f4f7b41a00000000000000000000000090f1cb932dbf94385434c40d53df3727f00e50b10000000000000000000000000000000000000000000001c9f23e7ccc897c65e500000000000000000000000000000000000000000000000000000000",
"output": "0x",
"to": "0x4200000000000000000000000000000000000007",
"type": "CALL",
"value": "0x0"
}
],
"from": "0x90f1cb932dbf94385434c40d53df3727f00e50b1",
"gas": "0x32e3f",
"gasUsed": "0x32e3f",
"input": "0x2e1a7d4d0000000000000000000000000000000000000000000001c9f23e7ccc897c65e5",
"output": "0x",
"time": "406.907662ms",
"to": "0x136b1ec699c62b0606854056f02dc7bb80482d63",
"type": "CALL",
"value": "0x0"
}
{
"blockHash": "0x4f5fdc9747712cb61871d6d35618a6580671d5ddb85796c9d0790453509cf4cc",
"blockNumber": "0x169900c",
"contractAddress": null,
"cumulativeGasUsed": "0x1c2ca",
"from": "0x9c8f005ab27adb94f3d49020a15722db2fcd9f27",
"gasUsed": "0x1c2ca",
"logs": [
{
"address": "0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000",
"blockHash": "0x4f5fdc9747712cb61871d6d35618a6580671d5ddb85796c9d0790453509cf4cc",
"blockNumber": "0x169900c",
"data": "0x00000000000000000000000000000000000000000000000000232bff5f46c000",
"logIndex": "0x0",
"removed": false,
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x0000000000000000000000009c8f005ab27adb94f3d49020a15722db2fcd9f27",
"0x0000000000000000000000000000000000000000000000000000000000000000"
],
"transactionHash": "0x26b854fe0b8f0c5ad15d5c3c1291107cc870f5d7351cfc399e23e68f22231fbe",
"transactionIndex": "0x0"
},
{
"address": "0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000",
"blockHash": "0x4f5fdc9747712cb61871d6d35618a6580671d5ddb85796c9d0790453509cf4cc",
"blockNumber": "0x169900c",
"data": "0x00000000000000000000000000000000000000000000000000232bff5f46c000",
"logIndex": "0x1",
"removed": false,
"topics": [
"0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5",
"0x0000000000000000000000009c8f005ab27adb94f3d49020a15722db2fcd9f27"
],
"transactionHash": "0x26b854fe0b8f0c5ad15d5c3c1291107cc870f5d7351cfc399e23e68f22231fbe",
"transactionIndex": "0x0"
},
{
"address": "0x4200000000000000000000000000000000000007",
"blockHash": "0x4f5fdc9747712cb61871d6d35618a6580671d5ddb85796c9d0790453509cf4cc",
"blockNumber": "0x169900c",
"data": "0x00000000000000000000000042000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000001b04d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a41532ec340000000000000000000000009c8f005ab27adb94f3d49020a15722db2fcd9f270000000000000000000000009c8f005ab27adb94f3d49020a15722db2fcd9f2700000000000000000000000000000000000000000000000000232bff5f46c0000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logIndex": "0x2",
"removed": false,
"topics": [
"0xcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a",
"0x00000000000000000000000099c9fc46f92e8a1c0dec1b1747d010903e884be1"
],
"transactionHash": "0x26b854fe0b8f0c5ad15d5c3c1291107cc870f5d7351cfc399e23e68f22231fbe",
"transactionIndex": "0x0"
},
{
"address": "0x4200000000000000000000000000000000000010",
"blockHash": "0x4f5fdc9747712cb61871d6d35618a6580671d5ddb85796c9d0790453509cf4cc",
"blockNumber": "0x169900c",
"data": "0x0000000000000000000000009c8f005ab27adb94f3d49020a15722db2fcd9f2700000000000000000000000000000000000000000000000000232bff5f46c00000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000",
"logIndex": "0x3",
"removed": false,
"topics": [
"0x73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x000000000000000000000000deaddeaddeaddeaddeaddeaddeaddeaddead0000",
"0x0000000000000000000000009c8f005ab27adb94f3d49020a15722db2fcd9f27"
],
"transactionHash": "0x26b854fe0b8f0c5ad15d5c3c1291107cc870f5d7351cfc399e23e68f22231fbe",
"transactionIndex": "0x0"
}
],
"logsBloom": "0x00000000000000000010000000000000000000000000001000100000001000000000000000000080000000000000008000000800000000000000000000000240000000000000000040000008000000000000000000000000000000004000000100000000020000000000000000000800080000000000000000000010000000000001000000000000000000000000000000800000000000000020000000200000000000000000000001000000000000000000200000000000000000000000000000000002010000000000000400000000000002100000000008000004000020001000000000000000000000000000000100000000000000000000000000000000",
"status": "0x1",
"to": "0x4200000000000000000000000000000000000010",
"transactionHash": "0x26b854fe0b8f0c5ad15d5c3c1291107cc870f5d7351cfc399e23e68f22231fbe",
"transactionIndex": "0x0"
}
{
"blockHash": "0x13bf6e592e572c0a021488b6f2d910114be3491fc08a35f2ee2b38063df24abf",
"blockNumber": "0x169a45d",
"contractAddress": null,
"cumulativeGasUsed": "0x1c49a",
"from": "0x3178490d60b5cceaa5a79fd4d9050c7405bab80c",
"gasUsed": "0x1c49a",
"logs": [
{
"address": "0x76fb31fb4af56892a25e32cfc43de717950c9278",
"blockHash": "0x13bf6e592e572c0a021488b6f2d910114be3491fc08a35f2ee2b38063df24abf",
"blockNumber": "0x169a45d",
"data": "0x0000000000000000000000000000000000000000000000a3b61828488b117259",
"logIndex": "0x0",
"removed": false,
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x0000000000000000000000003178490d60b5cceaa5a79fd4d9050c7405bab80c",
"0x0000000000000000000000000000000000000000000000000000000000000000"
],
"transactionHash": "0x32d3b5a0178a33cfbf904cfd36f66a13ff8576f409f15aae86dc3ff0e101c93a",
"transactionIndex": "0x0"
},
{
"address": "0x76fb31fb4af56892a25e32cfc43de717950c9278",
"blockHash": "0x13bf6e592e572c0a021488b6f2d910114be3491fc08a35f2ee2b38063df24abf",
"blockNumber": "0x169a45d",
"data": "0x0000000000000000000000000000000000000000000000a3b61828488b117259",
"logIndex": "0x1",
"removed": false,
"topics": [
"0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5",
"0x0000000000000000000000003178490d60b5cceaa5a79fd4d9050c7405bab80c"
],
"transactionHash": "0x32d3b5a0178a33cfbf904cfd36f66a13ff8576f409f15aae86dc3ff0e101c93a",
"transactionIndex": "0x0"
},
{
"address": "0x4200000000000000000000000000000000000007",
"blockHash": "0x13bf6e592e572c0a021488b6f2d910114be3491fc08a35f2ee2b38063df24abf",
"blockNumber": "0x169a45d",
"data": "0x00000000000000000000000042000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000001b04f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e4a9f9e6750000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae900000000000000000000000076fb31fb4af56892a25e32cfc43de717950c92780000000000000000000000003178490d60b5cceaa5a79fd4d9050c7405bab80c0000000000000000000000003178490d60b5cceaa5a79fd4d9050c7405bab80c0000000000000000000000000000000000000000000000a3b61828488b11725900000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logIndex": "0x2",
"removed": false,
"topics": [
"0xcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a",
"0x00000000000000000000000099c9fc46f92e8a1c0dec1b1747d010903e884be1"
],
"transactionHash": "0x32d3b5a0178a33cfbf904cfd36f66a13ff8576f409f15aae86dc3ff0e101c93a",
"transactionIndex": "0x0"
},
{
"address": "0x4200000000000000000000000000000000000010",
"blockHash": "0x13bf6e592e572c0a021488b6f2d910114be3491fc08a35f2ee2b38063df24abf",
"blockNumber": "0x169a45d",
"data": "0x0000000000000000000000003178490d60b5cceaa5a79fd4d9050c7405bab80c0000000000000000000000000000000000000000000000a3b61828488b11725900000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000",
"logIndex": "0x3",
"removed": false,
"topics": [
"0x73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e",
"0x0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae9",
"0x00000000000000000000000076fb31fb4af56892a25e32cfc43de717950c9278",
"0x0000000000000000000000003178490d60b5cceaa5a79fd4d9050c7405bab80c"
],
"transactionHash": "0x32d3b5a0178a33cfbf904cfd36f66a13ff8576f409f15aae86dc3ff0e101c93a",
"transactionIndex": "0x0"
}
],
"logsBloom": "0x00000000000000000010000000000000000000000000001000100000001000000000000000000080000000000000008000000000000000000000040000000000000000000000000040000008000000000000100000000000000000004000000000000000020000000000000000000820080000000000000000000010014000000001000000000000000000000000000000800000000000000004000000200000000000000000000001000000000000000000200000000000000000000000000000000002000000000000000400000000000002100400000008000000000020000000000000000000000010000000000000000000000000002000000000248000",
"status": "0x1",
"to": "0x4200000000000000000000000000000000000010",
"transactionHash": "0x32d3b5a0178a33cfbf904cfd36f66a13ff8576f409f15aae86dc3ff0e101c93a",
"transactionIndex": "0x0"
}
{
"blockHash": "0x1fae89e0362ec677f76f7f3b7693b0dc05de5b5e1c4f34ee9add4339cb6391b6",
"blockNumber": "0x16a58e2",
"contractAddress": null,
"cumulativeGasUsed": "0x1aef3",
"from": "0x6659612eb0e2464ccadf7a5e851bcd12873f6e04",
"gasUsed": "0x1aef3",
"logs": [
{
"address": "0xda10009cbd5d07dd0cecc66161fc93d7c9000da1",
"blockHash": "0x1fae89e0362ec677f76f7f3b7693b0dc05de5b5e1c4f34ee9add4339cb6391b6",
"blockNumber": "0x16a58e2",
"data": "0x0000000000000000000000000000000000000000000211654585005212800000",
"logIndex": "0x0",
"removed": false,
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x0000000000000000000000006659612eb0e2464ccadf7a5e851bcd12873f6e04",
"0x0000000000000000000000000000000000000000000000000000000000000000"
],
"transactionHash": "0x38236157c6941ef64f4dd0dfa7efed4a82ef9fccdcdda75a8ee89cbe831b182b",
"transactionIndex": "0x0"
},
{
"address": "0x4200000000000000000000000000000000000007",
"blockHash": "0x1fae89e0362ec677f76f7f3b7693b0dc05de5b5e1c4f34ee9add4339cb6391b6",
"blockNumber": "0x16a58e2",
"data": "0x000000000000000000000000467194771dae2967aef3ecbedd3bf9a310c76c650000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000001b05e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e4a9f9e6750000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000006659612eb0e2464ccadf7a5e851bcd12873f6e040000000000000000000000006659612eb0e2464ccadf7a5e851bcd12873f6e04000000000000000000000000000000000000000000021165458500521280000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logIndex": "0x1",
"removed": false,
"topics": [
"0xcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a",
"0x00000000000000000000000010e6593cdda8c58a1d0f14c5164b376352a55f2f"
],
"transactionHash": "0x38236157c6941ef64f4dd0dfa7efed4a82ef9fccdcdda75a8ee89cbe831b182b",
"transactionIndex": "0x0"
},
{
"address": "0x467194771dae2967aef3ecbedd3bf9a310c76c65",
"blockHash": "0x1fae89e0362ec677f76f7f3b7693b0dc05de5b5e1c4f34ee9add4339cb6391b6",
"blockNumber": "0x16a58e2",
"data": "0x0000000000000000000000006659612eb0e2464ccadf7a5e851bcd12873f6e04000000000000000000000000000000000000000000021165458500521280000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000",
"logIndex": "0x2",
"removed": false,
"topics": [
"0x73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e",
"0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f",
"0x000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1",
"0x0000000000000000000000006659612eb0e2464ccadf7a5e851bcd12873f6e04"
],
"transactionHash": "0x38236157c6941ef64f4dd0dfa7efed4a82ef9fccdcdda75a8ee89cbe831b182b",
"transactionIndex": "0x0"
}
],
"logsBloom": "0x000000000000008000100000000000000000000000000000001000000010000000000000000000800000000000000080000000000000000000000000000000c0000000000000000041000008000080000000000000000000000000000000008000400000020000000000000000000800000000000000000000002010000000200000000100000000000000000000000000000000800000000000000400000200000000000000000001000000010000000000000000000000000000000000000000000002000000000000000400000000200000100000000000000000000020000000000020000000000800000000000000000000000000100000000000000000",
"status": "0x1",
"to": "0x467194771dae2967aef3ecbedd3bf9a310c76c65",
"transactionHash": "0x38236157c6941ef64f4dd0dfa7efed4a82ef9fccdcdda75a8ee89cbe831b182b",
"transactionIndex": "0x0"
}
{
"blockHash": "0x8a150d06f327859edb6e45e347105df56e047c690617d784c7aadedd0d426ff9",
"blockNumber": "0x1698be0",
"contractAddress": null,
"cumulativeGasUsed": "0x36ebf",
"from": "0x90f1cb932dbf94385434c40d53df3727f00e50b1",
"gasUsed": "0x36ebf",
"logs": [
{
"address": "0x8700daec35af8ff88c16bdf0418774cb3d7599b4",
"blockHash": "0x8a150d06f327859edb6e45e347105df56e047c690617d784c7aadedd0d426ff9",
"blockNumber": "0x1698be0",
"data": "0x0000000000000000000000000000000000000000000001c9f23e7ccc897c65e5",
"logIndex": "0x0",
"removed": false,
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x00000000000000000000000090f1cb932dbf94385434c40d53df3727f00e50b1",
"0x0000000000000000000000000000000000000000000000000000000000000000"
],
"transactionHash": "0xed57a510022157b14542491a501daed1d58003e4b274b331d2fc40dcc43f0941",
"transactionIndex": "0x0"
},
{
"address": "0x4200000000000000000000000000000000000007",
"blockHash": "0x8a150d06f327859edb6e45e347105df56e047c690617d784c7aadedd0d426ff9",
"blockNumber": "0x1698be0",
"data": "0x000000000000000000000000136b1ec699c62b0606854056f02dc7bb80482d630000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000001b04c00000000000000000000000000000000000000000000000000000000002dc6c00000000000000000000000000000000000000000000000000000000000000044f4f7b41a00000000000000000000000090f1cb932dbf94385434c40d53df3727f00e50b10000000000000000000000000000000000000000000001c9f23e7ccc897c65e500000000000000000000000000000000000000000000000000000000",
"logIndex": "0x1",
"removed": false,
"topics": [
"0xcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a",
"0x00000000000000000000000039ea01a0298c315d149a490e34b59dbf2ec7e48f"
],
"transactionHash": "0xed57a510022157b14542491a501daed1d58003e4b274b331d2fc40dcc43f0941",
"transactionIndex": "0x0"
},
{
"address": "0x136b1ec699c62b0606854056f02dc7bb80482d63",
"blockHash": "0x8a150d06f327859edb6e45e347105df56e047c690617d784c7aadedd0d426ff9",
"blockNumber": "0x1698be0",
"data": "0x00000000000000000000000090f1cb932dbf94385434c40d53df3727f00e50b10000000000000000000000000000000000000000000001c9f23e7ccc897c65e5",
"logIndex": "0x2",
"removed": false,
"topics": [
"0xbb2689ff876f7ef453cf8865dde5ab10349d222e2e1383c5152fbdb083f02da2",
"0x00000000000000000000000090f1cb932dbf94385434c40d53df3727f00e50b1"
],
"transactionHash": "0xed57a510022157b14542491a501daed1d58003e4b274b331d2fc40dcc43f0941",
"transactionIndex": "0x0"
}
],
"logsBloom": "0x00000000000000000010000000000040000000000000000000000000081000000000000000000080000000000000008000000000000000001000000000000000000000080000000041000008000000000000000000000000000000000000080000100000020000000000000200000800000000000000000000000010000000000002000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000002000000000200000000000001000000100000000000000000000020020000000000000000000000000000000000000000000000800000000000000000",
"status": "0x1",
"to": "0x136b1ec699c62b0606854056f02dc7bb80482d63",
"transactionHash": "0xed57a510022157b14542491a501daed1d58003e4b274b331d2fc40dcc43f0941",
"transactionIndex": "0x0"
}
{
"0x4200000000000000000000000000000000000000": {
"balance": "0x0",
"code": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c806382e3702d1461003b578063cafa81dc14610072575b600080fd5b61005e610049366004610112565b60006020819052908152604090205460ff1681565b604051901515815260200160405180910390f35b61008561008036600461015a565b610087565b005b6001600080833360405160200161009f929190610229565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291815281516020928301208352908201929092520160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905550565b60006020828403121561012457600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561016c57600080fd5b813567ffffffffffffffff8082111561018457600080fd5b818401915084601f83011261019857600080fd5b8135818111156101aa576101aa61012b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156101f0576101f061012b565b8160405282815287602084870101111561020957600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000835160005b8181101561024a5760208187018101518583015201610230565b81811115610259576000828501525b5060609390931b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016919092019081526014019291505056fea26469706673582212200b48ded2e68f3541ccec6b89e65ba6788c333cfabcd8ebb2d833e41d3b8df28164736f6c63430008090033",
"nonce": 0,
"storage": {
"0xd21effe9499bc64d50ca07a52775e216265a2b43768d634d0e93da33d178c1fe": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"0x4200000000000000000000000000000000000007": {
"balance": "0x0",
"code": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063a71198691161005b578063a71198691461012a578063b1b1b2091461014a578063cbd4ece91461016d578063ecc704281461018057600080fd5b806321d800ec1461008d5780633dbb202b146100c55780636e296e45146100da57806382e3702d14610107575b600080fd5b6100b061009b366004610826565b60006020819052908152604090205460ff1681565b60405190151581526020015b60405180910390f35b6100d86100d3366004610942565b610197565b005b6100e26102e2565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100bc565b6100b0610115366004610826565b60026020526000908152604090205460ff1681565b6005546100e29073ffffffffffffffffffffffffffffffffffffffff1681565b6100b0610158366004610826565b60016020526000908152604090205460ff1681565b6100d861017b3660046109ad565b61038b565b61018960035481565b6040519081526020016100bc565b60006101a784338560035461078d565b80516020808301919091206000908152600290915260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517fcafa81dc0000000000000000000000000000000000000000000000000000000081529091507342000000000000000000000000000000000000009063cafa81dc9061023c908490600401610a89565b600060405180830381600087803b15801561025657600080fd5b505af115801561026a573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a3385600354866040516102bc9493929190610aa3565b60405180910390a26001600360008282546102d79190610aef565b909155505050505050565b60045460009073ffffffffffffffffffffffffffffffffffffffff1661dead141561036e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f78446f6d61696e4d65737361676553656e646572206973206e6f74207365740060448201526064015b60405180910390fd5b5060045473ffffffffffffffffffffffffffffffffffffffff1690565b60055473ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffeeeeffffffffffffffffffffffffffffffffeeef330173ffffffffffffffffffffffffffffffffffffffff161461046a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f50726f7669646564206d65737361676520636f756c64206e6f7420626520766560448201527f7269666965642e000000000000000000000000000000000000000000000000006064820152608401610365565b60006104788585858561078d565b8051602080830191909120600081815260019092526040909120549192509060ff1615610527576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f50726f7669646564206d6573736167652068617320616c72656164792062656560448201527f6e2072656365697665642e0000000000000000000000000000000000000000006064820152608401610365565b73ffffffffffffffffffffffffffffffffffffffff8616734200000000000000000000000000000000000000141561059957600090815260016020819052604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909117905550610787565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff878116919091179091556040516000918816906105f2908790610b2e565b6000604051808303816000865af19150503d806000811461062f576040519150601f19603f3d011682016040523d82523d6000602084013e610634565b606091505b5050600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801515600114156106d557600082815260016020819052604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169092179091555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a2610701565b60405182907f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f90600090a25b600083334360405160200161071893929190610b4a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600090815291829052902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505b50505050565b6060848484846040516024016107a69493929190610b9c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b60006020828403121561083857600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461086357600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126108a857600080fd5b813567ffffffffffffffff808211156108c3576108c3610868565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561090957610909610868565b8160405283815286602085880101111561092257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561095757600080fd5b6109608461083f565b9250602084013567ffffffffffffffff81111561097c57600080fd5b61098886828701610897565b925050604084013563ffffffff811681146109a257600080fd5b809150509250925092565b600080600080608085870312156109c357600080fd5b6109cc8561083f565b93506109da6020860161083f565b9250604085013567ffffffffffffffff8111156109f657600080fd5b610a0287828801610897565b949793965093946060013593505050565b60005b83811015610a2e578181015183820152602001610a16565b838111156107875750506000910152565b60008151808452610a57816020860160208601610a13565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610a9c6020830184610a3f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff85168152608060208201526000610ad26080830186610a3f565b905083604083015263ffffffff8316606083015295945050505050565b60008219821115610b29577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b60008251610b40818460208701610a13565b9190910192915050565b60008451610b5c818460208901610a13565b60609490941b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001691909301908152601481019190915260340192915050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152610bd56080830185610a3f565b90508260608301529594505050505056fea26469706673582212202e10f5e906e4d6b76a9239c97481d533896c41191186b3ec3ca5feab5203fde664736f6c63430008090033",
"nonce": 0,
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000000001b04d",
"0x56cd54638e7c1388997f530b64562a8d4d938866fe3dd082986ff807670ec616": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"0x4200000000000000000000000000000000000010": {
"balance": "0x0",
"code": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c80633cb747bf116100505780633cb747bf146100ca578063662a633a146100ea578063a3a79548146100fd57600080fd5b806332b7006d1461006c57806336c717c114610081575b600080fd5b61007f61007a366004610d0f565b610110565b005b6001546100a19073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6000546100a19073ffffffffffffffffffffffffffffffffffffffff1681565b61007f6100f8366004610d80565b610126565b61007f61010b366004610e18565b6106c1565b61011f853333878787876106d8565b5050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1661015e60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461021d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4f564d5f58434841494e3a206d657373656e67657220636f6e7472616374207560448201527f6e61757468656e7469636174656400000000000000000000000000000000000060648201526084015b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661025360005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b815260040160206040518083038186803b15801561029857600080fd5b505afa1580156102ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102d09190610e9b565b73ffffffffffffffffffffffffffffffffffffffff1614610373576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4f564d5f58434841494e3a2077726f6e672073656e646572206f662063726f7360448201527f732d646f6d61696e206d657373616765000000000000000000000000000000006064820152608401610214565b61039d877f1d1d8b6300000000000000000000000000000000000000000000000000000000610a32565b801561045357508673ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156103ec57600080fd5b505af1158015610400573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104249190610e9b565b73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16145b15610567576040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152602482018690528816906340c10f1990604401600060405180830381600087803b1580156104c857600080fd5b505af11580156104dc573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd898888888860405161055a9493929190610f08565b60405180910390a46106b7565b600063a9f9e67560e01b8989888a89898960405160240161058e9796959493929190610f3e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526001549091506106339073ffffffffffffffffffffffffffffffffffffffff16600083610a57565b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167f7ea89a4591614515571c2b51f5ea06494056f261c10ab1ed8c03c7590d87bce0898989896040516106ad9493929190610f08565b60405180910390a4505b5050505050505050565b6106d0863387878787876106d8565b505050505050565b6040517f9dc29fac0000000000000000000000000000000000000000000000000000000081523360048201526024810185905273ffffffffffffffffffffffffffffffffffffffff881690639dc29fac90604401600060405180830381600087803b15801561074657600080fd5b505af115801561075a573d6000803e3d6000fd5b5050505060008773ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156107a857600080fd5b505af11580156107bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e09190610e9b565b9050606073ffffffffffffffffffffffffffffffffffffffff891673deaddeaddeaddeaddeaddeaddeaddeaddead000014156108d5576040517f1532ec340000000000000000000000000000000000000000000000000000000090610851908a908a908a9089908990602401610f9b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050610994565b6040517fa9f9e67500000000000000000000000000000000000000000000000000000000906109149084908c908c908c908c908b908b90602401610f3e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290505b6001546109b89073ffffffffffffffffffffffffffffffffffffffff168683610a57565b3373ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e8a8a89896040516106ad9493929190610f08565b6000610a3d83610ae8565b8015610a4e5750610a4e8383610b4c565b90505b92915050565b6000546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b90610ab190869085908790600401611016565b600060405180830381600087803b158015610acb57600080fd5b505af1158015610adf573d6000803e3d6000fd5b50505050505050565b6000610b14827f01ffc9a700000000000000000000000000000000000000000000000000000000610b4c565b8015610a515750610b45827fffffffff00000000000000000000000000000000000000000000000000000000610b4c565b1592915050565b604080517fffffffff00000000000000000000000000000000000000000000000000000000831660248083019190915282518083039091018152604490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a7000000000000000000000000000000000000000000000000000000001790529051600091908290819073ffffffffffffffffffffffffffffffffffffffff87169061753090610c06908690611092565b6000604051808303818686fa925050503d8060008114610c42576040519150601f19603f3d011682016040523d82523d6000602084013e610c47565b606091505b5091509150602081511015610c625760009350505050610a51565b818015610c7e575080806020019051810190610c7e91906110ae565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610caa57600080fd5b50565b803563ffffffff81168114610cc157600080fd5b919050565b60008083601f840112610cd857600080fd5b50813567ffffffffffffffff811115610cf057600080fd5b602083019150836020828501011115610d0857600080fd5b9250929050565b600080600080600060808688031215610d2757600080fd5b8535610d3281610c88565b945060208601359350610d4760408701610cad565b9250606086013567ffffffffffffffff811115610d6357600080fd5b610d6f88828901610cc6565b969995985093965092949392505050565b600080600080600080600060c0888a031215610d9b57600080fd5b8735610da681610c88565b96506020880135610db681610c88565b95506040880135610dc681610c88565b94506060880135610dd681610c88565b93506080880135925060a088013567ffffffffffffffff811115610df957600080fd5b610e058a828b01610cc6565b989b979a50959850939692959293505050565b60008060008060008060a08789031215610e3157600080fd5b8635610e3c81610c88565b95506020870135610e4c81610c88565b945060408701359350610e6160608801610cad565b9250608087013567ffffffffffffffff811115610e7d57600080fd5b610e8989828a01610cc6565b979a9699509497509295939492505050565b600060208284031215610ead57600080fd5b8151610eb881610c88565b9392505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152606060408201526000610c7e606083018486610ebf565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a0830152610f8e60c083018486610ebf565b9998505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525084604083015260806060830152610fdb608083018486610ebf565b979650505050505050565b60005b83811015611001578181015183820152602001610fe9565b83811115611010576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260008351806060840152611051816080850160208801610fe6565b63ffffffff93909316604083015250601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160160800192915050565b600082516110a4818460208701610fe6565b9190910192915050565b6000602082840312156110c057600080fd5b81518015158114610eb857600080fdfea264697066735822122038e8e2f2aaba8e45262542b2bfcd3b0c7b236b5eb945f0c4380d3b5f4028f11164736f6c63430008090033",
"nonce": 0,
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000004200000000000000000000000000000000000007",
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000099c9fc46f92e8a1c0dec1b1747d010903e884be1"
}
},
"0x9c8f005ab27adb94f3d49020a15722db2fcd9f27": {
"balance": "0x40703c17c6d4",
"code": "0x",
"nonce": 0,
"storage": {}
},
"0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000": {
"balance": "0x0",
"code": "0x608060405234801561001057600080fd5b50600436106101005760003560e01c806370a0823111610097578063a9059cbb11610066578063a9059cbb14610215578063ae1f6aaf14610228578063c01e1bd61461026d578063dd62ed3e1461028d57600080fd5b806370a08231146101b157806395d89b41146101e75780639dc29fac146101ef578063a457c2d71461020257600080fd5b806323b872dd116100d357806323b872dd14610167578063313ce5671461017a578063395093511461018957806340c10f191461019c57600080fd5b806301ffc9a71461010557806306fdde031461012d578063095ea7b31461014257806318160ddd14610155575b600080fd5b610118610113366004610c6d565b6102d3565b60405190151581526020015b60405180910390f35b610135610393565b6040516101249190610cb6565b610118610150366004610d52565b610425565b6002545b604051908152602001610124565b610118610175366004610d7c565b6104db565b60405160128152602001610124565b610118610197366004610d52565b61058c565b6101af6101aa366004610d52565b61063d565b005b6101596101bf366004610db8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61013561071c565b6101af6101fd366004610d52565b61072b565b610118610210366004610d52565b6107fe565b610118610223366004610d52565b6108af565b6006546102489073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610124565b6005546102489073ffffffffffffffffffffffffffffffffffffffff1681565b61015961029b366004610dd3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b60007f01ffc9a7a5cef8baa21ed3c5c0d7e23accb804b619e9333b597f47a0d84076e27f1d1d8b63000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000084167f01ffc9a700000000000000000000000000000000000000000000000000000000148061038b57507fffffffff00000000000000000000000000000000000000000000000000000000848116908216145b949350505050565b6060600380546103a290610e06565b80601f01602080910402602001604051908101604052809291908181526020018280546103ce90610e06565b801561041b5780601f106103f05761010080835404028352916020019161041b565b820191906000526020600020905b8154815290600101906020018083116103fe57829003601f168201915b5050505050905090565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f4f564d5f4554483a20617070726f76652069732064697361626c65642070656e60448201527f64696e67206675727468657220636f6d6d756e6974792064697363757373696f60648201527f6e2e000000000000000000000000000000000000000000000000000000000000608482015260009060a4015b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604760248201527f4f564d5f4554483a207472616e7366657246726f6d2069732064697361626c6560448201527f642070656e64696e67206675727468657220636f6d6d756e697479206469736360648201527f757373696f6e2e00000000000000000000000000000000000000000000000000608482015260009060a4016104d2565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f4f564d5f4554483a20696e637265617365416c6c6f77616e636520697320646960448201527f7361626c65642070656e64696e67206675727468657220636f6d6d756e69747960648201527f2064697363757373696f6e2e0000000000000000000000000000000000000000608482015260009060a4016104d2565b60065473ffffffffffffffffffffffffffffffffffffffff1633146106be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f6e6c79204c32204272696467652063616e206d696e7420616e64206275726e60448201526064016104d2565b6106c88282610960565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161071091815260200190565b60405180910390a25050565b6060600480546103a290610e06565b60065473ffffffffffffffffffffffffffffffffffffffff1633146107ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f6e6c79204c32204272696467652063616e206d696e7420616e64206275726e60448201526064016104d2565b6107b68282610a80565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161071091815260200190565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f4f564d5f4554483a206465637265617365416c6c6f77616e636520697320646960448201527f7361626c65642070656e64696e67206675727468657220636f6d6d756e69747960648201527f2064697363757373696f6e2e0000000000000000000000000000000000000000608482015260009060a4016104d2565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f564d5f4554483a207472616e736665722069732064697361626c656420706560448201527f6e64696e67206675727468657220636f6d6d756e69747920646973637573736960648201527f6f6e2e0000000000000000000000000000000000000000000000000000000000608482015260009060a4016104d2565b73ffffffffffffffffffffffffffffffffffffffff82166109dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016104d2565b80600260008282546109ef9190610e89565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610a29908490610e89565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8216610b23576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016104d2565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610bd9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016104d2565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602081905260408120838303905560028054849290610c15908490610ea1565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b600060208284031215610c7f57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610caf57600080fd5b9392505050565b600060208083528351808285015260005b81811015610ce357858101830151858201604001528201610cc7565b81811115610cf5576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610d4d57600080fd5b919050565b60008060408385031215610d6557600080fd5b610d6e83610d29565b946020939093013593505050565b600080600060608486031215610d9157600080fd5b610d9a84610d29565b9250610da860208501610d29565b9150604084013590509250925092565b600060208284031215610dca57600080fd5b610caf82610d29565b60008060408385031215610de657600080fd5b610def83610d29565b9150610dfd60208401610d29565b90509250929050565b600181811c90821680610e1a57607f821691505b60208210811415610e54577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610e9c57610e9c610e5a565b500190565b600082821015610eb357610eb3610e5a565b50039056fea26469706673582212203d7fb50030ef7ba9f3e38703216d01cd0231ec1f800d1fcca134a651c58c574264736f6c63430008090033",
"nonce": 0,
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000001ea9e7e5b9eb3ad119b9",
"0x0000000000000000000000000000000000000000000000000000000000000005": "0x0000000000000000000000000000000000000000000000000000000000000000",
"0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000004200000000000000000000000000000000000010",
"0x392cee78a7ed6bfb84759857691585b9601a228d4d7e003c2b1c657fd70ea4bc": "0x00000000000000000000000000000000000000000000000000236c6ef479ead4"
}
}
}
{
"0x3178490d60b5cceaa5a79fd4d9050c7405bab80c": {
"balance": "0x203b088b1ee7e4",
"code": "0x",
"nonce": 25,
"storage": {}
},
"0x4200000000000000000000000000000000000000": {
"balance": "0x0",
"code": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c806382e3702d1461003b578063cafa81dc14610072575b600080fd5b61005e610049366004610112565b60006020819052908152604090205460ff1681565b604051901515815260200160405180910390f35b61008561008036600461015a565b610087565b005b6001600080833360405160200161009f929190610229565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291815281516020928301208352908201929092520160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905550565b60006020828403121561012457600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561016c57600080fd5b813567ffffffffffffffff8082111561018457600080fd5b818401915084601f83011261019857600080fd5b8135818111156101aa576101aa61012b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156101f0576101f061012b565b8160405282815287602084870101111561020957600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000835160005b8181101561024a5760208187018101518583015201610230565b81811115610259576000828501525b5060609390931b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016919092019081526014019291505056fea26469706673582212200b48ded2e68f3541ccec6b89e65ba6788c333cfabcd8ebb2d833e41d3b8df28164736f6c63430008090033",
"nonce": 0,
"storage": {
"0xb6ad38a27f840d6bba487f3e259a8cfb2e32abd98d88beacb84ab9418a2f308e": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"0x4200000000000000000000000000000000000007": {
"balance": "0x0",
"code": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063a71198691161005b578063a71198691461012a578063b1b1b2091461014a578063cbd4ece91461016d578063ecc704281461018057600080fd5b806321d800ec1461008d5780633dbb202b146100c55780636e296e45146100da57806382e3702d14610107575b600080fd5b6100b061009b366004610826565b60006020819052908152604090205460ff1681565b60405190151581526020015b60405180910390f35b6100d86100d3366004610942565b610197565b005b6100e26102e2565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100bc565b6100b0610115366004610826565b60026020526000908152604090205460ff1681565b6005546100e29073ffffffffffffffffffffffffffffffffffffffff1681565b6100b0610158366004610826565b60016020526000908152604090205460ff1681565b6100d861017b3660046109ad565b61038b565b61018960035481565b6040519081526020016100bc565b60006101a784338560035461078d565b80516020808301919091206000908152600290915260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517fcafa81dc0000000000000000000000000000000000000000000000000000000081529091507342000000000000000000000000000000000000009063cafa81dc9061023c908490600401610a89565b600060405180830381600087803b15801561025657600080fd5b505af115801561026a573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a3385600354866040516102bc9493929190610aa3565b60405180910390a26001600360008282546102d79190610aef565b909155505050505050565b60045460009073ffffffffffffffffffffffffffffffffffffffff1661dead141561036e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f78446f6d61696e4d65737361676553656e646572206973206e6f74207365740060448201526064015b60405180910390fd5b5060045473ffffffffffffffffffffffffffffffffffffffff1690565b60055473ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffeeeeffffffffffffffffffffffffffffffffeeef330173ffffffffffffffffffffffffffffffffffffffff161461046a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f50726f7669646564206d65737361676520636f756c64206e6f7420626520766560448201527f7269666965642e000000000000000000000000000000000000000000000000006064820152608401610365565b60006104788585858561078d565b8051602080830191909120600081815260019092526040909120549192509060ff1615610527576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f50726f7669646564206d6573736167652068617320616c72656164792062656560448201527f6e2072656365697665642e0000000000000000000000000000000000000000006064820152608401610365565b73ffffffffffffffffffffffffffffffffffffffff8616734200000000000000000000000000000000000000141561059957600090815260016020819052604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909117905550610787565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff878116919091179091556040516000918816906105f2908790610b2e565b6000604051808303816000865af19150503d806000811461062f576040519150601f19603f3d011682016040523d82523d6000602084013e610634565b606091505b5050600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801515600114156106d557600082815260016020819052604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169092179091555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a2610701565b60405182907f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f90600090a25b600083334360405160200161071893929190610b4a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600090815291829052902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505b50505050565b6060848484846040516024016107a69493929190610b9c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b60006020828403121561083857600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461086357600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126108a857600080fd5b813567ffffffffffffffff808211156108c3576108c3610868565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561090957610909610868565b8160405283815286602085880101111561092257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561095757600080fd5b6109608461083f565b9250602084013567ffffffffffffffff81111561097c57600080fd5b61098886828701610897565b925050604084013563ffffffff811681146109a257600080fd5b809150509250925092565b600080600080608085870312156109c357600080fd5b6109cc8561083f565b93506109da6020860161083f565b9250604085013567ffffffffffffffff8111156109f657600080fd5b610a0287828801610897565b949793965093946060013593505050565b60005b83811015610a2e578181015183820152602001610a16565b838111156107875750506000910152565b60008151808452610a57816020860160208601610a13565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610a9c6020830184610a3f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff85168152608060208201526000610ad26080830186610a3f565b905083604083015263ffffffff8316606083015295945050505050565b60008219821115610b29577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b60008251610b40818460208701610a13565b9190910192915050565b60008451610b5c818460208901610a13565b60609490941b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001691909301908152601481019190915260340192915050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152610bd56080830185610a3f565b90508260608301529594505050505056fea26469706673582212202e10f5e906e4d6b76a9239c97481d533896c41191186b3ec3ca5feab5203fde664736f6c63430008090033",
"nonce": 0,
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000000001b04f",
"0x3322d05c07eafa912f11b56def40a67135198db85f5721bf3a549270c99900f3": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"0x4200000000000000000000000000000000000010": {
"balance": "0x0",
"code": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c80633cb747bf116100505780633cb747bf146100ca578063662a633a146100ea578063a3a79548146100fd57600080fd5b806332b7006d1461006c57806336c717c114610081575b600080fd5b61007f61007a366004610d0f565b610110565b005b6001546100a19073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6000546100a19073ffffffffffffffffffffffffffffffffffffffff1681565b61007f6100f8366004610d80565b610126565b61007f61010b366004610e18565b6106c1565b61011f853333878787876106d8565b5050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1661015e60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461021d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4f564d5f58434841494e3a206d657373656e67657220636f6e7472616374207560448201527f6e61757468656e7469636174656400000000000000000000000000000000000060648201526084015b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661025360005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b815260040160206040518083038186803b15801561029857600080fd5b505afa1580156102ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102d09190610e9b565b73ffffffffffffffffffffffffffffffffffffffff1614610373576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4f564d5f58434841494e3a2077726f6e672073656e646572206f662063726f7360448201527f732d646f6d61696e206d657373616765000000000000000000000000000000006064820152608401610214565b61039d877f1d1d8b6300000000000000000000000000000000000000000000000000000000610a32565b801561045357508673ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156103ec57600080fd5b505af1158015610400573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104249190610e9b565b73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16145b15610567576040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152602482018690528816906340c10f1990604401600060405180830381600087803b1580156104c857600080fd5b505af11580156104dc573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd898888888860405161055a9493929190610f08565b60405180910390a46106b7565b600063a9f9e67560e01b8989888a89898960405160240161058e9796959493929190610f3e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526001549091506106339073ffffffffffffffffffffffffffffffffffffffff16600083610a57565b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167f7ea89a4591614515571c2b51f5ea06494056f261c10ab1ed8c03c7590d87bce0898989896040516106ad9493929190610f08565b60405180910390a4505b5050505050505050565b6106d0863387878787876106d8565b505050505050565b6040517f9dc29fac0000000000000000000000000000000000000000000000000000000081523360048201526024810185905273ffffffffffffffffffffffffffffffffffffffff881690639dc29fac90604401600060405180830381600087803b15801561074657600080fd5b505af115801561075a573d6000803e3d6000fd5b5050505060008773ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156107a857600080fd5b505af11580156107bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e09190610e9b565b9050606073ffffffffffffffffffffffffffffffffffffffff891673deaddeaddeaddeaddeaddeaddeaddeaddead000014156108d5576040517f1532ec340000000000000000000000000000000000000000000000000000000090610851908a908a908a9089908990602401610f9b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050610994565b6040517fa9f9e67500000000000000000000000000000000000000000000000000000000906109149084908c908c908c908c908b908b90602401610f3e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290505b6001546109b89073ffffffffffffffffffffffffffffffffffffffff168683610a57565b3373ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e8a8a89896040516106ad9493929190610f08565b6000610a3d83610ae8565b8015610a4e5750610a4e8383610b4c565b90505b92915050565b6000546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b90610ab190869085908790600401611016565b600060405180830381600087803b158015610acb57600080fd5b505af1158015610adf573d6000803e3d6000fd5b50505050505050565b6000610b14827f01ffc9a700000000000000000000000000000000000000000000000000000000610b4c565b8015610a515750610b45827fffffffff00000000000000000000000000000000000000000000000000000000610b4c565b1592915050565b604080517fffffffff00000000000000000000000000000000000000000000000000000000831660248083019190915282518083039091018152604490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a7000000000000000000000000000000000000000000000000000000001790529051600091908290819073ffffffffffffffffffffffffffffffffffffffff87169061753090610c06908690611092565b6000604051808303818686fa925050503d8060008114610c42576040519150601f19603f3d011682016040523d82523d6000602084013e610c47565b606091505b5091509150602081511015610c625760009350505050610a51565b818015610c7e575080806020019051810190610c7e91906110ae565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610caa57600080fd5b50565b803563ffffffff81168114610cc157600080fd5b919050565b60008083601f840112610cd857600080fd5b50813567ffffffffffffffff811115610cf057600080fd5b602083019150836020828501011115610d0857600080fd5b9250929050565b600080600080600060808688031215610d2757600080fd5b8535610d3281610c88565b945060208601359350610d4760408701610cad565b9250606086013567ffffffffffffffff811115610d6357600080fd5b610d6f88828901610cc6565b969995985093965092949392505050565b600080600080600080600060c0888a031215610d9b57600080fd5b8735610da681610c88565b96506020880135610db681610c88565b95506040880135610dc681610c88565b94506060880135610dd681610c88565b93506080880135925060a088013567ffffffffffffffff811115610df957600080fd5b610e058a828b01610cc6565b989b979a50959850939692959293505050565b60008060008060008060a08789031215610e3157600080fd5b8635610e3c81610c88565b95506020870135610e4c81610c88565b945060408701359350610e6160608801610cad565b9250608087013567ffffffffffffffff811115610e7d57600080fd5b610e8989828a01610cc6565b979a9699509497509295939492505050565b600060208284031215610ead57600080fd5b8151610eb881610c88565b9392505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152606060408201526000610c7e606083018486610ebf565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a0830152610f8e60c083018486610ebf565b9998505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525084604083015260806060830152610fdb608083018486610ebf565b979650505050505050565b60005b83811015611001578181015183820152602001610fe9565b83811115611010576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260008351806060840152611051816080850160208801610fe6565b63ffffffff93909316604083015250601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160160800192915050565b600082516110a4818460208701610fe6565b9190910192915050565b6000602082840312156110c057600080fd5b81518015158114610eb857600080fdfea264697066735822122038e8e2f2aaba8e45262542b2bfcd3b0c7b236b5eb945f0c4380d3b5f4028f11164736f6c63430008090033",
"nonce": 0,
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000004200000000000000000000000000000000000007",
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000099c9fc46f92e8a1c0dec1b1747d010903e884be1"
}
},
"0x76fb31fb4af56892a25e32cfc43de717950c9278": {
"balance": "0x0",
"code": "0x608060405234801561001057600080fd5b50600436106101215760003560e01c806370a08231116100ad578063a9059cbb11610071578063a9059cbb14610344578063ae1f6aaf14610374578063c01e1bd614610392578063d505accf146103b0578063dd62ed3e146103cc57610121565b806370a082311461027a5780637ecebe00146102aa57806395d89b41146102da5780639dc29fac146102f8578063a457c2d71461031457610121565b806323b872dd116100f457806323b872dd146101c2578063313ce567146101f25780633644e51514610210578063395093511461022e57806340c10f191461025e57610121565b806301ffc9a71461012657806306fdde0314610156578063095ea7b31461017457806318160ddd146101a4575b600080fd5b610140600480360381019061013b9190611a33565b6103fc565b60405161014d9190611a7b565b60405180910390f35b61015e6104d2565b60405161016b9190611b2f565b60405180910390f35b61018e60048036038101906101899190611be5565b610564565b60405161019b9190611a7b565b60405180910390f35b6101ac610582565b6040516101b99190611c34565b60405180910390f35b6101dc60048036038101906101d79190611c4f565b61058c565b6040516101e99190611a7b565b60405180910390f35b6101fa610684565b6040516102079190611cbe565b60405180910390f35b61021861068d565b6040516102259190611cf2565b60405180910390f35b61024860048036038101906102439190611be5565b61069c565b6040516102559190611a7b565b60405180910390f35b61027860048036038101906102739190611be5565b610748565b005b610294600480360381019061028f9190611d0d565b610834565b6040516102a19190611c34565b60405180910390f35b6102c460048036038101906102bf9190611d0d565b61087c565b6040516102d19190611c34565b60405180910390f35b6102e26108cc565b6040516102ef9190611b2f565b60405180910390f35b610312600480360381019061030d9190611be5565b61095e565b005b61032e60048036038101906103299190611be5565b610a4a565b60405161033b9190611a7b565b60405180910390f35b61035e60048036038101906103599190611be5565b610b35565b60405161036b9190611a7b565b60405180910390f35b61037c610b53565b6040516103899190611d49565b60405180910390f35b61039a610b79565b6040516103a79190611d49565b60405180910390f35b6103ca60048036038101906103c59190611dbc565b610b9f565b005b6103e660048036038101906103e19190611e5e565b610ce1565b6040516103f39190611c34565b60405180910390f35b6000807f01ffc9a7a5cef8baa21ed3c5c0d7e23accb804b619e9333b597f47a0d84076e290506000639dc29fac60e01b6340c10f1960e01b63c01e1bd660e01b18189050817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806104c95750807bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b92505050919050565b6060600380546104e190611ecd565b80601f016020809104026020016040519081016040528092919081815260200182805461050d90611ecd565b801561055a5780601f1061052f5761010080835404028352916020019161055a565b820191906000526020600020905b81548152906001019060200180831161053d57829003601f168201915b5050505050905090565b6000610578610571610d68565b8484610d70565b6001905092915050565b6000600254905090565b6000610599848484610f3b565b6000600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006105e4610d68565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610664576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161065b90611f71565b60405180910390fd5b61067885610670610d68565b858403610d70565b60019150509392505050565b60006012905090565b60006106976111bc565b905090565b600061073e6106a9610d68565b8484600160006106b7610d68565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546107399190611fc0565b610d70565b6001905092915050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107cf90612062565b60405180910390fd5b6107e2828261127f565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885826040516108289190611c34565b60405180910390a25050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60006108c5600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206113df565b9050919050565b6060600480546108db90611ecd565b80601f016020809104026020016040519081016040528092919081815260200182805461090790611ecd565b80156109545780601f1061092957610100808354040283529160200191610954565b820191906000526020600020905b81548152906001019060200180831161093757829003601f168201915b5050505050905090565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e590612062565b60405180910390fd5b6109f882826113ed565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca582604051610a3e9190611c34565b60405180910390a25050565b60008060016000610a59610d68565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610b16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0d906120f4565b60405180910390fd5b610b2a610b21610d68565b85858403610d70565b600191505092915050565b6000610b49610b42610d68565b8484610f3b565b6001905092915050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b83421115610be2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd990612160565b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610c118c6115c4565b89604051602001610c2796959493929190612180565b6040516020818303038152906040528051906020012090506000610c4a82611622565b90506000610c5a8287878761163c565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc19061222d565b60405180910390fd5b610cd58a8a8a610d70565b50505050505050505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610de0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dd7906122bf565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610e50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4790612351565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051610f2e9190611c34565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610fab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fa2906123e3565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561101b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101290612475565b60405180910390fd5b611026838383611667565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050818110156110ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110a390612507565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461113f9190611fc0565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516111a39190611c34565b60405180910390a36111b684848461166c565b50505050565b60007f000000000000000000000000000000000000000000000000000000000000000a46141561120e577f17b074fd049541578d029dfa94d1389a7db759e0497e5e30d2b6f7d75413e140905061127c565b6112797f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7fc79ca22c0992a4cca3636d52362fc61ce7d8001b81a7b225d701c42fb0636f327fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6611671565b90505b90565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156112ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112e690612573565b60405180910390fd5b6112fb60008383611667565b806002600082825461130d9190611fc0565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546113629190611fc0565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516113c79190611c34565b60405180910390a36113db6000838361166c565b5050565b600081600001549050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561145d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145490612605565b60405180910390fd5b61146982600083611667565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050818110156114ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e690612697565b60405180910390fd5b8181036000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816002600082825461154691906126b7565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516115ab9190611c34565b60405180910390a36115bf8360008461166c565b505050565b600080600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050611611816113df565b915061161c816116ab565b50919050565b600061163561162f6111bc565b836116c1565b9050919050565b600080600061164d878787876116f4565b9150915061165a81611801565b8192505050949350505050565b505050565b505050565b6000838383463060405160200161168c9594939291906126eb565b6040516020818303038152906040528051906020012090509392505050565b6001816000016000828254019250508190555050565b600082826040516020016116d69291906127b6565b60405160208183030381529060405280519060200120905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c111561172f5760006003915091506117f8565b601b8560ff16141580156117475750601c8560ff1614155b156117595760006004915091506117f8565b60006001878787876040516000815260200160405260405161177e94939291906127ed565b6020604051602081039080840390855afa1580156117a0573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156117ef576000600192509250506117f8565b80600092509250505b94509492505050565b6000600481111561181557611814612832565b5b81600481111561182857611827612832565b5b1415611833576119d3565b6001600481111561184757611846612832565b5b81600481111561185a57611859612832565b5b141561189b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611892906128ad565b60405180910390fd5b600260048111156118af576118ae612832565b5b8160048111156118c2576118c1612832565b5b1415611903576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118fa90612919565b60405180910390fd5b6003600481111561191757611916612832565b5b81600481111561192a57611929612832565b5b141561196b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611962906129ab565b60405180910390fd5b60048081111561197e5761197d612832565b5b81600481111561199157611990612832565b5b14156119d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c990612a3d565b60405180910390fd5b5b50565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611a10816119db565b8114611a1b57600080fd5b50565b600081359050611a2d81611a07565b92915050565b600060208284031215611a4957611a486119d6565b5b6000611a5784828501611a1e565b91505092915050565b60008115159050919050565b611a7581611a60565b82525050565b6000602082019050611a906000830184611a6c565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611ad0578082015181840152602081019050611ab5565b83811115611adf576000848401525b50505050565b6000601f19601f8301169050919050565b6000611b0182611a96565b611b0b8185611aa1565b9350611b1b818560208601611ab2565b611b2481611ae5565b840191505092915050565b60006020820190508181036000830152611b498184611af6565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b7c82611b51565b9050919050565b611b8c81611b71565b8114611b9757600080fd5b50565b600081359050611ba981611b83565b92915050565b6000819050919050565b611bc281611baf565b8114611bcd57600080fd5b50565b600081359050611bdf81611bb9565b92915050565b60008060408385031215611bfc57611bfb6119d6565b5b6000611c0a85828601611b9a565b9250506020611c1b85828601611bd0565b9150509250929050565b611c2e81611baf565b82525050565b6000602082019050611c496000830184611c25565b92915050565b600080600060608486031215611c6857611c676119d6565b5b6000611c7686828701611b9a565b9350506020611c8786828701611b9a565b9250506040611c9886828701611bd0565b9150509250925092565b600060ff82169050919050565b611cb881611ca2565b82525050565b6000602082019050611cd36000830184611caf565b92915050565b6000819050919050565b611cec81611cd9565b82525050565b6000602082019050611d076000830184611ce3565b92915050565b600060208284031215611d2357611d226119d6565b5b6000611d3184828501611b9a565b91505092915050565b611d4381611b71565b82525050565b6000602082019050611d5e6000830184611d3a565b92915050565b611d6d81611ca2565b8114611d7857600080fd5b50565b600081359050611d8a81611d64565b92915050565b611d9981611cd9565b8114611da457600080fd5b50565b600081359050611db681611d90565b92915050565b600080600080600080600060e0888a031215611ddb57611dda6119d6565b5b6000611de98a828b01611b9a565b9750506020611dfa8a828b01611b9a565b9650506040611e0b8a828b01611bd0565b9550506060611e1c8a828b01611bd0565b9450506080611e2d8a828b01611d7b565b93505060a0611e3e8a828b01611da7565b92505060c0611e4f8a828b01611da7565b91505092959891949750929550565b60008060408385031215611e7557611e746119d6565b5b6000611e8385828601611b9a565b9250506020611e9485828601611b9a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680611ee557607f821691505b60208210811415611ef957611ef8611e9e565b5b50919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206160008201527f6c6c6f77616e6365000000000000000000000000000000000000000000000000602082015250565b6000611f5b602883611aa1565b9150611f6682611eff565b604082019050919050565b60006020820190508181036000830152611f8a81611f4e565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611fcb82611baf565b9150611fd683611baf565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561200b5761200a611f91565b5b828201905092915050565b7f4f6e6c79204c32204272696467652063616e206d696e7420616e64206275726e600082015250565b600061204c602083611aa1565b915061205782612016565b602082019050919050565b6000602082019050818103600083015261207b8161203f565b9050919050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b60006120de602583611aa1565b91506120e982612082565b604082019050919050565b6000602082019050818103600083015261210d816120d1565b9050919050565b7f45524332305065726d69743a206578706972656420646561646c696e65000000600082015250565b600061214a601d83611aa1565b915061215582612114565b602082019050919050565b600060208201905081810360008301526121798161213d565b9050919050565b600060c0820190506121956000830189611ce3565b6121a26020830188611d3a565b6121af6040830187611d3a565b6121bc6060830186611c25565b6121c96080830185611c25565b6121d660a0830184611c25565b979650505050505050565b7f45524332305065726d69743a20696e76616c6964207369676e61747572650000600082015250565b6000612217601e83611aa1565b9150612222826121e1565b602082019050919050565b600060208201905081810360008301526122468161220a565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006122a9602483611aa1565b91506122b48261224d565b604082019050919050565b600060208201905081810360008301526122d88161229c565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b600061233b602283611aa1565b9150612346826122df565b604082019050919050565b6000602082019050818103600083015261236a8161232e565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b60006123cd602583611aa1565b91506123d882612371565b604082019050919050565b600060208201905081810360008301526123fc816123c0565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b600061245f602383611aa1565b915061246a82612403565b604082019050919050565b6000602082019050818103600083015261248e81612452565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b60006124f1602683611aa1565b91506124fc82612495565b604082019050919050565b60006020820190508181036000830152612520816124e4565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b600061255d601f83611aa1565b915061256882612527565b602082019050919050565b6000602082019050818103600083015261258c81612550565b9050919050565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b60006125ef602183611aa1565b91506125fa82612593565b604082019050919050565b6000602082019050818103600083015261261e816125e2565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b6000612681602283611aa1565b915061268c82612625565b604082019050919050565b600060208201905081810360008301526126b081612674565b9050919050565b60006126c282611baf565b91506126cd83611baf565b9250828210156126e0576126df611f91565b5b828203905092915050565b600060a0820190506127006000830188611ce3565b61270d6020830187611ce3565b61271a6040830186611ce3565b6127276060830185611c25565b6127346080830184611d3a565b9695505050505050565b600081905092915050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b600061277f60028361273e565b915061278a82612749565b600282019050919050565b6000819050919050565b6127b06127ab82611cd9565b612795565b82525050565b60006127c182612772565b91506127cd828561279f565b6020820191506127dd828461279f565b6020820191508190509392505050565b60006080820190506128026000830187611ce3565b61280f6020830186611caf565b61281c6040830185611ce3565b6128296060830184611ce3565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b6000612897601883611aa1565b91506128a282612861565b602082019050919050565b600060208201905081810360008301526128c68161288a565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000612903601f83611aa1565b915061290e826128cd565b602082019050919050565b60006020820190508181036000830152612932816128f6565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000612995602283611aa1565b91506129a082612939565b604082019050919050565b600060208201905081810360008301526129c481612988565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000612a27602283611aa1565b9150612a32826129cb565b604082019050919050565b60006020820190508181036000830152612a5681612a1a565b905091905056fea26469706673582212207181ce9a02b427094b74c5404e30a090e6ee25656076ae413e01f3c7f06475d564736f6c63430008090033",
"nonce": 1,
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000002": "0x00000000000000000000000000000000000000000000225ba536a2b6ff234ac2",
"0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae9",
"0x0000000000000000000000000000000000000000000000000000000000000007": "0x0000000000000000000000004200000000000000000000000000000000000010",
"0x1509dc2d3edb4ce500ec2cb71c3704f1ff95f76ef6d47e814e70a9baeb685496": "0x0000000000000000000000000000000000000000000000a3b61828488b117259"
}
}
}
{
"0x4200000000000000000000000000000000000000": {
"balance": "0x0",
"code": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c806382e3702d1461003b578063cafa81dc14610072575b600080fd5b61005e610049366004610112565b60006020819052908152604090205460ff1681565b604051901515815260200160405180910390f35b61008561008036600461015a565b610087565b005b6001600080833360405160200161009f929190610229565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291815281516020928301208352908201929092520160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905550565b60006020828403121561012457600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561016c57600080fd5b813567ffffffffffffffff8082111561018457600080fd5b818401915084601f83011261019857600080fd5b8135818111156101aa576101aa61012b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156101f0576101f061012b565b8160405282815287602084870101111561020957600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000835160005b8181101561024a5760208187018101518583015201610230565b81811115610259576000828501525b5060609390931b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016919092019081526014019291505056fea26469706673582212200b48ded2e68f3541ccec6b89e65ba6788c333cfabcd8ebb2d833e41d3b8df28164736f6c63430008090033",
"nonce": 0,
"storage": {
"0xc32253d1d1c74c419f0e9cc13cf38144381fbc9374b0b8cd31f260009e851a74": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"0x4200000000000000000000000000000000000007": {
"balance": "0x0",
"code": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063a71198691161005b578063a71198691461012a578063b1b1b2091461014a578063cbd4ece91461016d578063ecc704281461018057600080fd5b806321d800ec1461008d5780633dbb202b146100c55780636e296e45146100da57806382e3702d14610107575b600080fd5b6100b061009b366004610826565b60006020819052908152604090205460ff1681565b60405190151581526020015b60405180910390f35b6100d86100d3366004610942565b610197565b005b6100e26102e2565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100bc565b6100b0610115366004610826565b60026020526000908152604090205460ff1681565b6005546100e29073ffffffffffffffffffffffffffffffffffffffff1681565b6100b0610158366004610826565b60016020526000908152604090205460ff1681565b6100d861017b3660046109ad565b61038b565b61018960035481565b6040519081526020016100bc565b60006101a784338560035461078d565b80516020808301919091206000908152600290915260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517fcafa81dc0000000000000000000000000000000000000000000000000000000081529091507342000000000000000000000000000000000000009063cafa81dc9061023c908490600401610a89565b600060405180830381600087803b15801561025657600080fd5b505af115801561026a573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a3385600354866040516102bc9493929190610aa3565b60405180910390a26001600360008282546102d79190610aef565b909155505050505050565b60045460009073ffffffffffffffffffffffffffffffffffffffff1661dead141561036e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f78446f6d61696e4d65737361676553656e646572206973206e6f74207365740060448201526064015b60405180910390fd5b5060045473ffffffffffffffffffffffffffffffffffffffff1690565b60055473ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffeeeeffffffffffffffffffffffffffffffffeeef330173ffffffffffffffffffffffffffffffffffffffff161461046a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f50726f7669646564206d65737361676520636f756c64206e6f7420626520766560448201527f7269666965642e000000000000000000000000000000000000000000000000006064820152608401610365565b60006104788585858561078d565b8051602080830191909120600081815260019092526040909120549192509060ff1615610527576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f50726f7669646564206d6573736167652068617320616c72656164792062656560448201527f6e2072656365697665642e0000000000000000000000000000000000000000006064820152608401610365565b73ffffffffffffffffffffffffffffffffffffffff8616734200000000000000000000000000000000000000141561059957600090815260016020819052604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909117905550610787565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff878116919091179091556040516000918816906105f2908790610b2e565b6000604051808303816000865af19150503d806000811461062f576040519150601f19603f3d011682016040523d82523d6000602084013e610634565b606091505b5050600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801515600114156106d557600082815260016020819052604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169092179091555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a2610701565b60405182907f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f90600090a25b600083334360405160200161071893929190610b4a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600090815291829052902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505b50505050565b6060848484846040516024016107a69493929190610b9c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b60006020828403121561083857600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461086357600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126108a857600080fd5b813567ffffffffffffffff808211156108c3576108c3610868565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561090957610909610868565b8160405283815286602085880101111561092257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561095757600080fd5b6109608461083f565b9250602084013567ffffffffffffffff81111561097c57600080fd5b61098886828701610897565b925050604084013563ffffffff811681146109a257600080fd5b809150509250925092565b600080600080608085870312156109c357600080fd5b6109cc8561083f565b93506109da6020860161083f565b9250604085013567ffffffffffffffff8111156109f657600080fd5b610a0287828801610897565b949793965093946060013593505050565b60005b83811015610a2e578181015183820152602001610a16565b838111156107875750506000910152565b60008151808452610a57816020860160208601610a13565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610a9c6020830184610a3f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff85168152608060208201526000610ad26080830186610a3f565b905083604083015263ffffffff8316606083015295945050505050565b60008219821115610b29577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b60008251610b40818460208701610a13565b9190910192915050565b60008451610b5c818460208901610a13565b60609490941b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001691909301908152601481019190915260340192915050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152610bd56080830185610a3f565b90508260608301529594505050505056fea26469706673582212202e10f5e906e4d6b76a9239c97481d533896c41191186b3ec3ca5feab5203fde664736f6c63430008090033",
"nonce": 0,
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000000001b05e",
"0x174b99571f743bb9e3d8522491be4132c795fc625571f8b9f181353f5aac7dd7": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"0x467194771dae2967aef3ecbedd3bf9a310c76c65": {
"balance": "0x0",
"code": "0x608060405234801561001057600080fd5b50600436106100b45760003560e01c806365fae35e1161007157806365fae35e14610230578063662a633a146102745780639c52a7f114610377578063a3a79548146103bb578063bf353dbb1461048e578063c01e1bd6146104e6576100b4565b8063092d0ce3146100b957806332b7006d146100ed5780633cb747bf146101a057806343d726d6146101d457806347535d7b146101de57806356eff267146101fc575b600080fd5b6100c161051a565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61019e6004803603608081101561010357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803563ffffffff1690602001909291908035906020019064010000000081111561015a57600080fd5b82018360208201111561016c57600080fd5b8035906020019184600183028401116401000000008311171561018e57600080fd5b909192939192939050505061053e565b005b6101a8610614565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101dc610638565b005b6101e6610722565b6040518082815260200191505060405180910390f35b610204610728565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102726004803603602081101561024657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061074c565b005b610375600480360360c081101561028a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561033157600080fd5b82018360208201111561034357600080fd5b8035906020019184600183028401116401000000008311171561036557600080fd5b909192939192939050505061088a565b005b6103b96004803603602081101561038d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610cda565b005b61048c600480360360a08110156103d157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803563ffffffff1690602001909291908035906020019064010000000081111561044857600080fd5b82018360208201111561045a57600080fd5b8035906020019184600183028401116401000000008311171561047c57600080fd5b9091929391929390505050610e19565b005b6104d0600480360360208110156104a457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ef0565b6040518082815260200191505060405180910390f35b6104ee610f08565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b7f00000000000000000000000010e6593cdda8c58a1d0f14c5164b376352a55f2f81565b7f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146105ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4c32444149546f6b656e4272696467652f746f6b656e2d6e6f742d646169000081525060200191505060405180910390fd5b61060d333386868686610f2c565b5050505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60018060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146106ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4c32444149546f6b656e4272696467652f6e6f742d617574686f72697a65640081525060200191505060405180910390fd5b60006002819055507f1cdde67b72a90f19919ac732a437ac2f7a10fc128d28c2a6e525d89ce5cd9d3a60405160405180910390a1565b60025481565b7f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da181565b60018060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414610800576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4c32444149546f6b656e4272696467652f6e6f742d617574686f72697a65640081525060200191505060405180910390fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508073ffffffffffffffffffffffffffffffffffffffff167fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a6060405160405180910390a250565b7f00000000000000000000000010e6593cdda8c58a1d0f14c5164b376352a55f2f6108b36112f5565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610936576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180611427602e913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166109556112f5565b73ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b815260040160206040518083038186803b15801561099a57600080fd5b505afa1580156109ae573d6000803e3d6000fd5b505050506040513d60208110156109c457600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614610a41576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001806114556030913960400191505060405180910390fd5b7f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16148015610ae757507f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da173ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16145b610b59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4c32444149546f6b656e4272696467652f746f6b656e2d6e6f742d646169000081525060200191505060405180910390fd5b7f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da173ffffffffffffffffffffffffffffffffffffffff166340c10f1986866040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015610bea57600080fd5b505af1158015610bfe573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd8988888888604051808573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a45050505050505050565b60018060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414610d8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4c32444149546f6b656e4272696467652f6e6f742d617574686f72697a65640081525060200191505060405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508073ffffffffffffffffffffffffffffffffffffffff167f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b60405160405180910390a250565b7f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614610eda576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4c32444149546f6b656e4272696467652f746f6b656e2d6e6f742d646169000081525060200191505060405180910390fd5b610ee8338686868686610f2c565b505050505050565b60016020528060005260406000206000915090505481565b7f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f81565b600160025414610fa4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f4c32444149546f6b656e4272696467652f636c6f73656400000000000000000081525060200191505060405180910390fd5b7f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da173ffffffffffffffffffffffffffffffffffffffff16639dc29fac33866040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b15801561103557600080fd5b505af1158015611049573d6000803e3d6000fd5b50505050600063a9f9e67560e01b7f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f7f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da18989898888604051602401808873ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505098505050505050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506111de7f00000000000000000000000010e6593cdda8c58a1d0f14c5164b376352a55f2f858361131e565b3373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da173ffffffffffffffffffffffffffffffffffffffff167f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f73ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e89898888604051808573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a450505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6113266112f5565b73ffffffffffffffffffffffffffffffffffffffff16633dbb202b8483856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff168152602001806020018363ffffffff168152602001828103825284818151815260200191508051906020019080838360005b838110156113bb5780820151818401526020810190506113a0565b50505050905090810190601f1680156113e85780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561140957600080fd5b505af115801561141d573d6000803e3d6000fd5b5050505050505056fe4f564d5f58434841494e3a206d657373656e67657220636f6e747261637420756e61757468656e746963617465644f564d5f58434841494e3a2077726f6e672073656e646572206f662063726f73732d646f6d61696e206d657373616765a264697066735822122096b15b6d3a22ffc8a296ccd771ce8d2bb75f0fbbd83b41c342a38aac4330798e64736f6c63430007060033",
"nonce": 1,
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000004200000000000000000000000000000000000007",
"0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000001"
}
},
"0x6659612eb0e2464ccadf7a5e851bcd12873f6e04": {
"balance": "0x2b08bb3dcd1c1c",
"code": "0x",
"nonce": 113,
"storage": {}
},
"0xda10009cbd5d07dd0cecc66161fc93d7c9000da1": {
"balance": "0x0",
"code": "0x608060405234801561001057600080fd5b50600436106101425760003560e01c806370a08231116100b8578063a457c2d71161007c578063a457c2d7146103b0578063a9059cbb146103dc578063bf353dbb14610408578063cd0d00961461042e578063d505accf14610436578063dd62ed3e1461048757610142565b806370a082311461030a5780637ecebe001461033057806395d89b41146103565780639c52a7f11461035e5780639dc29fac1461038457610142565b8063313ce5671161010a578063313ce5671461025c5780633644e5151461027a578063395093511461028257806340c10f19146102ae57806354fd4d50146102dc57806365fae35e146102e457610142565b806306fdde0314610147578063095ea7b3146101c457806318160ddd1461020457806323b872dd1461021e57806330adf81f14610254575b600080fd5b61014f6104b5565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610189578181015183820152602001610171565b50505050905090810190601f1680156101b65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101f0600480360360408110156101da57600080fd5b506001600160a01b0381351690602001356104df565b604080519115158252519081900360200190f35b61020c610534565b60408051918252519081900360200190f35b6101f06004803603606081101561023457600080fd5b506001600160a01b0381358116916020810135909116906040013561053a565b61020c610725565b610264610749565b6040805160ff9092168252519081900360200190f35b61020c61074e565b6101f06004803603604081101561029857600080fd5b506001600160a01b0381351690602001356107ae565b6102da600480360360408110156102c457600080fd5b506001600160a01b038135169060200135610835565b005b61014f610957565b6102da600480360360208110156102fa57600080fd5b50356001600160a01b0316610974565b61020c6004803603602081101561032057600080fd5b50356001600160a01b0316610a12565b61020c6004803603602081101561034657600080fd5b50356001600160a01b0316610a24565b61014f610a36565b6102da6004803603602081101561037457600080fd5b50356001600160a01b0316610a55565b6102da6004803603604081101561039a57600080fd5b506001600160a01b038135169060200135610af2565b6101f0600480360360408110156103c657600080fd5b506001600160a01b038135169060200135610c84565b6101f0600480360360408110156103f257600080fd5b506001600160a01b038135169060200135610d55565b61020c6004803603602081101561041e57600080fd5b50356001600160a01b0316610e7a565b61020c610e8c565b6102da600480360360e081101561044c57600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135610eb0565b61020c6004803603604081101561049d57600080fd5b506001600160a01b0381358116916020013516611134565b6040518060400160405280600e81526020016d2230b49029ba30b13632b1b7b4b760911b81525081565b3360008181526003602090815260408083206001600160a01b03871680855290835281842086905581518681529151939490939092600080516020611259833981519152928290030190a35060015b92915050565b60015481565b60006001600160a01b0383161580159061055d57506001600160a01b0383163014155b6105a4576040805162461bcd60e51b81526020600482015260136024820152724461692f696e76616c69642d6164647265737360681b604482015290519081900360640190fd5b6001600160a01b0384166000908152600260205260409020548281101561060d576040805162461bcd60e51b81526020600482015260186024820152774461692f696e73756666696369656e742d62616c616e636560401b604482015290519081900360640190fd5b6001600160a01b03851633146106c7576001600160a01b038516600090815260036020908152604080832033845290915290205460001981146106c5578381101561069c576040805162461bcd60e51b815260206004820152601a6024820152794461692f696e73756666696369656e742d616c6c6f77616e636560301b604482015290519081900360640190fd5b6001600160a01b0386166000908152600360209081526040808320338452909152902084820390555b505b6001600160a01b038086166000818152600260209081526040808320888703905593881680835291849020805488019055835187815293519193600080516020611239833981519152929081900390910190a3506001949350505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b6000467f000000000000000000000000000000000000000000000000000000000000000a81146107865761078181611151565b6107a8565b7fc7bbf40a5fb081e6759d5d0ce2447e84427793536887332b932877b94ce51bd65b91505090565b3360009081526003602090815260408083206001600160a01b038616845290915281205481906107de9084611228565b3360008181526003602090815260408083206001600160a01b038a16808552908352928190208590558051858152905194955091936000805160206112598339815191529281900390910190a35060019392505050565b3360009081526020819052604090205460011461088e576040805162461bcd60e51b815260206004820152601260248201527111185a4bdb9bdd0b585d5d1a1bdc9a5e995960721b604482015290519081900360640190fd5b6001600160a01b038216158015906108af57506001600160a01b0382163014155b6108f6576040805162461bcd60e51b81526020600482015260136024820152724461692f696e76616c69642d6164647265737360681b604482015290519081900360640190fd5b6001600160a01b03821660009081526002602052604090208054820190556001546109219082611228565b6001556040805182815290516001600160a01b038416916000916000805160206112398339815191529181900360200190a35050565b604051806040016040528060018152602001601960f91b81525081565b336000908152602081905260409020546001146109cd576040805162461bcd60e51b815260206004820152601260248201527111185a4bdb9bdd0b585d5d1a1bdc9a5e995960721b604482015290519081900360640190fd5b6001600160a01b03811660008181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250565b60026020526000908152604090205481565b60046020526000908152604090205481565b6040518060400160405280600381526020016244414960e81b81525081565b33600090815260208190526040902054600114610aae576040805162461bcd60e51b815260206004820152601260248201527111185a4bdb9bdd0b585d5d1a1bdc9a5e995960721b604482015290519081900360640190fd5b6001600160a01b038116600081815260208190526040808220829055517f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b9190a250565b6001600160a01b03821660009081526002602052604090205481811015610b5b576040805162461bcd60e51b81526020600482015260186024820152774461692f696e73756666696369656e742d62616c616e636560401b604482015290519081900360640190fd5b6001600160a01b0383163314801590610b84575033600090815260208190526040902054600114155b15610c33576001600160a01b03831660009081526003602090815260408083203384529091529020546000198114610c315782811015610c08576040805162461bcd60e51b815260206004820152601a6024820152794461692f696e73756666696369656e742d616c6c6f77616e636560301b604482015290519081900360640190fd5b6001600160a01b0384166000908152600360209081526040808320338452909152902083820390555b505b6001600160a01b0383166000818152600260209081526040808320868603905560018054879003905580518681529051929392600080516020611239833981519152929181900390910190a3505050565b3360009081526003602090815260408083206001600160a01b038616845290915281205482811015610cfa576040805162461bcd60e51b815260206004820152601a6024820152794461692f696e73756666696369656e742d616c6c6f77616e636560301b604482015290519081900360640190fd5b3360008181526003602090815260408083206001600160a01b03891680855290835292819020948790039485905580518581529051929392600080516020611259833981519152929181900390910190a35060019392505050565b60006001600160a01b03831615801590610d7857506001600160a01b0383163014155b610dbf576040805162461bcd60e51b81526020600482015260136024820152724461692f696e76616c69642d6164647265737360681b604482015290519081900360640190fd5b3360009081526002602052604090205482811015610e1f576040805162461bcd60e51b81526020600482015260186024820152774461692f696e73756666696369656e742d62616c616e636560401b604482015290519081900360640190fd5b33600081815260026020908152604080832087860390556001600160a01b0388168084529281902080548801905580518781529051929392600080516020611239833981519152929181900390910190a35060019392505050565b60006020819052908152604090205481565b7f000000000000000000000000000000000000000000000000000000000000000a81565b83421115610efa576040805162461bcd60e51b815260206004820152601260248201527111185a4bdc195c9b5a5d0b595e1c1a5c995960721b604482015290519081900360640190fd5b4660007f000000000000000000000000000000000000000000000000000000000000000a8214610f3257610f2d82611151565b610f54565b7fc7bbf40a5fb081e6759d5d0ce2447e84427793536887332b932877b94ce51bd65b6001600160a01b03808b1660008181526004602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981840152808401859052948e166060860152608085018d905260a085015260c08085018c90528251808603909101815260e08501835280519082012061190160f01b6101008601526101028501959095526101228085019590955281518085039095018552610142909301905282519290910191909120915015801590611098575060018186868660405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611079573d6000803e3d6000fd5b505050602060405103516001600160a01b0316896001600160a01b0316145b6110de576040805162461bcd60e51b815260206004820152601260248201527111185a4bda5b9d985b1a590b5c195c9b5a5d60721b604482015290519081900360640190fd5b6001600160a01b03808a166000818152600360209081526040808320948d16808452948252918290208b905581518b815291516000805160206112598339815191529281900390910190a3505050505050505050565b600360209081526000928352604080842090915290825290205481565b604080518082018252600e81526d2230b49029ba30b13632b1b7b4b760911b6020918201528151808301835260018152601960f91b9082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818301527f0b1461ddc0c1d5ded79a1db0f74dae949050a7c0b28728c724b24958c27a328b818401527fad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5606082015260808101939093523060a0808501919091528251808503909101815260c0909301909152815191012090565b8082018281101561052e57600080fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a26469706673582212204174ca7efe9461957e50debebcf436a7f5badaf0bd4b64389fd2735d2369a5b264736f6c63430007060033",
"nonce": 1,
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000061bf8d88298b1ffe52f94d",
"0x3d696424a1574a5cfad82632e041a0db95524994dc24c3dc663736e964bde80b": "0x0000000000000000000000000000000000000000000211654585005212800000",
"0x8d978f993a82ab3ac5aed2bd07c006cca7add3f770030beb5560ea0fb804b15c": "0x0000000000000000000000000000000000000000000000000000000000000001"
}
}
}
#!/bin/bash
HASH=$1
if [[ -z $HASH ]]; then
exit 1
fi
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd )"
TRACES=$DIR/call-traces
RECEIPTS=$DIR/receipts
DIFFS=$DIR/state-diffs
mkdir -p $TRACES
mkdir -p $RECEIPTS
mkdir -p $DIFFS
cast rpc \
debug_traceTransaction \
$HASH \
'{"tracer": "callTracer"}' | jq > $TRACES/$HASH.json
cast receipt $HASH --json | jq > $RECEIPTS/$HASH.json
cast rpc \
debug_traceTransaction \
$HASH \
'{"tracer": "prestateTracer"}' | jq > $DIFFS/$HASH.json
package crossdomain
import (
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
)
var (
// Standard ABI types
Uint256Type, _ = abi.NewType("uint256", "", nil)
BytesType, _ = abi.NewType("bytes", "", nil)
AddressType, _ = abi.NewType("address", "", nil)
)
// WithdrawalMessage represents a Withdrawal. The Withdrawal
// and LegacyWithdrawal types must implement this interface.
type WithdrawalMessage interface {
Encode() ([]byte, error)
Decode([]byte) error
Hash() (common.Hash, error)
StorageSlot() (common.Hash, error)
}
package crossdomain
import (
"errors"
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
var _ WithdrawalMessage = (*Withdrawal)(nil)
// Withdrawal represents a withdrawal transaction on L2
type Withdrawal struct {
Nonce *big.Int
Sender *common.Address
Target *common.Address
Value *big.Int
GasLimit *big.Int
Data []byte
}
// NewWithdrawal will create a Withdrawal
func NewWithdrawal(
nonce *big.Int,
sender, target *common.Address,
value, gasLimit *big.Int,
data []byte,
) *Withdrawal {
return &Withdrawal{
Nonce: nonce,
Sender: sender,
Target: target,
Value: value,
GasLimit: gasLimit,
Data: data,
}
}
// Encode will serialize the Withdrawal so that it is suitable for hashing.
func (w *Withdrawal) Encode() ([]byte, error) {
args := abi.Arguments{
{Name: "nonce", Type: Uint256Type},
{Name: "sender", Type: AddressType},
{Name: "target", Type: AddressType},
{Name: "value", Type: Uint256Type},
{Name: "gasLimit", Type: Uint256Type},
{Name: "data", Type: BytesType},
}
enc, err := args.Pack(w.Nonce, w.Sender, w.Target, w.Value, w.GasLimit, w.Data)
if err != nil {
return nil, err
}
return enc, nil
}
// Decode will deserialize a Withdrawal
func (w *Withdrawal) Decode(data []byte) error {
args := abi.Arguments{
{Name: "nonce", Type: Uint256Type},
{Name: "sender", Type: AddressType},
{Name: "target", Type: AddressType},
{Name: "value", Type: Uint256Type},
{Name: "gasLimit", Type: Uint256Type},
{Name: "data", Type: BytesType},
}
decoded, err := args.Unpack(data)
if err != nil {
return err
}
nonce, ok := decoded[0].(*big.Int)
if !ok {
return errors.New("cannot abi decode nonce")
}
sender, ok := decoded[1].(common.Address)
if !ok {
return errors.New("cannot abi decode sender")
}
target, ok := decoded[2].(common.Address)
if !ok {
return errors.New("cannot abi decode target")
}
value, ok := decoded[3].(*big.Int)
if !ok {
return errors.New("cannot abi decode value")
}
gasLimit, ok := decoded[4].(*big.Int)
if !ok {
return errors.New("cannot abi decode gasLimit")
}
msgData, ok := decoded[5].([]byte)
if !ok {
return errors.New("cannot abi decode data")
}
w.Nonce = nonce
w.Sender = &sender
w.Target = &target
w.Value = value
w.GasLimit = gasLimit
w.Data = msgData
return nil
}
// Hash will hash the Withdrawal. This is the hash that is computed in
// the L2ToL1MessagePasser. The encoding is the same as the v1 cross domain
// message encoding without the 4byte selector prepended.
func (w *Withdrawal) Hash() (common.Hash, error) {
encoded, err := w.Encode()
if err != nil {
return common.Hash{}, err
}
hash := crypto.Keccak256(encoded)
return common.BytesToHash(hash), nil
}
// StorageSlot will compute the storage slot that will be set to
// true in the L2ToL1MessagePasser. The withdrawal proof sent to
// L1 will prove that this storage slot is set to "true".
func (w *Withdrawal) StorageSlot() (common.Hash, error) {
hash, err := w.Hash()
if err != nil {
return common.Hash{}, err
}
preimage := make([]byte, 64)
copy(preimage, hash.Bytes())
slot := crypto.Keccak256(preimage)
return common.BytesToHash(slot), nil
}
package crossdomain_test
import (
"fmt"
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/stretchr/testify/require"
)
// FuzzEncodeDecodeWithdrawal will fuzz encoding and decoding of a Withdrawal
func FuzzEncodeDecodeWithdrawal(f *testing.F) {
f.Fuzz(func(t *testing.T, _nonce, _sender, _target, _value, _gasLimit, data []byte) {
nonce := new(big.Int).SetBytes(_nonce)
sender := common.BytesToAddress(_sender)
target := common.BytesToAddress(_target)
value := new(big.Int).SetBytes(_value)
gasLimit := new(big.Int).SetBytes(_gasLimit)
withdrawal := crossdomain.NewWithdrawal(
nonce,
&sender,
&target,
value,
gasLimit,
data,
)
encoded, err := withdrawal.Encode()
require.Nil(t, err)
var w crossdomain.Withdrawal
err = w.Decode(encoded)
require.Nil(t, err)
require.Equal(t, withdrawal.Nonce.Uint64(), w.Nonce.Uint64())
require.Equal(t, withdrawal.Sender, w.Sender)
require.Equal(t, withdrawal.Target, w.Target)
require.Equal(t, withdrawal.Value.Uint64(), w.Value.Uint64())
require.Equal(t, withdrawal.GasLimit.Uint64(), w.GasLimit.Uint64())
require.Equal(t, withdrawal.Data, w.Data)
})
}
// TestWithdrawalHashing will test the correct computation of Withdrawal hashes
// and the storage slot that the withdrawal hash is stored in. Test vectors
// generated with forge
func TestWithdrawalHashing(t *testing.T) {
type expect struct {
Hash common.Hash
Slot common.Hash
}
cases := []struct {
Withdrawal *crossdomain.Withdrawal
Expect expect
}{
{
Withdrawal: crossdomain.NewWithdrawal(
big.NewInt(0),
ptr(common.HexToAddress("0xaa179e0640054db6ba4fe9b291dd3b248f4b4960")),
ptr(common.HexToAddress("0x9b2b72e299e04f00fc5b386972d8951bb870d65e")),
big.NewInt(1),
decimalStringToBig("124808255574871339965699013847079823271"),
hexutil.MustDecode("0x2e1d8f26c6611c04d9f8ea352444b9d366f76c19897c851f5ce9a4d650cf2355f92da68491af279f78110a31c6cb26db09b20b3b1307ff99be0bc410d8bf6994b0e87ced86b747773597dfd1da84268508e34a46a087088ed9276738ffe39e7a1264"),
),
Expect: expect{
Hash: common.HexToHash("0xbddee6e1e89962069cb559abae8342ea3490f9488509c22c482c4ba73988165c"),
Slot: common.HexToHash("0x26bea3ec4f60cfc1152358454086b7f6a3b669d84a0ec088b2e316ff88c2a892"),
},
},
{
Withdrawal: crossdomain.NewWithdrawal(
big.NewInt(0),
ptr(common.HexToAddress("0x00000000000000000000000000000000000011bc")),
ptr(common.HexToAddress("0x00000000000000000000000000000000000033eb")),
big.NewInt(26),
decimalStringToBig("22338"),
hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000004"),
),
Expect: expect{
Hash: common.HexToHash("0x65768976d27ba8a7f91c5b267b97d29830103171863c0ba24f3234ef07d0f8e3"),
Slot: common.HexToHash("0xd73bc49fa8e52d7717fb65cbec7ff0e30bf4e2fbbd38924d1b2efa1f96381517"),
},
},
{
Withdrawal: crossdomain.NewWithdrawal(
big.NewInt(0),
ptr(common.HexToAddress("0x4b0ca57cb88a41771d2cc24ac9fd50afeaa3eedd")),
ptr(common.HexToAddress("0x8a5e8410b2c3e1036c49ff8acae1e659e2508200")),
big.NewInt(3),
decimalStringToBig("115792089237316195423570985008687907853269984665640564039457584007913129639935"),
hexutil.MustDecode("0xce6b96a23be7a1ac1de74f3202dfc4cedaef69502204c0d92f7b352a837a"),
),
Expect: expect{
Hash: common.HexToHash("0x4ba164b689ac62c27c68f41b5f3c4731eb2c25c2d39e4aadcc413d150764624f"),
Slot: common.HexToHash("0xf055f7cec6a95c9bfc93fc2dc0262d2323a7d4e74af5ee608f0fe2acc83fa1ef"),
},
},
}
for i, test := range cases {
t.Run(fmt.Sprintf("case%d", i), func(t *testing.T) {
hash, err := test.Withdrawal.Hash()
require.Nil(t, err)
require.Equal(t, hash, test.Expect.Hash)
slot, err := test.Withdrawal.StorageSlot()
require.Nil(t, err)
require.Equal(t, slot, test.Expect.Slot)
})
}
}
func decimalStringToBig(n string) *big.Int {
ret, ok := new(big.Int).SetString(n, 10)
if !ok {
panic("")
}
return ret
}
func ptr(i common.Address) *common.Address {
return &i
}
......@@ -9,7 +9,10 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus/beacon"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
)
......@@ -35,20 +38,55 @@ type Deployment struct {
Address common.Address
}
type Deployer func(*backends.SimulatedBackend, *bind.TransactOpts, Constructor) (common.Address, error)
type Deployer func(*backends.SimulatedBackend, *bind.TransactOpts, Constructor) (*types.Transaction, error)
func NewBackend() *backends.SimulatedBackend {
return NewBackendWithGenesisTimestamp(0)
}
func NewBackendWithGenesisTimestamp(ts uint64) *backends.SimulatedBackend {
chainConfig := params.ChainConfig{
ChainID: ChainID,
HomesteadBlock: big.NewInt(0),
DAOForkBlock: nil,
DAOForkSupport: false,
EIP150Block: big.NewInt(0),
EIP150Hash: common.Hash{},
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
ByzantiumBlock: big.NewInt(0),
ConstantinopleBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
MuirGlacierBlock: big.NewInt(0),
BerlinBlock: big.NewInt(0),
LondonBlock: big.NewInt(0),
ArrowGlacierBlock: big.NewInt(0),
GrayGlacierBlock: big.NewInt(0),
ShanghaiBlock: nil,
CancunBlock: nil,
// Activated proof of stake. We manually build/commit blocks in the simulator anyway,
// and the timestamp verification of PoS is not against the wallclock,
// preventing blocks from getting stuck temporarily in the future-blocks queue, decreasing setup time a lot.
MergeNetsplitBlock: big.NewInt(0),
TerminalTotalDifficulty: big.NewInt(0),
TerminalTotalDifficultyPassed: true,
}
return backends.NewSimulatedBackendWithOpts(
backends.WithCacheConfig(&core.CacheConfig{
Preimages: true,
}),
backends.WithGenesis(core.Genesis{
Config: params.AllEthashProtocolChanges,
Config: &chainConfig,
Timestamp: ts,
Difficulty: big.NewInt(0),
Alloc: core.GenesisAlloc{
crypto.PubkeyToAddress(TestKey.PublicKey): {Balance: thousandETH},
},
GasLimit: 15000000,
}),
backends.WithConsensus(beacon.New(ethash.NewFaker())),
)
}
......@@ -62,13 +100,22 @@ func Deploy(backend *backends.SimulatedBackend, constructors []Constructor, cb D
opts.GasLimit = 15_000_000
ctx := context.Background()
for i, deployment := range constructors {
addr, err := cb(backend, opts, deployment)
tx, err := cb(backend, opts, deployment)
if err != nil {
return nil, err
}
// The simulator performs asynchronous processing,
// so we need to both commit the change here as
// well as wait for the transaction receipt.
backend.Commit()
addr, err := bind.WaitDeployed(ctx, backend, tx)
if err != nil {
return nil, err
}
if addr == (common.Address{}) {
return nil, fmt.Errorf("no address for %s", deployment.Name)
}
......
......@@ -5,6 +5,7 @@ import (
"os"
"path/filepath"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rpc"
......@@ -12,7 +13,6 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/immutables"
"github.com/ethereum-optimism/optimism/op-chain-ops/state"
"github.com/ethereum/go-ethereum/common"
)
// DeployConfig represents the deployment configuration for Optimism
......@@ -40,7 +40,7 @@ type DeployConfig struct {
L1BlockTime uint64 `json:"l1BlockTime"`
L1GenesisBlockTimestamp hexutil.Uint64 `json:"l1GenesisBlockTimestamp"`
L1GenesisBlockNonce hexutil.Uint64 `json:"l1GenesisBlockNonce"`
CliqueSignerAddress common.Address `json:"cliqueSignerAddress"`
CliqueSignerAddress common.Address `json:"cliqueSignerAddress"` // proof of stake genesis if left zeroed.
L1GenesisBlockGasLimit hexutil.Uint64 `json:"l1GenesisBlockGasLimit"`
L1GenesisBlockDifficulty *hexutil.Big `json:"l1GenesisBlockDifficulty"`
L1GenesisBlockMixHash common.Hash `json:"l1GenesisBlockMixHash"`
......
......@@ -5,11 +5,10 @@ import (
"math/big"
"time"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
)
......@@ -100,12 +99,40 @@ func NewL1Genesis(config *DeployConfig) (*core.Genesis, error) {
return nil, errors.New("must define L1 ChainID")
}
chainConfig := *params.AllCliqueProtocolChanges
chainConfig := params.ChainConfig{
ChainID: uint642Big(config.L1ChainID),
HomesteadBlock: big.NewInt(0),
DAOForkBlock: nil,
DAOForkSupport: false,
EIP150Block: big.NewInt(0),
EIP150Hash: common.Hash{},
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
ByzantiumBlock: big.NewInt(0),
ConstantinopleBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
MuirGlacierBlock: big.NewInt(0),
BerlinBlock: big.NewInt(0),
LondonBlock: big.NewInt(0),
ArrowGlacierBlock: big.NewInt(0),
GrayGlacierBlock: big.NewInt(0),
ShanghaiBlock: nil,
CancunBlock: nil,
}
if config.CliqueSignerAddress != (common.Address{}) {
// warning: clique has an overly strict block header timestamp check against the system wallclock,
// causing blocks to get scheduled as "future block" and not get mined instantly when produced.
chainConfig.Clique = &params.CliqueConfig{
Period: config.L1BlockTime,
Epoch: 30000,
}
chainConfig.ChainID = uint642Big(config.L1ChainID)
} else {
chainConfig.MergeNetsplitBlock = big.NewInt(0)
chainConfig.TerminalTotalDifficulty = big.NewInt(0)
chainConfig.TerminalTotalDifficultyPassed = true
}
gasLimit := config.L1GenesisBlockGasLimit
if gasLimit == 0 {
......@@ -124,7 +151,10 @@ func NewL1Genesis(config *DeployConfig) (*core.Genesis, error) {
timestamp = hexutil.Uint64(time.Now().Unix())
}
extraData := append(append(make([]byte, 32), config.CliqueSignerAddress[:]...), make([]byte, crypto.SignatureLength)...)
extraData := make([]byte, 0)
if config.CliqueSignerAddress != (common.Address{}) {
extraData = append(append(make([]byte, 32), config.CliqueSignerAddress[:]...), make([]byte, crypto.SignatureLength)...)
}
return &core.Genesis{
Config: &chainConfig,
......
package genesis
import (
"context"
"errors"
"fmt"
"math/big"
"strings"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
......@@ -16,6 +17,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
)
......@@ -45,7 +47,7 @@ func BuildL1DeveloperGenesis(config *DeployConfig) (*core.Genesis, error) {
return nil, err
}
backend := deployer.NewBackend()
backend := deployer.NewBackendWithGenesisTimestamp(uint64(config.L1GenesisBlockTimestamp))
deployments, err := deployL1Contracts(config, backend)
if err != nil {
......@@ -78,7 +80,7 @@ func BuildL1DeveloperGenesis(config *DeployConfig) (*core.Genesis, error) {
if err != nil {
return nil, err
}
if err := upgradeProxy(
if _, err := upgradeProxy(
backend,
opts,
depsByName["L2OutputOracleProxy"].Address,
......@@ -96,7 +98,7 @@ func BuildL1DeveloperGenesis(config *DeployConfig) (*core.Genesis, error) {
if err != nil {
return nil, err
}
if err := upgradeProxy(
if _, err := upgradeProxy(
backend,
opts,
depsByName["OptimismPortalProxy"].Address,
......@@ -113,7 +115,7 @@ func BuildL1DeveloperGenesis(config *DeployConfig) (*core.Genesis, error) {
if err != nil {
return nil, err
}
if err := upgradeProxy(
if _, err := upgradeProxy(
backend,
opts,
depsByName["L1CrossDomainMessengerProxy"].Address,
......@@ -123,7 +125,7 @@ func BuildL1DeveloperGenesis(config *DeployConfig) (*core.Genesis, error) {
return nil, err
}
if err := upgradeProxy(
if _, err := upgradeProxy(
backend,
opts,
depsByName["L1StandardBridgeProxy"].Address,
......@@ -133,7 +135,8 @@ func BuildL1DeveloperGenesis(config *DeployConfig) (*core.Genesis, error) {
return nil, err
}
if err := upgradeProxy(
var lastUpgradeTx *types.Transaction
if lastUpgradeTx, err = upgradeProxy(
backend,
opts,
depsByName["OptimismMintableERC20FactoryProxy"].Address,
......@@ -143,7 +146,16 @@ func BuildL1DeveloperGenesis(config *DeployConfig) (*core.Genesis, error) {
return nil, err
}
// Commit all the upgrades at once, then wait for the last
// transaction to be mined. The simulator performs async
// processing, and as such we need to wait for the transaction
// receipt to appear before considering the above transactions
// committed to the chain.
backend.Commit()
if _, err := bind.WaitMined(context.Background(), backend, lastUpgradeTx); err != nil {
return nil, err
}
memDB := state.NewMemoryStateDB(genesis)
if err := SetL1Proxies(memDB, predeploys.DevProxyAdminAddr); err != nil {
......@@ -243,13 +255,13 @@ func deployL1Contracts(config *DeployConfig, backend *backends.SimulatedBackend)
return deployer.Deploy(backend, constructors, l1Deployer)
}
func l1Deployer(backend *backends.SimulatedBackend, opts *bind.TransactOpts, deployment deployer.Constructor) (common.Address, error) {
var addr common.Address
func l1Deployer(backend *backends.SimulatedBackend, opts *bind.TransactOpts, deployment deployer.Constructor) (*types.Transaction, error) {
var tx *types.Transaction
var err error
switch deployment.Name {
case "L2OutputOracle":
addr, _, _, err = bindings.DeployL2OutputOracle(
_, tx, _, err = bindings.DeployL2OutputOracle(
opts,
backend,
deployment.Args[0].(*big.Int),
......@@ -262,68 +274,66 @@ func l1Deployer(backend *backends.SimulatedBackend, opts *bind.TransactOpts, dep
deployment.Args[7].(common.Address),
)
case "OptimismPortal":
addr, _, _, err = bindings.DeployOptimismPortal(
_, tx, _, err = bindings.DeployOptimismPortal(
opts,
backend,
predeploys.DevL2OutputOracleAddr,
deployment.Args[0].(*big.Int),
)
case "L1CrossDomainMessenger":
addr, _, _, err = bindings.DeployL1CrossDomainMessenger(
_, tx, _, err = bindings.DeployL1CrossDomainMessenger(
opts,
backend,
predeploys.DevOptimismPortalAddr,
)
case "L1StandardBridge":
addr, _, _, err = bindings.DeployL1StandardBridge(
_, tx, _, err = bindings.DeployL1StandardBridge(
opts,
backend,
predeploys.DevL1CrossDomainMessengerAddr,
)
case "OptimismMintableERC20Factory":
addr, _, _, err = bindings.DeployOptimismMintableERC20Factory(
_, tx, _, err = bindings.DeployOptimismMintableERC20Factory(
opts,
backend,
predeploys.DevL1StandardBridgeAddr,
)
case "AddressManager":
addr, _, _, err = bindings.DeployAddressManager(
_, tx, _, err = bindings.DeployAddressManager(
opts,
backend,
)
case "ProxyAdmin":
addr, _, _, err = bindings.DeployProxyAdmin(
_, tx, _, err = bindings.DeployProxyAdmin(
opts,
backend,
common.Address{},
)
default:
if strings.HasSuffix(deployment.Name, "Proxy") {
addr, _, _, err = bindings.DeployProxy(opts, backend, deployer.TestAddress)
_, tx, _, err = bindings.DeployProxy(opts, backend, deployer.TestAddress)
} else {
err = fmt.Errorf("unknown contract %s", deployment.Name)
}
}
return addr, err
return tx, err
}
func upgradeProxy(backend *backends.SimulatedBackend, opts *bind.TransactOpts, proxyAddr common.Address, implAddr common.Address, callData []byte) error {
func upgradeProxy(backend *backends.SimulatedBackend, opts *bind.TransactOpts, proxyAddr common.Address, implAddr common.Address, callData []byte) (*types.Transaction, error) {
var tx *types.Transaction
proxy, err := bindings.NewProxy(proxyAddr, backend)
if err != nil {
return err
return nil, err
}
if callData == nil {
_, err = proxy.UpgradeTo(opts, implAddr)
tx, err = proxy.UpgradeTo(opts, implAddr)
} else {
_, err = proxy.UpgradeToAndCall(
tx, err = proxy.UpgradeToAndCall(
opts,
implAddr,
callData,
)
}
if err == nil {
backend.Commit()
}
return err
return tx, err
}
......@@ -8,15 +8,15 @@ import (
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-chain-ops/deployer"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/deployer"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/stretchr/testify/require"
)
......@@ -26,7 +26,7 @@ func TestBuildL1DeveloperGenesis(t *testing.T) {
dec := json.NewDecoder(bytes.NewReader(b))
config := new(DeployConfig)
require.NoError(t, dec.Decode(config))
config.L1GenesisBlockTimestamp = hexutil.Uint64(time.Now().Unix())
config.L1GenesisBlockTimestamp = hexutil.Uint64(time.Now().Unix() - 100)
genesis, err := BuildL1DeveloperGenesis(config)
require.NoError(t, err)
......
......@@ -4,8 +4,9 @@ go 1.18
require (
github.com/ethereum-optimism/optimism/l2geth v0.0.0-20220820030939-de38b6f6f77e
github.com/ethereum-optimism/optimism/op-bindings v0.8.6
github.com/ethereum-optimism/optimism/op-bindings v0.8.8
github.com/ethereum/go-ethereum v1.10.23
github.com/holiman/uint256 v1.2.0
github.com/mattn/go-isatty v0.0.14
github.com/stretchr/testify v1.8.0
github.com/urfave/cli/v2 v2.10.2
......@@ -32,7 +33,6 @@ require (
github.com/hashicorp/go-bexpr v0.1.11 // indirect
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
github.com/holiman/uint256 v1.2.0 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
......@@ -58,4 +58,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd
......@@ -172,12 +172,12 @@ github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73 h1:eXnnByFF0QiN1Qrq0wYmvI5lbDM8QQM0pv6AHx2FLnk=
github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo=
github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd h1:NchOnosWOkH9wlix8QevGHE+6vuRa+OMGvDNsczv2kQ=
github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo=
github.com/ethereum-optimism/optimism/l2geth v0.0.0-20220820030939-de38b6f6f77e h1:LUfy9ofKcen9Cm1T9JyGNnrPLR2AmyelFbohS6bs4X8=
github.com/ethereum-optimism/optimism/l2geth v0.0.0-20220820030939-de38b6f6f77e/go.mod h1:Oj5A6Qs/Ao1SP17i3uKroyhz49q/ehagSXRAlvwaI5Y=
github.com/ethereum-optimism/optimism/op-bindings v0.8.6 h1:jJYhmygt7hqGzYa+8sme9SdnKt1c3Y6EbWgIrRONoxw=
github.com/ethereum-optimism/optimism/op-bindings v0.8.6/go.mod h1:gUX5317IAvRMjB4GftayM87JVln3DTqukfirwJpEWnE=
github.com/ethereum-optimism/optimism/op-bindings v0.8.8 h1:HN625JI2VsRsli+U6GAXipg7lAKx8EOmGIovN79Az+I=
github.com/ethereum-optimism/optimism/op-bindings v0.8.8/go.mod h1:pyTCbh2o/SY+5/AL2Qo5GgAao3Gtt9Ff6tfK9Pa9emM=
github.com/ethereum/go-ethereum v1.10.4/go.mod h1:nEE0TP5MtxGzOMd7egIrbPJMQBnhVU3ELNxhBglIzhg=
github.com/ethereum/go-ethereum v1.10.16/go.mod h1:Anj6cxczl+AHy63o4X9O8yWNHuN5wMpfb8MAnHkWn7Y=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
......
......@@ -3,6 +3,8 @@ package immutables
import (
"fmt"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/deployer"
......@@ -84,47 +86,47 @@ func BuildL2(constructors []deployer.Constructor) (DeploymentResults, error) {
return results, nil
}
func l2Deployer(backend *backends.SimulatedBackend, opts *bind.TransactOpts, deployment deployer.Constructor) (common.Address, error) {
var addr common.Address
func l2Deployer(backend *backends.SimulatedBackend, opts *bind.TransactOpts, deployment deployer.Constructor) (*types.Transaction, error) {
var tx *types.Transaction
var err error
switch deployment.Name {
case "GasPriceOracle":
// The owner of the gas price oracle is not immutable, not required
// to be set here. It cannot be `address(0)`
owner := common.Address{1}
addr, _, _, err = bindings.DeployGasPriceOracle(opts, backend, owner)
_, tx, _, err = bindings.DeployGasPriceOracle(opts, backend, owner)
case "L1Block":
// No arguments required for the L1Block contract
addr, _, _, err = bindings.DeployL1Block(opts, backend)
_, tx, _, err = bindings.DeployL1Block(opts, backend)
case "L2CrossDomainMessenger":
otherMessenger, ok := deployment.Args[0].(common.Address)
if !ok {
return common.Address{}, fmt.Errorf("invalid type for otherMessenger")
return nil, fmt.Errorf("invalid type for otherMessenger")
}
addr, _, _, err = bindings.DeployL2CrossDomainMessenger(opts, backend, otherMessenger)
_, tx, _, err = bindings.DeployL2CrossDomainMessenger(opts, backend, otherMessenger)
case "L2StandardBridge":
otherBridge, ok := deployment.Args[0].(common.Address)
if !ok {
return common.Address{}, fmt.Errorf("invalid type for otherBridge")
return nil, fmt.Errorf("invalid type for otherBridge")
}
addr, _, _, err = bindings.DeployL2StandardBridge(opts, backend, otherBridge)
_, tx, _, err = bindings.DeployL2StandardBridge(opts, backend, otherBridge)
case "L2ToL1MessagePasser":
// No arguments required for L2ToL1MessagePasser
addr, _, _, err = bindings.DeployL2ToL1MessagePasser(opts, backend)
_, tx, _, err = bindings.DeployL2ToL1MessagePasser(opts, backend)
case "SequencerFeeVault":
// No arguments to SequencerFeeVault
addr, _, _, err = bindings.DeploySequencerFeeVault(opts, backend)
_, tx, _, err = bindings.DeploySequencerFeeVault(opts, backend)
case "OptimismMintableERC20Factory":
addr, _, _, err = bindings.DeployOptimismMintableERC20Factory(opts, backend, predeploys.L2StandardBridgeAddr)
_, tx, _, err = bindings.DeployOptimismMintableERC20Factory(opts, backend, predeploys.L2StandardBridgeAddr)
case "DeployerWhitelist":
addr, _, _, err = bindings.DeployDeployerWhitelist(opts, backend)
_, tx, _, err = bindings.DeployDeployerWhitelist(opts, backend)
case "LegacyMessagePasser":
addr, _, _, err = bindings.DeployLegacyMessagePasser(opts, backend)
_, tx, _, err = bindings.DeployLegacyMessagePasser(opts, backend)
case "L1BlockNumber":
addr, _, _, err = bindings.DeployL1BlockNumber(opts, backend)
_, tx, _, err = bindings.DeployL1BlockNumber(opts, backend)
default:
return addr, fmt.Errorf("unknown contract: %s", deployment.Name)
return tx, fmt.Errorf("unknown contract: %s", deployment.Name)
}
return addr, err
return tx, err
}
package actions
import (
"context"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
)
// Testing is an interface to Go-like testing,
// extended with a context getter for the test runner to shut down individual actions without interrupting the test,
// and a signaling function for when an invalid action is hit.
// This helps custom test runners navigate slow or invalid actions, e.g. during fuzzing.
type Testing interface {
e2eutils.TestingBase
// Ctx shares a context to execute an action with, the test runner may interrupt the action without stopping the test.
Ctx() context.Context
// InvalidAction indicates the failure is due to action incompatibility, does not stop the test.
InvalidAction(format string, args ...any)
}
// Action is a function that may change the state of one or more actors or check their state.
// Action definitions are meant to be very small building blocks,
// and then composed into larger patterns to write more elaborate tests.
type Action func(t Testing)
// ActionStatus defines the state of an action, to make a basic distinction between InvalidAction() and other calls.
type ActionStatus uint
const (
// ActionOK indicates the action is valid to apply
ActionOK ActionStatus = iota
// ActionInvalid indicates the action is not applicable, and a different next action may taken.
ActionInvalid
// More action status types may be used to indicate e.g. required rewinds,
// simple skips, or special cases for fuzzing.
)
// defaultTesting is a simple implementation of Testing that takes standard Go testing framework,
// and handles invalid actions as errors, and exposes a Reset function to change the context and action state,
// to recover after an invalid action or cancelled context.
type defaultTesting struct {
e2eutils.TestingBase
ctx context.Context
state ActionStatus
}
// Ctx shares a context to execute an action with, the test runner may interrupt the action without stopping the test.
func (st *defaultTesting) Ctx() context.Context {
return st.ctx
}
// InvalidAction indicates the failure is due to action incompatibility, does not stop the test.
// The format and args behave the same as fmt.Sprintf, testing.T.Errorf, etc.
func (st *defaultTesting) InvalidAction(format string, args ...any) {
st.TestingBase.Helper() // report the error on the call-site to make debugging clear, not here.
st.Errorf("invalid action err: "+format, args...)
st.state = ActionInvalid
}
// Reset prepares the testing util for the next action, changing the context and state back to OK.
func (st *defaultTesting) Reset(actionCtx context.Context) {
st.state = ActionOK
st.ctx = actionCtx
}
// State shares the current action state.
func (st *defaultTesting) State() ActionStatus {
return st.state
}
var _ Testing = (*defaultTesting)(nil)
package e2eutils
import (
"crypto/ecdsa"
"fmt"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
hdwallet "github.com/miguelmota/go-ethereum-hdwallet"
)
// DefaultMnemonicConfig is the default mnemonic used in testing.
// We prefer a mnemonic rather than direct private keys to make it easier
// to export all testing keys in external tooling for use during debugging.
var DefaultMnemonicConfig = &MnemonicConfig{
Mnemonic: "test test test test test test test test test test test junk",
Deployer: "m/44'/60'/0'/0/1",
// clique signer: removed, use engine API instead
Proposer: "m/44'/60'/0'/0/3",
Batcher: "m/44'/60'/0'/0/4",
SequencerP2P: "m/44'/60'/0'/0/5",
Alice: "m/44'/60'/0'/0/6",
Bob: "m/44'/60'/0'/0/7",
Mallory: "m/44'/60'/0'/0/8",
}
// MnemonicConfig configures the private keys for testing purposes.
type MnemonicConfig struct {
Mnemonic string
Deployer string
// rollup actors
Proposer string
Batcher string
SequencerP2P string
// prefunded L1/L2 accounts for testing
Alice string
Bob string
Mallory string
}
// Secrets computes the private keys for all mnemonic paths,
// which can then be kept around for fast precomputed private key access.
func (m *MnemonicConfig) Secrets() (*Secrets, error) {
wallet, err := hdwallet.NewFromMnemonic(m.Mnemonic)
if err != nil {
return nil, fmt.Errorf("failed to create wallet: %w", err)
}
account := func(path string) accounts.Account {
return accounts.Account{URL: accounts.URL{Path: path}}
}
deployer, err := wallet.PrivateKey(account(m.Deployer))
if err != nil {
return nil, err
}
proposer, err := wallet.PrivateKey(account(m.Proposer))
if err != nil {
return nil, err
}
batcher, err := wallet.PrivateKey(account(m.Batcher))
if err != nil {
return nil, err
}
sequencerP2P, err := wallet.PrivateKey(account(m.SequencerP2P))
if err != nil {
return nil, err
}
alice, err := wallet.PrivateKey(account(m.Alice))
if err != nil {
return nil, err
}
bob, err := wallet.PrivateKey(account(m.Bob))
if err != nil {
return nil, err
}
mallory, err := wallet.PrivateKey(account(m.Mallory))
if err != nil {
return nil, err
}
return &Secrets{
Deployer: deployer,
Proposer: proposer,
Batcher: batcher,
SequencerP2P: sequencerP2P,
Alice: alice,
Bob: bob,
Mallory: mallory,
}, nil
}
// Secrets bundles secp256k1 private keys for all common rollup actors for testing purposes.
type Secrets struct {
Deployer *ecdsa.PrivateKey
// rollup actors
Proposer *ecdsa.PrivateKey
Batcher *ecdsa.PrivateKey
SequencerP2P *ecdsa.PrivateKey
// prefunded L1/L2 accounts for testing
Alice *ecdsa.PrivateKey
Bob *ecdsa.PrivateKey
Mallory *ecdsa.PrivateKey
}
// EncodePrivKey encodes the given private key in 32 bytes
func EncodePrivKey(priv *ecdsa.PrivateKey) hexutil.Bytes {
privkey := make([]byte, 32)
blob := priv.D.Bytes()
copy(privkey[32-len(blob):], blob)
return privkey
}
// Addresses computes the ethereum address of each account,
// which can then be kept around for fast precomputed address access.
func (s *Secrets) Addresses() *Addresses {
return &Addresses{
Deployer: crypto.PubkeyToAddress(s.Deployer.PublicKey),
Proposer: crypto.PubkeyToAddress(s.Proposer.PublicKey),
Batcher: crypto.PubkeyToAddress(s.Batcher.PublicKey),
SequencerP2P: crypto.PubkeyToAddress(s.SequencerP2P.PublicKey),
Alice: crypto.PubkeyToAddress(s.Alice.PublicKey),
Bob: crypto.PubkeyToAddress(s.Bob.PublicKey),
Mallory: crypto.PubkeyToAddress(s.Mallory.PublicKey),
}
}
// Addresses bundles the addresses for all common rollup addresses for testing purposes.
type Addresses struct {
Deployer common.Address
// rollup actors
Proposer common.Address
Batcher common.Address
SequencerP2P common.Address
// prefunded L1/L2 accounts for testing
Alice common.Address
Bob common.Address
Mallory common.Address
}
func (a *Addresses) All() []common.Address {
return []common.Address{
a.Batcher,
a.Deployer,
a.Proposer,
a.Batcher,
a.SequencerP2P,
a.Alice,
a.Bob,
a.Mallory,
}
}
package e2eutils
import (
"math/big"
"os"
"path"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core"
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
)
var testingJWTSecret = [32]byte{123}
// WriteDefaultJWT writes a testing JWT to the temporary directory of the test and returns the path to the JWT file.
func WriteDefaultJWT(t TestingBase) string {
// Sadly the geth node config cannot load JWT secret from memory, it has to be a file
jwtPath := path.Join(t.TempDir(), "jwt_secret")
if err := os.WriteFile(jwtPath, []byte(hexutil.Encode(testingJWTSecret[:])), 0600); err != nil {
t.Fatalf("failed to prepare jwt file for geth: %v", err)
}
return jwtPath
}
func uint64ToBig(in uint64) *hexutil.Big {
return (*hexutil.Big)(new(big.Int).SetUint64(in))
}
// DeployParams bundles the deployment parameters to generate further testing inputs with.
type DeployParams struct {
DeployConfig *genesis.DeployConfig
MnemonicConfig *MnemonicConfig
Secrets *Secrets
Addresses *Addresses
}
// TestParams parametrizes the most essential rollup configuration parameters
type TestParams struct {
MaxSequencerDrift uint64
SequencerWindowSize uint64
ChannelTimeout uint64
}
func MakeDeployParams(t require.TestingT, tp *TestParams) *DeployParams {
mnemonicCfg := DefaultMnemonicConfig
secrets, err := mnemonicCfg.Secrets()
require.NoError(t, err)
addresses := secrets.Addresses()
deployConfig := &genesis.DeployConfig{
L1ChainID: 901,
L2ChainID: 902,
L2BlockTime: 2,
MaxSequencerDrift: tp.MaxSequencerDrift,
SequencerWindowSize: tp.SequencerWindowSize,
ChannelTimeout: tp.ChannelTimeout,
P2PSequencerAddress: addresses.SequencerP2P,
OptimismL2FeeRecipient: common.Address{0: 0x42, 19: 0xf0}, // tbd
BatchInboxAddress: common.Address{0: 0x42, 19: 0xff}, // tbd
BatchSenderAddress: addresses.Batcher,
L2OutputOracleSubmissionInterval: 6,
L2OutputOracleStartingTimestamp: -1,
L2OutputOracleProposer: addresses.Proposer,
L2OutputOracleOwner: common.Address{}, // tbd
L1BlockTime: 15,
L1GenesisBlockNonce: 0,
CliqueSignerAddress: common.Address{}, // proof of stake, no clique
L1GenesisBlockTimestamp: hexutil.Uint64(time.Now().Unix()),
L1GenesisBlockGasLimit: 15_000_000,
L1GenesisBlockDifficulty: uint64ToBig(1),
L1GenesisBlockMixHash: common.Hash{},
L1GenesisBlockCoinbase: common.Address{},
L1GenesisBlockNumber: 0,
L1GenesisBlockGasUsed: 0,
L1GenesisBlockParentHash: common.Hash{},
L1GenesisBlockBaseFeePerGas: uint64ToBig(1000_000_000), // 1 gwei
L2GenesisBlockNonce: 0,
L2GenesisBlockExtraData: []byte{},
L2GenesisBlockGasLimit: 15_000_000,
L2GenesisBlockDifficulty: uint64ToBig(0),
L2GenesisBlockMixHash: common.Hash{},
L2GenesisBlockCoinbase: common.Address{0: 0x42, 19: 0xf0}, // matching OptimismL2FeeRecipient
L2GenesisBlockNumber: 0,
L2GenesisBlockGasUsed: 0,
L2GenesisBlockParentHash: common.Hash{},
L2GenesisBlockBaseFeePerGas: uint64ToBig(1000_000_000),
OptimismBaseFeeRecipient: common.Address{0: 0x42, 19: 0xf1}, // tbd
OptimismL1FeeRecipient: addresses.Batcher,
L2CrossDomainMessengerOwner: common.Address{0: 0x42, 19: 0xf2}, // tbd
GasPriceOracleOwner: common.Address{0: 0x42, 19: 0xf3}, // tbd
GasPriceOracleOverhead: 2100,
GasPriceOracleScalar: 1000_000,
GasPriceOracleDecimals: 6,
DeploymentWaitConfirmations: 1,
EIP1559Elasticity: 10,
EIP1559Denominator: 50,
FundDevAccounts: false,
}
return &DeployParams{
DeployConfig: deployConfig,
MnemonicConfig: mnemonicCfg,
Secrets: secrets,
Addresses: addresses,
}
}
// DeploymentsL1 captures the L1 addresses used in the deployment,
// commonly just the developer predeploys during testing,
// but later deployed contracts may be used in some tests too.
type DeploymentsL1 struct {
L1CrossDomainMessengerProxy common.Address
L1StandardBridgeProxy common.Address
L2OutputOracleProxy common.Address
OptimismPortalProxy common.Address
}
// SetupData bundles the L1, L2, rollup and deployment configuration data: everything for a full test setup.
type SetupData struct {
L1Cfg *core.Genesis
L2Cfg *core.Genesis
RollupCfg *rollup.Config
DeploymentsL1 DeploymentsL1
}
// AllocParams defines genesis allocations to apply on top of the genesis generated by deploy parameters.
// These allocations override existing allocations per account,
// i.e. the allocations are merged with AllocParams having priority.
type AllocParams struct {
L1Alloc core.GenesisAlloc
L2Alloc core.GenesisAlloc
PrefundTestUsers bool
}
var etherScalar = new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)
// Ether converts a uint64 Ether amount into a *big.Int amount in wei units, for allocating test balances.
func Ether(v uint64) *big.Int {
return new(big.Int).Mul(new(big.Int).SetUint64(v), etherScalar)
}
// Setup computes the testing setup configurations from deployment configuration and optional allocation parameters.
func Setup(t require.TestingT, deployParams *DeployParams, alloc *AllocParams) *SetupData {
deployConf := deployParams.DeployConfig
l1Genesis, err := genesis.BuildL1DeveloperGenesis(deployConf)
require.NoError(t, err, "failed to create l1 genesis")
if alloc.PrefundTestUsers {
for _, addr := range deployParams.Addresses.All() {
l1Genesis.Alloc[addr] = core.GenesisAccount{
Balance: Ether(1e6),
}
}
}
for addr, val := range alloc.L1Alloc {
l1Genesis.Alloc[addr] = val
}
l1Block := l1Genesis.ToBlock()
l2Addrs := &genesis.L2Addresses{
ProxyAdmin: predeploys.DevProxyAdminAddr,
L1StandardBridgeProxy: predeploys.DevL1StandardBridgeAddr,
L1CrossDomainMessengerProxy: predeploys.DevL1CrossDomainMessengerAddr,
}
l2Genesis, err := genesis.BuildL2DeveloperGenesis(deployConf, l1Block, l2Addrs)
require.NoError(t, err, "failed to create l2 genesis")
if alloc.PrefundTestUsers {
for _, addr := range deployParams.Addresses.All() {
l2Genesis.Alloc[addr] = core.GenesisAccount{
Balance: Ether(1e6),
}
}
}
for addr, val := range alloc.L2Alloc {
l2Genesis.Alloc[addr] = val
}
rollupCfg := &rollup.Config{
Genesis: rollup.Genesis{
L1: eth.BlockID{
Hash: l1Block.Hash(),
Number: 0,
},
L2: eth.BlockID{
Hash: l2Genesis.ToBlock().Hash(),
Number: 0,
},
L2Time: uint64(deployConf.L1GenesisBlockTimestamp),
},
BlockTime: deployConf.L2BlockTime,
MaxSequencerDrift: deployConf.MaxSequencerDrift,
SeqWindowSize: deployConf.SequencerWindowSize,
ChannelTimeout: deployConf.ChannelTimeout,
L1ChainID: new(big.Int).SetUint64(deployConf.L1ChainID),
L2ChainID: new(big.Int).SetUint64(deployConf.L2ChainID),
P2PSequencerAddress: deployConf.P2PSequencerAddress,
FeeRecipientAddress: deployConf.OptimismL2FeeRecipient,
BatchInboxAddress: deployConf.BatchInboxAddress,
BatchSenderAddress: deployConf.BatchSenderAddress,
DepositContractAddress: predeploys.DevOptimismPortalAddr,
}
deploymentsL1 := DeploymentsL1{
L1CrossDomainMessengerProxy: predeploys.DevL1CrossDomainMessengerAddr,
L1StandardBridgeProxy: predeploys.DevL1StandardBridgeAddr,
L2OutputOracleProxy: predeploys.DevL2OutputOracleAddr,
OptimismPortalProxy: predeploys.DevOptimismPortalAddr,
}
return &SetupData{
L1Cfg: l1Genesis,
L2Cfg: l2Genesis,
RollupCfg: rollupCfg,
DeploymentsL1: deploymentsL1,
}
}
package e2eutils
import (
"encoding/hex"
"os"
"testing"
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
)
func TestWriteDefaultJWT(t *testing.T) {
jwtPath := WriteDefaultJWT(t)
data, err := os.ReadFile(jwtPath)
require.NoError(t, err)
require.Equal(t, "0x"+hex.EncodeToString(testingJWTSecret[:]), string(data))
}
func TestSetup(t *testing.T) {
tp := &TestParams{
MaxSequencerDrift: 40,
SequencerWindowSize: 120,
ChannelTimeout: 120,
}
dp := MakeDeployParams(t, tp)
alloc := &AllocParams{PrefundTestUsers: true}
sd := Setup(t, dp, alloc)
require.Contains(t, sd.L1Cfg.Alloc, dp.Addresses.Alice)
require.Equal(t, sd.L1Cfg.Alloc[dp.Addresses.Alice].Balance, Ether(1e6))
require.Contains(t, sd.L2Cfg.Alloc, dp.Addresses.Alice)
require.Equal(t, sd.L2Cfg.Alloc[dp.Addresses.Alice].Balance, Ether(1e6))
require.Contains(t, sd.L1Cfg.Alloc, predeploys.DevOptimismPortalAddr)
require.Contains(t, sd.L2Cfg.Alloc, predeploys.L1BlockAddr)
}
package e2eutils
// TestingBase is an interface used for standard Go testing.
// This interface is used for unit tests, benchmarks, and fuzz tests and also emulated in Hive.
//
// The Go testing.TB interface does not allow extensions by embedding the interface, so we repeat it here.
type TestingBase interface {
Cleanup(func())
Error(args ...any)
Errorf(format string, args ...any)
Fail()
FailNow()
Failed() bool
Fatal(args ...any)
Fatalf(format string, args ...any)
Helper()
Log(args ...any)
Logf(format string, args ...any)
Name() string
Setenv(key, value string)
Skip(args ...any)
SkipNow()
Skipf(format string, args ...any)
Skipped() bool
TempDir() string
}
......@@ -3,11 +3,12 @@ module github.com/ethereum-optimism/optimism/op-e2e
go 1.18
require (
github.com/ethereum-optimism/optimism/op-batcher v0.8.6
github.com/ethereum-optimism/optimism/op-bindings v0.8.6
github.com/ethereum-optimism/optimism/op-node v0.8.6
github.com/ethereum-optimism/optimism/op-proposer v0.8.6
github.com/ethereum-optimism/optimism/op-service v0.8.6
github.com/ethereum-optimism/optimism/op-batcher v0.8.8
github.com/ethereum-optimism/optimism/op-bindings v0.8.8
github.com/ethereum-optimism/optimism/op-chain-ops v0.8.8
github.com/ethereum-optimism/optimism/op-node v0.8.8
github.com/ethereum-optimism/optimism/op-proposer v0.8.8
github.com/ethereum-optimism/optimism/op-service v0.8.8
github.com/ethereum/go-ethereum v1.10.23
github.com/libp2p/go-libp2p v0.21.0
github.com/libp2p/go-libp2p-core v0.19.1
......@@ -155,4 +156,4 @@ require (
lukechampine.com/blake3 v1.1.7 // indirect
)
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd
......@@ -239,18 +239,20 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73 h1:eXnnByFF0QiN1Qrq0wYmvI5lbDM8QQM0pv6AHx2FLnk=
github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo=
github.com/ethereum-optimism/optimism/op-batcher v0.8.6 h1:phRqDO8qUIzJzRYt4+ZivSQx4gENeVcTiHY7wj4TnN4=
github.com/ethereum-optimism/optimism/op-batcher v0.8.6/go.mod h1:Ghz9Ilox6Ca5TjJAroZVheCleE5a/Ek4qjlW1yULb+A=
github.com/ethereum-optimism/optimism/op-bindings v0.8.6 h1:jJYhmygt7hqGzYa+8sme9SdnKt1c3Y6EbWgIrRONoxw=
github.com/ethereum-optimism/optimism/op-bindings v0.8.6/go.mod h1:gUX5317IAvRMjB4GftayM87JVln3DTqukfirwJpEWnE=
github.com/ethereum-optimism/optimism/op-node v0.8.6 h1:xNwN+Q/Rt17vSKawhBeG9qTcqcyh8JU8PGjK1iuGkF4=
github.com/ethereum-optimism/optimism/op-node v0.8.6/go.mod h1:gkyzgVHV3+tIhLZ8GhT+bL9GrrmouQCW4mKYukS0SHg=
github.com/ethereum-optimism/optimism/op-proposer v0.8.6 h1:iy8XAtkvrURBy3TT2Lf540cbWztxit7K4+BghZ4IsMI=
github.com/ethereum-optimism/optimism/op-proposer v0.8.6/go.mod h1:tuCLnXcO4MrtVyis1Yfo7wtL8EQta1u6zFdzHHj+RAc=
github.com/ethereum-optimism/optimism/op-service v0.8.6 h1:ruZp/BxL8TGn1y9EJmygypPTeVAFlAA0A/h8LsCoV+M=
github.com/ethereum-optimism/optimism/op-service v0.8.6/go.mod h1:gm8YNzERrL/CHBPWx3+01mR/NOVpLLw4GEUSnnTdyFU=
github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd h1:NchOnosWOkH9wlix8QevGHE+6vuRa+OMGvDNsczv2kQ=
github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo=
github.com/ethereum-optimism/optimism/op-batcher v0.8.8 h1:raKQUL3eQtWyJ+BNYPz7IN8aWIO5Dk+XPfNXjaTUFvM=
github.com/ethereum-optimism/optimism/op-batcher v0.8.8/go.mod h1:RnDJ6ilMHfvNhKwlTt4uhxABH8dbQ8arXdZjCvUI+8A=
github.com/ethereum-optimism/optimism/op-bindings v0.8.8 h1:HN625JI2VsRsli+U6GAXipg7lAKx8EOmGIovN79Az+I=
github.com/ethereum-optimism/optimism/op-bindings v0.8.8/go.mod h1:pyTCbh2o/SY+5/AL2Qo5GgAao3Gtt9Ff6tfK9Pa9emM=
github.com/ethereum-optimism/optimism/op-chain-ops v0.8.8 h1:wNn80nhMW4srM/TvA785mikElpPJhEtTLBBuYFxjUCM=
github.com/ethereum-optimism/optimism/op-chain-ops v0.8.8/go.mod h1:l9YB+bMCfYZV6rjcC6XL0VHa+6hkgdVPioHwBL9u6r8=
github.com/ethereum-optimism/optimism/op-node v0.8.8 h1:WuZF1RsZnB+u/wwWToVaC1lZWfGfgncLusUssA3Hm+o=
github.com/ethereum-optimism/optimism/op-node v0.8.8/go.mod h1:O5nXPCx8vn9c/CHgBC7vP5utcanIQ4uhWKkJ3pAaaSQ=
github.com/ethereum-optimism/optimism/op-proposer v0.8.8 h1:IV0P64q7RJ52yvLMBLAKyqeDOxdQPGHbhmIXGkMKG/8=
github.com/ethereum-optimism/optimism/op-proposer v0.8.8/go.mod h1:PSNjVKZQxjlkDTcXnoCt3Aeo6N6nY0Ma+R+ZHOTsXU8=
github.com/ethereum-optimism/optimism/op-service v0.8.8 h1:k5E78Zr2cGU0SwjoHpFXuC1eyfXhu3oKEOnDDaFi57I=
github.com/ethereum-optimism/optimism/op-service v0.8.8/go.mod h1:K0uybOhICTc2yfhrRj0cD1m7aPkOf5C9e6bUmvf4rGA=
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=
......
......@@ -194,9 +194,8 @@ var (
}
SequencerP2PKeyFlag = cli.StringFlag{
Name: "p2p.sequencer.key",
Usage: "File path of hex-encoded private key for signing off on p2p application messages as sequencer.",
Usage: "Hex-encoded private key for signing off on p2p application messages as sequencer.",
Required: false,
TakesFile: true,
Value: "",
EnvVar: p2pEnv("SEQUENCER_KEY"),
}
......
......@@ -5,8 +5,8 @@ go 1.18
require (
github.com/btcsuite/btcd/btcec/v2 v2.2.0
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1
github.com/ethereum-optimism/optimism/op-bindings v0.8.6
github.com/ethereum-optimism/optimism/op-chain-ops v0.8.6
github.com/ethereum-optimism/optimism/op-bindings v0.8.8
github.com/ethereum-optimism/optimism/op-chain-ops v0.8.8
github.com/ethereum/go-ethereum v1.10.23
github.com/golang/snappy v0.0.4
github.com/google/go-cmp v0.5.8
......@@ -159,4 +159,4 @@ require (
lukechampine.com/blake3 v1.1.7 // indirect
)
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd
......@@ -188,12 +188,12 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73 h1:eXnnByFF0QiN1Qrq0wYmvI5lbDM8QQM0pv6AHx2FLnk=
github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo=
github.com/ethereum-optimism/optimism/op-bindings v0.8.6 h1:jJYhmygt7hqGzYa+8sme9SdnKt1c3Y6EbWgIrRONoxw=
github.com/ethereum-optimism/optimism/op-bindings v0.8.6/go.mod h1:gUX5317IAvRMjB4GftayM87JVln3DTqukfirwJpEWnE=
github.com/ethereum-optimism/optimism/op-chain-ops v0.8.6 h1:tNGW3gztoIx2t+z64wAkDIvsUpvc468Y8IG9K4/hAKk=
github.com/ethereum-optimism/optimism/op-chain-ops v0.8.6/go.mod h1:RZ0R4dy/F/bMbKlDef7k1oSiD4BEx9GmwXYtnmx7mEk=
github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd h1:NchOnosWOkH9wlix8QevGHE+6vuRa+OMGvDNsczv2kQ=
github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo=
github.com/ethereum-optimism/optimism/op-bindings v0.8.8 h1:HN625JI2VsRsli+U6GAXipg7lAKx8EOmGIovN79Az+I=
github.com/ethereum-optimism/optimism/op-bindings v0.8.8/go.mod h1:pyTCbh2o/SY+5/AL2Qo5GgAao3Gtt9Ff6tfK9Pa9emM=
github.com/ethereum-optimism/optimism/op-chain-ops v0.8.8 h1:wNn80nhMW4srM/TvA785mikElpPJhEtTLBBuYFxjUCM=
github.com/ethereum-optimism/optimism/op-chain-ops v0.8.8/go.mod h1:l9YB+bMCfYZV6rjcC6XL0VHa+6hkgdVPioHwBL9u6r8=
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=
......
......@@ -82,12 +82,11 @@ type SignerSetup interface {
// LoadSignerSetup loads a configuration for a Signer to be set up later
func LoadSignerSetup(ctx *cli.Context) (SignerSetup, error) {
keyFile := ctx.GlobalString(flags.SequencerP2PKeyFlag.Name)
if keyFile != "" {
key := ctx.GlobalString(flags.SequencerP2PKeyFlag.Name)
if key != "" {
// Mnemonics are bad because they leak *all* keys when they leak.
// Unencrypted keys from file are bad because they are easy to leak (and we are not checking file permissions).
// TODO: load from encrypted keystore
priv, err := crypto.LoadECDSA(keyFile)
priv, err := crypto.HexToECDSA(key)
if err != nil {
return nil, fmt.Errorf("failed to read batch submitter key: %w", err)
}
......
......@@ -22,58 +22,60 @@ import (
// This stage can be reset by clearing it's batch buffer.
// This stage does not need to retain any references to L1 blocks.
type AttributesQueueOutput interface {
AddSafeAttributes(attributes *eth.PayloadAttributes)
SafeL2Head() eth.L2BlockRef
StageProgress
}
type AttributesQueue struct {
log log.Logger
config *rollup.Config
dl L1ReceiptsFetcher
next AttributesQueueOutput
progress Progress
batches []*BatchData
prev *BatchQueue
batch *BatchData
}
func NewAttributesQueue(log log.Logger, cfg *rollup.Config, l1Fetcher L1ReceiptsFetcher, next AttributesQueueOutput) *AttributesQueue {
func NewAttributesQueue(log log.Logger, cfg *rollup.Config, l1Fetcher L1ReceiptsFetcher, prev *BatchQueue) *AttributesQueue {
return &AttributesQueue{
log: log,
config: cfg,
dl: l1Fetcher,
next: next,
prev: prev,
}
}
func (aq *AttributesQueue) AddBatch(batch *BatchData) {
aq.log.Debug("Received next batch", "batch_epoch", batch.EpochNum, "batch_timestamp", batch.Timestamp, "tx_count", len(batch.Transactions))
aq.batches = append(aq.batches, batch)
}
func (aq *AttributesQueue) Progress() Progress {
return aq.progress
func (aq *AttributesQueue) Origin() eth.L1BlockRef {
return aq.prev.Origin()
}
func (aq *AttributesQueue) Step(ctx context.Context, outer Progress) error {
if changed, err := aq.progress.Update(outer); err != nil || changed {
return err
func (aq *AttributesQueue) NextAttributes(ctx context.Context, l2SafeHead eth.L2BlockRef) (*eth.PayloadAttributes, error) {
// Get a batch if we need it
if aq.batch == nil {
batch, err := aq.prev.NextBatch(ctx, l2SafeHead)
if err != nil {
return nil, err
}
if len(aq.batches) == 0 {
return io.EOF
aq.batch = batch
}
batch := aq.batches[0]
safeL2Head := aq.next.SafeL2Head()
// Actually generate the next attributes
if attrs, err := aq.createNextAttributes(ctx, aq.batch, l2SafeHead); err != nil {
return nil, err
} else {
// Clear out the local state once we will succeed
aq.batch = nil
return attrs, nil
}
}
// createNextAttributes transforms a batch into a payload attributes. This sets `NoTxPool` and appends the batched transactions
// to the attributes transaction list
func (aq *AttributesQueue) createNextAttributes(ctx context.Context, batch *BatchData, l2SafeHead eth.L2BlockRef) (*eth.PayloadAttributes, error) {
// sanity check parent hash
if batch.ParentHash != safeL2Head.Hash {
return NewCriticalError(fmt.Errorf("valid batch has bad parent hash %s, expected %s", batch.ParentHash, safeL2Head.Hash))
if batch.ParentHash != l2SafeHead.Hash {
return nil, NewResetError(fmt.Errorf("valid batch has bad parent hash %s, expected %s", batch.ParentHash, l2SafeHead.Hash))
}
fetchCtx, cancel := context.WithTimeout(ctx, 20*time.Second)
defer cancel()
attrs, err := PreparePayloadAttributes(fetchCtx, aq.config, aq.dl, safeL2Head, batch.Timestamp, batch.Epoch())
attrs, err := PreparePayloadAttributes(fetchCtx, aq.config, aq.dl, l2SafeHead, batch.Timestamp, batch.Epoch())
if err != nil {
return err
return nil, err
}
// we are verifying, not sequencing, we've got all transactions and do not pull from the tx-pool
......@@ -83,19 +85,9 @@ func (aq *AttributesQueue) Step(ctx context.Context, outer Progress) error {
aq.log.Info("generated attributes in payload queue", "txs", len(attrs.Transactions), "timestamp", batch.Timestamp)
// Slice off the batch once we are guaranteed to succeed
aq.batches = aq.batches[1:]
aq.next.AddSafeAttributes(attrs)
return nil
return attrs, nil
}
func (aq *AttributesQueue) ResetStep(ctx context.Context, l1Fetcher L1Fetcher) error {
aq.batches = aq.batches[:0]
aq.progress = aq.next.Progress()
func (aq *AttributesQueue) Reset(ctx context.Context, _ eth.L1BlockRef) error {
return io.EOF
}
func (aq *AttributesQueue) SafeL2Head() eth.L2BlockRef {
return aq.next.SafeL2Head()
}
......@@ -2,7 +2,6 @@ package derive
import (
"context"
"io"
"math/big"
"math/rand"
"testing"
......@@ -17,29 +16,10 @@ import (
"github.com/ethereum/go-ethereum/log"
)
type MockAttributesQueueOutput struct {
MockOriginStage
}
func (m *MockAttributesQueueOutput) AddSafeAttributes(attributes *eth.PayloadAttributes) {
m.Mock.MethodCalled("AddSafeAttributes", attributes)
}
func (m *MockAttributesQueueOutput) ExpectAddSafeAttributes(attributes *eth.PayloadAttributes) {
m.Mock.On("AddSafeAttributes", attributes).Once().Return()
}
func (m *MockAttributesQueueOutput) SafeL2Head() eth.L2BlockRef {
return m.Mock.MethodCalled("SafeL2Head").Get(0).(eth.L2BlockRef)
}
func (m *MockAttributesQueueOutput) ExpectSafeL2Head(head eth.L2BlockRef) {
m.Mock.On("SafeL2Head").Once().Return(head)
}
var _ AttributesQueueOutput = (*MockAttributesQueueOutput)(nil)
func TestAttributesQueue_Step(t *testing.T) {
// TestAttributesQueue checks that it properly uses the PreparePayloadAttributes function
// (which is well tested) and that it properly sets NoTxPool and adds in the candidate
// transactions.
func TestAttributesQueue(t *testing.T) {
// test config, only init the necessary fields
cfg := &rollup.Config{
BlockTime: 2,
......@@ -56,18 +36,9 @@ func TestAttributesQueue_Step(t *testing.T) {
l1Fetcher.ExpectInfoByHash(l1Info.InfoHash, l1Info, nil)
out := &MockAttributesQueueOutput{}
out.progress = Progress{
Origin: l1Info.BlockRef(),
Closed: false,
}
defer out.AssertExpectations(t)
safeHead := testutils.RandomL2BlockRef(rng)
safeHead.L1Origin = l1Info.ID()
out.ExpectSafeL2Head(safeHead)
batch := &BatchData{BatchV1{
ParentHash: safeHead.Hash,
EpochNum: rollup.Epoch(l1Info.InfoNum),
......@@ -85,13 +56,11 @@ func TestAttributesQueue_Step(t *testing.T) {
Transactions: []eth.Data{l1InfoTx, eth.Data("foobar"), eth.Data("example")},
NoTxPool: true,
}
out.ExpectAddSafeAttributes(&attrs)
aq := NewAttributesQueue(testlog.Logger(t, log.LvlError), cfg, l1Fetcher, out)
require.NoError(t, RepeatResetStep(t, aq.ResetStep, l1Fetcher, 1))
aq := NewAttributesQueue(testlog.Logger(t, log.LvlError), cfg, l1Fetcher, nil)
aq.AddBatch(batch)
actual, err := aq.createNextAttributes(context.Background(), batch, safeHead)
require.NoError(t, aq.Step(context.Background(), out.progress), "adding batch to next stage, no EOF yet")
require.Equal(t, io.EOF, aq.Step(context.Background(), out.progress), "done with batches")
require.Nil(t, err)
require.Equal(t, attrs, *actual)
}
......@@ -32,13 +32,18 @@ type BatchQueueOutput interface {
SafeL2Head() eth.L2BlockRef
}
type NextBatchProvider interface {
Origin() eth.L1BlockRef
NextBatch(ctx context.Context) (*BatchData, error)
}
// BatchQueue contains a set of batches for every L1 block.
// L1 blocks are contiguous and this does not support reorgs.
type BatchQueue struct {
log log.Logger
config *rollup.Config
next BatchQueueOutput
progress Progress
prev NextBatchProvider
origin eth.L1BlockRef
l1Blocks []eth.L1BlockRef
......@@ -47,62 +52,91 @@ type BatchQueue struct {
}
// NewBatchQueue creates a BatchQueue, which should be Reset(origin) before use.
func NewBatchQueue(log log.Logger, cfg *rollup.Config, next BatchQueueOutput) *BatchQueue {
func NewBatchQueue(log log.Logger, cfg *rollup.Config, prev NextBatchProvider) *BatchQueue {
return &BatchQueue{
log: log,
config: cfg,
next: next,
prev: prev,
}
}
func (bq *BatchQueue) Progress() Progress {
return bq.progress
func (bq *BatchQueue) Origin() eth.L1BlockRef {
return bq.prev.Origin()
}
func (bq *BatchQueue) Step(ctx context.Context, outer Progress) error {
if changed, err := bq.progress.Update(outer); err != nil {
return err
} else if changed {
if !bq.progress.Closed { // init inputs if we moved to a new open origin
bq.l1Blocks = append(bq.l1Blocks, bq.progress.Origin)
func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) (*BatchData, error) {
originBehind := bq.origin.Number < safeL2Head.L1Origin.Number
// Advance origin if needed
// Note: The entire pipeline has the same origin
// We just don't accept batches prior to the L1 origin of the L2 safe head
if bq.origin != bq.prev.Origin() {
bq.origin = bq.prev.Origin()
if !originBehind {
bq.l1Blocks = append(bq.l1Blocks, bq.origin)
} else {
// This is to handle the special case of startup. At startup we call Reset & include
// the L1 origin. That is the only time where immediately after `Reset` is called
// originBehind is false.
bq.l1Blocks = bq.l1Blocks[:0]
}
return nil
bq.log.Info("Advancing bq origin", "origin", bq.origin)
}
batch, err := bq.deriveNextBatch(ctx)
if err == io.EOF {
// very noisy, commented for now, or we should bump log level from trace to debug
// bq.log.Trace("need more L1 data before deriving next batch", "progress", bq.progress.Origin)
return io.EOF
// Load more data into the batch queue
outOfData := false
if batch, err := bq.prev.NextBatch(ctx); err == io.EOF {
outOfData = true
} else if err != nil {
return err
return nil, err
} else if !originBehind {
bq.AddBatch(batch, safeL2Head)
}
bq.next.AddBatch(batch)
return nil
// Skip adding data unless we are up to date with the origin, but do fully
// empty the previous stages
if originBehind {
if outOfData {
return nil, io.EOF
} else {
return nil, NotEnoughData
}
}
// Finally attempt to derive more batches
batch, err := bq.deriveNextBatch(ctx, outOfData, safeL2Head)
if err == io.EOF && outOfData {
return nil, io.EOF
} else if err == io.EOF {
return nil, NotEnoughData
} else if err != nil {
return nil, err
}
return batch, nil
}
func (bq *BatchQueue) ResetStep(ctx context.Context, l1Fetcher L1Fetcher) error {
func (bq *BatchQueue) Reset(ctx context.Context, base eth.L1BlockRef) error {
// Copy over the Origin from the next stage
// It is set in the engine queue (two stages away) such that the L2 Safe Head origin is the progress
bq.progress = bq.next.Progress()
bq.origin = base
bq.batches = make(map[uint64][]*BatchWithL1InclusionBlock)
// Include the new origin as an origin to build on
// Note: This is only for the initialization case. During normal resets we will later
// throw out this block.
bq.l1Blocks = bq.l1Blocks[:0]
bq.l1Blocks = append(bq.l1Blocks, bq.progress.Origin)
bq.l1Blocks = append(bq.l1Blocks, base)
return io.EOF
}
func (bq *BatchQueue) AddBatch(batch *BatchData) {
if bq.progress.Closed {
panic("write batch while closed")
}
func (bq *BatchQueue) AddBatch(batch *BatchData, l2SafeHead eth.L2BlockRef) {
if len(bq.l1Blocks) == 0 {
panic(fmt.Errorf("cannot add batch with timestamp %d, no origin was prepared", batch.Timestamp))
}
data := BatchWithL1InclusionBlock{
L1InclusionBlock: bq.progress.Origin,
L1InclusionBlock: bq.origin,
Batch: batch,
}
validity := CheckBatch(bq.config, bq.log, bq.l1Blocks, bq.next.SafeL2Head(), &data)
validity := CheckBatch(bq.config, bq.log, bq.l1Blocks, l2SafeHead, &data)
if validity == BatchDrop {
return // if we do drop the batch, CheckBatch will log the drop reason with WARN level.
}
......@@ -113,12 +147,11 @@ func (bq *BatchQueue) AddBatch(batch *BatchData) {
// following the validity rules imposed on consecutive batches,
// based on currently available buffered batch and L1 origin information.
// If no batch can be derived yet, then (nil, io.EOF) is returned.
func (bq *BatchQueue) deriveNextBatch(ctx context.Context) (*BatchData, error) {
func (bq *BatchQueue) deriveNextBatch(ctx context.Context, outOfData bool, l2SafeHead eth.L2BlockRef) (*BatchData, error) {
if len(bq.l1Blocks) == 0 {
return nil, NewCriticalError(errors.New("cannot derive next batch, no origin was prepared"))
}
epoch := bq.l1Blocks[0]
l2SafeHead := bq.next.SafeL2Head()
if l2SafeHead.L1Origin != epoch.ID() {
return nil, NewResetError(fmt.Errorf("buffered L1 chain epoch %s in batch queue does not match safe head %s", epoch, l2SafeHead))
......@@ -183,8 +216,8 @@ batchLoop:
// i.e. if the sequence window expired, we create empty batches
expiryEpoch := epoch.Number + bq.config.SeqWindowSize
forceNextEpoch :=
(expiryEpoch == bq.progress.Origin.Number && bq.progress.Closed) ||
expiryEpoch < bq.progress.Origin.Number
(expiryEpoch == bq.origin.Number && outOfData) ||
expiryEpoch < bq.origin.Number
if !forceNextEpoch {
// sequence window did not expire yet, still room to receive batches for the current epoch,
......
......@@ -7,8 +7,6 @@ import (
"math/rand"
"testing"
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/testlog"
......@@ -16,44 +14,28 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require"
)
// fakeBatchQueueOutput fakes the next stage (receive only) for the batch queue
// It tracks the progress state of the next stage.
// Upon receiving a batch, relevant characteristic of safeL2Head are immediately advanced.
type fakeBatchQueueOutput struct {
progress Progress
type fakeBatchQueueInput struct {
i int
batches []*BatchData
safeL2Head eth.L2BlockRef
errors []error
origin eth.L1BlockRef
}
var _ BatchQueueOutput = (*fakeBatchQueueOutput)(nil)
func (f *fakeBatchQueueOutput) AddBatch(batch *BatchData) {
f.batches = append(f.batches, batch)
if batch.ParentHash != f.safeL2Head.Hash {
panic("batch has wrong parent hash")
}
newEpoch := f.safeL2Head.L1Origin.Hash != batch.EpochHash
// Advance SafeL2Head
f.safeL2Head.Time = batch.Timestamp
f.safeL2Head.L1Origin.Number = uint64(batch.EpochNum)
f.safeL2Head.L1Origin.Hash = batch.EpochHash
if newEpoch {
f.safeL2Head.SequenceNumber = 0
} else {
f.safeL2Head.SequenceNumber += 1
}
f.safeL2Head.ParentHash = batch.ParentHash
f.safeL2Head.Hash = mockHash(batch.Timestamp, 2)
func (f *fakeBatchQueueInput) Origin() eth.L1BlockRef {
return f.origin
}
func (f *fakeBatchQueueOutput) SafeL2Head() eth.L2BlockRef {
return f.safeL2Head
}
func (f *fakeBatchQueueOutput) Progress() Progress {
return f.progress
func (f *fakeBatchQueueInput) NextBatch(ctx context.Context) (*BatchData, error) {
if f.i >= len(f.batches) {
return nil, io.EOF
}
b := f.batches[f.i]
e := f.errors[f.i]
f.i += 1
return b, e
}
func mockHash(time uint64, layer uint8) common.Hash {
......@@ -90,22 +72,18 @@ func L1Chain(l1Times []uint64) []eth.L1BlockRef {
return out
}
// TestBatchQueueEager adds a bunch of contiguous batches and asserts that
// enough calls to `NextBatch` return all of those batches.
func TestBatchQueueEager(t *testing.T) {
log := testlog.Logger(t, log.LvlTrace)
log := testlog.Logger(t, log.LvlCrit)
l1 := L1Chain([]uint64{10, 20, 30})
next := &fakeBatchQueueOutput{
safeL2Head: eth.L2BlockRef{
safeHead := eth.L2BlockRef{
Hash: mockHash(10, 2),
Number: 0,
ParentHash: common.Hash{},
Time: 10,
L1Origin: l1[0].ID(),
SequenceNumber: 0,
},
progress: Progress{
Origin: l1[0],
Closed: false,
},
}
cfg := &rollup.Config{
Genesis: rollup.Genesis{
......@@ -116,129 +94,44 @@ func TestBatchQueueEager(t *testing.T) {
SeqWindowSize: 30,
}
bq := NewBatchQueue(log, cfg, next)
require.Equal(t, io.EOF, bq.ResetStep(context.Background(), nil), "reset should complete without l1 fetcher, single step")
// We start with an open L1 origin as progress in the first step
progress := bq.progress
require.Equal(t, bq.progress.Closed, false)
batches := []*BatchData{b(12, l1[0]), b(14, l1[0]), b(16, l1[0]), b(18, l1[0]), b(20, l1[0]), b(22, l1[0]), b(24, l1[1]), nil}
errors := []error{nil, nil, nil, nil, nil, nil, nil, io.EOF}
// Add batches
batches := []*BatchData{b(12, l1[0]), b(14, l1[0])}
for _, batch := range batches {
bq.AddBatch(batch)
input := &fakeBatchQueueInput{
batches: batches,
errors: errors,
origin: l1[0],
}
// Step
require.NoError(t, RepeatStep(t, bq.Step, progress, 10))
// Verify Output
require.Equal(t, batches, next.batches)
}
func TestBatchQueueFull(t *testing.T) {
log := testlog.Logger(t, log.LvlTrace)
l1 := L1Chain([]uint64{10, 15, 20})
next := &fakeBatchQueueOutput{
safeL2Head: eth.L2BlockRef{
Hash: mockHash(10, 2),
Number: 0,
ParentHash: common.Hash{},
Time: 10,
L1Origin: l1[0].ID(),
SequenceNumber: 0,
},
progress: Progress{
Origin: l1[0],
Closed: false,
},
bq := NewBatchQueue(log, cfg, input)
_ = bq.Reset(context.Background(), l1[0])
// Advance the origin
input.origin = l1[1]
for i := 0; i < len(batches); i++ {
b, e := bq.NextBatch(context.Background(), safeHead)
require.ErrorIs(t, e, errors[i])
require.Equal(t, batches[i], b)
if b != nil {
safeHead.Number += 1
safeHead.Time += 2
safeHead.Hash = mockHash(b.Timestamp, 2)
safeHead.L1Origin = b.Epoch()
}
cfg := &rollup.Config{
Genesis: rollup.Genesis{
L2Time: 10,
},
BlockTime: 2,
MaxSequencerDrift: 600,
SeqWindowSize: 2,
}
bq := NewBatchQueue(log, cfg, next)
require.Equal(t, io.EOF, bq.ResetStep(context.Background(), nil), "reset should complete without l1 fetcher, single step")
// We start with an open L1 origin as progress in the first step
progress := bq.progress
require.Equal(t, bq.progress.Closed, false)
// Add batches
batches := []*BatchData{b(14, l1[0]), b(16, l1[0]), b(18, l1[1])}
for _, batch := range batches {
bq.AddBatch(batch)
}
// Missing first batch
err := bq.Step(context.Background(), progress)
require.Equal(t, err, io.EOF)
// Close previous to close bq
progress.Closed = true
err = bq.Step(context.Background(), progress)
require.Equal(t, err, nil)
require.Equal(t, bq.progress.Closed, true)
// Open previous to open bq with the new inclusion block
progress.Closed = false
progress.Origin = l1[1]
err = bq.Step(context.Background(), progress)
require.Equal(t, err, nil)
require.Equal(t, bq.progress.Closed, false)
// Close previous to close bq (for epoch 2)
progress.Closed = true
err = bq.Step(context.Background(), progress)
require.Equal(t, err, nil)
require.Equal(t, bq.progress.Closed, true)
// Open previous to open bq with the new inclusion block (epoch 2)
progress.Closed = false
progress.Origin = l1[2]
err = bq.Step(context.Background(), progress)
require.Equal(t, err, nil)
require.Equal(t, bq.progress.Closed, false)
// Finally add batch
firstBatch := b(12, l1[0])
bq.AddBatch(firstBatch)
// Close the origin
progress.Closed = true
err = bq.Step(context.Background(), progress)
require.Equal(t, err, nil)
require.Equal(t, bq.progress.Closed, true)
// Step, but should have full epoch now
require.NoError(t, RepeatStep(t, bq.Step, progress, 10))
// Verify Output
var final []*BatchData
final = append(final, firstBatch)
final = append(final, batches...)
require.Equal(t, final, next.batches)
}
func TestBatchQueueMissing(t *testing.T) {
log := testlog.Logger(t, log.LvlTrace)
log := testlog.Logger(t, log.LvlCrit)
l1 := L1Chain([]uint64{10, 15, 20})
next := &fakeBatchQueueOutput{
safeL2Head: eth.L2BlockRef{
safeHead := eth.L2BlockRef{
Hash: mockHash(10, 2),
Number: 0,
ParentHash: common.Hash{},
Time: 10,
L1Origin: l1[0].ID(),
SequenceNumber: 0,
},
progress: Progress{
Origin: l1[0],
Closed: false,
},
}
cfg := &rollup.Config{
Genesis: rollup.Genesis{
......@@ -249,56 +142,68 @@ func TestBatchQueueMissing(t *testing.T) {
SeqWindowSize: 2,
}
bq := NewBatchQueue(log, cfg, next)
require.Equal(t, io.EOF, bq.ResetStep(context.Background(), nil), "reset should complete without l1 fetcher, single step")
// We start with an open L1 origin as progress in the first step
progress := bq.progress
require.Equal(t, bq.progress.Closed, false)
// The batches at 18 and 20 are skipped to stop 22 from being eagerly processed.
// This test checks that batch timestamp 12 & 14 are created, 16 is used, and 18 is advancing the epoch.
// Due to the large sequencer time drift 16 is perfectly valid to have epoch 0 as origin.
batches := []*BatchData{b(16, l1[0]), b(22, l1[1])}
for _, batch := range batches {
bq.AddBatch(batch)
}
// Missing first batches with timestamp 12 and 14, nothing to do yet.
err := bq.Step(context.Background(), progress)
require.Equal(t, err, io.EOF)
errors := []error{nil, nil}
// Close l1[0]
progress.Closed = true
require.NoError(t, RepeatStep(t, bq.Step, progress, 10))
require.Equal(t, bq.progress.Closed, true)
input := &fakeBatchQueueInput{
batches: batches,
errors: errors,
origin: l1[0],
}
// Open l1[1]
progress.Closed = false
progress.Origin = l1[1]
require.NoError(t, RepeatStep(t, bq.Step, progress, 10))
require.Equal(t, bq.progress.Closed, false)
require.Empty(t, next.batches, "no batches yet, sequence window did not expire, waiting for 12 and 14")
bq := NewBatchQueue(log, cfg, input)
_ = bq.Reset(context.Background(), l1[0])
// Close l1[1]
progress.Closed = true
require.NoError(t, RepeatStep(t, bq.Step, progress, 10))
require.Equal(t, bq.progress.Closed, true)
for i := 0; i < len(batches); i++ {
b, e := bq.NextBatch(context.Background(), safeHead)
require.ErrorIs(t, e, NotEnoughData)
require.Nil(t, b)
}
// Open l1[2]
progress.Closed = false
progress.Origin = l1[2]
require.NoError(t, RepeatStep(t, bq.Step, progress, 10))
require.Equal(t, bq.progress.Closed, false)
// advance origin. Underlying stage still has no more batches
// This is not enough to auto advance yet
input.origin = l1[1]
b, e := bq.NextBatch(context.Background(), safeHead)
require.ErrorIs(t, e, io.EOF)
require.Nil(t, b)
// Advance the origin. At this point batch timestamps 12 and 14 will be created
input.origin = l1[2]
// Check for a generated batch at t = 12
b, e = bq.NextBatch(context.Background(), safeHead)
require.Nil(t, e)
require.Equal(t, b.Timestamp, uint64(12))
require.Empty(t, b.BatchV1.Transactions)
safeHead.Number += 1
safeHead.Time += 2
safeHead.Hash = mockHash(b.Timestamp, 2)
// Check for generated batch at t = 14
b, e = bq.NextBatch(context.Background(), safeHead)
require.Nil(t, e)
require.Equal(t, b.Timestamp, uint64(14))
require.Empty(t, b.BatchV1.Transactions)
safeHead.Number += 1
safeHead.Time += 2
safeHead.Hash = mockHash(b.Timestamp, 2)
// Check for the inputted batch at t = 16
b, e = bq.NextBatch(context.Background(), safeHead)
require.Nil(t, e)
require.Equal(t, b, batches[0])
safeHead.Number += 1
safeHead.Time += 2
safeHead.Hash = mockHash(b.Timestamp, 2)
// Check for the generated batch at t = 18. This batch advances the epoch
b, e = bq.NextBatch(context.Background(), safeHead)
require.Nil(t, e)
require.Equal(t, b.Timestamp, uint64(18))
require.Empty(t, b.BatchV1.Transactions)
require.Equal(t, rollup.Epoch(1), b.EpochNum)
// Close l1[2], this is the moment that l1[0] expires and empty batches 12 and 14 can be created,
// and batch 16 can then be used.
progress.Closed = true
require.NoError(t, RepeatStep(t, bq.Step, progress, 10))
require.Equal(t, bq.progress.Closed, true)
require.Equal(t, 4, len(next.batches), "expecting empty batches with timestamp 12 and 14 to be created and existing batch 16 to follow")
require.Equal(t, uint64(12), next.batches[0].Timestamp)
require.Equal(t, uint64(14), next.batches[1].Timestamp)
require.Equal(t, batches[0], next.batches[2])
require.Equal(t, uint64(18), next.batches[3].Timestamp)
require.Equal(t, rollup.Epoch(1), next.batches[3].EpochNum)
}
......@@ -2,55 +2,104 @@ package derive
import (
"context"
"errors"
"fmt"
"io"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
)
// CalldataSource readers raw transactions from a given block & then filters for
// batch submitter transactions.
// This is not a stage in the pipeline, but a wrapper for another stage in the pipeline
//
type DataIter interface {
Next(ctx context.Context) (eth.Data, error)
}
type L1TransactionFetcher interface {
InfoAndTxsByHash(ctx context.Context, hash common.Hash) (eth.BlockInfo, types.Transactions, error)
}
type DataSlice []eth.Data
func (ds *DataSlice) Next(ctx context.Context) (eth.Data, error) {
if len(*ds) == 0 {
return nil, io.EOF
}
out := (*ds)[0]
*ds = (*ds)[1:]
return out, nil
}
type CalldataSource struct {
// DataSourceFactory readers raw transactions from a given block & then filters for
// batch submitter transactions.
// This is not a stage in the pipeline, but a wrapper for another stage in the pipeline
type DataSourceFactory struct {
log log.Logger
cfg *rollup.Config
fetcher L1TransactionFetcher
}
func NewCalldataSource(log log.Logger, cfg *rollup.Config, fetcher L1TransactionFetcher) *CalldataSource {
return &CalldataSource{log: log, cfg: cfg, fetcher: fetcher}
func NewDataSourceFactory(log log.Logger, cfg *rollup.Config, fetcher L1TransactionFetcher) *DataSourceFactory {
return &DataSourceFactory{log: log, cfg: cfg, fetcher: fetcher}
}
// OpenData returns a CalldataSourceImpl. This struct implements the `Next` function.
func (ds *DataSourceFactory) OpenData(ctx context.Context, id eth.BlockID) DataIter {
return NewDataSource(ctx, ds.log, ds.cfg, ds.fetcher, id)
}
func (cs *CalldataSource) OpenData(ctx context.Context, id eth.BlockID) (DataIter, error) {
_, txs, err := cs.fetcher.InfoAndTxsByHash(ctx, id.Hash)
// DataSource is a fault tolerant approach to fetching data.
// The constructor will never fail & it will instead re-attempt the fetcher
// at a later point.
type DataSource struct {
// Internal state + data
open bool
data []eth.Data
// Required to re-attempt fetching
id eth.BlockID
cfg *rollup.Config // TODO: `DataFromEVMTransactions` should probably not take the full config
fetcher L1TransactionFetcher
log log.Logger
}
// NewDataSource creates a new calldata source. It suppresses errors in fetching the L1 block if they occur.
// If there is an error, it will attempt to fetch the result on the next call to `Next`.
func NewDataSource(ctx context.Context, log log.Logger, cfg *rollup.Config, fetcher L1TransactionFetcher, block eth.BlockID) DataIter {
_, txs, err := fetcher.InfoAndTxsByHash(ctx, block.Hash)
if err != nil {
return nil, fmt.Errorf("failed to fetch transactions: %w", err)
return &DataSource{
open: false,
id: block,
cfg: cfg,
fetcher: fetcher,
log: log,
}
} else {
return &DataSource{
open: true,
data: DataFromEVMTransactions(cfg, txs, log.New("origin", block)),
}
}
}
// Next returns the next piece of data if it has it. If the constructor failed, this
// will attempt to reinitialize itself. If it cannot find the block it returns a ResetError
// otherwise it returns a temporary error if fetching the block returns an error.
func (ds *DataSource) Next(ctx context.Context) (eth.Data, error) {
if !ds.open {
if _, txs, err := ds.fetcher.InfoAndTxsByHash(ctx, ds.id.Hash); err == nil {
ds.open = true
ds.data = DataFromEVMTransactions(ds.cfg, txs, log.New("origin", ds.id))
} else if errors.Is(err, ethereum.NotFound) {
return nil, NewResetError(fmt.Errorf("failed to open calldata source: %w", err))
} else {
return nil, NewTemporaryError(fmt.Errorf("failed to open calldata source: %w", err))
}
}
if len(ds.data) == 0 {
return nil, io.EOF
} else {
data := ds.data[0]
ds.data = ds.data[1:]
return data, nil
}
data := DataFromEVMTransactions(cs.cfg, txs, cs.log.New("origin", id))
return (*DataSlice)(&data), nil
}
// DataFromEVMTransactions filters all of the transactions and returns the calldata from transactions
// that are sent to the batch inbox address from the batch sender address.
// This will return an empty array if no valid transactions are found.
func DataFromEVMTransactions(config *rollup.Config, txs types.Transactions, log log.Logger) []eth.Data {
var out []eth.Data
l1Signer := config.L1Signer()
......
package derive
import (
"context"
"crypto/ecdsa"
"fmt"
"io"
"math/big"
"math/rand"
"testing"
......@@ -45,61 +42,15 @@ func (tx *testTx) Create(t *testing.T, signer types.Signer, rng *rand.Rand) *typ
return out
}
type calldataTestSetup struct {
inboxPriv *ecdsa.PrivateKey
batcherPriv *ecdsa.PrivateKey
cfg *rollup.Config
signer types.Signer
}
type calldataTest struct {
name string
txs []testTx
err error
}
func (ct *calldataTest) Run(t *testing.T, setup *calldataTestSetup) {
rng := rand.New(rand.NewSource(1234))
l1Src := &testutils.MockL1Source{}
txs := make([]*types.Transaction, len(ct.txs))
expectedData := make([]eth.Data, 0)
for i, tx := range ct.txs {
txs[i] = tx.Create(t, setup.signer, rng)
if tx.good {
expectedData = append(expectedData, txs[i].Data())
}
}
info := testutils.RandomBlockInfo(rng)
l1Src.ExpectInfoAndTxsByHash(info.Hash(), info, txs, ct.err)
defer l1Src.Mock.AssertExpectations(t)
src := NewCalldataSource(testlog.Logger(t, log.LvlError), setup.cfg, l1Src)
dataIter, err := src.OpenData(context.Background(), info.ID())
if ct.err != nil {
require.ErrorIs(t, err, ct.err)
return
}
require.NoError(t, err)
for {
dat, err := dataIter.Next(context.Background())
if err == io.EOF {
break
}
require.NoError(t, err)
require.Equal(t, dat, expectedData[0], "data must match next expected value")
expectedData = expectedData[1:]
}
require.Len(t, expectedData, 0, "all expected data should have been read")
}
func TestCalldataSource_OpenData(t *testing.T) {
// TestDataFromEVMTransactions creates some transactions from a specified template and asserts
// that DataFromEVMTransactions properly filters and returns the data from the authorized transactions
// inside the transaction set.
func TestDataFromEVMTransactions(t *testing.T) {
inboxPriv := testutils.RandomKey()
batcherPriv := testutils.RandomKey()
cfg := &rollup.Config{
......@@ -107,59 +58,68 @@ func TestCalldataSource_OpenData(t *testing.T) {
BatchInboxAddress: crypto.PubkeyToAddress(inboxPriv.PublicKey),
BatchSenderAddress: crypto.PubkeyToAddress(batcherPriv.PublicKey),
}
signer := cfg.L1Signer()
setup := &calldataTestSetup{
inboxPriv: inboxPriv,
batcherPriv: batcherPriv,
cfg: cfg,
signer: signer,
}
altInbox := testutils.RandomAddress(rand.New(rand.NewSource(1234)))
altAuthor := testutils.RandomKey()
testCases := []calldataTest{
{name: "simple", txs: []testTx{{to: &cfg.BatchInboxAddress, dataLen: 1234, author: batcherPriv, good: true}}},
{name: "other inbox", txs: []testTx{{to: &altInbox, dataLen: 1234, author: batcherPriv, good: false}}},
{name: "other author", txs: []testTx{{to: &cfg.BatchInboxAddress, dataLen: 1234, author: altAuthor, good: false}}},
{name: "inbox is author", txs: []testTx{{to: &cfg.BatchInboxAddress, dataLen: 1234, author: inboxPriv, good: false}}},
{name: "author is inbox", txs: []testTx{{to: &cfg.BatchSenderAddress, dataLen: 1234, author: batcherPriv, good: false}}},
{name: "unrelated", txs: []testTx{{to: &altInbox, dataLen: 1234, author: altAuthor, good: false}}},
{name: "contract creation", txs: []testTx{{to: nil, dataLen: 1234, author: batcherPriv, good: false}}},
{name: "empty tx", txs: []testTx{{to: &cfg.BatchInboxAddress, dataLen: 0, author: batcherPriv, good: true}}},
{name: "value tx", txs: []testTx{{to: &cfg.BatchInboxAddress, dataLen: 1234, value: 42, author: batcherPriv, good: true}}},
{name: "empty block", txs: []testTx{}},
{
name: "simple",
txs: []testTx{{to: &cfg.BatchInboxAddress, dataLen: 1234, author: batcherPriv, good: true}},
},
{
name: "other inbox",
txs: []testTx{{to: &altInbox, dataLen: 1234, author: batcherPriv, good: false}}},
{
name: "other author",
txs: []testTx{{to: &cfg.BatchInboxAddress, dataLen: 1234, author: altAuthor, good: false}}},
{
name: "inbox is author",
txs: []testTx{{to: &cfg.BatchInboxAddress, dataLen: 1234, author: inboxPriv, good: false}}},
{
name: "author is inbox",
txs: []testTx{{to: &cfg.BatchSenderAddress, dataLen: 1234, author: batcherPriv, good: false}}},
{
name: "unrelated",
txs: []testTx{{to: &altInbox, dataLen: 1234, author: altAuthor, good: false}}},
{
name: "contract creation",
txs: []testTx{{to: nil, dataLen: 1234, author: batcherPriv, good: false}}},
{
name: "empty tx",
txs: []testTx{{to: &cfg.BatchInboxAddress, dataLen: 0, author: batcherPriv, good: true}}},
{
name: "value tx",
txs: []testTx{{to: &cfg.BatchInboxAddress, dataLen: 1234, value: 42, author: batcherPriv, good: true}}},
{
name: "empty block", txs: []testTx{},
},
{
name: "mixed txs",
txs: []testTx{
{to: &cfg.BatchInboxAddress, dataLen: 1234, value: 42, author: batcherPriv, good: true},
{to: &cfg.BatchInboxAddress, dataLen: 3333, value: 32, author: altAuthor, good: false},
{to: &cfg.BatchInboxAddress, dataLen: 2000, value: 22, author: batcherPriv, good: true},
{to: &altInbox, dataLen: 2020, value: 12, author: batcherPriv, good: false},
},
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
testCase.Run(t, setup)
})
}
for i, tc := range testCases {
rng := rand.New(rand.NewSource(int64(i)))
signer := cfg.L1Signer()
t.Run("random combinations", func(t *testing.T) {
var all []testTx
for _, tc := range testCases {
all = append(all, tc.txs...)
var expectedData []eth.Data
var txs []*types.Transaction
for i, tx := range tc.txs {
txs = append(txs, tx.Create(t, signer, rng))
if tx.good {
expectedData = append(expectedData, txs[i].Data())
}
var combiTestCases []calldataTest
for i := 0; i < 100; i++ {
txs := append(make([]testTx, 0), all...)
rng := rand.New(rand.NewSource(42 + int64(i)))
rng.Shuffle(len(txs), func(i, j int) {
txs[i], txs[j] = txs[j], txs[i]
})
subset := txs[:rng.Intn(len(txs))]
combiTestCases = append(combiTestCases, calldataTest{
name: fmt.Sprintf("combi_%d_subset_%d", i, len(subset)),
txs: subset,
})
}
for _, testCase := range combiTestCases {
t.Run(testCase.name, func(t *testing.T) {
testCase.Run(t, setup)
})
out := DataFromEVMTransactions(cfg, txs, testlog.Logger(t, log.LvlCrit))
require.ElementsMatch(t, expectedData, out)
}
})
}
......@@ -2,7 +2,6 @@ package derive
import (
"context"
"fmt"
"io"
"github.com/ethereum-optimism/optimism/op-node/eth"
......@@ -11,6 +10,11 @@ import (
"github.com/ethereum/go-ethereum/log"
)
type NextDataProvider interface {
NextData(ctx context.Context) ([]byte, error)
Origin() eth.L1BlockRef
}
// ChannelBank is a stateful stage that does the following:
// 1. Unmarshalls frames from L1 transaction data
// 2. Applies those frames to a channel
......@@ -22,11 +26,6 @@ import (
// Specifically, the channel bank is not allowed to become too large between successive calls
// to `IngestData`. This means that we can do an ingest and then do a read while becoming too large.
type ChannelBankOutput interface {
StageProgress
WriteChannel(data []byte)
}
// ChannelBank buffers channel frames, and emits full channel data
type ChannelBank struct {
log log.Logger
......@@ -35,80 +34,78 @@ type ChannelBank struct {
channels map[ChannelID]*Channel // channels by ID
channelQueue []ChannelID // channels in FIFO order
progress Progress
next ChannelBankOutput
prev NextDataProvider
fetcher L1Fetcher
}
var _ Stage = (*ChannelBank)(nil)
var _ PullStage = (*ChannelBank)(nil)
// NewChannelBank creates a ChannelBank, which should be Reset(origin) before use.
func NewChannelBank(log log.Logger, cfg *rollup.Config, next ChannelBankOutput) *ChannelBank {
func NewChannelBank(log log.Logger, cfg *rollup.Config, prev NextDataProvider, fetcher L1Fetcher) *ChannelBank {
return &ChannelBank{
log: log,
cfg: cfg,
channels: make(map[ChannelID]*Channel),
channelQueue: make([]ChannelID, 0, 10),
next: next,
prev: prev,
fetcher: fetcher,
}
}
func (ib *ChannelBank) Progress() Progress {
return ib.progress
func (cb *ChannelBank) Origin() eth.L1BlockRef {
return cb.prev.Origin()
}
func (ib *ChannelBank) prune() {
func (cb *ChannelBank) prune() {
// check total size
totalSize := uint64(0)
for _, ch := range ib.channels {
for _, ch := range cb.channels {
totalSize += ch.size
}
// prune until it is reasonable again. The high-priority channel failed to be read, so we start pruning there.
for totalSize > MaxChannelBankSize {
id := ib.channelQueue[0]
ch := ib.channels[id]
ib.channelQueue = ib.channelQueue[1:]
delete(ib.channels, id)
id := cb.channelQueue[0]
ch := cb.channels[id]
cb.channelQueue = cb.channelQueue[1:]
delete(cb.channels, id)
totalSize -= ch.size
}
}
// IngestData adds new L1 data to the channel bank.
// Read() should be called repeatedly first, until everything has been read, before adding new data.\
func (ib *ChannelBank) IngestData(data []byte) {
if ib.progress.Closed {
panic("write data to bank while closed")
}
ib.log.Debug("channel bank got new data", "origin", ib.progress.Origin, "data_len", len(data))
func (cb *ChannelBank) IngestData(data []byte) {
origin := cb.Origin()
cb.log.Debug("channel bank got new data", "origin", origin, "data_len", len(data))
// TODO: Why is the prune here?
ib.prune()
cb.prune()
frames, err := ParseFrames(data)
if err != nil {
ib.log.Warn("malformed frame", "err", err)
cb.log.Warn("malformed frame", "err", err)
return
}
// Process each frame
for _, f := range frames {
currentCh, ok := ib.channels[f.ID]
currentCh, ok := cb.channels[f.ID]
if !ok {
// create new channel if it doesn't exist yet
currentCh = NewChannel(f.ID, ib.progress.Origin)
ib.channels[f.ID] = currentCh
ib.channelQueue = append(ib.channelQueue, f.ID)
currentCh = NewChannel(f.ID, origin)
cb.channels[f.ID] = currentCh
cb.channelQueue = append(cb.channelQueue, f.ID)
}
// check if the channel is not timed out
if currentCh.OpenBlockNumber()+ib.cfg.ChannelTimeout < ib.progress.Origin.Number {
ib.log.Warn("channel is timed out, ignore frame", "channel", f.ID, "frame", f.FrameNumber)
if currentCh.OpenBlockNumber()+cb.cfg.ChannelTimeout < origin.Number {
cb.log.Warn("channel is timed out, ignore frame", "channel", f.ID, "frame", f.FrameNumber)
continue
}
ib.log.Trace("ingesting frame", "channel", f.ID, "frame_number", f.FrameNumber, "length", len(f.Data))
if err := currentCh.AddFrame(f, ib.progress.Origin); err != nil {
ib.log.Warn("failed to ingest frame into channel", "channel", f.ID, "frame_number", f.FrameNumber, "err", err)
cb.log.Trace("ingesting frame", "channel", f.ID, "frame_number", f.FrameNumber, "length", len(f.Data))
if err := currentCh.AddFrame(f, origin); err != nil {
cb.log.Warn("failed to ingest frame into channel", "channel", f.ID, "frame_number", f.FrameNumber, "err", err)
continue
}
}
......@@ -116,72 +113,62 @@ func (ib *ChannelBank) IngestData(data []byte) {
// Read the raw data of the first channel, if it's timed-out or closed.
// Read returns io.EOF if there is nothing new to read.
func (ib *ChannelBank) Read() (data []byte, err error) {
if len(ib.channelQueue) == 0 {
func (cb *ChannelBank) Read() (data []byte, err error) {
if len(cb.channelQueue) == 0 {
return nil, io.EOF
}
first := ib.channelQueue[0]
ch := ib.channels[first]
timedOut := ch.OpenBlockNumber()+ib.cfg.ChannelTimeout < ib.progress.Origin.Number
first := cb.channelQueue[0]
ch := cb.channels[first]
timedOut := ch.OpenBlockNumber()+cb.cfg.ChannelTimeout < cb.Origin().Number
if timedOut {
ib.log.Debug("channel timed out", "channel", first, "frames", len(ch.inputs))
delete(ib.channels, first)
ib.channelQueue = ib.channelQueue[1:]
cb.log.Debug("channel timed out", "channel", first, "frames", len(ch.inputs))
delete(cb.channels, first)
cb.channelQueue = cb.channelQueue[1:]
return nil, io.EOF
}
if !ch.IsReady() {
return nil, io.EOF
}
delete(ib.channels, first)
ib.channelQueue = ib.channelQueue[1:]
delete(cb.channels, first)
cb.channelQueue = cb.channelQueue[1:]
r := ch.Reader()
// Suprress error here. io.ReadAll does return nil instead of io.EOF though.
data, _ = io.ReadAll(r)
return data, nil
}
func (ib *ChannelBank) Step(ctx context.Context, outer Progress) error {
if changed, err := ib.progress.Update(outer); err != nil || changed {
return err
}
// If the bank is behind the channel reader, then we are replaying old data to prepare the bank.
// Read if we can, and drop if it gives anything
if ib.next.Progress().Origin.Number > ib.progress.Origin.Number {
_, err := ib.Read()
return err
// NextData pulls the next piece of data from the channel bank.
// Note that it attempts to pull data out of the channel bank prior to
// loading data in (unlike most other stages). This is to ensure maintain
// consistency around channel bank pruning which depends upon the order
// of operations.
func (cb *ChannelBank) NextData(ctx context.Context) ([]byte, error) {
// Do the read from the channel bank first
data, err := cb.Read()
if err == io.EOF {
// continue - We will attempt to load data into the channel bank
} else if err != nil {
return nil, err
} else {
return data, nil
}
// otherwise, read the next channel data from the bank
data, err := ib.Read()
if err == io.EOF { // need new L1 data in the bank before we can read more channel data
return io.EOF
// Then load data into the channel bank
if data, err := cb.prev.NextData(ctx); err == io.EOF {
return nil, io.EOF
} else if err != nil {
return err
return nil, err
} else {
cb.IngestData(data)
return nil, NotEnoughData
}
ib.next.WriteChannel(data)
return nil
}
// ResetStep walks back the L1 chain, starting at the origin of the next stage,
// to find the origin that the channel bank should be reset to,
// to get consistent reads starting at origin.
// Any channel data before this origin will be timed out by the time the channel bank is synced up to the origin,
// so it is not relevant to replay it into the bank.
func (ib *ChannelBank) ResetStep(ctx context.Context, l1Fetcher L1Fetcher) error {
ib.progress = ib.next.Progress()
ib.log.Debug("walking back to find reset origin for channel bank", "origin", ib.progress.Origin)
// go back in history if we are not distant enough from the next stage
resetBlock := ib.progress.Origin.Number - ib.cfg.ChannelTimeout
if ib.progress.Origin.Number < ib.cfg.ChannelTimeout {
resetBlock = 0 // don't underflow
}
parent, err := l1Fetcher.L1BlockRefByNumber(ctx, resetBlock)
if err != nil {
return NewTemporaryError(fmt.Errorf("failed to find channel bank block, failed to retrieve L1 reference: %w", err))
}
ib.progress.Origin = parent
func (cb *ChannelBank) Reset(ctx context.Context, base eth.L1BlockRef) error {
cb.channels = make(map[ChannelID]*Channel)
cb.channelQueue = make([]ChannelID, 0, 10)
return io.EOF
}
......
......@@ -2,78 +2,63 @@ package derive
import (
"bytes"
"context"
"fmt"
"io"
"math/rand"
"strconv"
"strings"
"testing"
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum-optimism/optimism/op-node/testutils"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require"
)
type MockChannelBankOutput struct {
MockOriginStage
}
func (m *MockChannelBankOutput) WriteChannel(data []byte) {
m.MethodCalled("WriteChannel", data)
type fakeChannelBankInput struct {
origin eth.L1BlockRef
data []struct {
data []byte
err error
}
}
func (m *MockChannelBankOutput) ExpectWriteChannel(data []byte) {
m.On("WriteChannel", data).Once().Return()
func (f *fakeChannelBankInput) Origin() eth.L1BlockRef {
return f.origin
}
var _ ChannelBankOutput = (*MockChannelBankOutput)(nil)
type bankTestSetup struct {
origins []eth.L1BlockRef
t *testing.T
rng *rand.Rand
cb *ChannelBank
out *MockChannelBankOutput
l1 *testutils.MockL1Source
func (f *fakeChannelBankInput) NextData(_ context.Context) ([]byte, error) {
out := f.data[0]
f.data = f.data[1:]
return out.data, out.err
}
type channelBankTestCase struct {
name string
originTimes []uint64
nextStartsAt int
channelTimeout uint64
fn func(bt *bankTestSetup)
func (f *fakeChannelBankInput) AddOutput(data []byte, err error) {
f.data = append(f.data, struct {
data []byte
err error
}{data: data, err: err})
}
func (ct *channelBankTestCase) Run(t *testing.T) {
cfg := &rollup.Config{
ChannelTimeout: ct.channelTimeout,
}
bt := &bankTestSetup{
t: t,
rng: rand.New(rand.NewSource(1234)),
l1: &testutils.MockL1Source{},
}
bt.origins = append(bt.origins, testutils.RandomBlockRef(bt.rng))
for i := range ct.originTimes[1:] {
ref := testutils.NextRandomRef(bt.rng, bt.origins[i])
bt.origins = append(bt.origins, ref)
// ExpectNextFrameData takes a set of test frame & turns into the raw data
// for reading into the channel bank via `NextData`
func (f *fakeChannelBankInput) AddFrames(frames ...testFrame) {
data := new(bytes.Buffer)
data.WriteByte(DerivationVersion0)
for _, frame := range frames {
ff := frame.ToFrame()
if err := ff.MarshalBinary(data); err != nil {
panic(fmt.Errorf("error in making frame during test: %w", err))
}
for i, x := range ct.originTimes {
bt.origins[i].Time = x
}
bt.out = &MockChannelBankOutput{MockOriginStage{progress: Progress{Origin: bt.origins[ct.nextStartsAt], Closed: false}}}
bt.cb = NewChannelBank(testlog.Logger(t, log.LvlError), cfg, bt.out)
ct.fn(bt)
f.AddOutput(data.Bytes(), nil)
}
var _ NextDataProvider = (*fakeChannelBankInput)(nil)
// format: <channelID-data>:<frame-number>:<content><optional-last-frame-marker "!">
// example: "abc:0:helloworld!"
type testFrame string
......@@ -113,153 +98,76 @@ func (tf testFrame) ToFrame() Frame {
}
}
func (bt *bankTestSetup) ingestData(data []byte) {
bt.cb.IngestData(data)
}
func TestChannelBankSimple(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
a := testutils.RandomBlockRef(rng)
func (bt *bankTestSetup) ingestFrames(frames ...testFrame) {
data := new(bytes.Buffer)
data.WriteByte(DerivationVersion0)
for _, fr := range frames {
f := fr.ToFrame()
if err := f.MarshalBinary(data); err != nil {
panic(fmt.Errorf("error in making frame during test: %w", err))
}
}
bt.ingestData(data.Bytes())
}
func (bt *bankTestSetup) repeatStep(max int, outer int, outerClosed bool, err error) {
require.Equal(bt.t, err, RepeatStep(bt.t, bt.cb.Step, Progress{Origin: bt.origins[outer], Closed: outerClosed}, max))
}
func (bt *bankTestSetup) repeatResetStep(max int, err error) {
require.Equal(bt.t, err, RepeatResetStep(bt.t, bt.cb.ResetStep, bt.l1, max))
}
input := &fakeChannelBankInput{origin: a}
input.AddFrames("a:0:first", "a:2:third!")
input.AddFrames("a:1:second")
input.AddOutput(nil, io.EOF)
func (bt *bankTestSetup) assertOrigin(i int) {
require.Equal(bt.t, bt.cb.progress.Origin, bt.origins[i])
}
func (bt *bankTestSetup) assertOriginTime(x uint64) {
require.Equal(bt.t, x, bt.cb.progress.Origin.Time)
}
func (bt *bankTestSetup) expectChannel(data string) {
bt.out.ExpectWriteChannel([]byte(data))
}
func (bt *bankTestSetup) expectL1BlockRefByNumber(i int) {
bt.l1.ExpectL1BlockRefByNumber(bt.origins[i].Number, bt.origins[i], nil)
}
func (bt *bankTestSetup) assertExpectations() {
bt.l1.AssertExpectations(bt.t)
bt.l1.ExpectedCalls = nil
bt.out.AssertExpectations(bt.t)
bt.out.ExpectedCalls = nil
}
cfg := &rollup.Config{ChannelTimeout: 10}
func TestL1ChannelBank(t *testing.T) {
testCases := []channelBankTestCase{
{
name: "time outs and buffering",
originTimes: []uint64{0, 1, 2, 3, 4, 5},
nextStartsAt: 3, // Start next stage at block #3
channelTimeout: 2, // Start at block #1
fn: func(bt *bankTestSetup) {
bt.expectL1BlockRefByNumber(1)
bt.repeatResetStep(10, nil)
bt.ingestFrames("a:0:first") // will time out b/c not closed
cb := NewChannelBank(testlog.Logger(t, log.LvlCrit), cfg, input, nil)
bt.repeatStep(10, 1, true, nil)
bt.repeatStep(10, 2, false, nil)
bt.assertOrigin(2)
// Load the first + third frame
out, err := cb.NextData(context.Background())
require.ErrorIs(t, err, NotEnoughData)
require.Equal(t, []byte(nil), out)
bt.repeatStep(10, 2, true, nil)
bt.repeatStep(10, 3, false, nil)
bt.assertOrigin(3)
// Load the second frame
out, err = cb.NextData(context.Background())
require.ErrorIs(t, err, NotEnoughData)
require.Equal(t, []byte(nil), out)
bt.repeatStep(10, 3, true, nil)
bt.repeatStep(10, 4, false, nil)
bt.assertOrigin(4)
// Pull out the channel data
out, err = cb.NextData(context.Background())
require.Nil(t, err)
require.Equal(t, "firstsecondthird", string(out))
// Properly closed channel
bt.expectChannel("foobarclosed")
bt.ingestFrames("b:0:foobar")
bt.ingestFrames("b:1:closed!")
bt.repeatStep(10, 4, true, nil)
bt.assertExpectations()
},
},
{
name: "duplicate frames",
originTimes: []uint64{0, 1, 2, 3, 4, 5},
nextStartsAt: 3, // Start next stage at block #3
channelTimeout: 2, // Start at block #1c
fn: func(bt *bankTestSetup) {
bt.expectL1BlockRefByNumber(1)
bt.repeatResetStep(10, nil)
bt.ingestFrames("a:0:first") // will time out b/c not closed
// No more data
out, err = cb.NextData(context.Background())
require.Nil(t, out)
require.Equal(t, io.EOF, err)
}
bt.repeatStep(10, 1, true, nil)
bt.repeatStep(10, 2, false, nil)
bt.assertOrigin(2)
func TestChannelBankDuplicates(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
a := testutils.RandomBlockRef(rng)
bt.repeatStep(10, 2, true, nil)
bt.repeatStep(10, 3, false, nil)
bt.assertOrigin(3)
input := &fakeChannelBankInput{origin: a}
input.AddFrames("a:0:first", "a:2:third!")
input.AddFrames("a:0:altfirst", "a:2:altthird!")
input.AddFrames("a:1:second")
input.AddOutput(nil, io.EOF)
bt.repeatStep(10, 3, true, nil)
bt.repeatStep(10, 4, false, nil)
bt.assertOrigin(4)
cfg := &rollup.Config{ChannelTimeout: 10}
bt.ingestFrames("a:0:first")
bt.repeatStep(1, 4, false, nil)
bt.ingestFrames("a:1:second")
bt.repeatStep(1, 4, false, nil)
bt.ingestFrames("a:0:altfirst") // ignored as duplicate
bt.repeatStep(1, 4, false, nil)
bt.ingestFrames("a:1:altsecond") // ignored as duplicate
bt.repeatStep(1, 4, false, nil)
bt.ingestFrames("b:0:new")
bt.repeatStep(1, 4, false, nil)
cb := NewChannelBank(testlog.Logger(t, log.LvlCrit), cfg, input, nil)
// close origin 4
bt.repeatStep(2, 4, true, nil)
// Load the first + third frame
out, err := cb.NextData(context.Background())
require.ErrorIs(t, err, NotEnoughData)
require.Equal(t, []byte(nil), out)
// open origin 1
bt.repeatStep(2, 5, false, nil)
bt.ingestFrames("b:1:hi!") // close the other one first, but blocked
bt.repeatStep(1, 5, false, nil)
bt.ingestFrames("a:2:!") // empty closing frame
bt.expectChannel("firstsecond")
bt.expectChannel("newhi")
bt.repeatStep(5, 5, false, nil)
bt.assertExpectations()
},
},
{
name: "skip bad frames",
originTimes: []uint64{101, 102},
nextStartsAt: 0,
channelTimeout: 3,
fn: func(bt *bankTestSetup) {
// don't do the whole setup process, just override where the stages are
bt.cb.progress = Progress{Origin: bt.origins[0], Closed: false}
bt.out.progress = Progress{Origin: bt.origins[0], Closed: false}
// Load the duplicate frames
out, err = cb.NextData(context.Background())
require.ErrorIs(t, err, NotEnoughData)
require.Equal(t, []byte(nil), out)
bt.assertOriginTime(101)
// Load the second frame
out, err = cb.NextData(context.Background())
require.ErrorIs(t, err, NotEnoughData)
require.Equal(t, []byte(nil), out)
badTx := new(bytes.Buffer)
badTx.WriteByte(DerivationVersion0)
goodFrame := testFrame("a:0:helloworld!").ToFrame()
if err := goodFrame.MarshalBinary(badTx); err != nil {
panic(fmt.Errorf("error in marshalling frame: %w", err))
}
badTx.Write(testutils.RandomData(bt.rng, 30)) // incomplete frame data
bt.ingestData(badTx.Bytes())
// Expect the bad frame to render the entire chunk invalid.
bt.repeatStep(2, 0, false, nil)
bt.assertExpectations()
},
},
}
for _, testCase := range testCases {
t.Run(testCase.name, testCase.Run)
}
// Pull out the channel data. Expect to see the original set & not the duplicates
out, err = cb.NextData(context.Background())
require.Nil(t, err)
require.Equal(t, "firstsecondthird", string(out))
// No more data
out, err = cb.NextData(context.Background())
require.Nil(t, out)
require.Equal(t, io.EOF, err)
}
......@@ -5,6 +5,7 @@ import (
"context"
"io"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum/go-ethereum/log"
)
......@@ -13,41 +14,36 @@ import (
// This is a pure function from the channel, but each channel (or channel fragment)
// must be tagged with an L1 inclusion block to be passed to the the batch queue.
type BatchQueueStage interface {
StageProgress
AddBatch(batch *BatchData)
}
type ChannelInReader struct {
log log.Logger
nextBatchFn func() (BatchWithL1InclusionBlock, error)
progress Progress
next BatchQueueStage
prev *ChannelBank
}
var _ ChannelBankOutput = (*ChannelInReader)(nil)
var _ PullStage = (*ChannelInReader)(nil)
// NewChannelInReader creates a ChannelInReader, which should be Reset(origin) before use.
func NewChannelInReader(log log.Logger, next BatchQueueStage) *ChannelInReader {
return &ChannelInReader{log: log, next: next}
func NewChannelInReader(log log.Logger, prev *ChannelBank) *ChannelInReader {
return &ChannelInReader{
log: log,
prev: prev,
}
}
func (cr *ChannelInReader) Progress() Progress {
return cr.progress
func (cr *ChannelInReader) Origin() eth.L1BlockRef {
return cr.prev.Origin()
}
// TODO: Take full channel for better logging
func (cr *ChannelInReader) WriteChannel(data []byte) {
if cr.progress.Closed {
panic("write channel while closed")
}
if f, err := BatchReader(bytes.NewBuffer(data), cr.progress.Origin); err == nil {
func (cr *ChannelInReader) WriteChannel(data []byte) error {
if f, err := BatchReader(bytes.NewBuffer(data), cr.Origin()); err == nil {
cr.nextBatchFn = f
return nil
} else {
cr.log.Error("Error creating batch reader from channel data", "err", err)
return err
}
}
......@@ -57,32 +53,37 @@ func (cr *ChannelInReader) NextChannel() {
cr.nextBatchFn = nil
}
func (cr *ChannelInReader) Step(ctx context.Context, outer Progress) error {
if changed, err := cr.progress.Update(outer); err != nil || changed {
return err
}
// NextBatch pulls out the next batch from the channel if it has it.
// It returns io.EOF when it cannot make any more progress.
// It will return a temporary error if it needs to be called again to advance some internal state.
func (cr *ChannelInReader) NextBatch(ctx context.Context) (*BatchData, error) {
if cr.nextBatchFn == nil {
return io.EOF
if data, err := cr.prev.NextData(ctx); err == io.EOF {
return nil, io.EOF
} else if err != nil {
return nil, err
} else {
if err := cr.WriteChannel(data); err != nil {
return nil, NewTemporaryError(err)
}
}
}
// TODO: can batch be non nil while err == io.EOF
// This depends on the behavior of rlp.Stream
batch, err := cr.nextBatchFn()
if err == io.EOF {
return io.EOF
cr.NextChannel()
return nil, NotEnoughData
} else if err != nil {
cr.log.Warn("failed to read batch from channel reader, skipping to next channel now", "err", err)
cr.NextChannel()
return nil
return nil, NotEnoughData
}
cr.next.AddBatch(batch.Batch)
return nil
return batch.Batch, nil
}
func (cr *ChannelInReader) ResetStep(ctx context.Context, l1Fetcher L1Fetcher) error {
func (cr *ChannelInReader) Reset(ctx context.Context, _ eth.L1BlockRef) error {
cr.nextBatchFn = nil
cr.progress = cr.next.Progress()
return io.EOF
}
......@@ -13,6 +13,8 @@ import (
"github.com/ethereum/go-ethereum/rlp"
)
var ErrNotDepositTx = errors.New("first transaction in block is not a deposit tx")
type ChannelOut struct {
id ChannelID
// Frame ID of the next frame to emit. Increment after emitting
......@@ -153,6 +155,9 @@ func blockToBatch(block *types.Block, w io.Writer) error {
opaqueTxs = append(opaqueTxs, otx)
}
l1InfoTx := block.Transactions()[0]
if l1InfoTx.Type() != types.DepositTxType {
return ErrNotDepositTx
}
l1Info, err := L1InfoDepositTxData(l1InfoTx.Data())
if err != nil {
return err // TODO: wrap err
......
package derive
import (
"math/big"
"testing"
"github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/require"
)
func TestChannelOutAddBlock(t *testing.T) {
cout, err := NewChannelOut()
require.NoError(t, err)
t.Run("returns err if first tx is not an l1info tx", func(t *testing.T) {
header := &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(100)}
block := types.NewBlockWithHeader(header).WithBody(
[]*types.Transaction{
types.NewTx(&types.DynamicFeeTx{}),
},
nil,
)
err := cout.AddBlock(block)
require.Error(t, err)
require.Equal(t, ErrNotDepositTx, err)
})
}
......@@ -17,6 +17,11 @@ import (
"github.com/ethereum/go-ethereum/log"
)
type NextAttributesProvider interface {
Origin() eth.L1BlockRef
NextAttributes(context.Context, eth.L2BlockRef) (*eth.PayloadAttributes, error)
}
type Engine interface {
GetPayload(ctx context.Context, payloadId eth.PayloadID) (*eth.ExecutionPayload, error)
ForkchoiceUpdate(ctx context.Context, state *eth.ForkchoiceState, attr *eth.PayloadAttributes) (*eth.ForkchoiceUpdatedResult, error)
......@@ -64,8 +69,6 @@ type EngineQueue struct {
finalizedL1 eth.BlockID
progress Progress
safeAttributes []*eth.PayloadAttributes
unsafePayloads PayloadsQueue // queue of unsafe payloads, ordered by ascending block number, may have gaps
......@@ -73,14 +76,15 @@ type EngineQueue struct {
finalityData []FinalityData
engine Engine
prev NextAttributesProvider
progress Progress // only used for pipeline resets
metrics Metrics
}
var _ AttributesQueueOutput = (*EngineQueue)(nil)
// NewEngineQueue creates a new EngineQueue, which should be Reset(origin) before use.
func NewEngineQueue(log log.Logger, cfg *rollup.Config, engine Engine, metrics Metrics) *EngineQueue {
func NewEngineQueue(log log.Logger, cfg *rollup.Config, engine Engine, metrics Metrics, prev NextAttributesProvider) *EngineQueue {
return &EngineQueue{
log: log,
cfg: cfg,
......@@ -91,6 +95,7 @@ func NewEngineQueue(log log.Logger, cfg *rollup.Config, engine Engine, metrics M
MaxSize: maxUnsafePayloadsMemory,
SizeFn: payloadMemSize,
},
prev: prev,
}
}
......@@ -146,17 +151,30 @@ func (eq *EngineQueue) LastL2Time() uint64 {
return uint64(eq.safeAttributes[len(eq.safeAttributes)-1].Timestamp)
}
func (eq *EngineQueue) Step(ctx context.Context, outer Progress) error {
if changed, err := eq.progress.Update(outer); err != nil || changed {
return err
}
func (eq *EngineQueue) Step(ctx context.Context, _ Progress) error {
if len(eq.safeAttributes) > 0 {
return eq.tryNextSafeAttributes(ctx)
}
outOfData := false
if len(eq.safeAttributes) == 0 {
if next, err := eq.prev.NextAttributes(ctx, eq.safeHead); err == io.EOF {
outOfData = true
} else if err != nil {
return err
} else {
eq.safeAttributes = append(eq.safeAttributes, next)
return NotEnoughData
}
}
if eq.unsafePayloads.Len() > 0 {
return eq.tryNextUnsafePayload(ctx)
}
if outOfData {
return io.EOF
} else {
return nil
}
}
// tryFinalizeL2 traverses the past L1 blocks, checks if any has been finalized,
......@@ -186,11 +204,11 @@ func (eq *EngineQueue) postProcessSafeL2() {
eq.finalityData = append(eq.finalityData[:0], eq.finalityData[1:finalityLookback]...)
}
// remember the last L2 block that we fully derived from the given finality data
if len(eq.finalityData) == 0 || eq.finalityData[len(eq.finalityData)-1].L1Block.Number < eq.progress.Origin.Number {
if len(eq.finalityData) == 0 || eq.finalityData[len(eq.finalityData)-1].L1Block.Number < eq.prev.Origin().Number {
// append entry for new L1 block
eq.finalityData = append(eq.finalityData, FinalityData{
L2Block: eq.safeHead,
L1Block: eq.progress.Origin.ID(),
L1Block: eq.prev.Origin().ID(),
})
} else {
// if it's a now L2 block that was derived from the same latest L1 block, then just update the entry
......@@ -205,7 +223,7 @@ func (eq *EngineQueue) logSyncProgress(reason string) {
"l2_safe", eq.safeHead,
"l2_unsafe", eq.unsafeHead,
"l2_time", eq.unsafeHead.Time,
"l1_derived", eq.progress.Origin,
"l1_derived", eq.prev.Origin(),
)
}
......@@ -398,6 +416,15 @@ func (eq *EngineQueue) ResetStep(ctx context.Context, l1Fetcher L1Fetcher) error
return NewResetError(fmt.Errorf("cannot reset block derivation to start at L2 block %s with time %d older than its L1 origin %s with time %d, time invariant is broken",
safe, safe.Time, l1Origin, l1Origin.Time))
}
pipelineNumber := l1Origin.Number - eq.cfg.ChannelTimeout
if l1Origin.Number < eq.cfg.ChannelTimeout {
pipelineNumber = 0
}
pipelineOrigin, err := l1Fetcher.L1BlockRefByNumber(ctx, pipelineNumber)
if err != nil {
return NewTemporaryError(fmt.Errorf("failed to fetch the new L1 progress: origin: %v; err: %w", pipelineNumber, err))
}
eq.log.Debug("Reset engine queue", "safeHead", safe, "unsafe", unsafe, "safe_timestamp", safe.Time, "unsafe_timestamp", unsafe.Time, "l1Origin", l1Origin)
eq.unsafeHead = unsafe
eq.safeHead = safe
......@@ -405,8 +432,7 @@ func (eq *EngineQueue) ResetStep(ctx context.Context, l1Fetcher L1Fetcher) error
eq.finalityData = eq.finalityData[:0]
// note: we do not clear the unsafe payloadds queue; if the payloads are not applicable anymore the parent hash checks will clear out the old payloads.
eq.progress = Progress{
Origin: l1Origin,
Closed: false,
Origin: pipelineOrigin,
}
eq.metrics.RecordL2Ref("l2_finalized", finalized)
eq.metrics.RecordL2Ref("l2_safe", safe)
......
package derive
import (
"context"
"io"
"math/rand"
"testing"
......@@ -14,6 +16,20 @@ import (
"github.com/ethereum/go-ethereum/log"
)
type fakeAttributesQueue struct {
origin eth.L1BlockRef
}
func (f *fakeAttributesQueue) Origin() eth.L1BlockRef {
return f.origin
}
func (f *fakeAttributesQueue) NextAttributes(_ context.Context, _ eth.L2BlockRef) (*eth.PayloadAttributes, error) {
return nil, io.EOF
}
var _ NextAttributesProvider = (*fakeAttributesQueue)(nil)
func TestEngineQueue_Finalize(t *testing.T) {
logger := testlog.Logger(t, log.LvlInfo)
......@@ -209,9 +225,12 @@ func TestEngineQueue_Finalize(t *testing.T) {
// and we fetch the L1 origin of that as starting point for engine queue
l1F.ExpectL1BlockRefByHash(refB.Hash, refB, nil)
l1F.ExpectL1BlockRefByNumber(refB.Number, refB, nil)
prev := &fakeAttributesQueue{}
eq := NewEngineQueue(logger, cfg, eng, metrics)
require.NoError(t, RepeatResetStep(t, eq.ResetStep, l1F, 20))
eq := NewEngineQueue(logger, cfg, eng, metrics, prev)
require.ErrorIs(t, eq.ResetStep(context.Background(), l1F), io.EOF)
require.Equal(t, refB1, eq.SafeL2Head(), "L2 reset should go back to sequence window ago: blocks with origin E and D are not safe until we reconcile, C is extra, and B1 is the end we look for")
require.Equal(t, refB, eq.Progress().Origin, "Expecting to be set back derivation L1 progress to B")
......@@ -219,20 +238,19 @@ func TestEngineQueue_Finalize(t *testing.T) {
// now say C1 was included in D and became the new safe head
eq.progress.Origin = refD
prev.origin = refD
eq.safeHead = refC1
eq.postProcessSafeL2()
// now say D0 was included in E and became the new safe head
eq.progress.Origin = refE
prev.origin = refE
eq.safeHead = refD0
eq.postProcessSafeL2()
// let's finalize D (current L1), from which we fully derived C1 (it was safe head), but not D0 (included in E)
eq.Finalize(refD.ID())
// Now a few steps later, without consuming any additional L1 inputs,
// we should be able to resolve that B1 is now finalized, since it was included in finalized L1 block C
require.NoError(t, RepeatStep(t, eq.Step, eq.progress, 10))
require.Equal(t, refC1, eq.Finalized(), "C1 was included in finalized D, and should now be finalized")
l1F.AssertExpectations(t)
......
package derive
import (
"errors"
"fmt"
)
......@@ -91,3 +92,7 @@ func NewCriticalError(err error) error {
var ErrTemporary = NewTemporaryError(nil)
var ErrReset = NewResetError(nil)
var ErrCritical = NewCriticalError(nil)
// NotEnoughData implies that the function currently does not have enough data to progress
// but if it is retried enough times, it will eventually return a real value or io.EOF
var NotEnoughData = errors.New("not enough data")
......@@ -2,105 +2,75 @@ package derive
import (
"context"
"fmt"
"io"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum/go-ethereum/log"
)
// This is a generic wrapper around fetching all transactions in a block & then
// it feeds one L1 transaction at a time to the next stage
// DataIter is a minimal iteration interface to fetch rollup input data from an arbitrary data-availability source
type DataIter interface {
// Next can be repeatedly called for more data, until it returns an io.EOF error.
// It never returns io.EOF and data at the same time.
Next(ctx context.Context) (eth.Data, error)
}
// DataAvailabilitySource provides rollup input data
type DataAvailabilitySource interface {
// OpenData does any initial data-fetching work and returns an iterator to fetch data with.
OpenData(ctx context.Context, id eth.BlockID) (DataIter, error)
OpenData(ctx context.Context, id eth.BlockID) DataIter
}
type L1SourceOutput interface {
StageProgress
IngestData(data []byte)
type NextBlockProvider interface {
NextL1Block(context.Context) (eth.L1BlockRef, error)
Origin() eth.L1BlockRef
}
type L1Retrieval struct {
log log.Logger
dataSrc DataAvailabilitySource
next L1SourceOutput
progress Progress
prev NextBlockProvider
data eth.Data
datas DataIter
}
var _ Stage = (*L1Retrieval)(nil)
var _ PullStage = (*L1Retrieval)(nil)
func NewL1Retrieval(log log.Logger, dataSrc DataAvailabilitySource, next L1SourceOutput) *L1Retrieval {
func NewL1Retrieval(log log.Logger, dataSrc DataAvailabilitySource, prev NextBlockProvider) *L1Retrieval {
return &L1Retrieval{
log: log,
dataSrc: dataSrc,
next: next,
prev: prev,
}
}
func (l1r *L1Retrieval) Progress() Progress {
return l1r.progress
func (l1r *L1Retrieval) Origin() eth.L1BlockRef {
return l1r.prev.Origin()
}
func (l1r *L1Retrieval) Step(ctx context.Context, outer Progress) error {
if changed, err := l1r.progress.Update(outer); err != nil || changed {
return err
}
// specific to L1 source: if the L1 origin is closed, there is no more data to retrieve.
if l1r.progress.Closed {
return io.EOF
}
// create a source if we have none
// NextData does an action in the L1 Retrieval stage
// If there is data, it pushes it to the next stage.
// If there is no more data open ourselves if we are closed or close ourselves if we are open
func (l1r *L1Retrieval) NextData(ctx context.Context) ([]byte, error) {
if l1r.datas == nil {
datas, err := l1r.dataSrc.OpenData(ctx, l1r.progress.Origin.ID())
if err != nil {
return NewTemporaryError(fmt.Errorf("can't fetch L1 data: %v: %w", l1r.progress.Origin, err))
next, err := l1r.prev.NextL1Block(ctx)
if err == io.EOF {
return nil, io.EOF
} else if err != nil {
return nil, err
}
l1r.datas = datas
return nil
l1r.datas = l1r.dataSrc.OpenData(ctx, next.ID())
}
// buffer data if we have none
if l1r.data == nil {
l1r.log.Debug("fetching next piece of data")
data, err := l1r.datas.Next(ctx)
if err == io.EOF {
l1r.progress.Closed = true
l1r.datas = nil
return io.EOF
return nil, io.EOF
} else if err != nil {
return NewTemporaryError(fmt.Errorf("context to retrieve next L1 data failed: %w", err))
// CalldataSource appropriately wraps the error so avoid double wrapping errors here.
return nil, err
} else {
l1r.data = data
return nil
return data, nil
}
}
// flush the data to next stage
l1r.next.IngestData(l1r.data)
// and nil the data, the next step will retrieve the next data
l1r.data = nil
return nil
}
func (l1r *L1Retrieval) ResetStep(ctx context.Context, l1Fetcher L1Fetcher) error {
l1r.progress = l1r.next.Progress()
l1r.datas = nil
l1r.data = nil
// ResetStep re-initializes the L1 Retrieval stage to block of it's `next` progress.
// Note that we open up the `l1r.datas` here because it is requires to maintain the
// internal invariants that later propagate up the derivation pipeline.
func (l1r *L1Retrieval) Reset(ctx context.Context, base eth.L1BlockRef) error {
l1r.datas = l1r.dataSrc.OpenData(ctx, base.ID())
l1r.log.Info("Reset of L1Retrieval done", "origin", base)
return io.EOF
}
......@@ -2,6 +2,7 @@ package derive
import (
"context"
"io"
"math/rand"
"testing"
......@@ -11,65 +12,145 @@ import (
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum-optimism/optimism/op-node/testutils"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/log"
)
type fakeDataIter struct {
idx int
data []eth.Data
errs []error
}
func (cs *fakeDataIter) Next(ctx context.Context) (eth.Data, error) {
i := cs.idx
cs.idx += 1
return cs.data[i], cs.errs[i]
}
type MockDataSource struct {
mock.Mock
}
func (m *MockDataSource) OpenData(ctx context.Context, id eth.BlockID) (DataIter, error) {
func (m *MockDataSource) OpenData(ctx context.Context, id eth.BlockID) DataIter {
out := m.Mock.MethodCalled("OpenData", id)
return out[0].(DataIter), *out[1].(*error)
return out[0].(DataIter)
}
func (m *MockDataSource) ExpectOpenData(id eth.BlockID, iter DataIter, err error) {
m.Mock.On("OpenData", id).Return(iter, &err)
func (m *MockDataSource) ExpectOpenData(id eth.BlockID, iter DataIter) {
m.Mock.On("OpenData", id).Return(iter)
}
var _ DataAvailabilitySource = (*MockDataSource)(nil)
type MockIngestData struct {
MockOriginStage
type MockL1Traversal struct {
mock.Mock
}
func (im *MockIngestData) IngestData(data []byte) {
im.Mock.MethodCalled("IngestData", data)
func (m *MockL1Traversal) Origin() eth.L1BlockRef {
out := m.Mock.MethodCalled("Origin")
return out[0].(eth.L1BlockRef)
}
func (im *MockIngestData) ExpectIngestData(data []byte) {
im.Mock.On("IngestData", data).Return()
func (m *MockL1Traversal) ExpectOrigin(block eth.L1BlockRef) {
m.Mock.On("Origin").Return(block)
}
var _ L1SourceOutput = (*MockIngestData)(nil)
func (m *MockL1Traversal) NextL1Block(_ context.Context) (eth.L1BlockRef, error) {
out := m.Mock.MethodCalled("NextL1Block")
return out[0].(eth.L1BlockRef), *out[1].(*error)
}
func TestL1Retrieval_Step(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
func (m *MockL1Traversal) ExpectNextL1Block(block eth.L1BlockRef, err error) {
m.Mock.On("NextL1Block").Return(block, &err)
}
next := &MockIngestData{MockOriginStage{progress: Progress{Origin: testutils.RandomBlockRef(rng), Closed: true}}}
var _ NextBlockProvider = (*MockL1Traversal)(nil)
// TestL1RetrievalReset tests the reset. The reset just opens up a new
// data for the specified block.
func TestL1RetrievalReset(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
dataSrc := &MockDataSource{}
a := testutils.RandomBlockRef(rng)
dataSrc.ExpectOpenData(a.ID(), &fakeDataIter{})
defer dataSrc.AssertExpectations(t)
a := testutils.RandomData(rng, 10)
b := testutils.RandomData(rng, 15)
iter := &DataSlice{a, b}
l1r := NewL1Retrieval(testlog.Logger(t, log.LvlError), dataSrc, nil)
outer := Progress{Origin: testutils.NextRandomRef(rng, next.progress.Origin), Closed: false}
// We assert that it opens up the correct data on a reset
_ = l1r.Reset(context.Background(), a)
}
// mock some L1 data to open for the origin that is opened by the outer stage
dataSrc.ExpectOpenData(outer.Origin.ID(), iter, nil)
// TestL1RetrievalNextData tests that the `NextData` function properly
// handles different error cases and returns the expected data
// if there is no error.
func TestL1RetrievalNextData(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
a := testutils.RandomBlockRef(rng)
tests := []struct {
name string
prevBlock eth.L1BlockRef
prevErr error // error returned by prev.NextL1Block
openErr error // error returned by NextData if prev.NextL1Block fails
datas []eth.Data
datasErrs []error
expectedErrs []error
}{
{
name: "simple retrieval",
prevBlock: a,
prevErr: nil,
openErr: nil,
datas: []eth.Data{testutils.RandomData(rng, 10), testutils.RandomData(rng, 10), testutils.RandomData(rng, 10), nil},
datasErrs: []error{nil, nil, nil, io.EOF},
expectedErrs: []error{nil, nil, nil, io.EOF},
},
{
name: "out of data",
prevErr: io.EOF,
openErr: io.EOF,
},
{
name: "fail to open data",
prevBlock: a,
prevErr: nil,
openErr: nil,
datas: []eth.Data{nil},
datasErrs: []error{NewCriticalError(ethereum.NotFound)},
expectedErrs: []error{ErrCritical},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
l1t := &MockL1Traversal{}
l1t.ExpectNextL1Block(test.prevBlock, test.prevErr)
dataSrc := &MockDataSource{}
dataSrc.ExpectOpenData(test.prevBlock.ID(), &fakeDataIter{data: test.datas, errs: test.datasErrs})
next.ExpectIngestData(a)
next.ExpectIngestData(b)
ret := NewL1Retrieval(testlog.Logger(t, log.LvlCrit), dataSrc, l1t)
defer dataSrc.AssertExpectations(t)
defer next.AssertExpectations(t)
// If prevErr != nil we forced an error while getting data from the previous stage
if test.openErr != nil {
data, err := ret.NextData(context.Background())
require.Nil(t, data)
require.ErrorIs(t, err, test.openErr)
}
l1r := NewL1Retrieval(testlog.Logger(t, log.LvlError), dataSrc, next)
// Go through the fake data an assert that data is passed through and the correct
// errors are returned.
for i := range test.expectedErrs {
data, err := ret.NextData(context.Background())
require.Equal(t, test.datas[i], hexutil.Bytes(data))
require.ErrorIs(t, err, test.expectedErrs[i])
}
// first we expect the stage to reset to the origin of the inner stage
require.NoError(t, RepeatResetStep(t, l1r.ResetStep, nil, 1))
require.Equal(t, next.Progress(), l1r.Progress(), "stage needs to adopt the progress of next stage on reset")
l1t.AssertExpectations(t)
})
}
// and then start processing the data of the next stage
require.NoError(t, RepeatStep(t, l1r.Step, outer, 10))
}
......@@ -11,42 +11,46 @@ import (
"github.com/ethereum/go-ethereum/log"
)
// L1 Traversal fetches the next L1 block and exposes it through the progress API
type L1BlockRefByNumberFetcher interface {
L1BlockRefByNumber(context.Context, uint64) (eth.L1BlockRef, error)
}
type L1Traversal struct {
log log.Logger
block eth.L1BlockRef
done bool
l1Blocks L1BlockRefByNumberFetcher
next StageProgress
progress Progress
log log.Logger
}
var _ Stage = (*L1Traversal)(nil)
var _ PullStage = (*L1Traversal)(nil)
func NewL1Traversal(log log.Logger, l1Blocks L1BlockRefByNumberFetcher, next StageProgress) *L1Traversal {
func NewL1Traversal(log log.Logger, l1Blocks L1BlockRefByNumberFetcher) *L1Traversal {
return &L1Traversal{
log: log,
l1Blocks: l1Blocks,
next: next,
}
}
func (l1t *L1Traversal) Progress() Progress {
return l1t.progress
func (l1t *L1Traversal) Origin() eth.L1BlockRef {
return l1t.block
}
func (l1t *L1Traversal) Step(ctx context.Context, outer Progress) error {
if !l1t.progress.Closed { // close origin and do another pipeline sweep, before we try to move to the next origin
l1t.progress.Closed = true
return nil
// NextL1Block returns the next block. It does not advance, but it can only be
// called once before returning io.EOF
func (l1t *L1Traversal) NextL1Block(_ context.Context) (eth.L1BlockRef, error) {
if !l1t.done {
l1t.done = true
return l1t.block, nil
} else {
return eth.L1BlockRef{}, io.EOF
}
}
// If we reorg to a shorter chain, then we'll only derive new L2 data once the L1 reorg
// becomes longer than the previous L1 chain.
// This is fine, assuming the new L1 chain is live, but we may want to reconsider this.
origin := l1t.progress.Origin
// AdvanceL1Block advances the internal state of L1 Traversal
func (l1t *L1Traversal) AdvanceL1Block(ctx context.Context) error {
origin := l1t.block
nextL1Origin, err := l1t.l1Blocks.L1BlockRefByNumber(ctx, origin.Number+1)
if errors.Is(err, ethereum.NotFound) {
l1t.log.Debug("can't find next L1 block info (yet)", "number", origin.Number+1, "origin", origin)
......@@ -54,16 +58,20 @@ func (l1t *L1Traversal) Step(ctx context.Context, outer Progress) error {
} else if err != nil {
return NewTemporaryError(fmt.Errorf("failed to find L1 block info by number, at origin %s next %d: %w", origin, origin.Number+1, err))
}
if l1t.progress.Origin.Hash != nextL1Origin.ParentHash {
return NewResetError(fmt.Errorf("detected L1 reorg from %s to %s with conflicting parent %s", l1t.progress.Origin, nextL1Origin, nextL1Origin.ParentID()))
if l1t.block.Hash != nextL1Origin.ParentHash {
return NewResetError(fmt.Errorf("detected L1 reorg from %s to %s with conflicting parent %s", l1t.block, nextL1Origin, nextL1Origin.ParentID()))
}
l1t.progress.Origin = nextL1Origin
l1t.progress.Closed = false
l1t.block = nextL1Origin
l1t.done = false
return nil
}
func (l1t *L1Traversal) ResetStep(ctx context.Context, l1Fetcher L1Fetcher) error {
l1t.progress = l1t.next.Progress()
l1t.log.Info("completed reset of derivation pipeline", "origin", l1t.progress.Origin)
// Reset sets the internal L1 block to the supplied base.
// Note that the next call to `NextL1Block` will return the block after `base`
// TODO: Walk one back/figure this out.
func (l1t *L1Traversal) Reset(ctx context.Context, base eth.L1BlockRef) error {
l1t.block = base
l1t.done = false
l1t.log.Info("completed reset of derivation pipeline", "origin", base)
return io.EOF
}
package derive
import (
"context"
"errors"
"io"
"math/rand"
"testing"
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum-optimism/optimism/op-node/testutils"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/log"
)
func TestL1Traversal_Step(t *testing.T) {
// TestL1TraversalNext tests that the `Next` function only returns
// a block reference once and then properly returns io.EOF afterwards
func TestL1TraversalNext(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
a := testutils.RandomBlockRef(rng)
tr := NewL1Traversal(testlog.Logger(t, log.LvlError), nil)
// Load up the initial state with a reset
_ = tr.Reset(context.Background(), a)
// First call should always succeed
ref, err := tr.NextL1Block(context.Background())
require.Nil(t, err)
require.Equal(t, a, ref)
// Subsequent calls should return io.EOF
ref, err = tr.NextL1Block(context.Background())
require.Equal(t, eth.L1BlockRef{}, ref)
require.Equal(t, io.EOF, err)
ref, err = tr.NextL1Block(context.Background())
require.Equal(t, eth.L1BlockRef{}, ref)
require.Equal(t, io.EOF, err)
}
// TestL1TraversalAdvance tests that the `Advance` function properly
// handles different error cases and returns the expected block ref
// if there is no error.
func TestL1TraversalAdvance(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
a := testutils.RandomBlockRef(rng)
b := testutils.NextRandomRef(rng, a)
c := testutils.NextRandomRef(rng, b)
d := testutils.NextRandomRef(rng, c)
e := testutils.NextRandomRef(rng, d)
f := testutils.RandomBlockRef(rng) // a fork, doesn't build on d
f.Number = e.Number + 1 // even though it might be the next number
l1Fetcher := &testutils.MockL1Source{}
l1Fetcher.ExpectL1BlockRefByNumber(b.Number, b, nil)
// pretend there's an RPC error
l1Fetcher.ExpectL1BlockRefByNumber(c.Number, c, errors.New("rpc error - check back later"))
l1Fetcher.ExpectL1BlockRefByNumber(c.Number, c, nil)
// pretend the block is not there yet for a while
l1Fetcher.ExpectL1BlockRefByNumber(d.Number, d, ethereum.NotFound)
l1Fetcher.ExpectL1BlockRefByNumber(d.Number, d, ethereum.NotFound)
// it will show up though
l1Fetcher.ExpectL1BlockRefByNumber(d.Number, d, nil)
l1Fetcher.ExpectL1BlockRefByNumber(e.Number, e, nil)
l1Fetcher.ExpectL1BlockRefByNumber(f.Number, f, nil)
next := &MockOriginStage{progress: Progress{Origin: a, Closed: false}}
tr := NewL1Traversal(testlog.Logger(t, log.LvlError), l1Fetcher, next)
defer l1Fetcher.AssertExpectations(t)
defer next.AssertExpectations(t)
require.NoError(t, RepeatResetStep(t, tr.ResetStep, nil, 1))
require.Equal(t, a, tr.Progress().Origin, "stage needs to adopt the origin of next stage on reset")
require.False(t, tr.Progress().Closed, "stage needs to be open after reset")
require.ErrorIs(t, RepeatStep(t, tr.Step, Progress{}, 10), ErrTemporary, "expected temporary error because of RPC mock fail")
require.NoError(t, RepeatStep(t, tr.Step, Progress{}, 10))
require.Equal(t, c, tr.Progress().Origin, "expected to be stuck on ethereum.NotFound on d")
require.NoError(t, RepeatStep(t, tr.Step, Progress{}, 1))
require.Equal(t, c, tr.Progress().Origin, "expected to be stuck again, should get the EOF within 1 step")
require.ErrorIs(t, RepeatStep(t, tr.Step, Progress{}, 10), ErrReset, "completed pipeline, until L1 input f that causes a reorg")
// x is at the same height as b but does not extend `a`
x := testutils.RandomBlockRef(rng)
x.Number = b.Number
tests := []struct {
name string
startBlock eth.L1BlockRef
nextBlock eth.L1BlockRef
fetcherErr error
expectedErr error
}{
{
name: "simple extension",
startBlock: a,
nextBlock: b,
fetcherErr: nil,
expectedErr: nil,
},
{
name: "reorg",
startBlock: a,
nextBlock: x,
fetcherErr: nil,
expectedErr: ErrReset,
},
{
name: "not found",
startBlock: a,
nextBlock: eth.L1BlockRef{},
fetcherErr: ethereum.NotFound,
expectedErr: io.EOF,
},
{
name: "temporary error",
startBlock: a,
nextBlock: eth.L1BlockRef{},
fetcherErr: errors.New("interrupted connection"),
expectedErr: ErrTemporary,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
src := &testutils.MockL1Source{}
src.ExpectL1BlockRefByNumber(test.startBlock.Number+1, test.nextBlock, test.fetcherErr)
tr := NewL1Traversal(testlog.Logger(t, log.LvlError), src)
// Load up the initial state with a reset
_ = tr.Reset(context.Background(), test.startBlock)
// Advance it + assert output
err := tr.AdvanceL1Block(context.Background())
require.ErrorIs(t, err, test.expectedErr)
if test.expectedErr == nil {
ref, err := tr.NextL1Block(context.Background())
require.Nil(t, err)
require.Equal(t, test.nextBlock, ref)
}
src.AssertExpectations(t)
})
}
}
......@@ -28,6 +28,12 @@ type StageProgress interface {
Progress() Progress
}
type PullStage interface {
// Reset resets a pull stage. `base` refers to the L1 Block Reference to reset to.
// TODO: Return L1 Block reference
Reset(ctx context.Context, base eth.L1BlockRef) error
}
type Stage interface {
StageProgress
......@@ -69,6 +75,7 @@ type DerivationPipeline struct {
// Index of the stage that is currently being reset.
// >= len(stages) if no additional resetting is required
resetting int
pullResetIdx int
// Index of the stage that is currently being processed.
active int
......@@ -76,6 +83,9 @@ type DerivationPipeline struct {
// stages in execution order. A stage Step that:
stages []Stage
pullStages []PullStage
traversal *L1Traversal
eng EngineQueueStage
metrics Metrics
......@@ -83,15 +93,21 @@ type DerivationPipeline struct {
// NewDerivationPipeline creates a derivation pipeline, which should be reset before use.
func NewDerivationPipeline(log log.Logger, cfg *rollup.Config, l1Fetcher L1Fetcher, engine Engine, metrics Metrics) *DerivationPipeline {
eng := NewEngineQueue(log, cfg, engine, metrics)
attributesQueue := NewAttributesQueue(log, cfg, l1Fetcher, eng)
batchQueue := NewBatchQueue(log, cfg, attributesQueue)
chInReader := NewChannelInReader(log, batchQueue)
bank := NewChannelBank(log, cfg, chInReader)
dataSrc := NewCalldataSource(log, cfg, l1Fetcher)
l1Src := NewL1Retrieval(log, dataSrc, bank)
l1Traversal := NewL1Traversal(log, l1Fetcher, l1Src)
stages := []Stage{eng, attributesQueue, batchQueue, chInReader, bank, l1Src, l1Traversal}
// Pull stages
l1Traversal := NewL1Traversal(log, l1Fetcher)
dataSrc := NewDataSourceFactory(log, cfg, l1Fetcher) // auxiliary stage for L1Retrieval
l1Src := NewL1Retrieval(log, dataSrc, l1Traversal)
bank := NewChannelBank(log, cfg, l1Src, l1Fetcher)
chInReader := NewChannelInReader(log, bank)
batchQueue := NewBatchQueue(log, cfg, chInReader)
attributesQueue := NewAttributesQueue(log, cfg, l1Fetcher, batchQueue)
// Push stages (that act like pull stages b/c we push from the innermost stages prior to the outermost stages)
eng := NewEngineQueue(log, cfg, engine, metrics, attributesQueue)
stages := []Stage{eng}
pullStages := []PullStage{attributesQueue, batchQueue, chInReader, bank, l1Src, l1Traversal}
return &DerivationPipeline{
log: log,
......@@ -100,13 +116,16 @@ func NewDerivationPipeline(log log.Logger, cfg *rollup.Config, l1Fetcher L1Fetch
resetting: 0,
active: 0,
stages: stages,
pullStages: pullStages,
eng: eng,
metrics: metrics,
traversal: l1Traversal,
}
}
func (dp *DerivationPipeline) Reset() {
dp.resetting = 0
dp.pullResetIdx = 0
}
func (dp *DerivationPipeline) Progress() Progress {
......@@ -160,7 +179,24 @@ func (dp *DerivationPipeline) Step(ctx context.Context) error {
return nil
}
}
// Then reset the pull based stages
if dp.pullResetIdx < len(dp.pullStages) {
// Use the last stage's progress as the one to pull from
inner := dp.stages[len(dp.stages)-1].Progress()
// Do the reset
if err := dp.pullStages[dp.pullResetIdx].Reset(ctx, inner.Origin); err == io.EOF {
// dp.log.Debug("reset of stage completed", "stage", dp.pullResetIdx, "origin", dp.pullStages[dp.pullResetIdx].Progress().Origin)
dp.pullResetIdx += 1
return nil
} else if err != nil {
return fmt.Errorf("stage %d failed resetting: %w", dp.pullResetIdx, err)
} else {
return nil
}
}
// Lastly advance the stages
for i, stage := range dp.stages {
var outer Progress
if i+1 < len(dp.stages) {
......@@ -174,5 +210,6 @@ func (dp *DerivationPipeline) Step(ctx context.Context) error {
return nil
}
}
return io.EOF
// If every stage has returned io.EOF, try to advance the L1 Origin
return dp.traversal.AdvanceL1Block(ctx)
}
......@@ -440,6 +440,10 @@ func (s *state) eventLoop() {
} else if err != nil && errors.Is(err, derive.ErrCritical) {
s.log.Error("Derivation process critical error", "err", err)
return
} else if err != nil && errors.Is(err, derive.NotEnoughData) {
stepAttempts = 0 // don't do a backoff for this error
reqStep()
continue
} else if err != nil {
s.log.Error("Derivation process error", "attempts", stepAttempts, "err", err)
reqStep()
......
......@@ -3,9 +3,9 @@ module github.com/ethereum-optimism/optimism/op-proposer
go 1.18
require (
github.com/ethereum-optimism/optimism/op-bindings v0.8.6
github.com/ethereum-optimism/optimism/op-node v0.8.6
github.com/ethereum-optimism/optimism/op-service v0.8.6
github.com/ethereum-optimism/optimism/op-bindings v0.8.8
github.com/ethereum-optimism/optimism/op-node v0.8.8
github.com/ethereum-optimism/optimism/op-service v0.8.8
github.com/ethereum/go-ethereum v1.10.23
github.com/miguelmota/go-ethereum-hdwallet v0.1.1
github.com/stretchr/testify v1.8.0
......@@ -76,4 +76,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd
......@@ -148,14 +148,14 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73 h1:eXnnByFF0QiN1Qrq0wYmvI5lbDM8QQM0pv6AHx2FLnk=
github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo=
github.com/ethereum-optimism/optimism/op-bindings v0.8.6 h1:jJYhmygt7hqGzYa+8sme9SdnKt1c3Y6EbWgIrRONoxw=
github.com/ethereum-optimism/optimism/op-bindings v0.8.6/go.mod h1:gUX5317IAvRMjB4GftayM87JVln3DTqukfirwJpEWnE=
github.com/ethereum-optimism/optimism/op-node v0.8.6 h1:xNwN+Q/Rt17vSKawhBeG9qTcqcyh8JU8PGjK1iuGkF4=
github.com/ethereum-optimism/optimism/op-node v0.8.6/go.mod h1:gkyzgVHV3+tIhLZ8GhT+bL9GrrmouQCW4mKYukS0SHg=
github.com/ethereum-optimism/optimism/op-service v0.8.6 h1:ruZp/BxL8TGn1y9EJmygypPTeVAFlAA0A/h8LsCoV+M=
github.com/ethereum-optimism/optimism/op-service v0.8.6/go.mod h1:gm8YNzERrL/CHBPWx3+01mR/NOVpLLw4GEUSnnTdyFU=
github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd h1:NchOnosWOkH9wlix8QevGHE+6vuRa+OMGvDNsczv2kQ=
github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo=
github.com/ethereum-optimism/optimism/op-bindings v0.8.8 h1:HN625JI2VsRsli+U6GAXipg7lAKx8EOmGIovN79Az+I=
github.com/ethereum-optimism/optimism/op-bindings v0.8.8/go.mod h1:pyTCbh2o/SY+5/AL2Qo5GgAao3Gtt9Ff6tfK9Pa9emM=
github.com/ethereum-optimism/optimism/op-node v0.8.8 h1:WuZF1RsZnB+u/wwWToVaC1lZWfGfgncLusUssA3Hm+o=
github.com/ethereum-optimism/optimism/op-node v0.8.8/go.mod h1:O5nXPCx8vn9c/CHgBC7vP5utcanIQ4uhWKkJ3pAaaSQ=
github.com/ethereum-optimism/optimism/op-service v0.8.8 h1:k5E78Zr2cGU0SwjoHpFXuC1eyfXhu3oKEOnDDaFi57I=
github.com/ethereum-optimism/optimism/op-service v0.8.8/go.mod h1:K0uybOhICTc2yfhrRj0cD1m7aPkOf5C9e6bUmvf4rGA=
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=
......
......@@ -65,4 +65,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd
......@@ -108,8 +108,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73 h1:eXnnByFF0QiN1Qrq0wYmvI5lbDM8QQM0pv6AHx2FLnk=
github.com/ethereum-optimism/op-geth v0.0.0-20220921202220-511148385c73/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo=
github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd h1:NchOnosWOkH9wlix8QevGHE+6vuRa+OMGvDNsczv2kQ=
github.com/ethereum-optimism/op-geth v0.0.0-20220926184707-53d23c240afd/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo=
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=
......
......@@ -51,7 +51,7 @@ services:
--sequencer.enabled
--sequencer.l1-confs=0
--verifier.l1-confs=0
--p2p.sequencer.key=/config/p2p-sequencer-key.txt
--p2p.sequencer.key=8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba
--rollup.config=/rollup.json
--rpc.addr=0.0.0.0
--rpc.port=8545
......
8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba
......@@ -54,6 +54,9 @@ npx hardhat take-dump --network $CONTRACTS_TARGET_NETWORK
mv addresses.json ./genesis
cp ./genesis/$CONTRACTS_TARGET_NETWORK.json ./genesis/state-dump.latest.json
# expose the deployments
cp -rf ./deployments ./genesis/deployments
# service the addresses and dumps
echo "Starting server."
python3 -m http.server \
......
......@@ -386,9 +386,17 @@ export abstract class BaseServiceV2<
const app = express()
// Body parsing.
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
// Keep the raw body around in case the application needs it.
app.use(
bodyParser.json({
verify: (req, res, buf, encoding) => {
;(req as any).rawBody = buf?.toString(encoding || 'utf8') || ''
},
})
)
// Logging.
app.use(
morgan('short', {
......
AddressAliasHelper_Test:test_fuzz_roundtrip(address) (runs: 256, μ: 466, ~: 466)
GasBenchMark_L1CrossDomainMessenger:test_L1MessengerSendMessage_benchmark_0() (gas: 261333)
GasBenchMark_L1CrossDomainMessenger:test_L1MessengerSendMessage_benchmark_1() (gas: 75493)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 348050)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 112228)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 348072)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 112203)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 40534)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 348072)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 112250)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 348094)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 112225)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 40569)
GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 68671)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 74964)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 35777)
......@@ -65,19 +66,21 @@ L1CrossDomainMessenger_Test:test_L1MessengerTwiceSendMessage() (gas: 1490366)
L1CrossDomainMessenger_Test:test_L1MessengerUnpause() (gas: 41003)
L1CrossDomainMessenger_Test:test_L1MessengerXDomainSenderReverts() (gas: 24283)
L1CrossDomainMessenger_Test:test_L1MessengerxDomainMessageSenderResets() (gas: 81947)
L1StandardBridge_Test:test_depositERC20() (gas: 573485)
L1StandardBridge_Test:test_depositERC20To() (gas: 575692)
L1StandardBridge_Test:test_depositETH() (gas: 367591)
L1StandardBridge_Test:test_depositETHTo() (gas: 324772)
L1StandardBridge_Test:test_finalizeBridgeERC20FailSendBack() (gas: 674560)
L1StandardBridge_Test:test_finalizeERC20Withdrawal() (gas: 486305)
L1StandardBridge_Test:test_finalizeETHWithdrawal() (gas: 58841)
L1StandardBridge_Test:test_initialize() (gas: 22127)
L1StandardBridge_Test:test_onlyEOADepositERC20() (gas: 22376)
L1StandardBridge_Test:test_onlyEOADepositETH() (gas: 40836)
L1StandardBridge_Test:test_onlyL2BridgeFinalizeERC20Withdrawal() (gas: 31648)
L1StandardBridge_Test:test_onlyPortalFinalizeERC20Withdrawal() (gas: 31211)
L1StandardBridge_Test:test_receive() (gas: 514232)
L1StandardBridge_Test:test_depositERC20() (gas: 573393)
L1StandardBridge_Test:test_depositERC20To() (gas: 575512)
L1StandardBridge_Test:test_depositETH() (gas: 367613)
L1StandardBridge_Test:test_depositETHTo() (gas: 324750)
L1StandardBridge_Test:test_finalizeBridgeETH_incorrectValueReverts() (gas: 34246)
L1StandardBridge_Test:test_finalizeBridgeETH_sendToMessengerReverts() (gas: 34325)
L1StandardBridge_Test:test_finalizeBridgeETH_sendToSelfReverts() (gas: 34284)
L1StandardBridge_Test:test_finalizeERC20Withdrawal() (gas: 484456)
L1StandardBridge_Test:test_finalizeETHWithdrawal() (gas: 58729)
L1StandardBridge_Test:test_initialize() (gas: 22082)
L1StandardBridge_Test:test_onlyEOADepositERC20() (gas: 22420)
L1StandardBridge_Test:test_onlyEOADepositETH() (gas: 40793)
L1StandardBridge_Test:test_onlyL2BridgeFinalizeERC20Withdrawal() (gas: 31579)
L1StandardBridge_Test:test_onlyPortalFinalizeERC20Withdrawal() (gas: 31188)
L1StandardBridge_Test:test_receive() (gas: 514254)
L2CrossDomainMessenger_Test:testCannot_L2MessengerPause() (gas: 10860)
L2CrossDomainMessenger_Test:test_L1MessengerRelayMessageRevertsOnReentrancy() (gas: 167641)
L2CrossDomainMessenger_Test:test_L2MessengerMessageVersion() (gas: 8411)
......@@ -92,41 +95,43 @@ L2CrossDomainMessenger_Test:test_L2MessengerTwiceSendMessage() (gas: 136338)
L2CrossDomainMessenger_Test:test_L2MessengerXDomainSenderReverts() (gas: 10576)
L2CrossDomainMessenger_Test:test_L2MessengerxDomainMessageSenderResets() (gas: 50459)
L2OutputOracleTest:testCannot_ProposeWithUnmatchedBlockhash() (gas: 26829)
L2OutputOracleTest:testCannot_constructWithBadTimestamp() (gas: 52842)
L2OutputOracleTest:testCannot_deleteL2Output_ifNotOwner() (gas: 25123)
L2OutputOracleTest:testCannot_deleteL2Output_withWrongRoot() (gas: 91445)
L2OutputOracleTest:testCannot_deleteL2Output_withWrongRoot() (gas: 91467)
L2OutputOracleTest:testCannot_deleteL2Output_withWrongTime() (gas: 87450)
L2OutputOracleTest:testCannot_proposeEmptyOutput() (gas: 24128)
L2OutputOracleTest:testCannot_proposeFutureTimetamp() (gas: 26097)
L2OutputOracleTest:testCannot_proposeEmptyOutput() (gas: 24150)
L2OutputOracleTest:testCannot_proposeFutureTimetamp() (gas: 26074)
L2OutputOracleTest:testCannot_proposeL2OutputIfNotProposer() (gas: 23564)
L2OutputOracleTest:testCannot_proposeOnWrongFork() (gas: 26424)
L2OutputOracleTest:testCannot_proposeUnexpectedBlockNumber() (gas: 25983)
L2OutputOracleTest:testCannot_proposeOnWrongFork() (gas: 26381)
L2OutputOracleTest:testCannot_proposeUnexpectedBlockNumber() (gas: 26005)
L2OutputOracleTest:test_changeProposer() (gas: 56127)
L2OutputOracleTest:test_computeL2Timestamp() (gas: 30307)
L2OutputOracleTest:test_computeL2Timestamp() (gas: 30284)
L2OutputOracleTest:test_constructor() (gas: 49046)
L2OutputOracleTest:test_deleteOutput() (gas: 77242)
L2OutputOracleTest:test_getL2Output() (gas: 88546)
L2OutputOracleTest:test_latestBlockNumber() (gas: 76284)
L2OutputOracleTest:test_nextBlockNumber() (gas: 15232)
L2OutputOracleTest:test_deleteOutput() (gas: 77260)
L2OutputOracleTest:test_getL2Output() (gas: 88523)
L2OutputOracleTest:test_latestBlockNumber() (gas: 76242)
L2OutputOracleTest:test_nextBlockNumber() (gas: 15254)
L2OutputOracleTest:test_proposeWithBlockhashAndHeight() (gas: 75046)
L2OutputOracleTest:test_proposingAnotherOutput() (gas: 76881)
L2OutputOracleTest:test_updateOwner() (gas: 46073)
L2OutputOracleTest:test_proposingAnotherOutput() (gas: 76903)
L2OutputOracleTest:test_updateOwner() (gas: 46095)
L2OutputOracleUpgradeable_Test:test_cannotInitImpl() (gas: 19555)
L2OutputOracleUpgradeable_Test:test_cannotInitProxy() (gas: 24554)
L2OutputOracleUpgradeable_Test:test_initValuesOnProxy() (gas: 39086)
L2OutputOracleUpgradeable_Test:test_upgrading() (gas: 180632)
L2StandardBridge_Test:test_ERC20BridgeFailed_whenLocalTokenIsBridge() (gas: 128674)
L2StandardBridge_Test:test_cannotWithdrawEthWithoutSendingIt() (gas: 21619)
L2StandardBridge_Test:test_finalizeBridgeERC20FailSendBack() (gas: 493550)
L2StandardBridge_Test:test_finalizeDeposit() (gas: 94693)
L2StandardBridge_Test:test_finalizeDeposit_failsToCompleteOutboundTransfer() (gas: 152465)
L2StandardBridge_Test:test_initialize() (gas: 10616)
L2StandardBridge_Test:test_receive() (gas: 132729)
L2StandardBridge_Test:test_withdraw() (gas: 347956)
L2StandardBridge_Test:test_withdrawTo() (gas: 348657)
L2StandardBridge_Test:test_withdraw_onlyEOA() (gas: 251674)
L2StandardBridge_Test:test_cannotWithdrawEthWithoutSendingIt() (gas: 21816)
L2StandardBridge_Test:test_finalizeBridgeETH_incorrectValueReverts() (gas: 23835)
L2StandardBridge_Test:test_finalizeBridgeETH_sendToMessengerReverts() (gas: 23973)
L2StandardBridge_Test:test_finalizeBridgeETH_sendToSelfReverts() (gas: 23873)
L2StandardBridge_Test:test_finalizeDeposit() (gas: 93660)
L2StandardBridge_Test:test_initialize() (gas: 10594)
L2StandardBridge_Test:test_receive() (gas: 132751)
L2StandardBridge_Test:test_withdraw() (gas: 347893)
L2StandardBridge_Test:test_withdrawTo() (gas: 348648)
L2StandardBridge_Test:test_withdraw_onlyEOA() (gas: 251656)
L2ToL1MessagePasserTest:test_burn() (gas: 113395)
L2ToL1MessagePasserTest:test_fuzz_initiateWithdrawal(address,address,uint256,uint256,bytes) (runs: 256, μ: 76163, ~: 75939)
L2ToL1MessagePasserTest:test_initiateWithdrawal_fromContract() (gas: 72486)
L2ToL1MessagePasserTest:test_initiateWithdrawal_fromEOA() (gas: 76433)
L2ToL1MessagePasserTest:test_initiateWithdrawal_fromEOA() (gas: 76434)
LegacyERC20ETH_Test:test_approve() (gas: 10796)
LegacyERC20ETH_Test:test_burn() (gas: 10681)
LegacyERC20ETH_Test:test_crossDomain() (gas: 10577)
......@@ -146,10 +151,10 @@ OptimismMintableERC20_Test:test_l2Bridge() (gas: 9746)
OptimismMintableERC20_Test:test_mint() (gas: 65763)
OptimismMintableERC20_Test:test_mintRevertsFromNotBridge() (gas: 13252)
OptimismMintableERC20_Test:test_remoteToken() (gas: 9740)
OptimismMintableTokenFactory_Test:test_bridge() (gas: 7663)
OptimismMintableTokenFactory_Test:test_createStandardL2Token() (gas: 1109735)
OptimismMintableTokenFactory_Test:test_createStandardL2TokenSameTwice() (gas: 2205567)
OptimismMintableTokenFactory_Test:test_createStandardL2TokenShouldRevertIfRemoteIsZero() (gas: 9398)
OptimismMintableTokenFactory_Test:test_bridge() (gas: 7697)
OptimismMintableTokenFactory_Test:test_createStandardL2Token() (gas: 1109835)
OptimismMintableTokenFactory_Test:test_createStandardL2TokenSameTwice() (gas: 2205767)
OptimismMintableTokenFactory_Test:test_createStandardL2TokenShouldRevertIfRemoteIsZero() (gas: 9420)
OptimismPortalUpgradeable_Test:test_cannotInitImpl() (gas: 10813)
OptimismPortalUpgradeable_Test:test_cannotInitProxy() (gas: 15789)
OptimismPortalUpgradeable_Test:test_initValuesOnProxy() (gas: 15967)
......@@ -300,4 +305,4 @@ 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: 143526)
SequencerFeeVault_Test:test_withdraw() (gas: 143547)
......@@ -138,3 +138,19 @@ Unless explicitly discussed otherwise, you MUST include the following basic upgr
2. Include a `uint8 public constant VERSION = X` at the TOP of your contract.
3. Include a function `initialize` with the modifier `reinitializer(VERSION)`.
4. In the `constructor`, set any `immutable` variables and call the `initialize` function for setting mutables.
### Versioning
All (non-library and non-abstract) contracts MUST extend the `Semver` base contract which exposes a `version()` function that returns a semver-compliant version string.
During the Bedrock development process the `Semver` value for all contracts SHOULD return `0.0.1` (this is not particularly important, but it's an easy standard to follow).
When the initial Bedrock upgrade is released, the `Semver` value MUST be updated to `1.0.0`.
After the initial Bedrock upgrade, contracts MUST use the following versioning scheme:
- `patch` releases are to be used only for changes that do NOT modify contract bytecode (such as updating comments).
- `minor` releases are to be used for changes that modify bytecode OR changes that expand the contract ABI provided that these changes do NOT break the existing interface.
- `major` releases are to be used for changes that break the existing contract interface OR changes that modify the security model of a contract.
#### Exceptions
We have made an exception to the `Semver` rule for the `WETH` contract to avoid making changes to a well-known, simple, and recognizable contract.
......@@ -128,8 +128,8 @@ contract L2OutputOracle is OwnableUpgradeable, Semver {
address _owner
) Semver(0, 0, 1) {
require(
_l2BlockTime < block.timestamp,
"L2OutputOracle: initial L2 block time must be less than current time"
_startingTimestamp <= block.timestamp,
"L2OutputOracle: starting L2 timestamp must be less than current time"
);
SUBMISSION_INTERVAL = _submissionInterval;
......
......@@ -59,26 +59,6 @@ contract L2StandardBridge is StandardBridge, Semver {
bytes extraData
);
/**
* @custom:legacy
* @notice Emitted whenever a deposit fails.
*
* @param l1Token Address of the token on L1.
* @param l2Token Address of the corresponding token on L2.
* @param from Address of the depositor.
* @param to Address of the recipient on L2.
* @param amount Amount of the ERC20 deposited.
* @param extraData Extra data attached to the deposit.
*/
event DepositFailed(
address indexed l1Token,
address indexed l2Token,
address indexed from,
address to,
uint256 amount,
bytes extraData
);
/**
* @custom:semver 0.0.2
*
......@@ -152,22 +132,11 @@ contract L2StandardBridge is StandardBridge, Semver {
) external payable virtual {
if (_l1Token == address(0) && _l2Token == Predeploys.LEGACY_ERC20_ETH) {
finalizeBridgeETH(_from, _to, _amount, _extraData);
emit DepositFinalized(_l1Token, _l2Token, _from, _to, _amount, _extraData);
} else {
bool finalized = finalizeBridgeERC20(
_l2Token,
_l1Token,
_from,
_to,
_amount,
_extraData
);
if (finalized) {
emit DepositFinalized(_l1Token, _l2Token, _from, _to, _amount, _extraData);
} else {
emit DepositFailed(_l1Token, _l2Token, _from, _to, _amount, _extraData);
}
finalizeBridgeERC20(_l2Token, _l1Token, _from, _to, _amount, _extraData);
}
emit DepositFinalized(_l1Token, _l2Token, _from, _to, _amount, _extraData);
}
/**
......@@ -191,15 +160,11 @@ contract L2StandardBridge is StandardBridge, Semver {
) internal {
address l1Token = OptimismMintableERC20(_l2Token).l1Token();
if (_l2Token == Predeploys.LEGACY_ERC20_ETH) {
require(
msg.value == _amount,
"L2StandardBridge: ETH withdrawals must include sufficient ETH value"
);
_initiateBridgeETH(_from, _to, _amount, _minGasLimit, _extraData);
} else {
_initiateBridgeERC20(_l2Token, l1Token, _from, _to, _amount, _minGasLimit, _extraData);
}
emit WithdrawalInitiated(l1Token, _l2Token, _from, _to, _amount, _extraData);
}
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol";
import { AddressAliasHelper } from "../vendor/AddressAliasHelper.sol";
contract AddressAliasHelper_Test is Test {
function test_fuzz_roundtrip(address _address) external {
address aliased = AddressAliasHelper.applyL1ToL2Alias(_address);
address unaliased = AddressAliasHelper.undoL1ToL2Alias(aliased);
assertEq(_address, unaliased);
}
}
......@@ -90,14 +90,14 @@ contract L2OutputOracle_Initializer is CommonTest {
L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER));
// Constructor arguments
address proposer = 0x000000000000000000000000000000000000AbBa;
address owner = 0x000000000000000000000000000000000000ACDC;
uint256 submissionInterval = 1800;
uint256 l2BlockTime = 2;
bytes32 genesisL2Output = keccak256(abi.encode(0));
uint256 historicalTotalBlocks = 199;
uint256 startingBlockNumber = 200;
uint256 startingTimestamp = 1000;
address internal proposer = 0x000000000000000000000000000000000000AbBa;
address internal owner = 0x000000000000000000000000000000000000ACDC;
uint256 internal submissionInterval = 1800;
uint256 internal l2BlockTime = 2;
bytes32 internal genesisL2Output = keccak256(abi.encode(0));
uint256 internal historicalTotalBlocks = 199;
uint256 internal startingBlockNumber = 200;
uint256 internal startingTimestamp = 1000;
// Test data
uint256 initL1Time;
......
......@@ -392,47 +392,57 @@ contract L1StandardBridge_Test is Bridge_Initializer {
);
}
function test_finalizeBridgeERC20FailSendBack() external {
deal(address(BadL1Token), address(L1Bridge), 100, true);
uint256 slot = stdstore
.target(address(L1Bridge))
.sig("deposits(address,address)")
.with_key(address(BadL1Token))
.with_key(address(L2Token))
.find();
// Give the L1 bridge some ERC20 tokens
vm.store(address(L1Bridge), bytes32(slot), bytes32(uint256(100)));
assertEq(L1Bridge.deposits(address(BadL1Token), address(L2Token)), 100);
vm.expectEmit(true, true, true, true);
emit ERC20BridgeInitiated(
address(BadL1Token),
address(L2Token),
bob,
function test_finalizeBridgeETH_incorrectValueReverts() external {
address messenger = address(L1Bridge.messenger());
vm.mockCall(
messenger,
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L1Bridge.otherBridge()))
);
vm.deal(messenger, 100);
vm.prank(messenger);
vm.expectRevert("StandardBridge: amount sent does not match amount required");
L1Bridge.finalizeBridgeETH{value: 50}(
alice,
alice,
100,
hex""
);
}
function test_finalizeBridgeETH_sendToSelfReverts() external {
address messenger = address(L1Bridge.messenger());
vm.mockCall(
address(L1Bridge.messenger()),
messenger,
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L1Bridge.otherBridge()))
);
vm.prank(address(L1Bridge.messenger()));
L1Bridge.finalizeBridgeERC20(
address(BadL1Token),
address(L2Token),
vm.deal(messenger, 100);
vm.prank(messenger);
vm.expectRevert("StandardBridge: cannot send to self");
L1Bridge.finalizeBridgeETH{value: 100}(
alice,
bob,
address(L1Bridge),
100,
hex""
);
}
assertEq(BadL1Token.balanceOf(address(L1Bridge)), 100);
assertEq(BadL1Token.balanceOf(address(alice)), 0);
function test_finalizeBridgeETH_sendToMessengerReverts() external {
address messenger = address(L1Bridge.messenger());
vm.mockCall(
messenger,
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L1Bridge.otherBridge()))
);
vm.deal(messenger, 100);
vm.prank(messenger);
vm.expectRevert("StandardBridge: cannot send to messenger");
L1Bridge.finalizeBridgeETH{value: 100}(
alice,
messenger,
100,
hex""
);
}
}
......@@ -28,6 +28,24 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
assertEq(proposal.timestamp, initL1Time);
}
function testCannot_constructWithBadTimestamp() external {
vm.expectRevert(
"L2OutputOracle: starting L2 timestamp must be less than current time"
);
new L2OutputOracle(
submissionInterval,
genesisL2Output,
historicalTotalBlocks,
startingBlockNumber,
// startingTimestamp is in the future
block.timestamp + 1,
l2BlockTime,
proposer,
owner
);
}
/****************
* Getter Tests *
****************/
......
......@@ -50,7 +50,7 @@ contract L2StandardBridge_Test is Bridge_Initializer {
function test_cannotWithdrawEthWithoutSendingIt() external {
assertEq(address(messagePasser).balance, 0);
vm.expectRevert("L2StandardBridge: ETH withdrawals must include sufficient ETH value");
vm.expectRevert("StandardBridge: bridging ETH must include sufficient ETH value");
vm.prank(alice, alice);
L2Bridge.withdraw(
address(Predeploys.LEGACY_ERC20_ETH),
......@@ -157,57 +157,16 @@ contract L2StandardBridge_Test is Bridge_Initializer {
);
}
// finalizeDeposit
// - only callable by l1TokenBridge
// - invalid deposit emits DepositFailed
// - invalid deposit calls Withdrawer.initiateWithdrawal
function test_finalizeDeposit_failsToCompleteOutboundTransfer() external {
// TODO: events and calls
function test_finalizeBridgeETH_incorrectValueReverts() external {
vm.mockCall(
address(L2Bridge.messenger()),
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L2Bridge.otherBridge()))
);
address invalidL2Token = address(0x1234);
vm.deal(address(L2Messenger), 100);
vm.prank(address(L2Messenger));
// For simplicity, the next two expectEmit events skip
// verification of the non-indexed event data
vm.expectEmit(true, true, true, false, address(messagePasser));
emit WithdrawalInitiated(0, address(L2Messenger), address(L1Messenger), 0, 0, hex"");
vm.expectEmit(true, true, true, false, address(L2Messenger));
emit SentMessage(address(L1Bridge), address(0), hex"", 0, 0);
vm.expectEmit(true, true, true, true);
emit ERC20BridgeInitiated(
invalidL2Token,
address(L1Token),
alice,
alice,
100,
hex""
);
vm.expectEmit(true, true, true, true);
emit ERC20BridgeFailed(
invalidL2Token,
address(L1Token),
alice,
alice,
100,
hex""
);
vm.expectEmit(true, true, true, true);
emit DepositFailed(
address(L1Token),
invalidL2Token,
alice,
alice,
100,
hex""
);
L2Bridge.finalizeDeposit(
address(L1Token),
invalidL2Token,
vm.expectRevert("StandardBridge: amount sent does not match amount required");
L2Bridge.finalizeBridgeETH{value: 50}(
alice,
alice,
100,
......@@ -215,63 +174,37 @@ contract L2StandardBridge_Test is Bridge_Initializer {
);
}
// finalizeBridgeERC20
// - fails when the local token's address equals bridge address
function test_ERC20BridgeFailed_whenLocalTokenIsBridge() external {
function test_finalizeBridgeETH_sendToSelfReverts() external {
vm.mockCall(
address(L2Bridge.messenger()),
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L2Bridge.otherBridge()))
);
// fails when the local token's address equals bridge address
vm.expectEmit(true, true, true, true);
emit ERC20BridgeFailed(address(L2Bridge), address(L1Token), alice, bob, 100, hex"");
vm.deal(address(L2Messenger), 100);
vm.prank(address(L2Messenger));
L2Bridge.finalizeDeposit(address(L1Token), address(L2Bridge), alice, bob, 100, hex"");
}
function test_finalizeBridgeERC20FailSendBack() external {
deal(address(BadL2Token), address(L2Bridge), 100, true);
uint256 slot = stdstore
.target(address(L2Bridge))
.sig("deposits(address,address)")
.with_key(address(BadL2Token))
.with_key(address(L1Token))
.find();
// Give the L2 bridge some ERC20 tokens
vm.store(address(L2Bridge), bytes32(slot), bytes32(uint256(100)));
assertEq(L2Bridge.deposits(address(BadL2Token), address(L1Token)), 100);
vm.expectEmit(true, true, true, true);
emit ERC20BridgeInitiated(
address(BadL2Token),
address(L1Token),
bob,
vm.expectRevert("StandardBridge: cannot send to self");
L2Bridge.finalizeBridgeETH{value: 100}(
alice,
address(L2Bridge),
100,
hex""
);
}
function test_finalizeBridgeETH_sendToMessengerReverts() external {
vm.mockCall(
address(L2Bridge.messenger()),
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L2Bridge.otherBridge()))
);
vm.prank(address(L2Bridge.messenger()));
L2Bridge.finalizeBridgeERC20(
address(BadL2Token),
address(L1Token),
vm.deal(address(L2Messenger), 100);
vm.prank(address(L2Messenger));
vm.expectRevert("StandardBridge: cannot send to messenger");
L2Bridge.finalizeBridgeETH{value: 100}(
alice,
bob,
address(L2Messenger),
100,
hex""
);
assertEq(BadL2Token.balanceOf(address(L2Bridge)), 100);
assertEq(BadL2Token.balanceOf(address(alice)), 0);
}
}
......@@ -26,6 +26,63 @@ contract L2ToL1MessagePasserTest is CommonTest {
messagePasser = new L2ToL1MessagePasser();
}
function test_fuzz_initiateWithdrawal(
address _sender,
address _target,
uint256 _value,
uint256 _gasLimit,
bytes memory _data
) external {
uint256 nonce = messagePasser.nonce();
vm.expectEmit(true, true, true, true);
emit WithdrawalInitiated(
nonce,
_sender,
_target,
_value,
_gasLimit,
_data
);
bytes32 withdrawalHash = Hashing.hashWithdrawal(
Types.WithdrawalTransaction({
nonce: nonce,
sender: _sender,
target: _target,
value: _value,
gasLimit: _gasLimit,
data: _data
})
);
vm.expectEmit(true, true, true, true);
emit WithdrawalInitiatedExtension1(withdrawalHash);
vm.deal(_sender, _value);
vm.prank(_sender);
messagePasser.initiateWithdrawal{ value: _value }(
_target,
_gasLimit,
_data
);
assertEq(
messagePasser.sentMessages(withdrawalHash),
true
);
bytes32 slot = keccak256(bytes.concat(
withdrawalHash,
bytes32(0)
));
assertEq(
vm.load(address(messagePasser), slot),
bytes32(uint256(1))
);
}
// Test: initiateWithdrawal should emit the correct log when called by a contract
function test_initiateWithdrawal_fromContract() external {
vm.expectEmit(true, true, true, true);
......
......@@ -3,6 +3,7 @@ pragma solidity 0.8.15;
/* Contract Imports */
import { OptimismMintableERC20 } from "../universal/OptimismMintableERC20.sol";
import { Semver } from "./Semver.sol";
/**
* @custom:proxied
......@@ -13,7 +14,7 @@ import { OptimismMintableERC20 } from "../universal/OptimismMintableERC20.sol";
* who may be less familiar with deploying smart contracts. Designed to be backwards
* compatible with the older StandardL2ERC20Factory contract.
*/
contract OptimismMintableERC20Factory {
contract OptimismMintableERC20Factory is Semver {
/**
* @notice Address of the StandardBridge on this chain.
*/
......@@ -45,7 +46,7 @@ contract OptimismMintableERC20Factory {
/**
* @param _bridge Address of the StandardBridge on this chain.
*/
constructor(address _bridge) {
constructor(address _bridge) Semver(0, 0, 1) {
bridge = _bridge;
}
......
......@@ -127,25 +127,6 @@ abstract contract StandardBridge {
bytes extraData
);
/**
* @notice Emitted when an ERC20 bridge to this chain fails.
*
* @param localToken Address of the ERC20 on this chain.
* @param remoteToken Address of the ERC20 on the remote chain.
* @param from Address of the sender.
* @param to Address of the receiver.
* @param amount Amount of the ERC20 sent.
* @param extraData Extra data sent with the transaction.
*/
event ERC20BridgeFailed(
address indexed localToken,
address indexed remoteToken,
address indexed from,
address to,
uint256 amount,
bytes extraData
);
/**
* @notice Only allow EOAs to call the functions. Note that this is not safe against contracts
* calling code within their constructors, but also doesn't really matter since we're
......@@ -171,14 +152,6 @@ abstract contract StandardBridge {
_;
}
/**
* @notice Ensures that the caller is this contract.
*/
modifier onlySelf() {
require(msg.sender == address(this), "StandardBridge: function can only be called by self");
_;
}
/**
* @param _messenger Address of CrossDomainMessenger on this network.
* @param _otherBridge Address of the other StandardBridge contract.
......@@ -315,8 +288,10 @@ abstract contract StandardBridge {
) public payable onlyOtherBridge {
require(msg.value == _amount, "StandardBridge: amount sent does not match amount required");
require(_to != address(this), "StandardBridge: cannot send to self");
require(_to != address(messenger), "StandardBridge: cannot send to messenger");
emit ETHBridgeFinalized(_from, _to, _amount, _extraData);
bool success = SafeCall.call(_to, gasleft(), _amount, hex"");
require(success, "StandardBridge: ETH transfer failed");
}
......@@ -341,52 +316,7 @@ abstract contract StandardBridge {
address _to,
uint256 _amount,
bytes calldata _extraData
) public onlyOtherBridge returns (bool) {
try this.completeOutboundTransfer(_localToken, _remoteToken, _to, _amount) {
emit ERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);
return true;
} catch {
// Something went wrong during the bridging process, return to sender.
// Can happen if a bridge UI specifies the wrong L2 token.
// We reverse the to and from addresses to make sure the tokens are returned to the
// sender on the other chain and preserve the accuracy of accounting based on emitted
// events.
_initiateBridgeERC20Unchecked(
_localToken,
_remoteToken,
_to,
_from,
_amount,
0, // _minGasLimit, 0 is fine here
_extraData
);
emit ERC20BridgeFailed(_localToken, _remoteToken, _from, _to, _amount, _extraData);
return false;
}
}
/**
* @notice Completes an outbound token transfer. Public function, but can only be called by
* this contract. It's security critical that there be absolutely no way for anyone to
* trigger this function, except by explicit trigger within this contract. Used as a
* simple way to be able to try/catch any type of revert that could occur during an
* ERC20 mint/transfer.
*
* @param _localToken Address of the ERC20 on this chain.
* @param _remoteToken Address of the corresponding token on the remote chain.
* @param _to Address of the receiver.
* @param _amount Amount of the ERC20 being bridged.
*/
function completeOutboundTransfer(
address _localToken,
address _remoteToken,
address _to,
uint256 _amount
) public onlySelf {
// Make sure external function calls can't be used to trigger calls to
// completeOutboundTransfer. We only make external (write) calls to _localToken.
require(_localToken != address(this), "StandardBridge: local token cannot be self");
) public onlyOtherBridge {
if (_isOptimismMintableERC20(_localToken)) {
require(
_isCorrectTokenPair(_localToken, _remoteToken),
......@@ -398,6 +328,8 @@ abstract contract StandardBridge {
deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] - _amount;
IERC20(_localToken).safeTransfer(_to, _amount);
}
emit ERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);
}
/**
......@@ -418,6 +350,11 @@ abstract contract StandardBridge {
uint32 _minGasLimit,
bytes memory _extraData
) internal {
require(
msg.value == _amount,
"StandardBridge: bridging ETH must include sufficient ETH value"
);
emit ETHBridgeInitiated(_from, _to, _amount, _extraData);
messenger.sendMessage{ value: _amount }(
......@@ -454,10 +391,6 @@ abstract contract StandardBridge {
uint32 _minGasLimit,
bytes calldata _extraData
) internal {
// Make sure external function calls can't be used to trigger calls to
// completeOutboundTransfer. We only make external (write) calls to _localToken.
require(_localToken != address(this), "StandardBridge: local token cannot be self");
if (_isOptimismMintableERC20(_localToken)) {
require(
_isCorrectTokenPair(_localToken, _remoteToken),
......@@ -470,39 +403,8 @@ abstract contract StandardBridge {
deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] + _amount;
}
_initiateBridgeERC20Unchecked(
_localToken,
_remoteToken,
_from,
_to,
_amount,
_minGasLimit,
_extraData
);
}
emit ERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);
/**
* @notice Sends ERC20 tokens to a receiver's address on the other chain WITHOUT doing any
* validation. Be EXTREMELY careful when using this function.
*
* @param _localToken Address of the ERC20 on this chain.
* @param _remoteToken Address of the corresponding token on the remote chain.
* @param _to Address of the receiver.
* @param _amount Amount of local tokens to deposit.
* @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.
* @param _extraData Extra data to be sent with the transaction. Note that the recipient will
* not be triggered with this data, but it will be emitted and can be used
* to identify the transaction.
*/
function _initiateBridgeERC20Unchecked(
address _localToken,
address _remoteToken,
address _from,
address _to,
uint256 _amount,
uint32 _minGasLimit,
bytes calldata _extraData
) internal {
messenger.sendMessage(
address(otherBridge),
abi.encodeWithSelector(
......@@ -519,8 +421,6 @@ abstract contract StandardBridge {
),
_minGasLimit
);
emit ERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);
}
/**
......
......@@ -26,6 +26,7 @@
"coverage:lcov": "yarn build:differential && forge coverage --report lcov",
"gas-snapshot": "yarn build:differential && forge snapshot",
"storage-snapshot": "./scripts/storage-snapshot.sh",
"validate-spacers": "hardhat validate-spacers",
"slither": "./scripts/slither.sh",
"clean": "rm -rf ./dist ./artifacts ./forge-artifacts ./cache ./tsconfig.tsbuildinfo ./src/contract-artifacts.ts",
"lint:ts:check": "eslint . --max-warnings=0",
......
......@@ -5,3 +5,4 @@ import './check-op-node'
import './check-l2-config'
import './watch'
import './forge-verify'
import './validate-spacers'
import { task } from 'hardhat/config'
task(
'validate-spacers',
'validates that spacer variables are in the correct positions'
).setAction(async (args, hre) => {
const names = await hre.artifacts.getAllFullyQualifiedNames()
for (const name of names) {
// Script is remarkably slow because of getBuildInfo, so better to skip test files since they
// don't matter for this check.
if (name.includes('.t.sol')) {
continue
}
const buildInfo = await hre.artifacts.getBuildInfo(name)
for (const source of Object.values(buildInfo.output.contracts)) {
for (const [contractName, contract] of Object.entries(source)) {
const storageLayout = (contract as any).storageLayout
for (const variable of storageLayout?.storage || []) {
if (variable.label.startsWith('spacer_')) {
const [, slot, offset, length] = variable.label.split('_')
// Check that the slot is correct.
if (slot !== variable.slot) {
throw new Error(
`${contractName} ${variable.label} is in slot ${variable.slot} but should be in ${slot}`
)
}
// Check that the offset is correct.
if (parseInt(offset, 10) !== variable.offset) {
throw new Error(
`${contractName} ${variable.label} is at offset ${variable.offset} but should be at ${offset}`
)
}
// Figure out the length of the variable.
let variableLength: number
if (variable.type.startsWith('t_mapping')) {
variableLength = 32
} else if (variable.type.startsWith('t_uint')) {
variableLength = variable.type.match(/uint([0-9]+)/)?.[1] / 8
} else if (variable.type.startsWith('t_bytes_')) {
variableLength = 32
} else if (variable.type.startsWith('t_bytes')) {
variableLength = variable.type.match(/uint([0-9]+)/)?.[1]
} else if (variable.type.startsWith('t_address')) {
variableLength = 20
} else {
throw new Error('unsupported type, add it to the script')
}
// Check that the length is correct.
if (parseInt(length, 10) !== variableLength) {
throw new Error(
`${contractName} ${variable.label} is ${variableLength} bytes long but should be ${length}`
)
}
}
}
}
}
}
})
......@@ -15,7 +15,7 @@ contract MintManager is Ownable {
/**
* @notice The GovernanceToken that the MintManager can mint tokens
*/
GovernanceToken public governanceToken;
GovernanceToken public immutable governanceToken;
/**
* @notice The amount of tokens that can be minted per year. The value is a fixed
......
......@@ -10,7 +10,7 @@ import { Semver } from "@eth-optimism/contracts-bedrock/contracts/universal/Semv
* @title L1ERC721Bridge
* @notice The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to
* make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract
* acts as an escrow for ERC721 tokens deposted into L2.
* acts as an escrow for ERC721 tokens deposited into L2.
*/
contract L1ERC721Bridge is ERC721Bridge, Semver {
/**
......@@ -55,55 +55,6 @@ contract L1ERC721Bridge is ERC721Bridge, Semver {
uint256 _tokenId,
bytes calldata _extraData
) external onlyOtherBridge {
try this.completeOutboundTransfer(_localToken, _remoteToken, _to, _tokenId) {
// slither-disable-next-line reentrancy-events
emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);
} catch {
// If the token ID for this L1/L2 NFT pair is not escrowed in the L1 Bridge or if
// another error occurred during finalization, we initiate a cross-domain message to
// send the NFT back to its original owner on L2. This can happen if an L2 native NFT is
// bridged to L1, or if a user mistakenly entered an incorrect L1 ERC721 address.
// In either case, we stop the process here and construct a withdrawal in which we
// flip the to and from addresses. This ensures that event-based accounting
// will indicate net-zero transfer to the recipient. The ERC721BridgeFailed event
// emitted below can also be used to identify this occurence.
bytes memory message = abi.encodeWithSelector(
L2ERC721Bridge.finalizeBridgeERC721.selector,
_remoteToken,
_localToken,
_to,
_from, // Refund the NFT to the original owner on the remote chain.
_tokenId,
_extraData
);
// Send the message to the L2 bridge.
// slither-disable-next-line reentrancy-events
messenger.sendMessage(otherBridge, message, 600_000);
// slither-disable-next-line reentrancy-events
emit ERC721BridgeFailed(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);
}
}
/**
* @notice Completes an outbound token transfer. Public function, but can only be called by
* this contract. It's security critical that there be absolutely no way for anyone to
* trigger this function, except by explicit trigger within this contract. Used as a
* simple way to be able to try/catch any type of revert that could occur during an
* ERC721 mint/transfer.
*
* @param _localToken Address of the ERC721 on this chain.
* @param _remoteToken Address of the corresponding token on the remote chain.
* @param _to Address of the receiver.
* @param _tokenId ID of the token being deposited.
*/
function completeOutboundTransfer(
address _localToken,
address _remoteToken,
address _to,
uint256 _tokenId
) external onlySelf {
require(_localToken != address(this), "L1ERC721Bridge: local token cannot be self");
// Checks that the L1/L2 NFT pair has a token ID that is escrowed in the L1 Bridge.
......@@ -119,6 +70,9 @@ contract L1ERC721Bridge is ERC721Bridge, Semver {
// When a withdrawal is finalized on L1, the L1 Bridge transfers the NFT to the
// withdrawer.
IERC721(_localToken).safeTransferFrom(address(this), _to, _tokenId);
// slither-disable-next-line reentrancy-events
emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);
}
/**
......
......@@ -51,65 +51,15 @@ contract L2ERC721Bridge is ERC721Bridge, Semver {
uint256 _tokenId,
bytes calldata _extraData
) external onlyOtherBridge {
try this.completeOutboundTransfer(_localToken, _remoteToken, _to, _tokenId) {
// slither-disable-next-line reentrancy-events
emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);
} catch {
// Either the L2 token which is being deposited-into disagrees about the correct address
// of its L1 token, or does not support the correct interface.
// This should only happen if there is a malicious L2 token, or if a user somehow
// specified the wrong L2 token address to deposit into.
// There is no way to prevent malicious token contracts altogether, but this does limit
// user error and mitigate some forms of malicious contract behavior.
/// In either case, we stop the process here and construct a withdrawal in which we
// flip the to and from addresses. This ensures that event-based accounting
// will indicate net-zero transfer to the recipient. The ERC721BridgeFailed event
// emitted below can also be used to identify this occurence.
bytes memory message = abi.encodeWithSelector(
L1ERC721Bridge.finalizeBridgeERC721.selector,
_remoteToken,
_localToken,
_to,
_from, // Refund the NFT to the original owner on the remote chain.
_tokenId,
_extraData
);
// Send the message to the L1 bridge
// slither-disable-next-line reentrancy-events
messenger.sendMessage(otherBridge, message, 0);
// slither-disable-next-line reentrancy-events
emit ERC721BridgeFailed(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);
}
}
/**
* @notice Completes an outbound token transfer. Public function, but can only be called by
* this contract. It's security critical that there be absolutely no way for anyone to
* trigger this function, except by explicit trigger within this contract. Used as a
* simple way to be able to try/catch any type of revert that could occur during an
* ERC721 mint/transfer.
*
* @param _localToken Address of the ERC721 on this chain.
* @param _remoteToken Address of the corresponding token on the remote chain.
* @param _to Address of the receiver.
* @param _tokenId ID of the token being deposited.
*/
function completeOutboundTransfer(
address _localToken,
address _remoteToken,
address _to,
uint256 _tokenId
) external onlySelf {
require(_localToken != address(this), "L2ERC721Bridge: local token cannot be self");
// Note that supportsInterface makes a callback to the _localToken address which is user
// provided.
require(
// Note that supportsInterface makes a callback to the _localToken address
// which is user provided.
ERC165Checker.supportsInterface(_localToken, type(IOptimismMintableERC721).interfaceId),
"L2ERC721Bridge: local token interface is not compliant"
);
require(
_remoteToken == IOptimismMintableERC721(_localToken).remoteToken(),
"L2ERC721Bridge: wrong remote token for Optimism Mintable ERC721 local token"
......@@ -118,6 +68,9 @@ contract L2ERC721Bridge is ERC721Bridge, Semver {
// When a deposit is finalized, we give the NFT with the same tokenId to the account
// on L2. Note that safeMint makes a callback to the _to address which is user provided.
IOptimismMintableERC721(_localToken).safeMint(_to, _tokenId);
// slither-disable-next-line reentrancy-events
emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);
}
/**
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
pragma solidity 0.8.16;
import { IDripCheck } from "../IDripCheck.sol";
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
pragma solidity 0.8.16;
import { IDripCheck } from "../IDripCheck.sol";
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
pragma solidity 0.8.16;
import { IDripCheck } from "../IDripCheck.sol";
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
pragma solidity 0.8.16;
import { IDripCheck } from "../IDripCheck.sol";
......
......@@ -30,24 +30,6 @@ abstract contract ERC721Bridge {
bytes extraData
);
/**
* @notice Emitted when an NFT is refunded to the owner after an ERC721 bridge from the other
* chain fails.
*
* @param localToken Address of the token on this domain.
* @param remoteToken Address of the token on the remote domain.
* @param to Address to receive the refunded token.
* @param tokenId ID of the specific token being refunded.
* @param extraData Extra data for use on the client-side.
*/
event ERC721Refunded(
address indexed localToken,
address indexed remoteToken,
address indexed to,
uint256 tokenId,
bytes extraData
);
/**
* @notice Emitted when an ERC721 bridge from the other network is finalized.
*
......@@ -67,25 +49,6 @@ abstract contract ERC721Bridge {
bytes extraData
);
/**
* @notice Emitted when an ERC721 bridge from the other network fails.
*
* @param localToken Address of the token on this domain.
* @param remoteToken Address of the token on the remote domain.
* @param from Address that initiated bridging action.
* @param to Address to receive the token.
* @param tokenId ID of the specific token deposited.
* @param extraData Extra data for use on the client-side.
*/
event ERC721BridgeFailed(
address indexed localToken,
address indexed remoteToken,
address indexed from,
address to,
uint256 tokenId,
bytes extraData
);
/**
* @notice Messenger contract on this domain.
*/
......@@ -112,19 +75,14 @@ abstract contract ERC721Bridge {
_;
}
/**
* @notice Ensures that the caller is this contract.
*/
modifier onlySelf() {
require(msg.sender == address(this), "ERC721Bridge: function can only be called by self");
_;
}
/**
* @param _messenger Address of the CrossDomainMessenger on this network.
* @param _otherBridge Address of the ERC721 bridge on the other network.
*/
constructor(address _messenger, address _otherBridge) {
require(_messenger != address(0), "ERC721Bridge: messenger cannot be address(0)");
require(_otherBridge != address(0), "ERC721Bridge: other bridge cannot be address(0)");
messenger = CrossDomainMessenger(_messenger);
otherBridge = _otherBridge;
}
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import {
OwnableUpgradeable
} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { OptimismMintableERC721 } from "./OptimismMintableERC721.sol";
import { Semver } from "@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol";
......@@ -11,7 +8,7 @@ import { Semver } from "@eth-optimism/contracts-bedrock/contracts/universal/Semv
* @title OptimismMintableERC721Factory
* @notice Factory contract for creating OptimismMintableERC721 contracts.
*/
contract OptimismMintableERC721Factory is Semver, OwnableUpgradeable {
contract OptimismMintableERC721Factory is Semver {
/**
* @notice Emitted whenever a new OptimismMintableERC721 contract is created.
*
......@@ -23,12 +20,12 @@ contract OptimismMintableERC721Factory is Semver, OwnableUpgradeable {
/**
* @notice Address of the ERC721 bridge on this network.
*/
address public bridge;
address public immutable bridge;
/**
* @notice Chain ID for the remote network.
*/
uint256 public remoteChainId;
uint256 public immutable remoteChainId;
/**
* @notice Tracks addresses created by this factory.
......@@ -41,15 +38,6 @@ contract OptimismMintableERC721Factory is Semver, OwnableUpgradeable {
* @param _bridge Address of the ERC721 bridge on this network.
*/
constructor(address _bridge, uint256 _remoteChainId) Semver(1, 0, 0) {
initialize(_bridge, _remoteChainId);
}
/**
* @notice Initializes the factory.
*
* @param _bridge Address of the ERC721 bridge on this network.
*/
function initialize(address _bridge, uint256 _remoteChainId) public initializer {
require(
_bridge != address(0),
"OptimismMintableERC721Factory: bridge cannot be address(0)"
......@@ -61,9 +49,6 @@ contract OptimismMintableERC721Factory is Semver, OwnableUpgradeable {
bridge = _bridge;
remoteChainId = _remoteChainId;
// Initialize upgradable OZ contracts
__Ownable_init();
}
/**
......@@ -83,11 +68,6 @@ contract OptimismMintableERC721Factory is Semver, OwnableUpgradeable {
"OptimismMintableERC721Factory: L1 token address cannot be address(0)"
);
require(
bridge != address(0),
"OptimismMintableERC721Factory: bridge address must be initialized"
);
OptimismMintableERC721 localToken = new OptimismMintableERC721(
bridge,
remoteChainId,
......
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { ethers } from 'hardhat'
import { HardhatRuntimeEnvironment } from 'hardhat/types'
import '@eth-optimism/hardhat-deploy-config'
import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy'
import fetch from 'node-fetch'
import {
isTargetL1Network,
predeploy,
getProxyAdmin,
validateERC721Bridge,
} from '../../src/nft-bridge-deploy-helpers'
// Handle the `ops` deployment
const getL1CrossDomainMessengerProxyDeployment = async (
hre: HardhatRuntimeEnvironment
) => {
const network = hre.network.name
if (network === 'ops-l1') {
const res = await fetch(
'http://localhost:8080/deployments/local/Proxy__OVM_L1CrossDomainMessenger.json'
)
return res.json()
} else {
return hre.deployments.get('Proxy__OVM_L1CrossDomainMessenger')
}
}
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const { deploy } = hre.deployments
const { getAddress } = hre.ethers.utils
if (!isTargetL1Network(hre.network.name)) {
console.log(`Deploying to unsupported network ${hre.network.name}`)
return
}
console.log(`Deploying L1ERC721Bridge to ${hre.network.name}`)
console.log(`Using deployer ${deployer}`)
const Deployment__L1ERC721BridgeProxy = await hre.deployments.get(
'L1ERC721BridgeProxy'
)
const L1ERC721BridgeProxy = await hre.ethers.getContractAt(
'Proxy',
Deployment__L1ERC721BridgeProxy.address
)
const admin = await L1ERC721BridgeProxy.callStatic.admin()
if (getAddress(admin) !== getAddress(deployer)) {
throw new Error('deployer is not proxy admin')
}
// Get the address of the currently deployed L1CrossDomainMessenger.
// This should be the address of the proxy
const Deployment__L1CrossDomainMessengerProxy =
await getL1CrossDomainMessengerProxyDeployment(hre)
await hre.deployments.deploy('L1ERC721Bridge', {
const L1CrossDomainMessengerProxyAddress =
Deployment__L1CrossDomainMessengerProxy.address
// Deploy the L1ERC721Bridge. The arguments are
// - messenger
// - otherBridge
// Since this is the L1ERC721Bridge, the otherBridge is the
// predeploy address
await deploy('L1ERC721Bridge', {
from: deployer,
args: [ethers.constants.AddressZero, ethers.constants.AddressZero],
args: [L1CrossDomainMessengerProxyAddress, predeploy],
log: true,
waitConfirmations: 1,
})
const Deployment__L1ERC721Bridge = await hre.deployments.get('L1ERC721Bridge')
console.log(
`L1ERC721Bridge deployed to ${Deployment__L1ERC721Bridge.address}`
)
await validateERC721Bridge(hre, Deployment__L1ERC721Bridge.address, {
messenger: L1CrossDomainMessengerProxyAddress,
otherBridge: predeploy,
})
{
// Upgrade the Proxy to the newly deployed implementation
const tx = await L1ERC721BridgeProxy.upgradeTo(
Deployment__L1ERC721Bridge.address
)
const receipt = await tx.wait()
console.log(`L1ERC721BridgeProxy upgraded: ${receipt.transactionHash}`)
}
{
// Set the admin correctly
const newAdmin = getProxyAdmin(hre.network.name)
const tx = await L1ERC721BridgeProxy.changeAdmin(newAdmin)
const receipt = await tx.wait()
console.log(`L1ERC721BridgeProxy admin updated: ${receipt.transactionHash}`)
}
await validateERC721Bridge(hre, L1ERC721BridgeProxy.address, {
messenger: L1CrossDomainMessengerProxyAddress,
otherBridge: predeploy,
})
}
......
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
import '@eth-optimism/hardhat-deploy-config'
import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy'
import { isTargetL1Network } from '../../src/nft-bridge-deploy-helpers'
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const { deploy } = hre.deployments
if (!isTargetL1Network(hre.network.name)) {
console.log(`Deploying to unsupported network ${hre.network.name}`)
return
}
console.log(`Deploying L1ERC721BridgeProxy to ${hre.network.name}`)
console.log(`Using deployer ${deployer}`)
const { deploy } = await hre.deployments.deterministic(
'L1ERC721BridgeProxy',
{
await deploy('L1ERC721BridgeProxy', {
contract: 'Proxy',
salt: hre.ethers.utils.solidityKeccak256(
['string'],
['L1ERC721BridgeProxy']
),
from: deployer,
args: [hre.deployConfig.ddd],
args: [deployer],
log: true,
}
)
waitConfirmations: 1,
})
await deploy()
const Deployment__L1ERC721BridgeProxy = await hre.deployments.get(
'L1ERC721BridgeProxy'
)
console.log(
`L1ERC721BridgeProxy deployed to ${Deployment__L1ERC721BridgeProxy.address}`
)
}
deployFn.tags = ['L1ERC721BridgeProxy']
......
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { ethers } from 'hardhat'
import '@eth-optimism/hardhat-deploy-config'
import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy'
import { predeploys } from '@eth-optimism/contracts'
import {
isTargetL2Network,
predeploy,
validateERC721Bridge,
getProxyAdmin,
} from '../../src/nft-bridge-deploy-helpers'
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const { getAddress } = hre.ethers.utils
if (!isTargetL2Network(hre.network.name)) {
console.log(`Deploying to unsupported network ${hre.network.name}`)
return
}
console.log(`Deploying L2ERC721Bridge to ${hre.network.name}`)
console.log(`Using deployer ${deployer}`)
const L2ERC721BridgeProxy = await hre.ethers.getContractAt('Proxy', predeploy)
// Check to make sure that the admin of the proxy is the deployer.
// The deployer of the L2ERC721Bridge should be the same as the
// admin of the L2ERC721BridgeProxy so that it is easy to upgrade
// the implementation. The admin is then changed depending on the
// network after the L2ERC721BridgeProxy is upgraded to the implementation
const admin = await L2ERC721BridgeProxy.callStatic.admin()
if (getAddress(admin) !== getAddress(deployer)) {
throw new Error(`Unexpected admin ${admin}`)
}
const Deployment__L1ERC721Bridge = await hre.deployments.get(
'L1ERC721BridgeProxy'
)
const L1ERC721BridgeAddress = Deployment__L1ERC721Bridge.address
// Deploy the L2ERC721Bridge implementation
await hre.deployments.deploy('L2ERC721Bridge', {
from: deployer,
args: [ethers.constants.AddressZero, ethers.constants.AddressZero],
args: [predeploys.L2CrossDomainMessenger, L1ERC721BridgeAddress],
log: true,
waitConfirmations: 1,
})
const Deployment__L2ERC721Bridge = await hre.deployments.get('L2ERC721Bridge')
console.log(
`L2ERC721Bridge deployed to ${Deployment__L2ERC721Bridge.address}`
)
await validateERC721Bridge(hre, Deployment__L2ERC721Bridge.address, {
messenger: predeploys.L2CrossDomainMessenger,
otherBridge: L1ERC721BridgeAddress,
})
{
// Upgrade the implementation of the proxy to the newly deployed
// L2ERC721Bridge
const tx = await L2ERC721BridgeProxy.upgradeTo(
Deployment__L2ERC721Bridge.address
)
const receipt = await tx.wait()
console.log(
`Upgraded the implementation of the L2ERC721BridgeProxy: ${receipt.transactionhash}`
)
}
await validateERC721Bridge(hre, L2ERC721BridgeProxy.address, {
messenger: predeploys.L2CrossDomainMessenger,
otherBridge: L1ERC721BridgeAddress,
})
{
const newAdmin = getProxyAdmin(hre.network.name)
console.log(`Changing admin to ${newAdmin}`)
const tx = await L2ERC721BridgeProxy.changeAdmin(newAdmin)
const receipt = await tx.wait()
console.log(
`Changed admin of the L2ERC721BridgeProxy: ${receipt.transactionHash}`
)
}
}
deployFn.tags = ['L2ERC721BridgeImplementation']
deployFn.dependencies = ['L2ERC721BridgeProxy']
deployFn.dependencies = ['L2ERC721BridgeProxy', 'L1ERC721BridgeProxy']
export default deployFn
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
import '@eth-optimism/hardhat-deploy-config'
import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy'
const predeploy = '0x4200000000000000000000000000000000000014'
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const { getAddress } = hre.ethers.utils
console.log(`Deploying L2ERC721BridgeProxy to ${hre.network.name}`)
console.log(`Using deployer ${deployer}`)
// Check to make sure that the Proxy has not been deployed yet
const pre = await hre.ethers.provider.getCode(predeploy, 'latest')
if (pre !== '0x') {
console.log(`Code already deployed to ${predeploy}`)
return
}
const { deploy } = await hre.deployments.deterministic(
'L2ERC721BridgeProxy',
{
// A special deployer account must be used
const mainnetDeployer = getAddress(
'0x53A6eecC2dD4795Fcc68940ddc6B4d53Bd88Bd9E'
)
const goerliDeployer = getAddress(
'0x5c679a57e018f5f146838138d3e032ef4913d551'
)
const localDeployer = getAddress('0xdfc82d475833a50de90c642770f34a9db7deb725')
// Deploy the L2ERC721BridgeProxy as a predeploy address
if (hre.network.name === 'optimism') {
if (getAddress(deployer) !== mainnetDeployer) {
throw new Error(`Incorrect deployer: ${deployer}`)
}
} else if (hre.network.name === 'optimism-goerli') {
if (getAddress(deployer) !== goerliDeployer) {
throw new Error(`Incorrect deployer: ${deployer}`)
}
} else if (hre.network.name === 'ops-l2') {
if (getAddress(deployer) !== localDeployer) {
throw new Error(`Incorrect deployer: ${deployer}`)
}
} else {
throw new Error(`Unknown network: ${hre.network.name}`)
}
// Set the deployer as the admin of the Proxy. This is
// temporary, the admin will be updated when deploying
// the implementation
await hre.deployments.deploy('L2ERC721BridgeProxy', {
contract: 'Proxy',
salt: hre.ethers.utils.solidityKeccak256(
['string'],
['L2ERC721BridgeProxy']
),
from: deployer,
args: [hre.deployConfig.ddd],
args: [deployer],
log: true,
}
)
waitConfirmations: 1,
})
await deploy()
// Check that the Proxy was deployed to the correct address
const code = await hre.ethers.provider.getCode(predeploy)
if (code === '0x') {
throw new Error('Code is not set at expected predeploy address')
}
console.log(`L2ERC721BridgeProxy deployed to ${predeploy}`)
}
deployFn.tags = ['L2ERC721BridgeProxy']
......
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { ethers } from 'hardhat'
import '@eth-optimism/hardhat-deploy-config'
import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy'
import { getProxyAdmin, predeploy } from '../../src/nft-bridge-deploy-helpers'
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const { getAddress } = hre.ethers.utils
console.log(`Deploying OptimismMintableERC721Factory to ${hre.network.name}`)
console.log(`Using deployer ${deployer}`)
const Deployment__OptimismMintableERC721FactoryProxy =
await hre.deployments.get('OptimismMintableERC721FactoryProxy')
const OptimismMintableERC721FactoryProxy = await hre.ethers.getContractAt(
'Proxy',
Deployment__OptimismMintableERC721FactoryProxy.address
)
// Check that the admin of the OptimismMintableERC721FactoryProxy is the
// deployer. This makes it easy to upgrade the implementation of the proxy
// and then transfer the admin privilege after deploying the implementation
const admin = await OptimismMintableERC721FactoryProxy.callStatic.admin()
if (getAddress(admin) !== getAddress(deployer)) {
throw new Error('deployer is not proxy admin')
}
let remoteChainId: number
if (hre.network.name === 'optimism') {
remoteChainId = 1
} else if (hre.network.name === 'optimism-goerli') {
remoteChainId = 5
} else if (hre.network.name === 'ops-l2') {
remoteChainId = 31337
} else {
remoteChainId = hre.deployConfig.remoteChainId
}
if (typeof remoteChainId !== 'number') {
throw new Error('remoteChainId not defined')
}
await hre.deployments.deploy('OptimismMintableERC721Factory', {
from: deployer,
args: [ethers.constants.AddressZero, 0],
args: [predeploy, remoteChainId],
log: true,
waitConfirmations: 1,
})
const Deployment__OptimismMintableERC721Factory = await hre.deployments.get(
'OptimismMintableERC721Factory'
)
console.log(
`OptimismMintableERC721Factory deployed to ${Deployment__OptimismMintableERC721Factory.address}`
)
{
// Upgrade the Proxy to the newly deployed implementation
const tx = await OptimismMintableERC721FactoryProxy.upgradeTo(
Deployment__OptimismMintableERC721Factory.address
)
const receipt = await tx.wait()
console.log(
`OptimismMintableERC721FactoryProxy upgraded: ${receipt.transactionHash}`
)
}
{
const newAdmin = getProxyAdmin(hre.network.name)
const tx = await OptimismMintableERC721FactoryProxy.changeAdmin(newAdmin)
const receipt = await tx.wait()
console.log(
`OptimismMintableERC721FactoryProxy admin updated: ${receipt.transactionHash}`
)
}
}
deployFn.tags = ['OptimismMintableERC721FactoryImplementation']
......
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
import '@eth-optimism/hardhat-deploy-config'
import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy'
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const { deploy } = hre.deployments
const { deploy } = await hre.deployments.deterministic(
'OptimismMintableERC721FactoryProxy',
{
console.log(
`Deploying OptimismMintableERC721FactoryProxy to ${hre.network.name}`
)
console.log(`Using deployer ${deployer}`)
// Deploy the OptimismMintableERC721FactoryProxy with
// the deployer as the admin. The admin and implementation
// will be updated with the deployment of the implementation
await deploy('OptimismMintableERC721FactoryProxy', {
contract: 'Proxy',
salt: hre.ethers.utils.solidityKeccak256(
['string'],
['OptimismMintableERC721FactoryProxy']
),
from: deployer,
args: [hre.deployConfig.ddd],
args: [deployer],
log: true,
}
)
waitConfirmations: 1,
})
await deploy()
const Deployment__OptimismMintableERC721FactoryProxy =
await hre.deployments.get('OptimismMintableERC721FactoryProxy')
console.log(
`OptimismMintableERC721FactoryProxy deployed to ${Deployment__OptimismMintableERC721FactoryProxy.address}`
)
}
deployFn.tags = ['OptimismMintableERC721FactoryProxy']
......
......@@ -112,6 +112,21 @@ const config: HardhatUserConfig = {
},
},
},
'ops-l2': {
chainId: 17,
accounts: [
'0x3b8d2345102cce2443acb240db6e87c8edd4bb3f821b17fab8ea2c9da08ea132',
'0xa6aecc98b63bafb0de3b29ae9964b14acb4086057808be29f90150214ebd4a0f',
],
url: 'http://127.0.0.1:8545',
},
'ops-l1': {
chainId: 31337,
accounts: [
'0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',
],
url: 'http://127.0.0.1:9545',
},
},
paths: {
deployConfig: './config/deploy',
......
#!/bin/bash
set -e
L1_NETWORK=ops-l1
L2_NETWORK=ops-l2
# Step 1: deploy the Proxy to the predeploy address on L2
npx hardhat deploy --tags L2ERC721BridgeProxy --network $L2_NETWORK
# Step 2: deploy the Proxy for the L1ERC721Bridge to L1
npx hardhat deploy --tags L1ERC721BridgeProxy --network $L1_NETWORK
# Step 3: deploy the L2ERC721Bridge implementation
npx hardhat deploy --tags L2ERC721BridgeImplementation --network $L2_NETWORK
# Step 4: deploy the L1ERC721Bridge implementation to L1
npx hardhat deploy --tags L1ERC721BridgeImplementation --network $L1_NETWORK
# Step 5: deploy the Proxy for the OptimismMintableERC721Factory to L2
npx hardhat deploy --tags OptimismMintableERC721FactoryProxy --network $L2_NETWORK
# Step 5: deploy the OptimismMintableERC721Factory to L2
npx hardhat deploy --tags OptimismMintableERC721FactoryImplementation --network $L2_NETWORK
import { utils } from 'ethers'
// https://optimistic.etherscan.io/address/0x2501c477d0a35545a387aa4a3eee4292a9a8b3f0
export const l2MainnetMultisig = '0x2501c477D0A35545a387Aa4A3EEe4292A9a8B3F0'
// https://etherscan.io/address/0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A
export const l1MainnetMultisig = '0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A'
// https://goerli.etherscan.io/address/0xf80267194936da1E98dB10bcE06F3147D580a62e
export const goerliAdmin = '0xf80267194936da1E98dB10bcE06F3147D580a62e'
export const predeploy = '0x4200000000000000000000000000000000000014'
export const predeployDeployer = '0xdfc82d475833a50de90c642770f34a9db7deb725'
export const isTargetL2Network = (network: string): boolean => {
switch (network) {
case 'optimism':
case 'optimism-goerli':
case 'ops-l2':
return true
default:
return false
}
}
export const isTargetL1Network = (network: string): boolean => {
switch (network) {
case 'mainnet':
case 'goerli':
case 'ops-l1':
return true
default:
return false
}
}
export const getProxyAdmin = (network: string): string => {
switch (network) {
case 'optimism':
return l2MainnetMultisig
case 'mainnet':
return l1MainnetMultisig
case 'goerli':
case 'optimism-goerli':
return goerliAdmin
case 'ops-l1':
case 'ops-l2':
return predeployDeployer
default:
throw new Error(`unknown network ${network}`)
}
}
export const validateERC721Bridge = async (hre, address: string, expected) => {
const L1ERC721Bridge = await hre.ethers.getContractAt('ERC721Bridge', address)
const messenger = await L1ERC721Bridge.messenger()
const otherBridge = await L1ERC721Bridge.otherBridge()
if (utils.getAddress(messenger) !== utils.getAddress(expected.messenger)) {
throw new Error(`messenger mismatch`)
}
if (
utils.getAddress(otherBridge) !== utils.getAddress(expected.otherBridge)
) {
throw new Error(`otherBridge mismatch`)
}
}
......@@ -85,6 +85,24 @@ describe('L1ERC721Bridge', () => {
describe('constructor', async () => {
it('initializes correctly', async () => {
it('reverts if cross domain messenger is address(0)', async () => {
await expect(
Factory__L1ERC721Bridge.deploy(
constants.AddressZero,
DUMMY_L2_BRIDGE_ADDRESS
)
).to.be.revertedWith('ERC721Bridge: messenger cannot be address(0)')
})
it('reverts if other bridge is address(0)', async () => {
await expect(
Factory__L1ERC721Bridge.deploy(
Fake__L1CrossDomainMessenger.address,
constants.AddressZero
)
).to.be.revertedWith('ERC721Bridge: other bridge cannot be address(0)')
})
expect(await L1ERC721Bridge.messenger()).equals(
Fake__L1CrossDomainMessenger.address
)
......@@ -367,56 +385,6 @@ describe('L1ERC721Bridge', () => {
)
})
it('should refund an L2 NFT that fails to be finalized on l1', async () => {
const RANDOM_L1_ERC721_ADDRESS = ethers.utils.getAddress(
'0x' + 'cdbc'.repeat(10)
)
// alice sends bob an nft that has an incorrect l1 erc721 address
await expect(
L1ERC721Bridge.finalizeBridgeERC721(
RANDOM_L1_ERC721_ADDRESS, // incorrect address for the l1 erc721
DUMMY_L2_ERC721_ADDRESS,
aliceAddress,
bobsAddress,
tokenId,
NON_NULL_BYTES32,
{
from: Fake__L1CrossDomainMessenger.address,
}
)
)
.to.emit(L1ERC721Bridge, 'ERC721BridgeFailed')
.withArgs(
RANDOM_L1_ERC721_ADDRESS,
DUMMY_L2_ERC721_ADDRESS,
aliceAddress,
bobsAddress,
tokenId,
NON_NULL_BYTES32
)
// Get the second call from `Fake__L1CrossDomainMessenger` because the first call is `finalizeBridgeERC721`.
const depositCallToMessenger =
Fake__L1CrossDomainMessenger.sendMessage.getCall(1)
// Check the correct cross-chain call was sent:
// Message should be sent to the L2 bridge
expect(depositCallToMessenger.args[0]).to.equal(DUMMY_L2_BRIDGE_ADDRESS)
// Message data should be a call telling the L2DepositedERC721 to finalize the deposit
expect(depositCallToMessenger.args[1]).to.equal(
IL2ERC721Bridge.encodeFunctionData('finalizeBridgeERC721', [
DUMMY_L2_ERC721_ADDRESS,
RANDOM_L1_ERC721_ADDRESS,
bobsAddress,
aliceAddress,
tokenId,
NON_NULL_BYTES32,
])
)
// Gas limit is 0
expect(depositCallToMessenger.args[2]).to.equal(FINALIZATION_GAS)
})
it('should credit funds to the withdrawer to finalize withdrawal', async () => {
// finalizing the withdrawal emits an ERC721BridgeFinalized event with the correct arguments.
await expect(
......@@ -454,17 +422,4 @@ describe('L1ERC721Bridge', () => {
})
})
})
describe('completeOutboundTransfer', async () => {
it('reverts if caller is not L1 bridge', async () => {
await expect(
L1ERC721Bridge.completeOutboundTransfer(
L1ERC721.address,
DUMMY_L2_ERC721_ADDRESS,
bobsAddress,
tokenId
)
).to.be.revertedWith('ERC721Bridge: function can only be called by self')
})
})
})
......@@ -36,6 +36,7 @@ describe('L2ERC721Bridge', () => {
Factory__L1ERC721Bridge = await ethers.getContractFactory('L1ERC721Bridge')
})
let Factory__L2ERC721Bridge: ContractFactory
let L2ERC721Bridge: Contract
let L2ERC721: Contract
let Fake__L2CrossDomainMessenger: FakeContract
......@@ -48,9 +49,11 @@ describe('L2ERC721Bridge', () => {
)
// Deploy the contract under test
L2ERC721Bridge = await (
await ethers.getContractFactory('L2ERC721Bridge')
).deploy(Fake__L2CrossDomainMessenger.address, DUMMY_L1BRIDGE_ADDRESS)
Factory__L2ERC721Bridge = await ethers.getContractFactory('L2ERC721Bridge')
L2ERC721Bridge = await Factory__L2ERC721Bridge.deploy(
Fake__L2CrossDomainMessenger.address,
DUMMY_L1BRIDGE_ADDRESS
)
// Deploy an L2 ERC721
L2ERC721 = await (
......@@ -66,6 +69,24 @@ describe('L2ERC721Bridge', () => {
})
describe('constructor', async () => {
it('reverts if cross domain messenger is address(0)', async () => {
await expect(
Factory__L2ERC721Bridge.deploy(
constants.AddressZero,
DUMMY_L1BRIDGE_ADDRESS
)
).to.be.revertedWith('ERC721Bridge: messenger cannot be address(0)')
})
it('reverts if other bridge is address(0)', async () => {
await expect(
Factory__L2ERC721Bridge.deploy(
Fake__L2CrossDomainMessenger.address,
constants.AddressZero
)
).to.be.revertedWith('ERC721Bridge: other bridge cannot be address(0)')
})
it('initializes correctly', async () => {
expect(await L2ERC721Bridge.messenger()).equals(
Fake__L2CrossDomainMessenger.address
......@@ -109,62 +130,6 @@ describe('L2ERC721Bridge', () => {
).to.be.revertedWith(ERR_INVALID_X_DOMAIN_MESSAGE)
})
it('should initialize a withdrawal if the L2 token is not compliant', async () => {
// Deploy a non compliant ERC721
const NonCompliantERC721 = await (
await ethers.getContractFactory(
'@openzeppelin/contracts/token/ERC721/ERC721.sol:ERC721'
)
).deploy('L2Token', 'L2T')
Fake__L2CrossDomainMessenger.xDomainMessageSender.returns(
DUMMY_L1BRIDGE_ADDRESS
)
// A failed attempt to finalize the deposit causes an ERC721BridgeFailed event to be emitted.
await expect(
L2ERC721Bridge.connect(l2MessengerImpersonator).finalizeBridgeERC721(
NonCompliantERC721.address,
DUMMY_L1ERC721_ADDRESS,
aliceAddress,
bobsAddress,
TOKEN_ID,
NON_NULL_BYTES32,
{
from: Fake__L2CrossDomainMessenger.address,
}
)
)
.to.emit(L2ERC721Bridge, 'ERC721BridgeFailed')
.withArgs(
NonCompliantERC721.address,
DUMMY_L1ERC721_ADDRESS,
aliceAddress,
bobsAddress,
TOKEN_ID,
NON_NULL_BYTES32
)
const withdrawalCallToMessenger =
Fake__L2CrossDomainMessenger.sendMessage.getCall(0)
expect(withdrawalCallToMessenger.args[0]).to.equal(DUMMY_L1BRIDGE_ADDRESS)
expect(withdrawalCallToMessenger.args[1]).to.equal(
Factory__L1ERC721Bridge.interface.encodeFunctionData(
'finalizeBridgeERC721',
[
DUMMY_L1ERC721_ADDRESS,
NonCompliantERC721.address,
bobsAddress,
aliceAddress,
TOKEN_ID,
NON_NULL_BYTES32,
]
)
)
expect(withdrawalCallToMessenger.args[2]).to.equal(0)
})
it('should credit funds to the depositor', async () => {
Fake__L2CrossDomainMessenger.xDomainMessageSender.returns(
DUMMY_L1BRIDGE_ADDRESS
......@@ -213,19 +178,6 @@ describe('L2ERC721Bridge', () => {
})
})
describe('completeOutboundTransfer', async () => {
it('reverts if caller is not L2 bridge', async () => {
await expect(
L2ERC721Bridge.completeOutboundTransfer(
L2ERC721.address,
DUMMY_L1ERC721_ADDRESS,
bobsAddress,
TOKEN_ID
)
).to.be.revertedWith('ERC721Bridge: function can only be called by self')
})
})
describe('withdrawals', () => {
let L2Token: Contract
beforeEach(async () => {
......
......@@ -28,6 +28,30 @@ const deployFn: DeployFunction = async (hre) => {
defaultHardhatNetworkHdAccountsConfigParams
).slice(0, 20)
// Set balances on L1 for the predeploy deployers
// 0xa961b0d6dce82db098cf70a42a14add3ee3db2d5
await hre.network.provider.send('hardhat_setBalance', [
'0xa961b0d6dce82db098cf70a42a14add3ee3db2d5',
'0x8000000000000000000000',
])
accounts.push({
privateKey:
'0xa6aecc98b63bafb0de3b29ae9964b14acb4086057808be29f90150214ebd4a0f',
balance: '',
})
// 0xdfc82d475833a50de90c642770f34a9db7deb725
await hre.network.provider.send('hardhat_setBalance', [
'0xdfc82d475833a50de90c642770f34a9db7deb725',
'0x8000000000000000000000',
])
accounts.push({
privateKey:
'0x3b8d2345102cce2443acb240db6e87c8edd4bb3f821b17fab8ea2c9da08ea132',
balance: '',
})
// Fund the accounts in parallel to speed things up.
await Promise.all(
accounts.map(async (account, index) => {
......
......@@ -7,12 +7,13 @@ import * as mkdirp from 'mkdirp'
import { ethers } from 'ethers'
import { task } from 'hardhat/config'
import { remove0x } from '@eth-optimism/core-utils'
import '@eth-optimism/hardhat-deploy-config'
import { predeploys } from '../src/predeploys'
import { getContractFromArtifact } from '../src/deploy-utils'
import { names } from '../src/address-names'
task('take-dump').setAction(async (args, hre) => {
task('take-dump').setAction(async ({}, hre) => {
/* eslint-disable @typescript-eslint/no-var-requires */
// Needs to be imported here or hardhat will throw a fit about hardhat being imported from
......
......@@ -2,6 +2,7 @@ export type EventName =
| 'TransactionEnqueued'
| 'SequencerBatchAppended'
| 'StateBatchAppended'
| 'SequencerBatchAppendedTransaction'
export class MissingElementError extends Error {
constructor(public name: EventName) {
......
......@@ -206,6 +206,21 @@ export const handleEventsSequencerBatchAppended: EventHandlerSet<
}
}
// Same consistency checks but for transaction entries.
if (
entry.transactionEntries.length > 0 &&
entry.transactionEntries[0].index > 0
) {
const prevTransactionEntry = await db.getTransactionByIndex(
entry.transactionEntries[0].index - 1
)
// We should *always* have a previous transaction here.
if (prevTransactionEntry === null) {
throw new MissingElementError('SequencerBatchAppendedTransaction')
}
}
await db.putTransactionEntries(entry.transactionEntries)
// Add an additional field to the enqueued transactions in the database
......
......@@ -277,6 +277,8 @@ export class L1IngestionService extends BaseService<L1IngestionServiceOptions> {
const handlers = {
SequencerBatchAppended:
this.state.db.getLatestTransactionBatch.bind(this.state.db),
SequencerBatchAppendedTransaction:
this.state.db.getLatestTransaction.bind(this.state.db),
StateBatchAppended: this.state.db.getLatestStateRootBatch.bind(
this.state.db
),
......
......@@ -106,7 +106,7 @@ extendConfig(
(config: HardhatConfig, userConfig: Readonly<HardhatUserConfig>) => {
config.paths.deployConfig = normalizePath(
config,
userConfig.paths.deployConfig,
userConfig.paths?.deployConfig,
'deploy-config'
)
}
......
......@@ -95,6 +95,11 @@ type BackendGroupsConfig map[string]*BackendGroupConfig
type MethodMappingsConfig map[string]string
type BatchConfig struct {
MaxSize int `toml:"max_size"`
ErrorMessage string `toml:"error_message"`
}
type Config struct {
WSBackendGroup string `toml:"ws_backend_group"`
Server ServerConfig `toml:"server"`
......@@ -104,10 +109,12 @@ type Config struct {
RateLimit RateLimitConfig `toml:"rate_limit"`
BackendOptions BackendOptions `toml:"backend"`
Backends BackendsConfig `toml:"backends"`
BatchConfig BatchConfig `toml:"batch"`
Authentication map[string]string `toml:"authentication"`
BackendGroups BackendGroupsConfig `toml:"backend_groups"`
RPCMethodMappings map[string]string `toml:"rpc_method_mappings"`
WSMethodWhitelist []string `toml:"ws_method_whitelist"`
WhitelistErrorMessage string `toml:"whitelist_error_message"`
}
func ReadFromEnvOrConfig(value string) (string, error) {
......
......@@ -38,7 +38,7 @@ func TestBatching(t *testing.T) {
mocks []mockResult
reqs []*proxyd.RPCReq
expectedRes string
maxBatchSize int
maxUpstreamBatchSize int
numExpectedForwards int
}{
{
......@@ -50,7 +50,7 @@ func TestBatching(t *testing.T) {
NewRPCReq("3", "eth_chainId", nil),
},
expectedRes: asArray(chainIDResponse1, chainIDResponse2, chainIDResponse3),
maxBatchSize: 2,
maxUpstreamBatchSize: 2,
numExpectedForwards: 2,
},
{
......@@ -65,7 +65,7 @@ func TestBatching(t *testing.T) {
`{"error":{"code":-32011,"message":"no backends available for method"},"id":1,"jsonrpc":"2.0"}`,
`{"error":{"code":-32011,"message":"no backends available for method"},"id":2,"jsonrpc":"2.0"}`,
),
maxBatchSize: 10,
maxUpstreamBatchSize: 10,
numExpectedForwards: 1,
},
{
......@@ -79,7 +79,7 @@ func TestBatching(t *testing.T) {
`{"error":{"code":-32011,"message":"no backends available for method"},"id":1,"jsonrpc":"2.0"}`,
`{"error":{"code":-32011,"message":"no backends available for method"},"id":2,"jsonrpc":"2.0"}`,
),
maxBatchSize: 1,
maxUpstreamBatchSize: 1,
numExpectedForwards: 2,
},
{
......@@ -97,9 +97,24 @@ func TestBatching(t *testing.T) {
NewRPCReq("1", "eth_call", nil),
},
expectedRes: asArray(netVersionResponse1, chainIDResponse2, chainIDResponse1, callResponse1),
maxBatchSize: 2,
maxUpstreamBatchSize: 2,
numExpectedForwards: 3,
},
{
name: "over max size",
mocks: []mockResult{},
reqs: []*proxyd.RPCReq{
NewRPCReq("1", "net_version", nil),
NewRPCReq("2", "eth_chainId", nil),
NewRPCReq("3", "eth_chainId", nil),
NewRPCReq("4", "eth_call", nil),
NewRPCReq("5", "eth_call", nil),
NewRPCReq("6", "eth_call", nil),
},
expectedRes: "{\"error\":{\"code\":-32014,\"message\":\"over batch size custom message\"},\"id\":null,\"jsonrpc\":\"2.0\"}",
maxUpstreamBatchSize: 2,
numExpectedForwards: 0,
},
{
name: "eth_accounts does not get forwarded",
mocks: []mockResult{
......@@ -110,14 +125,14 @@ func TestBatching(t *testing.T) {
NewRPCReq("2", "eth_accounts", nil),
},
expectedRes: asArray(callResponse1, ethAccountsResponse2),
maxBatchSize: 2,
maxUpstreamBatchSize: 2,
numExpectedForwards: 1,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
config.Server.MaxUpstreamBatchSize = tt.maxBatchSize
config.Server.MaxUpstreamBatchSize = tt.maxUpstreamBatchSize
handler := tt.handler
if handler == nil {
......
......@@ -17,3 +17,7 @@ backends = ["good"]
eth_chainId = "main"
net_version = "main"
eth_call = "main"
[batch]
error_message = "over batch size custom message"
max_size = 5
\ No newline at end of file
whitelist_error_message = "rpc method is not whitelisted custom message"
[server]
rpc_port = 8545
......
whitelist_error_message = "rpc method is not whitelisted"
ws_backend_group = "main"
ws_method_whitelist = [
......
......@@ -10,7 +10,7 @@ import (
)
const (
notWhitelistedResponse = `{"jsonrpc":"2.0","error":{"code":-32001,"message":"rpc method is not whitelisted"},"id":999}`
notWhitelistedResponse = `{"jsonrpc":"2.0","error":{"code":-32001,"message":"rpc method is not whitelisted custom message"},"id":999}`
parseErrResponse = `{"jsonrpc":"2.0","error":{"code":-32700,"message":"parse error"},"id":null}`
invalidJSONRPCVersionResponse = `{"error":{"code":-32601,"message":"invalid JSON-RPC version"},"id":null,"jsonrpc":"2.0"}`
invalidIDResponse = `{"error":{"code":-32601,"message":"invalid ID"},"id":null,"jsonrpc":"2.0"}`
......
......@@ -7,6 +7,8 @@ import (
"testing"
"time"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/proxyd"
"github.com/gorilla/websocket"
"github.com/stretchr/testify/require"
......@@ -42,6 +44,13 @@ func TestConcurrentWSPanic(t *testing.T) {
require.NoError(t, err)
defer shutdown()
// suppress tons of log messages
oldHandler := log.Root().GetHandler()
log.Root().SetHandler(log.DiscardHandler())
defer func() {
log.Root().SetHandler(oldHandler)
}()
<-readyCh
var wg sync.WaitGroup
......
......@@ -222,6 +222,20 @@ var (
}, []string{
"backend_name",
})
batchSizeHistogram = promauto.NewHistogram(prometheus.HistogramOpts{
Namespace: MetricsNamespace,
Name: "batch_size_summary",
Help: "Summary of batch sizes",
Buckets: []float64{
1,
5,
10,
25,
50,
100,
},
})
)
func RecordRedisError(source string) {
......@@ -278,3 +292,7 @@ func RecordCacheHit(method string) {
func RecordCacheMiss(method string) {
cacheMissesTotal.WithLabelValues(method).Inc()
}
func RecordBatchSize(size int) {
batchSizeHistogram.Observe(float64(size))
}
......@@ -55,6 +55,20 @@ func Start(config *Config) (func(), error) {
}
}
// While modifying shared globals is a bad practice, the alternative
// is to clone these errors on every invocation. This is inefficient.
// We'd also have to make sure that errors.Is and errors.As continue
// to function properly on the cloned errors.
if config.RateLimit.ErrorMessage != "" {
ErrOverRateLimit.Message = config.RateLimit.ErrorMessage
}
if config.WhitelistErrorMessage != "" {
ErrMethodNotWhitelisted.Message = config.WhitelistErrorMessage
}
if config.BatchConfig.ErrorMessage != "" {
ErrTooManyBatchRequests.Message = config.BatchConfig.ErrorMessage
}
maxConcurrentRPCs := config.Server.MaxConcurrentRPCs
if maxConcurrentRPCs == 0 {
maxConcurrentRPCs = math.MaxInt64
......@@ -225,6 +239,7 @@ func Start(config *Config) (func(), error) {
config.RateLimit,
config.Server.EnableRequestLog,
config.Server.MaxRequestBodyLogLen,
config.BatchConfig.MaxSize,
)
if err != nil {
return nil, fmt.Errorf("error creating server: %w", err)
......
......@@ -28,7 +28,7 @@ const (
ContextKeyAuth = "authorization"
ContextKeyReqID = "req_id"
ContextKeyXForwardedFor = "x_forwarded_for"
MaxBatchRPCCalls = 100
MaxBatchRPCCallsHardLimit = 100
cacheStatusHdr = "X-Proxyd-Cache-Status"
defaultServerTimeout = time.Second * 10
maxRequestBodyLogLen = 2000
......@@ -48,6 +48,7 @@ type Server struct {
authenticatedPaths map[string]string
timeout time.Duration
maxUpstreamBatchSize int
maxBatchSize int
upgrader *websocket.Upgrader
mainLim limiter.Store
overrideLims map[string]limiter.Store
......@@ -75,6 +76,7 @@ func NewServer(
rateLimitConfig RateLimitConfig,
enableRequestLog bool,
maxRequestBodyLogLen int,
maxBatchSize int,
) (*Server, error) {
if cache == nil {
cache = &NoopRPCCache{}
......@@ -92,6 +94,10 @@ func NewServer(
maxUpstreamBatchSize = defaultMaxUpstreamBatchSize
}
if maxBatchSize == 0 || maxBatchSize > MaxBatchRPCCallsHardLimit {
maxBatchSize = MaxBatchRPCCallsHardLimit
}
var mainLim limiter.Store
limExemptOrigins := make(map[string]bool)
limExemptUserAgents := make(map[string]bool)
......@@ -139,6 +145,7 @@ func NewServer(
cache: cache,
enableRequestLog: enableRequestLog,
maxRequestBodyLogLen: maxRequestBodyLogLen,
maxBatchSize: maxBatchSize,
upgrader: &websocket.Upgrader{
HandshakeTimeout: 5 * time.Second,
},
......@@ -244,12 +251,7 @@ func (s *Server) HandleRPC(w http.ResponseWriter, r *http.Request) {
}
if isLimited("") {
rpcErr := ErrOverRateLimit
if s.limConfig.ErrorMessage != "" {
rpcErr = ErrOverRateLimit.Clone()
rpcErr.Message = s.limConfig.ErrorMessage
}
RecordRPCError(ctx, BackendProxyd, "unknown", rpcErr)
RecordRPCError(ctx, BackendProxyd, "unknown", ErrOverRateLimit)
log.Warn(
"rate limited request",
"req_id", GetReqID(ctx),
......@@ -258,7 +260,7 @@ func (s *Server) HandleRPC(w http.ResponseWriter, r *http.Request) {
"origin", origin,
"remote_ip", xff,
)
writeRPCError(ctx, w, nil, rpcErr)
writeRPCError(ctx, w, nil, ErrOverRateLimit)
return
}
......@@ -296,7 +298,9 @@ func (s *Server) HandleRPC(w http.ResponseWriter, r *http.Request) {
return
}
if len(reqs) > MaxBatchRPCCalls {
RecordBatchSize(len(reqs))
if len(reqs) > s.maxBatchSize {
RecordRPCError(ctx, BackendProxyd, MethodUnknown, ErrTooManyBatchRequests)
writeRPCError(ctx, w, nil, ErrTooManyBatchRequests)
return
......@@ -394,13 +398,8 @@ func (s *Server) handleBatchRPC(ctx context.Context, reqs []json.RawMessage, isL
"req_id", GetReqID(ctx),
"method", parsedReq.Method,
)
rpcErr := ErrOverRateLimit
if s.limConfig.ErrorMessage != "" {
rpcErr = rpcErr.Clone()
rpcErr.Message = s.limConfig.ErrorMessage
}
RecordRPCError(ctx, BackendProxyd, parsedReq.Method, rpcErr)
responses[i] = NewRPCErrorRes(parsedReq.ID, rpcErr)
RecordRPCError(ctx, BackendProxyd, parsedReq.Method, ErrOverRateLimit)
responses[i] = NewRPCErrorRes(parsedReq.ID, ErrOverRateLimit)
continue
}
......
......@@ -283,7 +283,8 @@ The deposit contract handles two special cases:
[address-aliasing]: #address-aliasing
If the caller is a contract, the address will be transformed by adding
`0x1111000000000000000000000000000000001111` to it. This prevents attacks in which a
`0x1111000000000000000000000000000000001111` to it. The math is `unchecked` and done on a
Solidity `uint160` so the value will overflow. This prevents attacks in which a
contract on L1 has the same address as a contract on L2 but doesn't have the same code. We can safely ignore this
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.
......
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