Commit 38a10d7a authored by Andreas Bigger's avatar Andreas Bigger

Merge branch 'develop' into refcell/p2p_cli

parents 4d0bb35f 6e836959
---
'@eth-optimism/atst': minor
---
Update readAttestations and prepareWriteAttestation to handle keys longer than 32 bytes
---
'@eth-optimism/atst': minor
---
Move react api to @eth-optimism/atst/react so react isn't required to run the core sdk
---
'@eth-optimism/sdk': patch
---
Update migrated withdrawal gaslimit calculation
---
'@eth-optimism/atst': minor
---
Fix main and module in atst package.json
---
'@eth-optimism/fault-detector': patch
---
Fixes a bug that would cause the fault detector to error out if no outputs had been proposed yet.
......@@ -163,6 +163,10 @@ jobs:
description: Docker build context
type: string
default: "."
docker_target:
description: "target build stage"
type: string
default: ""
registry:
description: Docker registry
type: string
......@@ -196,7 +200,7 @@ jobs:
DOCKER_TAGS=$(echo -ne <<parameters.docker_tags>> | sed "s/,/\n/g" | sed "s/[^a-zA-Z0-9\n]/-/g" | sed -e "s|^|-t ${IMAGE_BASE}:|")
docker context create buildx-build
docker buildx create --use buildx-build
docker buildx build --platform=<<parameters.platforms>> --push \
docker buildx build --platform=<<parameters.platforms>> --target "<<parameters.docker_target>>" --push \
$(echo -ne $DOCKER_TAGS | tr '\n' ' ') \
-f <<parameters.docker_file>> \
<<parameters.docker_context>>
......@@ -534,7 +538,7 @@ jobs:
command: |
# Note: We don't use circle CI test splits because we need to split by test name, not by package. There is an additional
# constraint that gotestsum does not currently (nor likely will) accept files from different pacakges when building.
OP_TESTLOG_DISABLE_COLOR=true OP_E2E_DISABLE_PARALLEL=true OP_E2E_USE_HTTP=<<parameters.use_http>> gotestsum \
OP_TESTLOG_DISABLE_COLOR=true OP_E2E_DISABLE_PARALLEL=false OP_E2E_USE_HTTP=<<parameters.use_http>> gotestsum \
--format=standard-verbose --junitfile=/tmp/test-results/<<parameters.module>>_http_<<parameters.use_http>>.xml \
-- -timeout=20m ./...
working_directory: <<parameters.module>>
......@@ -845,7 +849,7 @@ jobs:
./hive \
-sim=<<parameters.sim>> \
-sim.loglevel=5 \
-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."
-client=go-ethereum,op-geth_optimism,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
......@@ -1132,6 +1136,14 @@ workflows:
docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
context:
- oplabs-gcr
- docker-publish:
name: chain-mon-docker-publish
docker_file: ./ops/docker/Dockerfile.packages
docker_name: chain-mon
docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
docker_target: wd-mon
context:
- oplabs-gcr
- hive-test:
name: hive-test-rpc
version: <<pipeline.git.revision>>
......
......@@ -62,8 +62,8 @@ require (
github.com/tklauser/go-sysconf v0.3.10 // indirect
github.com/tklauser/numcpus v0.4.0 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/crypto v0.0.0-20220307211146-efcb8507fb70 // indirect
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
golang.org/x/crypto v0.1.0 // indirect
golang.org/x/sys v0.1.0 // indirect
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
......
......@@ -631,8 +631,8 @@ golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220307211146-efcb8507fb70 h1:syTAU9FwmvzEoIYMqcPHOcVm4H3U5u90WsvuYgwpETU=
golang.org/x/crypto v0.0.0-20220307211146-efcb8507fb70/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
......@@ -708,7 +708,7 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220607020251-c690dde0001d h1:4SFsTMi4UahlKoloni7L4eYzhFRifURQLw+yv0QDCx8=
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
......@@ -790,8 +790,8 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
......@@ -799,8 +799,8 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
......
......@@ -191,6 +191,6 @@ require (
nhooyr.io/websocket v1.8.7 // indirect
)
replace github.com/ethereum/go-ethereum v1.11.2 => github.com/ethereum-optimism/op-geth v1.11.2-aea0402.0.20230301232322-c407b2a217b7
replace github.com/ethereum/go-ethereum v1.11.2 => github.com/ethereum-optimism/op-geth v1.11.2-de8c5df46.0.20230308025559-13ee9ab9153b
//replace github.com/ethereum/go-ethereum v1.11.2 => ../go-ethereum
......@@ -217,8 +217,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 h1:RWHKLhCrQThMfch+QJ1Z8veEq5ZO3DfIhZ7xgRP9WTc=
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3/go.mod h1:QziizLAiF0KqyLdNJYD7O5cpDlaFMNZzlxYNcWsJUxs=
github.com/ethereum-optimism/op-geth v1.11.2-aea0402.0.20230301232322-c407b2a217b7 h1:bkttBXCRDv2Mp4VoGBglr4BjS7icIuN8HS5ZFpeKfvE=
github.com/ethereum-optimism/op-geth v1.11.2-aea0402.0.20230301232322-c407b2a217b7/go.mod h1:/tjlXxOaovIyuF0l6+wCzr6AtDb3lYWTymmpQAQcqu8=
github.com/ethereum-optimism/op-geth v1.11.2-de8c5df46.0.20230308025559-13ee9ab9153b h1:7RNzqCwam//7PPieblo8GSIVukwrfoPO+0xT1yMp9Zw=
github.com/ethereum-optimism/op-geth v1.11.2-de8c5df46.0.20230308025559-13ee9ab9153b/go.mod h1:/tjlXxOaovIyuF0l6+wCzr6AtDb3lYWTymmpQAQcqu8=
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
......
......@@ -4,7 +4,7 @@ go 1.17
replace (
github.com/ethereum/go-ethereum v1.10.26 => github.com/ethereum-optimism/op-geth v0.0.0-20230214215134-401b7fd3309b
github.com/ethereum/go-ethereum v1.11.2 => github.com/ethereum-optimism/op-geth v1.11.2-aea0402.0.20230301232322-c407b2a217b7
github.com/ethereum/go-ethereum v1.11.2 => github.com/ethereum-optimism/op-geth v1.11.2-de8c5df46.0.20230308025559-13ee9ab9153b
)
require (
......
......@@ -81,6 +81,7 @@ func Main(version string, cliCtx *cli.Context) error {
rpcCfg.ListenAddr,
rpcCfg.ListenPort,
version,
oprpc.WithLogger(l),
)
if rpcCfg.EnableAdmin {
server.AddAPI(gethrpc.API{
......
......@@ -31,7 +31,7 @@ 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\":\"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\":[],\"name\":\"MESSENGER\",\"outputs\":[{\"internalType\":\"contractCrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OTHER_BRIDGE\",\"outputs\":[{\"internalType\":\"contractStandardBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"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\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
Bin: "0x6101206040523480156200001257600080fd5b5060405162002c0e38038062002c0e83398101604081905262000035916200006f565b6001600160a01b031660805273420000000000000000000000000000000000001060a052600160c081905260e052600061010052620000a1565b6000602082840312156200008257600080fd5b81516001600160a01b03811681146200009a57600080fd5b9392505050565b60805160a05160c05160e05161010051612acd620001416000396000610ee001526000610eb701526000610e8e015260008181610311015281816103c8015281816104ce015281816109af01528181611356015261198f015260008181610253015281816103fe015281816104a40152818161050501528181610985015281816109e601528181610c730152818161131901526119530152612acd6000f3fe60806040526004361061012d5760003560e01c8063838b2520116100a5578063927ede2d11610074578063a9f9e67511610059578063a9f9e67514610433578063b1a1a88214610453578063e11013dd1461046657600080fd5b8063927ede2d146103ec5780639a2ac6d51461042057600080fd5b8063838b25201461033357806387087623146103535780638f601f661461037357806391c49bf8146103b957600080fd5b80633cb747bf116100fc57806354fd4d50116100e157806354fd4d50146102bd57806358a997f6146102df5780637f46ddb2146102ff57600080fd5b80633cb747bf14610244578063540abf731461029d57600080fd5b80630166a07a146101eb57806309fc88431461020b5780631532ec341461021e5780631635f5fd1461023157600080fd5b366101e657333b156101c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b6101e4333362030d4060405180602001604052806000815250610479565b005b600080fd5b3480156101f757600080fd5b506101e46102063660046123ce565b61048c565b6101e461021936600461247f565b610882565b6101e461022c3660046124d2565b610959565b6101e461023f3660046124d2565b61096d565b34801561025057600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102a957600080fd5b506101e46102b8366004612545565b610e42565b3480156102c957600080fd5b506102d2610e87565b6040516102949190612632565b3480156102eb57600080fd5b506101e46102fa366004612645565b610f2a565b34801561030b57600080fd5b506102737f000000000000000000000000000000000000000000000000000000000000000081565b34801561033f57600080fd5b506101e461034e366004612545565b610ffe565b34801561035f57600080fd5b506101e461036e366004612645565b611043565b34801561037f57600080fd5b506103ab61038e3660046126c8565b600260209081526000928352604080842090915290825290205481565b604051908152602001610294565b3480156103c557600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610273565b3480156103f857600080fd5b506102737f000000000000000000000000000000000000000000000000000000000000000081565b6101e461042e366004612701565b611117565b34801561043f57600080fd5b506101e461044e3660046123ce565b611159565b6101e461046136600461247f565b611168565b6101e4610474366004612701565b611239565b610486848434858561127c565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156105aa57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa15801561056e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105929190612764565b73ffffffffffffffffffffffffffffffffffffffff16145b61065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101bd565b61066587611460565b156107b35761067487876114c2565b610726576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101bd565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b15801561079657600080fd5b505af11580156107aa573d6000803e3d6000fd5b50505050610835565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a16835292905220546107f19084906127b0565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c1683529390529190912091909155610835908585611569565b610879878787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061163d92505050565b50505050505050565b333b15610911576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101bd565b6109543333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061127c92505050565b505050565b610966858585858561096d565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015610a8b57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a739190612764565b73ffffffffffffffffffffffffffffffffffffffff16145b610b3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101bd565b823414610bcc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e7420726571756972656400000000000060648201526084016101bd565b3073ffffffffffffffffffffffffffffffffffffffff851603610c71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c66000000000000000000000000000000000000000000000000000000000060648201526084016101bd565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610d4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e67657200000000000000000000000000000000000000000000000060648201526084016101bd565b610d8e85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506116cb92505050565b6000610dab855a866040518060200160405280600081525061173e565b905080610e3a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526084016101bd565b505050505050565b61087987873388888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175892505050565b6060610eb27f0000000000000000000000000000000000000000000000000000000000000000611a9f565b610edb7f0000000000000000000000000000000000000000000000000000000000000000611a9f565b610f047f0000000000000000000000000000000000000000000000000000000000000000611a9f565b604051602001610f16939291906127c7565b604051602081830303815290604052905090565b333b15610fb9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101bd565b610e3a86863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bdc92505050565b61087987873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bdc92505050565b333b156110d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101bd565b610e3a86863333888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175892505050565b61048633858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061047992505050565b6108798787878787878761048c565b333b156111f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101bd565b61095433338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061047992505050565b6104863385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061127c92505050565b82341461130b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c7565000060648201526084016101bd565b61131785858584611beb565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b847f0000000000000000000000000000000000000000000000000000000000000000631635f5fd60e01b89898988604051602401611394949392919061283d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261142792918890600401612886565b6000604051808303818588803b15801561144057600080fd5b505af1158015611454573d6000803e3d6000fd5b50505050505050505050565b600061148c827f1d1d8b6300000000000000000000000000000000000000000000000000000000611c5e565b806114bc57506114bc827fec4fc8e300000000000000000000000000000000000000000000000000000000611c5e565b92915050565b60008273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561150f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115339190612764565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905092915050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109549084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611c81565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b38686866040516116b5939291906128cb565b60405180910390a4610e3a868686868686611d8d565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e631848460405161172a929190612909565b60405180910390a361048684848484611e15565b600080600080845160208601878a8af19695505050505050565b61176187611460565b156118af5761177087876114c2565b611822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101bd565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b15801561189257600080fd5b505af11580156118a6573d6000803e3d6000fd5b50505050611943565b6118d173ffffffffffffffffffffffffffffffffffffffff8816863086611e82565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461190f908490612922565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611951878787878786611ee0565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b7f0000000000000000000000000000000000000000000000000000000000000000630166a07a60e01b898b8a8a8a896040516024016119d19695949392919061293a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611a6492918790600401612886565b600060405180830381600087803b158015611a7e57600080fd5b505af1158015611a92573d6000803e3d6000fd5b5050505050505050505050565b606081600003611ae257505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611b0c5780611af681612995565b9150611b059050600a836129fc565b9150611ae6565b60008167ffffffffffffffff811115611b2757611b27612a10565b6040519080825280601f01601f191660200182016040528015611b51576020820181803683370190505b5090505b8415611bd457611b666001836127b0565b9150611b73600a86612a3f565b611b7e906030612922565b60f81b818381518110611b9357611b93612a53565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611bcd600a866129fc565b9450611b55565b949350505050565b61087987878787878787611758565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051611c4a929190612909565b60405180910390a361048684848484611f6e565b6000611c6983611fcd565b8015611c7a5750611c7a8383612031565b9392505050565b6000611ce3826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121009092919063ffffffff16565b8051909150156109545780806020019051810190611d019190612a82565b610954576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101bd565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611e05939291906128cb565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611e74929190612909565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526104869085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016115bb565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d0396868686604051611f58939291906128cb565b60405180910390a4610e3a86868686868661210f565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611e74929190612909565b6000611ff9827f01ffc9a700000000000000000000000000000000000000000000000000000000612031565b80156114bc575061202a827fffffffff00000000000000000000000000000000000000000000000000000000612031565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156120e9575060208210155b80156120f55750600081115b979650505050505050565b6060611bd48484600085612187565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611e05939291906128cb565b606082471015612219576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016101bd565b73ffffffffffffffffffffffffffffffffffffffff85163b612297576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101bd565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516122c09190612aa4565b60006040518083038185875af1925050503d80600081146122fd576040519150601f19603f3d011682016040523d82523d6000602084013e612302565b606091505b50915091506120f58282866060831561231c575081611c7a565b82511561232c5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101bd9190612632565b73ffffffffffffffffffffffffffffffffffffffff8116811461238257600080fd5b50565b60008083601f84011261239757600080fd5b50813567ffffffffffffffff8111156123af57600080fd5b6020830191508360208285010111156123c757600080fd5b9250929050565b600080600080600080600060c0888a0312156123e957600080fd5b87356123f481612360565b9650602088013561240481612360565b9550604088013561241481612360565b9450606088013561242481612360565b93506080880135925060a088013567ffffffffffffffff81111561244757600080fd5b6124538a828b01612385565b989b979a50959850939692959293505050565b803563ffffffff8116811461247a57600080fd5b919050565b60008060006040848603121561249457600080fd5b61249d84612466565b9250602084013567ffffffffffffffff8111156124b957600080fd5b6124c586828701612385565b9497909650939450505050565b6000806000806000608086880312156124ea57600080fd5b85356124f581612360565b9450602086013561250581612360565b935060408601359250606086013567ffffffffffffffff81111561252857600080fd5b61253488828901612385565b969995985093965092949392505050565b600080600080600080600060c0888a03121561256057600080fd5b873561256b81612360565b9650602088013561257b81612360565b9550604088013561258b81612360565b9450606088013593506125a060808901612466565b925060a088013567ffffffffffffffff81111561244757600080fd5b60005b838110156125d75781810151838201526020016125bf565b838111156104865750506000910152565b600081518084526126008160208601602086016125bc565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611c7a60208301846125e8565b60008060008060008060a0878903121561265e57600080fd5b863561266981612360565b9550602087013561267981612360565b94506040870135935061268e60608801612466565b9250608087013567ffffffffffffffff8111156126aa57600080fd5b6126b689828a01612385565b979a9699509497509295939492505050565b600080604083850312156126db57600080fd5b82356126e681612360565b915060208301356126f681612360565b809150509250929050565b6000806000806060858703121561271757600080fd5b843561272281612360565b935061273060208601612466565b9250604085013567ffffffffffffffff81111561274c57600080fd5b61275887828801612385565b95989497509550505050565b60006020828403121561277657600080fd5b8151611c7a81612360565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156127c2576127c2612781565b500390565b600084516127d98184602089016125bc565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551612815816001850160208a016125bc565b600192019182015283516128308160028401602088016125bc565b0160020195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261287c60808301846125e8565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006128b560608301856125e8565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061290060608301846125e8565b95945050505050565b828152604060208201526000611bd460408301846125e8565b6000821982111561293557612935612781565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a083015261298960c08301846125e8565b98975050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036129c6576129c6612781565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082612a0b57612a0b6129cd565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082612a4e57612a4e6129cd565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215612a9457600080fd5b81518015158114611c7a57600080fd5b60008251612ab68184602087016125bc565b919091019291505056fea164736f6c634300080f000a",
Bin: "0x6101206040523480156200001257600080fd5b5060405162002c8738038062002c8783398101604081905262000035916200006f565b6001600160a01b031660805273420000000000000000000000000000000000001060a052600160c081905260e052600061010052620000a1565b6000602082840312156200008257600080fd5b81516001600160a01b03811681146200009a57600080fd5b9392505050565b60805160a05160c05160e05161010051612b46620001416000396000610ee001526000610eb701526000610e8e015260008181610311015281816103c8015281816104ce015281816109af015281816113560152611a08015260008181610253015281816103fe015281816104a40152818161050501528181610985015281816109e601528181610c730152818161131901526119cc0152612b466000f3fe60806040526004361061012d5760003560e01c8063838b2520116100a5578063927ede2d11610074578063a9f9e67511610059578063a9f9e67514610433578063b1a1a88214610453578063e11013dd1461046657600080fd5b8063927ede2d146103ec5780639a2ac6d51461042057600080fd5b8063838b25201461033357806387087623146103535780638f601f661461037357806391c49bf8146103b957600080fd5b80633cb747bf116100fc57806354fd4d50116100e157806354fd4d50146102bd57806358a997f6146102df5780637f46ddb2146102ff57600080fd5b80633cb747bf14610244578063540abf731461029d57600080fd5b80630166a07a146101eb57806309fc88431461020b5780631532ec341461021e5780631635f5fd1461023157600080fd5b366101e657333b156101c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b6101e4333362030d4060405180602001604052806000815250610479565b005b600080fd5b3480156101f757600080fd5b506101e4610206366004612447565b61048c565b6101e46102193660046124f8565b610882565b6101e461022c36600461254b565b610959565b6101e461023f36600461254b565b61096d565b34801561025057600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102a957600080fd5b506101e46102b83660046125be565b610e42565b3480156102c957600080fd5b506102d2610e87565b60405161029491906126ab565b3480156102eb57600080fd5b506101e46102fa3660046126be565b610f2a565b34801561030b57600080fd5b506102737f000000000000000000000000000000000000000000000000000000000000000081565b34801561033f57600080fd5b506101e461034e3660046125be565b610ffe565b34801561035f57600080fd5b506101e461036e3660046126be565b611043565b34801561037f57600080fd5b506103ab61038e366004612741565b600260209081526000928352604080842090915290825290205481565b604051908152602001610294565b3480156103c557600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610273565b3480156103f857600080fd5b506102737f000000000000000000000000000000000000000000000000000000000000000081565b6101e461042e36600461277a565b611117565b34801561043f57600080fd5b506101e461044e366004612447565b611159565b6101e46104613660046124f8565b611168565b6101e461047436600461277a565b611239565b610486848434858561127c565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156105aa57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa15801561056e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059291906127dd565b73ffffffffffffffffffffffffffffffffffffffff16145b61065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101bd565b61066587611460565b156107b35761067487876114c2565b610726576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101bd565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b15801561079657600080fd5b505af11580156107aa573d6000803e3d6000fd5b50505050610835565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a16835292905220546107f1908490612829565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c16835293905291909120919091556108359085856115e2565b610879878787878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506116b692505050565b50505050505050565b333b15610911576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101bd565b6109543333348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061127c92505050565b505050565b610966858585858561096d565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015610a8b57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7391906127dd565b73ffffffffffffffffffffffffffffffffffffffff16145b610b3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a4016101bd565b823414610bcc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e7420726571756972656400000000000060648201526084016101bd565b3073ffffffffffffffffffffffffffffffffffffffff851603610c71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c66000000000000000000000000000000000000000000000000000000000060648201526084016101bd565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610d4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e67657200000000000000000000000000000000000000000000000060648201526084016101bd565b610d8e85858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061174492505050565b6000610dab855a86604051806020016040528060008152506117b7565b905080610e3a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526084016101bd565b505050505050565b61087987873388888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506117d192505050565b6060610eb27f0000000000000000000000000000000000000000000000000000000000000000611b18565b610edb7f0000000000000000000000000000000000000000000000000000000000000000611b18565b610f047f0000000000000000000000000000000000000000000000000000000000000000611b18565b604051602001610f1693929190612840565b604051602081830303815290604052905090565b333b15610fb9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101bd565b610e3a86863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c5592505050565b61087987873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c5592505050565b333b156110d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101bd565b610e3a86863333888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506117d192505050565b61048633858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061047992505050565b6108798787878787878761048c565b333b156111f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084016101bd565b61095433338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061047992505050565b6104863385348686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061127c92505050565b82341461130b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c7565000060648201526084016101bd565b61131785858584611c64565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b847f0000000000000000000000000000000000000000000000000000000000000000631635f5fd60e01b8989898860405160240161139494939291906128b6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b9092168252611427929188906004016128ff565b6000604051808303818588803b15801561144057600080fd5b505af1158015611454573d6000803e3d6000fd5b50505050505050505050565b600061148c827f1d1d8b6300000000000000000000000000000000000000000000000000000000611cd7565b806114bc57506114bc827fec4fc8e300000000000000000000000000000000000000000000000000000000611cd7565b92915050565b60006114ee837f1d1d8b6300000000000000000000000000000000000000000000000000000000611cd7565b15611597578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561153e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061156291906127dd565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161490506114bc565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561153e573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109549084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611cfa565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b386868660405161172e93929190612944565b60405180910390a4610e3a868686868686611e06565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e63184846040516117a3929190612982565b60405180910390a361048684848484611e8e565b600080600080845160208601878a8af19695505050505050565b6117da87611460565b15611928576117e987876114c2565b61189b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a4016101bd565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b15801561190b57600080fd5b505af115801561191f573d6000803e3d6000fd5b505050506119bc565b61194a73ffffffffffffffffffffffffffffffffffffffff8816863086611efb565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461198890849061299b565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b6119ca878787878786611f59565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b7f0000000000000000000000000000000000000000000000000000000000000000630166a07a60e01b898b8a8a8a89604051602401611a4a969594939291906129b3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611add929187906004016128ff565b600060405180830381600087803b158015611af757600080fd5b505af1158015611b0b573d6000803e3d6000fd5b5050505050505050505050565b606081600003611b5b57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611b855780611b6f81612a0e565b9150611b7e9050600a83612a75565b9150611b5f565b60008167ffffffffffffffff811115611ba057611ba0612a89565b6040519080825280601f01601f191660200182016040528015611bca576020820181803683370190505b5090505b8415611c4d57611bdf600183612829565b9150611bec600a86612ab8565b611bf790603061299b565b60f81b818381518110611c0c57611c0c612acc565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611c46600a86612a75565b9450611bce565b949350505050565b610879878787878787876117d1565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051611cc3929190612982565b60405180910390a361048684848484611fe7565b6000611ce283612046565b8015611cf35750611cf383836120aa565b9392505050565b6000611d5c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121799092919063ffffffff16565b8051909150156109545780806020019051810190611d7a9190612afb565b610954576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101bd565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611e7e93929190612944565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611eed929190612982565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526104869085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611634565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d0396868686604051611fd193929190612944565b60405180910390a4610e3a868686868686612188565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611eed929190612982565b6000612072827f01ffc9a7000000000000000000000000000000000000000000000000000000006120aa565b80156114bc57506120a3827fffffffff000000000000000000000000000000000000000000000000000000006120aa565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015612162575060208210155b801561216e5750600081115b979650505050505050565b6060611c4d8484600085612200565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611e7e93929190612944565b606082471015612292576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016101bd565b73ffffffffffffffffffffffffffffffffffffffff85163b612310576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101bd565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516123399190612b1d565b60006040518083038185875af1925050503d8060008114612376576040519150601f19603f3d011682016040523d82523d6000602084013e61237b565b606091505b509150915061216e82828660608315612395575081611cf3565b8251156123a55782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101bd91906126ab565b73ffffffffffffffffffffffffffffffffffffffff811681146123fb57600080fd5b50565b60008083601f84011261241057600080fd5b50813567ffffffffffffffff81111561242857600080fd5b60208301915083602082850101111561244057600080fd5b9250929050565b600080600080600080600060c0888a03121561246257600080fd5b873561246d816123d9565b9650602088013561247d816123d9565b9550604088013561248d816123d9565b9450606088013561249d816123d9565b93506080880135925060a088013567ffffffffffffffff8111156124c057600080fd5b6124cc8a828b016123fe565b989b979a50959850939692959293505050565b803563ffffffff811681146124f357600080fd5b919050565b60008060006040848603121561250d57600080fd5b612516846124df565b9250602084013567ffffffffffffffff81111561253257600080fd5b61253e868287016123fe565b9497909650939450505050565b60008060008060006080868803121561256357600080fd5b853561256e816123d9565b9450602086013561257e816123d9565b935060408601359250606086013567ffffffffffffffff8111156125a157600080fd5b6125ad888289016123fe565b969995985093965092949392505050565b600080600080600080600060c0888a0312156125d957600080fd5b87356125e4816123d9565b965060208801356125f4816123d9565b95506040880135612604816123d9565b945060608801359350612619608089016124df565b925060a088013567ffffffffffffffff8111156124c057600080fd5b60005b83811015612650578181015183820152602001612638565b838111156104865750506000910152565b60008151808452612679816020860160208601612635565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611cf36020830184612661565b60008060008060008060a087890312156126d757600080fd5b86356126e2816123d9565b955060208701356126f2816123d9565b945060408701359350612707606088016124df565b9250608087013567ffffffffffffffff81111561272357600080fd5b61272f89828a016123fe565b979a9699509497509295939492505050565b6000806040838503121561275457600080fd5b823561275f816123d9565b9150602083013561276f816123d9565b809150509250929050565b6000806000806060858703121561279057600080fd5b843561279b816123d9565b93506127a9602086016124df565b9250604085013567ffffffffffffffff8111156127c557600080fd5b6127d1878288016123fe565b95989497509550505050565b6000602082840312156127ef57600080fd5b8151611cf3816123d9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561283b5761283b6127fa565b500390565b60008451612852818460208901612635565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855161288e816001850160208a01612635565b600192019182015283516128a9816002840160208801612635565b0160020195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526128f56080830184612661565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260606020820152600061292e6060830185612661565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff841681528260208201526060604082015260006129796060830184612661565b95945050505050565b828152604060208201526000611c4d6040830184612661565b600082198211156129ae576129ae6127fa565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a0830152612a0260c0830184612661565b98975050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612a3f57612a3f6127fa565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082612a8457612a84612a46565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082612ac757612ac7612a46565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215612b0d57600080fd5b81518015158114611cf357600080fd5b60008251612b2f818460208701612635565b919091019291505056fea164736f6c634300080f000a",
}
// L1StandardBridgeABI is the input ABI used to generate the binding from.
......
......@@ -31,7 +31,7 @@ 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\":\"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\":[],\"name\":\"MESSENGER\",\"outputs\":[{\"internalType\":\"contractCrossDomainMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OTHER_BRIDGE\",\"outputs\":[{\"internalType\":\"contractStandardBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"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\":\"l1TokenBridge\",\"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\":\"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: "0x6101206040523480156200001257600080fd5b5060405162002b8d38038062002b8d83398101604081905262000035916200006f565b7342000000000000000000000000000000000000076080526001600160a01b031660a052600160c081905260e052600061010052620000a1565b6000602082840312156200008257600080fd5b81516001600160a01b03811681146200009a57600080fd5b9392505050565b60805160a05160c05160e05161010051612a4c620001416000396000610fd201526000610fa901526000610f800152600081816102280152818161030c0152818161050b015281816109cf015281816112ca015261160b015260008181610281015281816103a6015281816104e101528181610542015281816109a501528181610a0601528181610c930152818161128d01526115cf0152612a4c6000f3fe6080604052600436106100ec5760003560e01c806354fd4d501161008a5780638f601f66116100595780638f601f661461034e578063927ede2d14610394578063a3a79548146103c8578063e11013dd146103db57600080fd5b806354fd4d50146102c5578063662a633a146102e75780637f46ddb2146102fa578063870876231461032e57600080fd5b806332b7006d116100c657806332b7006d1461020657806336c717c1146102195780633cb747bf14610272578063540abf73146102a557600080fd5b80630166a07a146101c057806309fc8843146101e05780631635f5fd146101f357600080fd5b366101bb57333b15610185576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b6101b973deaddeaddeaddeaddeaddeaddeaddeaddead000033333462030d40604051806020016040528060008152506103ee565b005b600080fd5b3480156101cc57600080fd5b506101b96101db3660046122f9565b6104c9565b6101b96101ee3660046123aa565b6108b6565b6101b96102013660046123fd565b61098d565b6101b9610214366004612470565b610e5a565b34801561022557600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561027e57600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610248565b3480156102b157600080fd5b506101b96102c03660046124c4565b610f34565b3480156102d157600080fd5b506102da610f79565b60405161026991906125b1565b6101b96102f53660046122f9565b61101c565b34801561030657600080fd5b506102487f000000000000000000000000000000000000000000000000000000000000000081565b34801561033a57600080fd5b506101b96103493660046125c4565b61108f565b34801561035a57600080fd5b50610386610369366004612647565b600260209081526000928352604080842090915290825290205481565b604051908152602001610269565b3480156103a057600080fd5b506102487f000000000000000000000000000000000000000000000000000000000000000081565b6101b96103d63660046125c4565b611163565b6101b96103e9366004612680565b6111a7565b7fffffffffffffffffffffffff215221522152215221522152215221522153000073ffffffffffffffffffffffffffffffffffffffff87160161043d5761043885858585856111f0565b6104c1565b60008673ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ae91906126e3565b90506104bf878288888888886113d4565b505b505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156105e757507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105cf91906126e3565b73ffffffffffffffffffffffffffffffffffffffff16145b610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a40161017c565b6106a28761171b565b156107f0576106b1878761177d565b610763576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a40161017c565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156107d357600080fd5b505af11580156107e7573d6000803e3d6000fd5b50505050610872565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461082e90849061272f565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c1683529390529190912091909155610872908585611824565b6104bf878787878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118f892505050565b333b15610945576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b6109883333348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111f092505050565b505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015610aab57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9391906126e3565b73ffffffffffffffffffffffffffffffffffffffff16145b610b5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a40161017c565b823414610bec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e74207265717569726564000000000000606482015260840161017c565b3073ffffffffffffffffffffffffffffffffffffffff851603610c91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c660000000000000000000000000000000000000000000000000000000000606482015260840161017c565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610d6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e676572000000000000000000000000000000000000000000000000606482015260840161017c565b610dae85858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061198692505050565b6000610dcb855a8660405180602001604052806000815250611a27565b9050806104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c65640000000000000000000000000000000000000000000000000000000000606482015260840161017c565b333b15610ee9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b610f2d853333878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ee92505050565b5050505050565b6104bf87873388888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506113d492505050565b6060610fa47f0000000000000000000000000000000000000000000000000000000000000000611a41565b610fcd7f0000000000000000000000000000000000000000000000000000000000000000611a41565b610ff67f0000000000000000000000000000000000000000000000000000000000000000611a41565b60405160200161100893929190612746565b604051602081830303815290604052905090565b73ffffffffffffffffffffffffffffffffffffffff8716158015611069575073ffffffffffffffffffffffffffffffffffffffff861673deaddeaddeaddeaddeaddeaddeaddeaddead0000145b156110805761107b858585858561098d565b6104bf565b6104bf868887878787876104c9565b333b1561111e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b6104c186863333888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506113d492505050565b6104c1863387878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ee92505050565b6111ea3385348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111f092505050565b50505050565b82341461127f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c75650000606482015260840161017c565b61128b85858584611b7e565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b847f0000000000000000000000000000000000000000000000000000000000000000631635f5fd60e01b8989898860405160240161130894939291906127bc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261139b92918890600401612805565b6000604051808303818588803b1580156113b457600080fd5b505af11580156113c8573d6000803e3d6000fd5b50505050505050505050565b6113dd8761171b565b1561152b576113ec878761177d565b61149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a40161017c565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b15801561150e57600080fd5b505af1158015611522573d6000803e3d6000fd5b505050506115bf565b61154d73ffffffffffffffffffffffffffffffffffffffff8816863086611c1f565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461158b90849061284a565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b6115cd878787878786611c7d565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b7f0000000000000000000000000000000000000000000000000000000000000000630166a07a60e01b898b8a8a8a8960405160240161164d96959493929190612862565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b90921682526116e092918790600401612805565b600060405180830381600087803b1580156116fa57600080fd5b505af115801561170e573d6000803e3d6000fd5b5050505050505050505050565b6000611747827f1d1d8b6300000000000000000000000000000000000000000000000000000000611d0b565b806117775750611777827fec4fc8e300000000000000000000000000000000000000000000000000000000611d0b565b92915050565b60008273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ee91906126e3565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905092915050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109889084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611d2e565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89868686604051611970939291906128bd565b60405180910390a46104c1868686868686611e3a565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89868686604051611a13939291906128bd565b60405180910390a46111ea84848484611ec2565b600080600080845160208601878a8af19695505050505050565b606081600003611a8457505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611aae5780611a98816128fb565b9150611aa79050600a83612962565b9150611a88565b60008167ffffffffffffffff811115611ac957611ac9612976565b6040519080825280601f01601f191660200182016040528015611af3576020820181803683370190505b5090505b8415611b7657611b0860018361272f565b9150611b15600a866129a5565b611b2090603061284a565b60f81b818381518110611b3557611b356129b9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611b6f600a86612962565b9450611af7565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611c0b939291906128bd565b60405180910390a46111ea84848484611f2f565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526111ea9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611876565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611cf5939291906128bd565b60405180910390a46104c1868686868686611f8e565b6000611d1683612006565b8015611d275750611d27838361206a565b9392505050565b6000611d90826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121399092919063ffffffff16565b8051909150156109885780806020019051810190611dae91906129e8565b610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161017c565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611eb2939291906128bd565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611f21929190612a0a565b60405180910390a350505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611f21929190612a0a565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611eb2939291906128bd565b6000612032827f01ffc9a70000000000000000000000000000000000000000000000000000000061206a565b80156117775750612063827fffffffff0000000000000000000000000000000000000000000000000000000061206a565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015612122575060208210155b801561212e5750600081115b979650505050505050565b6060611b7684846000858573ffffffffffffffffffffffffffffffffffffffff85163b6121c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161017c565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516121eb9190612a23565b60006040518083038185875af1925050503d8060008114612228576040519150601f19603f3d011682016040523d82523d6000602084013e61222d565b606091505b509150915061212e82828660608315612247575081611d27565b8251156122575782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017c91906125b1565b73ffffffffffffffffffffffffffffffffffffffff811681146122ad57600080fd5b50565b60008083601f8401126122c257600080fd5b50813567ffffffffffffffff8111156122da57600080fd5b6020830191508360208285010111156122f257600080fd5b9250929050565b600080600080600080600060c0888a03121561231457600080fd5b873561231f8161228b565b9650602088013561232f8161228b565b9550604088013561233f8161228b565b9450606088013561234f8161228b565b93506080880135925060a088013567ffffffffffffffff81111561237257600080fd5b61237e8a828b016122b0565b989b979a50959850939692959293505050565b803563ffffffff811681146123a557600080fd5b919050565b6000806000604084860312156123bf57600080fd5b6123c884612391565b9250602084013567ffffffffffffffff8111156123e457600080fd5b6123f0868287016122b0565b9497909650939450505050565b60008060008060006080868803121561241557600080fd5b85356124208161228b565b945060208601356124308161228b565b935060408601359250606086013567ffffffffffffffff81111561245357600080fd5b61245f888289016122b0565b969995985093965092949392505050565b60008060008060006080868803121561248857600080fd5b85356124938161228b565b9450602086013593506124a860408701612391565b9250606086013567ffffffffffffffff81111561245357600080fd5b600080600080600080600060c0888a0312156124df57600080fd5b87356124ea8161228b565b965060208801356124fa8161228b565b9550604088013561250a8161228b565b94506060880135935061251f60808901612391565b925060a088013567ffffffffffffffff81111561237257600080fd5b60005b8381101561255657818101518382015260200161253e565b838111156111ea5750506000910152565b6000815180845261257f81602086016020860161253b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611d276020830184612567565b60008060008060008060a087890312156125dd57600080fd5b86356125e88161228b565b955060208701356125f88161228b565b94506040870135935061260d60608801612391565b9250608087013567ffffffffffffffff81111561262957600080fd5b61263589828a016122b0565b979a9699509497509295939492505050565b6000806040838503121561265a57600080fd5b82356126658161228b565b915060208301356126758161228b565b809150509250929050565b6000806000806060858703121561269657600080fd5b84356126a18161228b565b93506126af60208601612391565b9250604085013567ffffffffffffffff8111156126cb57600080fd5b6126d7878288016122b0565b95989497509550505050565b6000602082840312156126f557600080fd5b8151611d278161228b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561274157612741612700565b500390565b6000845161275881846020890161253b565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551612794816001850160208a0161253b565b600192019182015283516127af81600284016020880161253b565b0160020195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526127fb6080830184612567565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006128346060830185612567565b905063ffffffff83166040830152949350505050565b6000821982111561285d5761285d612700565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a08301526128b160c0830184612567565b98975050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681528260208201526060604082015260006128f26060830184612567565b95945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361292c5761292c612700565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261297157612971612933565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000826129b4576129b4612933565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156129fa57600080fd5b81518015158114611d2757600080fd5b828152604060208201526000611b766040830184612567565b60008251612a3581846020870161253b565b919091019291505056fea164736f6c634300080f000a",
Bin: "0x6101206040523480156200001257600080fd5b5060405162002c0638038062002c0683398101604081905262000035916200006f565b7342000000000000000000000000000000000000076080526001600160a01b031660a052600160c081905260e052600061010052620000a1565b6000602082840312156200008257600080fd5b81516001600160a01b03811681146200009a57600080fd5b9392505050565b60805160a05160c05160e05161010051612ac5620001416000396000610fd201526000610fa901526000610f800152600081816102280152818161030c0152818161050b015281816109cf015281816112ca015261160b015260008181610281015281816103a6015281816104e101528181610542015281816109a501528181610a0601528181610c930152818161128d01526115cf0152612ac56000f3fe6080604052600436106100ec5760003560e01c806354fd4d501161008a5780638f601f66116100595780638f601f661461034e578063927ede2d14610394578063a3a79548146103c8578063e11013dd146103db57600080fd5b806354fd4d50146102c5578063662a633a146102e75780637f46ddb2146102fa578063870876231461032e57600080fd5b806332b7006d116100c657806332b7006d1461020657806336c717c1146102195780633cb747bf14610272578063540abf73146102a557600080fd5b80630166a07a146101c057806309fc8843146101e05780631635f5fd146101f357600080fd5b366101bb57333b15610185576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b6101b973deaddeaddeaddeaddeaddeaddeaddeaddead000033333462030d40604051806020016040528060008152506103ee565b005b600080fd5b3480156101cc57600080fd5b506101b96101db366004612372565b6104c9565b6101b96101ee366004612423565b6108b6565b6101b9610201366004612476565b61098d565b6101b96102143660046124e9565b610e5a565b34801561022557600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561027e57600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610248565b3480156102b157600080fd5b506101b96102c036600461253d565b610f34565b3480156102d157600080fd5b506102da610f79565b604051610269919061262a565b6101b96102f5366004612372565b61101c565b34801561030657600080fd5b506102487f000000000000000000000000000000000000000000000000000000000000000081565b34801561033a57600080fd5b506101b961034936600461263d565b61108f565b34801561035a57600080fd5b506103866103693660046126c0565b600260209081526000928352604080842090915290825290205481565b604051908152602001610269565b3480156103a057600080fd5b506102487f000000000000000000000000000000000000000000000000000000000000000081565b6101b96103d636600461263d565b611163565b6101b96103e93660046126f9565b6111a7565b7fffffffffffffffffffffffff215221522152215221522152215221522153000073ffffffffffffffffffffffffffffffffffffffff87160161043d5761043885858585856111f0565b6104c1565b60008673ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ae919061275c565b90506104bf878288888888886113d4565b505b505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156105e757507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105cf919061275c565b73ffffffffffffffffffffffffffffffffffffffff16145b610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a40161017c565b6106a28761171b565b156107f0576106b1878761177d565b610763576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a40161017c565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156107d357600080fd5b505af11580156107e7573d6000803e3d6000fd5b50505050610872565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461082e9084906127a8565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c168352939052919091209190915561087290858561189d565b6104bf878787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061197192505050565b333b15610945576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b6109883333348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111f092505050565b505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015610aab57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a93919061275c565b73ffffffffffffffffffffffffffffffffffffffff16145b610b5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a40161017c565b823414610bec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e74207265717569726564000000000000606482015260840161017c565b3073ffffffffffffffffffffffffffffffffffffffff851603610c91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c660000000000000000000000000000000000000000000000000000000000606482015260840161017c565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610d6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e676572000000000000000000000000000000000000000000000000606482015260840161017c565b610dae85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506119ff92505050565b6000610dcb855a8660405180602001604052806000815250611aa0565b9050806104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c65640000000000000000000000000000000000000000000000000000000000606482015260840161017c565b333b15610ee9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b610f2d853333878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ee92505050565b5050505050565b6104bf87873388888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506113d492505050565b6060610fa47f0000000000000000000000000000000000000000000000000000000000000000611aba565b610fcd7f0000000000000000000000000000000000000000000000000000000000000000611aba565b610ff67f0000000000000000000000000000000000000000000000000000000000000000611aba565b604051602001611008939291906127bf565b604051602081830303815290604052905090565b73ffffffffffffffffffffffffffffffffffffffff8716158015611069575073ffffffffffffffffffffffffffffffffffffffff861673deaddeaddeaddeaddeaddeaddeaddeaddead0000145b156110805761107b858585858561098d565b6104bf565b6104bf868887878787876104c9565b333b1561111e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b6104c186863333888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506113d492505050565b6104c1863387878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ee92505050565b6111ea3385348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111f092505050565b50505050565b82341461127f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c75650000606482015260840161017c565b61128b85858584611bf7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b847f0000000000000000000000000000000000000000000000000000000000000000631635f5fd60e01b898989886040516024016113089493929190612835565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261139b9291889060040161287e565b6000604051808303818588803b1580156113b457600080fd5b505af11580156113c8573d6000803e3d6000fd5b50505050505050505050565b6113dd8761171b565b1561152b576113ec878761177d565b61149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a40161017c565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b15801561150e57600080fd5b505af1158015611522573d6000803e3d6000fd5b505050506115bf565b61154d73ffffffffffffffffffffffffffffffffffffffff8816863086611c98565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461158b9084906128c3565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b6115cd878787878786611cf6565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b7f0000000000000000000000000000000000000000000000000000000000000000630166a07a60e01b898b8a8a8a8960405160240161164d969594939291906128db565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b90921682526116e09291879060040161287e565b600060405180830381600087803b1580156116fa57600080fd5b505af115801561170e573d6000803e3d6000fd5b5050505050505050505050565b6000611747827f1d1d8b6300000000000000000000000000000000000000000000000000000000611d84565b806117775750611777827fec4fc8e300000000000000000000000000000000000000000000000000000000611d84565b92915050565b60006117a9837f1d1d8b6300000000000000000000000000000000000000000000000000000000611d84565b15611852578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181d919061275c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611777565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117f9573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109889084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611da7565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd898686866040516119e993929190612936565b60405180910390a46104c1868686868686611eb3565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89868686604051611a8c93929190612936565b60405180910390a46111ea84848484611f3b565b600080600080845160208601878a8af19695505050505050565b606081600003611afd57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611b275780611b1181612974565b9150611b209050600a836129db565b9150611b01565b60008167ffffffffffffffff811115611b4257611b426129ef565b6040519080825280601f01601f191660200182016040528015611b6c576020820181803683370190505b5090505b8415611bef57611b816001836127a8565b9150611b8e600a86612a1e565b611b999060306128c3565b60f81b818381518110611bae57611bae612a32565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611be8600a866129db565b9450611b70565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611c8493929190612936565b60405180910390a46111ea84848484611fa8565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526111ea9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016118ef565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611d6e93929190612936565b60405180910390a46104c1868686868686612007565b6000611d8f8361207f565b8015611da05750611da083836120e3565b9392505050565b6000611e09826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121b29092919063ffffffff16565b8051909150156109885780806020019051810190611e279190612a61565b610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161017c565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611f2b93929190612936565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611f9a929190612a83565b60405180910390a350505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611f9a929190612a83565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611f2b93929190612936565b60006120ab827f01ffc9a7000000000000000000000000000000000000000000000000000000006120e3565b801561177757506120dc827fffffffff000000000000000000000000000000000000000000000000000000006120e3565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561219b575060208210155b80156121a75750600081115b979650505050505050565b6060611bef84846000858573ffffffffffffffffffffffffffffffffffffffff85163b61223b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161017c565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516122649190612a9c565b60006040518083038185875af1925050503d80600081146122a1576040519150601f19603f3d011682016040523d82523d6000602084013e6122a6565b606091505b50915091506121a7828286606083156122c0575081611da0565b8251156122d05782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017c919061262a565b73ffffffffffffffffffffffffffffffffffffffff8116811461232657600080fd5b50565b60008083601f84011261233b57600080fd5b50813567ffffffffffffffff81111561235357600080fd5b60208301915083602082850101111561236b57600080fd5b9250929050565b600080600080600080600060c0888a03121561238d57600080fd5b873561239881612304565b965060208801356123a881612304565b955060408801356123b881612304565b945060608801356123c881612304565b93506080880135925060a088013567ffffffffffffffff8111156123eb57600080fd5b6123f78a828b01612329565b989b979a50959850939692959293505050565b803563ffffffff8116811461241e57600080fd5b919050565b60008060006040848603121561243857600080fd5b6124418461240a565b9250602084013567ffffffffffffffff81111561245d57600080fd5b61246986828701612329565b9497909650939450505050565b60008060008060006080868803121561248e57600080fd5b853561249981612304565b945060208601356124a981612304565b935060408601359250606086013567ffffffffffffffff8111156124cc57600080fd5b6124d888828901612329565b969995985093965092949392505050565b60008060008060006080868803121561250157600080fd5b853561250c81612304565b9450602086013593506125216040870161240a565b9250606086013567ffffffffffffffff8111156124cc57600080fd5b600080600080600080600060c0888a03121561255857600080fd5b873561256381612304565b9650602088013561257381612304565b9550604088013561258381612304565b9450606088013593506125986080890161240a565b925060a088013567ffffffffffffffff8111156123eb57600080fd5b60005b838110156125cf5781810151838201526020016125b7565b838111156111ea5750506000910152565b600081518084526125f88160208601602086016125b4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611da060208301846125e0565b60008060008060008060a0878903121561265657600080fd5b863561266181612304565b9550602087013561267181612304565b9450604087013593506126866060880161240a565b9250608087013567ffffffffffffffff8111156126a257600080fd5b6126ae89828a01612329565b979a9699509497509295939492505050565b600080604083850312156126d357600080fd5b82356126de81612304565b915060208301356126ee81612304565b809150509250929050565b6000806000806060858703121561270f57600080fd5b843561271a81612304565b93506127286020860161240a565b9250604085013567ffffffffffffffff81111561274457600080fd5b61275087828801612329565b95989497509550505050565b60006020828403121561276e57600080fd5b8151611da081612304565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156127ba576127ba612779565b500390565b600084516127d18184602089016125b4565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855161280d816001850160208a016125b4565b600192019182015283516128288160028401602088016125b4565b0160020195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261287460808301846125e0565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006128ad60608301856125e0565b905063ffffffff83166040830152949350505050565b600082198211156128d6576128d6612779565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a083015261292a60c08301846125e0565b98975050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061296b60608301846125e0565b95945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036129a5576129a5612779565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826129ea576129ea6129ac565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082612a2d57612a2d6129ac565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215612a7357600080fd5b81518015158114611da057600080fd5b828152604060208201526000611bef60408301846125e0565b60008251612aae8184602087016125b4565b919091019291505056fea164736f6c634300080f000a",
}
// L2StandardBridgeABI is the input ABI used to generate the binding from.
......
......@@ -13,7 +13,7 @@ const L2StandardBridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contr
var L2StandardBridgeStorageLayout = new(solc.StorageLayout)
var L2StandardBridgeDeployedBin = "0x6080604052600436106100ec5760003560e01c806354fd4d501161008a5780638f601f66116100595780638f601f661461034e578063927ede2d14610394578063a3a79548146103c8578063e11013dd146103db57600080fd5b806354fd4d50146102c5578063662a633a146102e75780637f46ddb2146102fa578063870876231461032e57600080fd5b806332b7006d116100c657806332b7006d1461020657806336c717c1146102195780633cb747bf14610272578063540abf73146102a557600080fd5b80630166a07a146101c057806309fc8843146101e05780631635f5fd146101f357600080fd5b366101bb57333b15610185576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b6101b973deaddeaddeaddeaddeaddeaddeaddeaddead000033333462030d40604051806020016040528060008152506103ee565b005b600080fd5b3480156101cc57600080fd5b506101b96101db3660046122f9565b6104c9565b6101b96101ee3660046123aa565b6108b6565b6101b96102013660046123fd565b61098d565b6101b9610214366004612470565b610e5a565b34801561022557600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561027e57600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610248565b3480156102b157600080fd5b506101b96102c03660046124c4565b610f34565b3480156102d157600080fd5b506102da610f79565b60405161026991906125b1565b6101b96102f53660046122f9565b61101c565b34801561030657600080fd5b506102487f000000000000000000000000000000000000000000000000000000000000000081565b34801561033a57600080fd5b506101b96103493660046125c4565b61108f565b34801561035a57600080fd5b50610386610369366004612647565b600260209081526000928352604080842090915290825290205481565b604051908152602001610269565b3480156103a057600080fd5b506102487f000000000000000000000000000000000000000000000000000000000000000081565b6101b96103d63660046125c4565b611163565b6101b96103e9366004612680565b6111a7565b7fffffffffffffffffffffffff215221522152215221522152215221522153000073ffffffffffffffffffffffffffffffffffffffff87160161043d5761043885858585856111f0565b6104c1565b60008673ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ae91906126e3565b90506104bf878288888888886113d4565b505b505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156105e757507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105cf91906126e3565b73ffffffffffffffffffffffffffffffffffffffff16145b610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a40161017c565b6106a28761171b565b156107f0576106b1878761177d565b610763576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a40161017c565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156107d357600080fd5b505af11580156107e7573d6000803e3d6000fd5b50505050610872565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461082e90849061272f565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c1683529390529190912091909155610872908585611824565b6104bf878787878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118f892505050565b333b15610945576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b6109883333348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111f092505050565b505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015610aab57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9391906126e3565b73ffffffffffffffffffffffffffffffffffffffff16145b610b5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a40161017c565b823414610bec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e74207265717569726564000000000000606482015260840161017c565b3073ffffffffffffffffffffffffffffffffffffffff851603610c91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c660000000000000000000000000000000000000000000000000000000000606482015260840161017c565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610d6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e676572000000000000000000000000000000000000000000000000606482015260840161017c565b610dae85858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061198692505050565b6000610dcb855a8660405180602001604052806000815250611a27565b9050806104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c65640000000000000000000000000000000000000000000000000000000000606482015260840161017c565b333b15610ee9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b610f2d853333878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ee92505050565b5050505050565b6104bf87873388888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506113d492505050565b6060610fa47f0000000000000000000000000000000000000000000000000000000000000000611a41565b610fcd7f0000000000000000000000000000000000000000000000000000000000000000611a41565b610ff67f0000000000000000000000000000000000000000000000000000000000000000611a41565b60405160200161100893929190612746565b604051602081830303815290604052905090565b73ffffffffffffffffffffffffffffffffffffffff8716158015611069575073ffffffffffffffffffffffffffffffffffffffff861673deaddeaddeaddeaddeaddeaddeaddeaddead0000145b156110805761107b858585858561098d565b6104bf565b6104bf868887878787876104c9565b333b1561111e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b6104c186863333888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506113d492505050565b6104c1863387878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ee92505050565b6111ea3385348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111f092505050565b50505050565b82341461127f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c75650000606482015260840161017c565b61128b85858584611b7e565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b847f0000000000000000000000000000000000000000000000000000000000000000631635f5fd60e01b8989898860405160240161130894939291906127bc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261139b92918890600401612805565b6000604051808303818588803b1580156113b457600080fd5b505af11580156113c8573d6000803e3d6000fd5b50505050505050505050565b6113dd8761171b565b1561152b576113ec878761177d565b61149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a40161017c565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b15801561150e57600080fd5b505af1158015611522573d6000803e3d6000fd5b505050506115bf565b61154d73ffffffffffffffffffffffffffffffffffffffff8816863086611c1f565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461158b90849061284a565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b6115cd878787878786611c7d565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b7f0000000000000000000000000000000000000000000000000000000000000000630166a07a60e01b898b8a8a8a8960405160240161164d96959493929190612862565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b90921682526116e092918790600401612805565b600060405180830381600087803b1580156116fa57600080fd5b505af115801561170e573d6000803e3d6000fd5b5050505050505050505050565b6000611747827f1d1d8b6300000000000000000000000000000000000000000000000000000000611d0b565b806117775750611777827fec4fc8e300000000000000000000000000000000000000000000000000000000611d0b565b92915050565b60008273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ee91906126e3565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905092915050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109889084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611d2e565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89868686604051611970939291906128bd565b60405180910390a46104c1868686868686611e3a565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89868686604051611a13939291906128bd565b60405180910390a46111ea84848484611ec2565b600080600080845160208601878a8af19695505050505050565b606081600003611a8457505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611aae5780611a98816128fb565b9150611aa79050600a83612962565b9150611a88565b60008167ffffffffffffffff811115611ac957611ac9612976565b6040519080825280601f01601f191660200182016040528015611af3576020820181803683370190505b5090505b8415611b7657611b0860018361272f565b9150611b15600a866129a5565b611b2090603061284a565b60f81b818381518110611b3557611b356129b9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611b6f600a86612962565b9450611af7565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611c0b939291906128bd565b60405180910390a46111ea84848484611f2f565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526111ea9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611876565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611cf5939291906128bd565b60405180910390a46104c1868686868686611f8e565b6000611d1683612006565b8015611d275750611d27838361206a565b9392505050565b6000611d90826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121399092919063ffffffff16565b8051909150156109885780806020019051810190611dae91906129e8565b610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161017c565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611eb2939291906128bd565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611f21929190612a0a565b60405180910390a350505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611f21929190612a0a565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611eb2939291906128bd565b6000612032827f01ffc9a70000000000000000000000000000000000000000000000000000000061206a565b80156117775750612063827fffffffff0000000000000000000000000000000000000000000000000000000061206a565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015612122575060208210155b801561212e5750600081115b979650505050505050565b6060611b7684846000858573ffffffffffffffffffffffffffffffffffffffff85163b6121c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161017c565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516121eb9190612a23565b60006040518083038185875af1925050503d8060008114612228576040519150601f19603f3d011682016040523d82523d6000602084013e61222d565b606091505b509150915061212e82828660608315612247575081611d27565b8251156122575782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017c91906125b1565b73ffffffffffffffffffffffffffffffffffffffff811681146122ad57600080fd5b50565b60008083601f8401126122c257600080fd5b50813567ffffffffffffffff8111156122da57600080fd5b6020830191508360208285010111156122f257600080fd5b9250929050565b600080600080600080600060c0888a03121561231457600080fd5b873561231f8161228b565b9650602088013561232f8161228b565b9550604088013561233f8161228b565b9450606088013561234f8161228b565b93506080880135925060a088013567ffffffffffffffff81111561237257600080fd5b61237e8a828b016122b0565b989b979a50959850939692959293505050565b803563ffffffff811681146123a557600080fd5b919050565b6000806000604084860312156123bf57600080fd5b6123c884612391565b9250602084013567ffffffffffffffff8111156123e457600080fd5b6123f0868287016122b0565b9497909650939450505050565b60008060008060006080868803121561241557600080fd5b85356124208161228b565b945060208601356124308161228b565b935060408601359250606086013567ffffffffffffffff81111561245357600080fd5b61245f888289016122b0565b969995985093965092949392505050565b60008060008060006080868803121561248857600080fd5b85356124938161228b565b9450602086013593506124a860408701612391565b9250606086013567ffffffffffffffff81111561245357600080fd5b600080600080600080600060c0888a0312156124df57600080fd5b87356124ea8161228b565b965060208801356124fa8161228b565b9550604088013561250a8161228b565b94506060880135935061251f60808901612391565b925060a088013567ffffffffffffffff81111561237257600080fd5b60005b8381101561255657818101518382015260200161253e565b838111156111ea5750506000910152565b6000815180845261257f81602086016020860161253b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611d276020830184612567565b60008060008060008060a087890312156125dd57600080fd5b86356125e88161228b565b955060208701356125f88161228b565b94506040870135935061260d60608801612391565b9250608087013567ffffffffffffffff81111561262957600080fd5b61263589828a016122b0565b979a9699509497509295939492505050565b6000806040838503121561265a57600080fd5b82356126658161228b565b915060208301356126758161228b565b809150509250929050565b6000806000806060858703121561269657600080fd5b84356126a18161228b565b93506126af60208601612391565b9250604085013567ffffffffffffffff8111156126cb57600080fd5b6126d7878288016122b0565b95989497509550505050565b6000602082840312156126f557600080fd5b8151611d278161228b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561274157612741612700565b500390565b6000845161275881846020890161253b565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551612794816001850160208a0161253b565b600192019182015283516127af81600284016020880161253b565b0160020195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526127fb6080830184612567565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006128346060830185612567565b905063ffffffff83166040830152949350505050565b6000821982111561285d5761285d612700565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a08301526128b160c0830184612567565b98975050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681528260208201526060604082015260006128f26060830184612567565b95945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361292c5761292c612700565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261297157612971612933565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000826129b4576129b4612933565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156129fa57600080fd5b81518015158114611d2757600080fd5b828152604060208201526000611b766040830184612567565b60008251612a3581846020870161253b565b919091019291505056fea164736f6c634300080f000a"
var L2StandardBridgeDeployedBin = "0x6080604052600436106100ec5760003560e01c806354fd4d501161008a5780638f601f66116100595780638f601f661461034e578063927ede2d14610394578063a3a79548146103c8578063e11013dd146103db57600080fd5b806354fd4d50146102c5578063662a633a146102e75780637f46ddb2146102fa578063870876231461032e57600080fd5b806332b7006d116100c657806332b7006d1461020657806336c717c1146102195780633cb747bf14610272578063540abf73146102a557600080fd5b80630166a07a146101c057806309fc8843146101e05780631635f5fd146101f357600080fd5b366101bb57333b15610185576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b6101b973deaddeaddeaddeaddeaddeaddeaddeaddead000033333462030d40604051806020016040528060008152506103ee565b005b600080fd5b3480156101cc57600080fd5b506101b96101db366004612372565b6104c9565b6101b96101ee366004612423565b6108b6565b6101b9610201366004612476565b61098d565b6101b96102143660046124e9565b610e5a565b34801561022557600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561027e57600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610248565b3480156102b157600080fd5b506101b96102c036600461253d565b610f34565b3480156102d157600080fd5b506102da610f79565b604051610269919061262a565b6101b96102f5366004612372565b61101c565b34801561030657600080fd5b506102487f000000000000000000000000000000000000000000000000000000000000000081565b34801561033a57600080fd5b506101b961034936600461263d565b61108f565b34801561035a57600080fd5b506103866103693660046126c0565b600260209081526000928352604080842090915290825290205481565b604051908152602001610269565b3480156103a057600080fd5b506102487f000000000000000000000000000000000000000000000000000000000000000081565b6101b96103d636600461263d565b611163565b6101b96103e93660046126f9565b6111a7565b7fffffffffffffffffffffffff215221522152215221522152215221522153000073ffffffffffffffffffffffffffffffffffffffff87160161043d5761043885858585856111f0565b6104c1565b60008673ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ae919061275c565b90506104bf878288888888886113d4565b505b505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480156105e757507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105cf919061275c565b73ffffffffffffffffffffffffffffffffffffffff16145b610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a40161017c565b6106a28761171b565b156107f0576106b1878761177d565b610763576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a40161017c565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156107d357600080fd5b505af11580156107e7573d6000803e3d6000fd5b50505050610872565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461082e9084906127a8565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c168352939052919091209190915561087290858561189d565b6104bf878787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061197192505050565b333b15610945576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b6109883333348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111f092505050565b505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015610aab57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a93919061275c565b73ffffffffffffffffffffffffffffffffffffffff16145b610b5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a40161017c565b823414610bec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e74207265717569726564000000000000606482015260840161017c565b3073ffffffffffffffffffffffffffffffffffffffff851603610c91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c660000000000000000000000000000000000000000000000000000000000606482015260840161017c565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610d6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e676572000000000000000000000000000000000000000000000000606482015260840161017c565b610dae85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506119ff92505050565b6000610dcb855a8660405180602001604052806000815250611aa0565b9050806104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c65640000000000000000000000000000000000000000000000000000000000606482015260840161017c565b333b15610ee9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b610f2d853333878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ee92505050565b5050505050565b6104bf87873388888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506113d492505050565b6060610fa47f0000000000000000000000000000000000000000000000000000000000000000611aba565b610fcd7f0000000000000000000000000000000000000000000000000000000000000000611aba565b610ff67f0000000000000000000000000000000000000000000000000000000000000000611aba565b604051602001611008939291906127bf565b604051602081830303815290604052905090565b73ffffffffffffffffffffffffffffffffffffffff8716158015611069575073ffffffffffffffffffffffffffffffffffffffff861673deaddeaddeaddeaddeaddeaddeaddeaddead0000145b156110805761107b858585858561098d565b6104bf565b6104bf868887878787876104c9565b333b1561111e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b6104c186863333888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506113d492505050565b6104c1863387878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ee92505050565b6111ea3385348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111f092505050565b50505050565b82341461127f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c75650000606482015260840161017c565b61128b85858584611bf7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b847f0000000000000000000000000000000000000000000000000000000000000000631635f5fd60e01b898989886040516024016113089493929190612835565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261139b9291889060040161287e565b6000604051808303818588803b1580156113b457600080fd5b505af11580156113c8573d6000803e3d6000fd5b50505050505050505050565b6113dd8761171b565b1561152b576113ec878761177d565b61149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a40161017c565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b15801561150e57600080fd5b505af1158015611522573d6000803e3d6000fd5b505050506115bf565b61154d73ffffffffffffffffffffffffffffffffffffffff8816863086611c98565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461158b9084906128c3565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b6115cd878787878786611cf6565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633dbb202b7f0000000000000000000000000000000000000000000000000000000000000000630166a07a60e01b898b8a8a8a8960405160240161164d969594939291906128db565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b90921682526116e09291879060040161287e565b600060405180830381600087803b1580156116fa57600080fd5b505af115801561170e573d6000803e3d6000fd5b5050505050505050505050565b6000611747827f1d1d8b6300000000000000000000000000000000000000000000000000000000611d84565b806117775750611777827fec4fc8e300000000000000000000000000000000000000000000000000000000611d84565b92915050565b60006117a9837f1d1d8b6300000000000000000000000000000000000000000000000000000000611d84565b15611852578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181d919061275c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611777565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117f9573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109889084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611da7565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd898686866040516119e993929190612936565b60405180910390a46104c1868686868686611eb3565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89868686604051611a8c93929190612936565b60405180910390a46111ea84848484611f3b565b600080600080845160208601878a8af19695505050505050565b606081600003611afd57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611b275780611b1181612974565b9150611b209050600a836129db565b9150611b01565b60008167ffffffffffffffff811115611b4257611b426129ef565b6040519080825280601f01601f191660200182016040528015611b6c576020820181803683370190505b5090505b8415611bef57611b816001836127a8565b9150611b8e600a86612a1e565b611b999060306128c3565b60f81b818381518110611bae57611bae612a32565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611be8600a866129db565b9450611b70565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611c8493929190612936565b60405180910390a46111ea84848484611fa8565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526111ea9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016118ef565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611d6e93929190612936565b60405180910390a46104c1868686868686612007565b6000611d8f8361207f565b8015611da05750611da083836120e3565b9392505050565b6000611e09826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121b29092919063ffffffff16565b8051909150156109885780806020019051810190611e279190612a61565b610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161017c565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611f2b93929190612936565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611f9a929190612a83565b60405180910390a350505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611f9a929190612a83565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611f2b93929190612936565b60006120ab827f01ffc9a7000000000000000000000000000000000000000000000000000000006120e3565b801561177757506120dc827fffffffff000000000000000000000000000000000000000000000000000000006120e3565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561219b575060208210155b80156121a75750600081115b979650505050505050565b6060611bef84846000858573ffffffffffffffffffffffffffffffffffffffff85163b61223b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161017c565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516122649190612a9c565b60006040518083038185875af1925050503d80600081146122a1576040519150601f19603f3d011682016040523d82523d6000602084013e6122a6565b606091505b50915091506121a7828286606083156122c0575081611da0565b8251156122d05782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017c919061262a565b73ffffffffffffffffffffffffffffffffffffffff8116811461232657600080fd5b50565b60008083601f84011261233b57600080fd5b50813567ffffffffffffffff81111561235357600080fd5b60208301915083602082850101111561236b57600080fd5b9250929050565b600080600080600080600060c0888a03121561238d57600080fd5b873561239881612304565b965060208801356123a881612304565b955060408801356123b881612304565b945060608801356123c881612304565b93506080880135925060a088013567ffffffffffffffff8111156123eb57600080fd5b6123f78a828b01612329565b989b979a50959850939692959293505050565b803563ffffffff8116811461241e57600080fd5b919050565b60008060006040848603121561243857600080fd5b6124418461240a565b9250602084013567ffffffffffffffff81111561245d57600080fd5b61246986828701612329565b9497909650939450505050565b60008060008060006080868803121561248e57600080fd5b853561249981612304565b945060208601356124a981612304565b935060408601359250606086013567ffffffffffffffff8111156124cc57600080fd5b6124d888828901612329565b969995985093965092949392505050565b60008060008060006080868803121561250157600080fd5b853561250c81612304565b9450602086013593506125216040870161240a565b9250606086013567ffffffffffffffff8111156124cc57600080fd5b600080600080600080600060c0888a03121561255857600080fd5b873561256381612304565b9650602088013561257381612304565b9550604088013561258381612304565b9450606088013593506125986080890161240a565b925060a088013567ffffffffffffffff8111156123eb57600080fd5b60005b838110156125cf5781810151838201526020016125b7565b838111156111ea5750506000910152565b600081518084526125f88160208601602086016125b4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611da060208301846125e0565b60008060008060008060a0878903121561265657600080fd5b863561266181612304565b9550602087013561267181612304565b9450604087013593506126866060880161240a565b9250608087013567ffffffffffffffff8111156126a257600080fd5b6126ae89828a01612329565b979a9699509497509295939492505050565b600080604083850312156126d357600080fd5b82356126de81612304565b915060208301356126ee81612304565b809150509250929050565b6000806000806060858703121561270f57600080fd5b843561271a81612304565b93506127286020860161240a565b9250604085013567ffffffffffffffff81111561274457600080fd5b61275087828801612329565b95989497509550505050565b60006020828403121561276e57600080fd5b8151611da081612304565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156127ba576127ba612779565b500390565b600084516127d18184602089016125b4565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855161280d816001850160208a016125b4565b600192019182015283516128288160028401602088016125b4565b0160020195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261287460808301846125e0565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006128ad60608301856125e0565b905063ffffffff83166040830152949350505050565b600082198211156128d6576128d6612779565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a083015261292a60c08301846125e0565b98975050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061296b60608301846125e0565b95945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036129a5576129a5612779565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826129ea576129ea6129ac565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082612a2d57612a2d6129ac565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215612a7357600080fd5b81518015158114611da057600080fd5b828152604060208201526000611bef60408301846125e0565b60008251612aae8184602087016125b4565b919091019291505056fea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(L2StandardBridgeStorageLayoutJSON), L2StandardBridgeStorageLayout); err != nil {
......
......@@ -49,7 +49,7 @@ type TypesWithdrawalTransaction struct {
// OptimismPortalMetaData contains all meta data concerning the OptimismPortal contract.
var OptimismPortalMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"_l2Oracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_guardian\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_paused\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"opaqueData\",\"type\":\"bytes\"}],\"name\":\"TransactionDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"WithdrawalFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"WithdrawalProven\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_FEE_MAX_CHANGE_DENOMINATOR\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ELASTICITY_MULTIPLIER\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"GUARDIAN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIAL_BASE_FEE\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_ORACLE\",\"outputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAXIMUM_BASE_FEE\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_RESOURCE_LIMIT\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINIMUM_BASE_FEE\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TARGET_RESOURCE_LIMIT\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"_gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"_isCreation\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"depositTransaction\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"donateETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structTypes.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\"}],\"name\":\"finalizeWithdrawalTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"finalizedWithdrawals\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_paused\",\"type\":\"bool\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"name\":\"isOutputFinalized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2Sender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"params\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"prevBaseFee\",\"type\":\"uint128\"},{\"internalType\":\"uint64\",\"name\":\"prevBoughtGas\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"prevBlockNum\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structTypes.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"messagePasserStorageRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"latestBlockhash\",\"type\":\"bytes32\"}],\"internalType\":\"structTypes.OutputRootProof\",\"name\":\"_outputRootProof\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"_withdrawalProof\",\"type\":\"bytes[]\"}],\"name\":\"proveWithdrawalTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"provenWithdrawals\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2OutputIndex\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
Bin: "0x6101206040523480156200001257600080fd5b506040516200596f3803806200596f83398101604081905262000035916200028e565b6001608052600260a052600060c0526001600160a01b0380841660e05282166101005262000063816200006c565b505050620002e6565b600054610100900460ff16158080156200008d5750600054600160ff909116105b80620000bd5750620000aa30620001c360201b6200205e1760201c565b158015620000bd575060005460ff166001145b620001265760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff1916600117905580156200014a576000805461ff0019166101001790555b603280546001600160a01b03191661dead1790556035805483151560ff1990911617905562000178620001d2565b8015620001bf576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03163b151590565b600054610100900460ff166200023f5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016200011d565b60408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b0217600155565b6001600160a01b03811681146200028b57600080fd5b50565b600080600060608486031215620002a457600080fd5b8351620002b18162000275565b6020850151909350620002c48162000275565b60408501519092508015158114620002db57600080fd5b809150509250925092565b60805160a05160c05160e0516101005161560c620003636000396000818161035701528181610ad201526113d50152600081816101c101528181610d3b01528181610f1c01528181611331015281816116eb0152818161195d01526123240152600061129c015260006112730152600061124a015261560c6000f3fe6080604052600436106101835760003560e01c80638456cb59116100d6578063ca3e99ba1161007f578063d53a822f11610059578063d53a822f146104ec578063e965084c1461050c578063e9e05c421461059857600080fd5b8063ca3e99ba14610421578063cd7c978914610436578063cff0ab961461044b57600080fd5b80638c3152e9116100b05780638c3152e9146103a45780639bf62d82146103c4578063a14238e7146103f157600080fd5b80638456cb5914610379578063867ead131461038e5780638b4c40b0146101a857600080fd5b80635c1f2827116101385780636bb0291e116101125780636bb0291e146103105780636dbffb7814610325578063724c184c1461034557600080fd5b80635c1f28271461029d5780635c975abb146102cf57806364b79208146102f957600080fd5b80633f4ba83a116101695780633f4ba83a146102465780634870496f1461025b57806354fd4d501461027b57600080fd5b80621c2ff6146101af57806313620abd1461020d57600080fd5b366101aa576101a83334620186a06000604051806020016040528060008152506105a6565b005b600080fd5b3480156101bb57600080fd5b506101e37f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561021957600080fd5b50610225633b9aca0081565b6040516fffffffffffffffffffffffffffffffff9091168152602001610204565b34801561025257600080fd5b506101a8610aba565b34801561026757600080fd5b506101a8610276366004614ca1565b610bdd565b34801561028757600080fd5b50610290611243565b6040516102049190614df7565b3480156102a957600080fd5b506102c16fffffffffffffffffffffffffffffffff81565b604051908152602001610204565b3480156102db57600080fd5b506035546102e99060ff1681565b6040519015158152602001610204565b34801561030557600080fd5b506102c1627a120081565b34801561031c57600080fd5b506102c1600481565b34801561033157600080fd5b506102e9610340366004614e0a565b6112e6565b34801561035157600080fd5b506101e37f000000000000000000000000000000000000000000000000000000000000000081565b34801561038557600080fd5b506101a86113bd565b34801561039a57600080fd5b506102c161271081565b3480156103b057600080fd5b506101a86103bf366004614e23565b6114dd565b3480156103d057600080fd5b506032546101e39073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103fd57600080fd5b506102e961040c366004614e0a565b60336020526000908152604090205460ff1681565b34801561042d57600080fd5b506102c1611e60565b34801561044257600080fd5b506102c1600881565b34801561045757600080fd5b506001546104b3906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff9283166020850152911690820152606001610204565b3480156104f857600080fd5b506101a8610507366004614e68565b611e71565b34801561051857600080fd5b5061056a610527366004614e0a565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff9283166020850152911690820152606001610204565b6101a86105a6366004614e83565b8260005a9050831561065d5773ffffffffffffffffffffffffffffffffffffffff87161561065d57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6152088567ffffffffffffffff1610156106f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4f7074696d69736d506f7274616c3a20676173206c696d6974206d757374206360448201527f6f76657220696e737472696e7369632067617320636f737400000000000000006064820152608401610654565b3332811461071a575033731111000000000000000000000000000000001111015b60003488888888604051602001610735959493929190614f08565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516107a59190614df7565b60405180910390a450506001546000906107e5907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f9c565b905080156109195760006107fd6004627a1200614fe2565b6001546108289190700100000000000000000000000000000000900467ffffffffffffffff1661504a565b90506000600861083c6004627a1200614fe2565b61084691906150be565b6001546108669084906fffffffffffffffffffffffffffffffff166150be565b6108709190614fe2565b6001549091506000906108b39061089a9084906fffffffffffffffffffffffffffffffff1661517a565b6127106fffffffffffffffffffffffffffffffff61207a565b905060018411156108da576108d761089a8260086108d2600189614f9c565b612099565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b6001805484919060109061094c908490700100000000000000000000000000000000900467ffffffffffffffff166151ee565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550627a1200600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315610a28576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d697400006064820152608401610654565b600154600090610a54906fffffffffffffffffffffffffffffffff1667ffffffffffffffff861661521a565b6fffffffffffffffffffffffffffffffff1690506000610a7848633b9aca006120ee565b610a829083615252565b905060005a610a919086614f9c565b905080821115610aad57610aad610aa88284614f9c565b612105565b5050505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610b7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e706175736500000000000000000000000000000000000000000000006064820152608401610654565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff1615610c4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610654565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610d09576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e7472616374006064820152608401610654565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610d97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbb9190615286565b519050610dd5610dd0368690038601866152eb565b612133565b8114610e63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f6600000000000000000000000000000000000000000000006064820152608401610654565b6000610e6e8761218f565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610fa05750805160408083015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610f78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9c9190615286565b5114155b61102c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610654565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506110f59101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f01000000000000000000000000000000000000000000000000000000000000006020830152906110eb888a615351565b8a604001356121bf565b611181576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610654565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b606061126e7f00000000000000000000000000000000000000000000000000000000000000006121e3565b6112977f00000000000000000000000000000000000000000000000000000000000000006121e3565b6112c07f00000000000000000000000000000000000000000000000000000000000000006121e3565b6040516020016112d2939291906153d5565b604051602081830303815290604052905090565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018290526000906113b79073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa158015611378573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139c9190615286565b602001516fffffffffffffffffffffffffffffffff16612320565b92915050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611482576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e207061757365000000000000000000000000000000000000000000000000006064820152608401610654565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610bd3565b60355460ff161561154a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610654565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead146115f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e006064820152608401610654565b60006115fe8261218f565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff808216948301859052700100000000000000000000000000000000909104169181019190915292935090036116e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610654565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa158015611754573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611778919061544b565b81602001516fffffffffffffffffffffffffffffffff161015611843576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610654565b61186281602001516fffffffffffffffffffffffffffffffff16612320565b611914576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610654565b60408181015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156119b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119dd9190615286565b8251815191925014611a97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610654565b611ab681602001516fffffffffffffffffffffffffffffffff16612320565b611b68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610654565b60008381526033602052604090205460ff1615611c07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610654565b600083815260336020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556080840151611c5090614e2090615464565b5a1015611cdf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a20696e73756666696369656e742067617360448201527f20746f2066696e616c697a65207769746864726177616c0000000000000000006064820152608401610654565b6020840151603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790556040840151600090611d5190614e205a611d429190614f9c565b87606001518860a001516123c3565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611db690841515815260200190565b60405180910390a280158015611dcc5750326001145b15611e59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610654565b5050505050565b611e6e6004627a1200614fe2565b81565b600054610100900460ff1615808015611e915750600054600160ff909116105b80611eab5750303b158015611eab575060005460ff166001145b611f37576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610654565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611f9557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055603580548315157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909116179055611ff76123dd565b801561205a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600061208f61208985856124c0565b836124d0565b90505b9392505050565b6000670de0b6b3a76400006120da6120b18583614fe2565b6120c390670de0b6b3a764000061504a565b6120d585670de0b6b3a76400006150be565b6124df565b6120e490866150be565b61208f9190614fe2565b6000818310156120fe5781612092565b5090919050565b6000805a90505b825a6121189083614f9c565b101561212e576121278261547c565b915061210c565b505050565b60008160000151826020015183604001518460600151604051602001612172949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a088015193516000976121729790969591016154b4565b6000806121cb86612510565b90506121d981868686612542565b9695505050505050565b60608160000361222657505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115612250578061223a8161547c565b91506122499050600a83615252565b915061222a565b60008167ffffffffffffffff81111561226b5761226b614ac7565b6040519080825280601f01601f191660200182016040528015612295576020820181803683370190505b5090505b8415612318576122aa600183614f9c565b91506122b7600a8661550b565b6122c2906030615464565b60f81b8183815181106122d7576122d761551f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612311600a86615252565b9450612299565b949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa15801561238d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b1919061544b565b6123bb9083615464565b421192915050565b600080600080845160208601878a8af19695505050505050565b600054610100900460ff16612474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610654565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6000818312156120fe5781612092565b60008183126120fe5781612092565b6000612092670de0b6b3a7640000836124f786612572565b61250191906150be565b61250b9190614fe2565b6127b6565b6060818051906020012060405160200161252c91815260200190565b6040516020818303038152906040529050919050565b6000612569846125538786866129f5565b8051602091820120825192909101919091201490565b95945050505050565b60008082136125dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610654565b600060606125ea8461347d565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136127e757506000919050565b680755bf798b4a1bf1e58212612859576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610654565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b60606000845111612a62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610654565b6000612a6d84613553565b90506000612a7a86613642565b9050600084604051602001612a9191815260200190565b60405160208183030381529060405290506000805b84518110156133f4576000858281518110612ac357612ac361551f565b602002602001015190508451831115612b5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610654565b82600003612c175780518051602091820120604051612bac92612b8692910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610654565b612d6e565b805151602011612ccd5780518051602091820120604051612c4192612b8692910190815260200190565b612c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610654565b805184516020808701919091208251919092012014612d6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610654565b612d7a60106001615464565b81602001515103612f5b5784518303612ef3576000612db68260200151601081518110612da957612da961551f565b60200260200101516137dd565b90506000815111612e49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610654565b60018751612e579190614f9c565b8314612ee5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610654565b965061209295505050505050565b6000858481518110612f0757612f0761551f565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110612f3257612f3261551f565b60200260200101519050612f458161393d565b9550612f52600186615464565b945050506133e1565b600281602001515103613359576000612f7382613962565b9050600081600081518110612f8a57612f8a61551f565b016020015160f81c90506000612fa160028361554e565b612fac906002615570565b90506000612fbd848360ff16613986565b90506000612fcb8a89613986565b90506000612fd983836139bc565b90508083511461306b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610654565b60ff851660021480613080575060ff85166003145b156132745780825114613115576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610654565b60006131318860200151600181518110612da957612da961551f565b905060008151116131c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610654565b60018d516131d29190614f9c565b8914613260576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610654565b9c506120929b505050505050505050505050565b60ff85161580613287575060ff85166001145b156132c6576132b387602001516001815181106132a6576132a661551f565b602002602001015161393d565b99506132bf818a615464565b985061334e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610654565b5050505050506133e1565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610654565b50806133ec8161547c565b915050612aa6565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610654565b60008082116134e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610654565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b805160609060008167ffffffffffffffff81111561357357613573614ac7565b6040519080825280602002602001820160405280156135b857816020015b60408051808201909152606080825260208201528152602001906001900390816135915790505b50905060005b8281101561363a5760405180604001604052808683815181106135e3576135e361551f565b602002602001015181526020016136128784815181106136055761360561551f565b6020026020010151613a6b565b8152508282815181106136275761362761551f565b60209081029190910101526001016135be565b509392505050565b80516060906000613654826002615593565b67ffffffffffffffff81111561366c5761366c614ac7565b6040519080825280601f01601f191660200182016040528015613696576020820181803683370190505b5090506000805b838110156137d3578581815181106136b7576136b761551f565b6020910101517fff000000000000000000000000000000000000000000000000000000000000008116925060041c7f0ff00000000000000000000000000000000000000000000000000000000000001683613713836002615593565b815181106137235761372361551f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f0f00000000000000000000000000000000000000000000000000000000000000821683613781836002615593565b61378c906001615464565b8151811061379c5761379c61551f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060010161369d565b5090949350505050565b606060008060006137ed85613a7e565b919450925090506000816001811115613808576138086155d0565b14613895576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d000000000000006064820152608401610654565b61389f8284615464565b85511461392e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e6465720000000000000000000000006064820152608401610654565b612569856020015184846144eb565b6060602082600001511061395957613954826137dd565b6113b7565b6113b78261458c565b60606113b76139818360200151600081518110612da957612da961551f565b613642565b6060825182106139a557506040805160208101909152600081526113b7565b61209283838486516139b79190614f9c565b6145a2565b600080600083518551106139d15783516139d4565b84515b90505b8082108015613a5b57508382815181106139f3576139f361551f565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858381518110613a3257613a3261551f565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b1561363a578160010191506139d7565b60606113b7613a798361477a565b614863565b600080600080846000015111613b3c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610654565b6020840151805160001a607f8111613b615760006001600094509450945050506144e4565b60b78111613d6f576000613b76608083614f9c565b905080876000015111613c31576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a401610654565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613caa57507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613d5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a401610654565b50600195509350600092506144e4915050565b60bf81116140bd576000613d8460b783614f9c565b905080876000015111613e3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a401610654565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613f1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a401610654565b600184015160088302610100031c60378111613fe1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a401610654565b613feb8184615464565b8951116140a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a401610654565b6140ab836001615464565b97509550600094506144e49350505050565b60f7811161419e5760006140d260c083614f9c565b90508087600001511161418d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a401610654565b6001955093508492506144e4915050565b60006141ab60f783614f9c565b905080876000015111614266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a401610654565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614344576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a401610654565b600184015160088302610100031c60378111614408576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a401610654565b6144128184615464565b8951116144c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a401610654565b6144d2836001615464565b97509550600194506144e49350505050565b9193909250565b606060008267ffffffffffffffff81111561450857614508614ac7565b6040519080825280601f01601f191660200182016040528015614532576020820181803683370190505b50905082600003614544579050612092565b60006145508587615464565b90506020820160005b85811015614571578281015182820152602001614559565b85811115614580576000868301525b50919695505050505050565b60606113b78260200151600084600001516144eb565b60608182601f011015614611576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610654565b82828401101561467d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610654565b818301845110156146ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610654565b6060821580156147095760405191506000825260208201604052614771565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561474257805183526020928301920161472a565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201526000825111614845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610654565b50604080518082019091528151815260209182019181019190915290565b6060600080600061487385613a7e565b91945092509050600181600181111561488e5761488e6155d0565b1461491b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d00000000000000006064820152608401610654565b84516149278385615464565b146149b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e64657200000000000000000000000000006064820152608401610654565b6040805160208082526104208201909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816149cd5790505090506000845b8751811015614abb57600080614a406040518060400160405280858d60000151614a249190614f9c565b8152602001858d60200151614a399190615464565b9052613a7e565b509150915060405180604001604052808383614a5c9190615464565b8152602001848c60200151614a719190615464565b815250858581518110614a8657614a8661551f565b6020908102919091010152614a9c600185615464565b9350614aa88183615464565b614ab29084615464565b925050506149fa565b50815295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614b3d57614b3d614ac7565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114614b6957600080fd5b919050565b600082601f830112614b7f57600080fd5b813567ffffffffffffffff811115614b9957614b99614ac7565b614bca60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614af6565b818152846020838601011115614bdf57600080fd5b816020850160208301376000918101602001919091529392505050565b600060c08284031215614c0e57600080fd5b60405160c0810167ffffffffffffffff8282108183111715614c3257614c32614ac7565b8160405282935084358352614c4960208601614b45565b6020840152614c5a60408601614b45565b6040840152606085013560608401526080850135608084015260a0850135915080821115614c8757600080fd5b50614c9485828601614b6e565b60a0830152505092915050565b600080600080600085870360e0811215614cba57600080fd5b863567ffffffffffffffff80821115614cd257600080fd5b614cde8a838b01614bfc565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614d1757600080fd5b60408901955060c0890135925080831115614d3157600080fd5b828901925089601f840112614d4557600080fd5b8235915080821115614d5657600080fd5b508860208260051b8401011115614d6c57600080fd5b959894975092955050506020019190565b60005b83811015614d98578181015183820152602001614d80565b83811115614da7576000848401525b50505050565b60008151808452614dc5816020860160208601614d7d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006120926020830184614dad565b600060208284031215614e1c57600080fd5b5035919050565b600060208284031215614e3557600080fd5b813567ffffffffffffffff811115614e4c57600080fd5b61231884828501614bfc565b80358015158114614b6957600080fd5b600060208284031215614e7a57600080fd5b61209282614e58565b600080600080600060a08688031215614e9b57600080fd5b614ea486614b45565b945060208601359350604086013567ffffffffffffffff8082168214614ec957600080fd5b819450614ed860608901614e58565b93506080880135915080821115614eee57600080fd5b50614efb88828901614b6e565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614f5c816049850160208701614d7d565b919091016049019695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015614fae57614fae614f6d565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614ff157614ff1614fb3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561504557615045614f6d565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561508457615084614f6d565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156150b8576150b8614f6d565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156150ff576150ff614f6d565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561513a5761513a614f6d565b6000871292508782058712848416161561515657615156614f6d565b8785058712818416161561516c5761516c614f6d565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156151b4576151b4614f6d565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156151e8576151e8614f6d565b50500190565b600067ffffffffffffffff80831681851680830382111561521157615211614f6d565b01949350505050565b60006fffffffffffffffffffffffffffffffff8083168185168183048111821515161561524957615249614f6d565b02949350505050565b60008261526157615261614fb3565b500490565b80516fffffffffffffffffffffffffffffffff81168114614b6957600080fd5b60006060828403121561529857600080fd5b6040516060810181811067ffffffffffffffff821117156152bb576152bb614ac7565b604052825181526152ce60208401615266565b60208201526152df60408401615266565b60408201529392505050565b6000608082840312156152fd57600080fd5b6040516080810181811067ffffffffffffffff8211171561532057615320614ac7565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff8084111561536c5761536c614ac7565b8360051b602061537d818301614af6565b86815291850191818101903684111561539557600080fd5b865b848110156153c9578035868111156153af5760008081fd5b6153bb36828b01614b6e565b845250918301918301615397565b50979650505050505050565b600084516153e7818460208901614d7d565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551615423816001850160208a01614d7d565b6001920191820152835161543e816002840160208801614d7d565b0160020195945050505050565b60006020828403121561545d57600080fd5b5051919050565b6000821982111561547757615477614f6d565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036154ad576154ad614f6d565b5060010190565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526154ff60c0830184614dad565b98975050505050505050565b60008261551a5761551a614fb3565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff83168061556157615561614fb3565b8060ff84160691505092915050565b600060ff821660ff84168082101561558a5761558a614f6d565b90039392505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156155cb576155cb614f6d565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a",
Bin: "0x6101206040523480156200001257600080fd5b50604051620059073803806200590783398101604081905262000035916200028e565b6001608052600260a052600060c0526001600160a01b0380841660e05282166101005262000063816200006c565b505050620002e6565b600054610100900460ff16158080156200008d5750600054600160ff909116105b80620000bd5750620000aa30620001c360201b62001fb61760201c565b158015620000bd575060005460ff166001145b620001265760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff1916600117905580156200014a576000805461ff0019166101001790555b603280546001600160a01b03191661dead1790556035805483151560ff1990911617905562000178620001d2565b8015620001bf576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03163b151590565b600054610100900460ff166200023f5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016200011d565b60408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b0217600155565b6001600160a01b03811681146200028b57600080fd5b50565b600080600060608486031215620002a457600080fd5b8351620002b18162000275565b6020850151909350620002c48162000275565b60408501519092508015158114620002db57600080fd5b809150509250925092565b60805160a05160c05160e051610100516155a4620003636000396000818161035701528181610ad201526113d50152600081816101c101528181610d3b01528181610f1c01528181611331015281816116eb0152818161195d015261227c0152600061129c015260006112730152600061124a01526155a46000f3fe6080604052600436106101835760003560e01c80638456cb59116100d6578063ca3e99ba1161007f578063d53a822f11610059578063d53a822f146104ec578063e965084c1461050c578063e9e05c421461059857600080fd5b8063ca3e99ba14610421578063cd7c978914610436578063cff0ab961461044b57600080fd5b80638c3152e9116100b05780638c3152e9146103a45780639bf62d82146103c4578063a14238e7146103f157600080fd5b80638456cb5914610379578063867ead131461038e5780638b4c40b0146101a857600080fd5b80635c1f2827116101385780636bb0291e116101125780636bb0291e146103105780636dbffb7814610325578063724c184c1461034557600080fd5b80635c1f28271461029d5780635c975abb146102cf57806364b79208146102f957600080fd5b80633f4ba83a116101695780633f4ba83a146102465780634870496f1461025b57806354fd4d501461027b57600080fd5b80621c2ff6146101af57806313620abd1461020d57600080fd5b366101aa576101a83334620186a06000604051806020016040528060008152506105a6565b005b600080fd5b3480156101bb57600080fd5b506101e37f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561021957600080fd5b50610225633b9aca0081565b6040516fffffffffffffffffffffffffffffffff9091168152602001610204565b34801561025257600080fd5b506101a8610aba565b34801561026757600080fd5b506101a8610276366004614c39565b610bdd565b34801561028757600080fd5b50610290611243565b6040516102049190614d8f565b3480156102a957600080fd5b506102c16fffffffffffffffffffffffffffffffff81565b604051908152602001610204565b3480156102db57600080fd5b506035546102e99060ff1681565b6040519015158152602001610204565b34801561030557600080fd5b506102c1627a120081565b34801561031c57600080fd5b506102c1600481565b34801561033157600080fd5b506102e9610340366004614da2565b6112e6565b34801561035157600080fd5b506101e37f000000000000000000000000000000000000000000000000000000000000000081565b34801561038557600080fd5b506101a86113bd565b34801561039a57600080fd5b506102c161271081565b3480156103b057600080fd5b506101a86103bf366004614dbb565b6114dd565b3480156103d057600080fd5b506032546101e39073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103fd57600080fd5b506102e961040c366004614da2565b60336020526000908152604090205460ff1681565b34801561042d57600080fd5b506102c1611db8565b34801561044257600080fd5b506102c1600881565b34801561045757600080fd5b506001546104b3906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff9283166020850152911690820152606001610204565b3480156104f857600080fd5b506101a8610507366004614e00565b611dc9565b34801561051857600080fd5b5061056a610527366004614da2565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff9283166020850152911690820152606001610204565b6101a86105a6366004614e1b565b8260005a9050831561065d5773ffffffffffffffffffffffffffffffffffffffff87161561065d57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6152088567ffffffffffffffff1610156106f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4f7074696d69736d506f7274616c3a20676173206c696d6974206d757374206360448201527f6f76657220696e737472696e7369632067617320636f737400000000000000006064820152608401610654565b3332811461071a575033731111000000000000000000000000000000001111015b60003488888888604051602001610735959493929190614ea0565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516107a59190614d8f565b60405180910390a450506001546000906107e5907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f34565b905080156109195760006107fd6004627a1200614f7a565b6001546108289190700100000000000000000000000000000000900467ffffffffffffffff16614fe2565b90506000600861083c6004627a1200614f7a565b6108469190615056565b6001546108669084906fffffffffffffffffffffffffffffffff16615056565b6108709190614f7a565b6001549091506000906108b39061089a9084906fffffffffffffffffffffffffffffffff16615112565b6127106fffffffffffffffffffffffffffffffff611fd2565b905060018411156108da576108d761089a8260086108d2600189614f34565b611ff1565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b6001805484919060109061094c908490700100000000000000000000000000000000900467ffffffffffffffff16615186565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550627a1200600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315610a28576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d697400006064820152608401610654565b600154600090610a54906fffffffffffffffffffffffffffffffff1667ffffffffffffffff86166151b2565b6fffffffffffffffffffffffffffffffff1690506000610a7848633b9aca00612046565b610a8290836151ea565b905060005a610a919086614f34565b905080821115610aad57610aad610aa88284614f34565b61205d565b5050505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610b7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e706175736500000000000000000000000000000000000000000000006064820152608401610654565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff1615610c4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610654565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610d09576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e7472616374006064820152608401610654565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610d97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbb919061521e565b519050610dd5610dd036869003860186615283565b61208b565b8114610e63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f6600000000000000000000000000000000000000000000006064820152608401610654565b6000610e6e876120e7565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610fa05750805160408083015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610f78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9c919061521e565b5114155b61102c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610654565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506110f59101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f01000000000000000000000000000000000000000000000000000000000000006020830152906110eb888a6152e9565b8a60400135612117565b611181576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610654565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b606061126e7f000000000000000000000000000000000000000000000000000000000000000061213b565b6112977f000000000000000000000000000000000000000000000000000000000000000061213b565b6112c07f000000000000000000000000000000000000000000000000000000000000000061213b565b6040516020016112d29392919061536d565b604051602081830303815290604052905090565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018290526000906113b79073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa158015611378573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139c919061521e565b602001516fffffffffffffffffffffffffffffffff16612278565b92915050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611482576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e207061757365000000000000000000000000000000000000000000000000006064820152608401610654565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610bd3565b60355460ff161561154a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610654565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead146115f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e006064820152608401610654565b60006115fe826120e7565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff808216948301859052700100000000000000000000000000000000909104169181019190915292935090036116e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610654565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa158015611754573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177891906153e3565b81602001516fffffffffffffffffffffffffffffffff161015611843576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610654565b61186281602001516fffffffffffffffffffffffffffffffff16612278565b611914576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610654565b60408181015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156119b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119dd919061521e565b8251815191925014611a97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610654565b611ab681602001516fffffffffffffffffffffffffffffffff16612278565b611b68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610654565b60008381526033602052604090205460ff1615611c07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610654565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a0880151611ca99392919061231b565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611d0e90841515815260200190565b60405180910390a280158015611d245750326001145b15611db1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610654565b5050505050565b611dc66004627a1200614f7a565b81565b600054610100900460ff1615808015611de95750600054600160ff909116105b80611e035750303b158015611e03575060005460ff166001145b611e8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610654565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611eed57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055603580548315157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909116179055611f4f612375565b8015611fb257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000611fe7611fe18585612458565b83612468565b90505b9392505050565b6000670de0b6b3a76400006120326120098583614f7a565b61201b90670de0b6b3a7640000614fe2565b61202d85670de0b6b3a7640000615056565b612477565b61203c9086615056565b611fe79190614f7a565b6000818310156120565781611fea565b5090919050565b6000805a90505b825a6120709083614f34565b10156120865761207f826153fc565b9150612064565b505050565b600081600001518260200151836040015184606001516040516020016120ca949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a088015193516000976120ca979096959101615434565b600080612123866124a8565b9050612131818686866124da565b9695505050505050565b60608160000361217e57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156121a85780612192816153fc565b91506121a19050600a836151ea565b9150612182565b60008167ffffffffffffffff8111156121c3576121c3614a5f565b6040519080825280601f01601f1916602001820160405280156121ed576020820181803683370190505b5090505b841561227057612202600183614f34565b915061220f600a8661548b565b61221a90603061549f565b60f81b81838151811061222f5761222f6154b7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612269600a866151ea565b94506121f1565b949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122e5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061230991906153e3565b612313908361549f565b421192915050565b600080603f60c88601604002045a101561235e576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080845160208601878a5af19695505050505050565b600054610100900460ff1661240c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610654565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6000818312156120565781611fea565b60008183126120565781611fea565b6000611fea670de0b6b3a76400008361248f8661250a565b6124999190615056565b6124a39190614f7a565b61274e565b606081805190602001206040516020016124c491815260200190565b6040516020818303038152906040529050919050565b6000612501846124eb87868661298d565b8051602091820120825192909101919091201490565b95945050505050565b6000808213612575576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610654565b6000606061258284613415565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361277f57506000919050565b680755bf798b4a1bf1e582126127f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610654565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606060008451116129fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610654565b6000612a05846134eb565b90506000612a12866135da565b9050600084604051602001612a2991815260200190565b60405160208183030381529060405290506000805b845181101561338c576000858281518110612a5b57612a5b6154b7565b602002602001015190508451831115612af6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610654565b82600003612baf5780518051602091820120604051612b4492612b1e92910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612baa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610654565b612d06565b805151602011612c655780518051602091820120604051612bd992612b1e92910190815260200190565b612baa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610654565b805184516020808701919091208251919092012014612d06576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610654565b612d126010600161549f565b81602001515103612ef35784518303612e8b576000612d4e8260200151601081518110612d4157612d416154b7565b6020026020010151613775565b90506000815111612de1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610654565b60018751612def9190614f34565b8314612e7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610654565b9650611fea95505050505050565b6000858481518110612e9f57612e9f6154b7565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110612eca57612eca6154b7565b60200260200101519050612edd816138d5565b9550612eea60018661549f565b94505050613379565b6002816020015151036132f1576000612f0b826138fa565b9050600081600081518110612f2257612f226154b7565b016020015160f81c90506000612f396002836154e6565b612f44906002615508565b90506000612f55848360ff1661391e565b90506000612f638a8961391e565b90506000612f718383613954565b905080835114613003576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610654565b60ff851660021480613018575060ff85166003145b1561320c57808251146130ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610654565b60006130c98860200151600181518110612d4157612d416154b7565b9050600081511161315c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610654565b60018d5161316a9190614f34565b89146131f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610654565b9c50611fea9b505050505050505050505050565b60ff8516158061321f575060ff85166001145b1561325e5761324b876020015160018151811061323e5761323e6154b7565b60200260200101516138d5565b9950613257818a61549f565b98506132e6565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610654565b505050505050613379565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610654565b5080613384816153fc565b915050612a3e565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610654565b6000808211613480576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610654565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b805160609060008167ffffffffffffffff81111561350b5761350b614a5f565b60405190808252806020026020018201604052801561355057816020015b60408051808201909152606080825260208201528152602001906001900390816135295790505b50905060005b828110156135d257604051806040016040528086838151811061357b5761357b6154b7565b602002602001015181526020016135aa87848151811061359d5761359d6154b7565b6020026020010151613a03565b8152508282815181106135bf576135bf6154b7565b6020908102919091010152600101613556565b509392505050565b805160609060006135ec82600261552b565b67ffffffffffffffff81111561360457613604614a5f565b6040519080825280601f01601f19166020018201604052801561362e576020820181803683370190505b5090506000805b8381101561376b5785818151811061364f5761364f6154b7565b6020910101517fff000000000000000000000000000000000000000000000000000000000000008116925060041c7f0ff000000000000000000000000000000000000000000000000000000000000016836136ab83600261552b565b815181106136bb576136bb6154b7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f0f0000000000000000000000000000000000000000000000000000000000000082168361371983600261552b565b61372490600161549f565b81518110613734576137346154b7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101613635565b5090949350505050565b6060600080600061378585613a16565b9194509250905060008160018111156137a0576137a0615568565b1461382d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d000000000000006064820152608401610654565b613837828461549f565b8551146138c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e6465720000000000000000000000006064820152608401610654565b61250185602001518484614483565b606060208260000151106138f1576138ec82613775565b6113b7565b6113b782614524565b60606113b76139198360200151600081518110612d4157612d416154b7565b6135da565b60608251821061393d57506040805160208101909152600081526113b7565b611fea838384865161394f9190614f34565b61453a565b6000806000835185511061396957835161396c565b84515b90505b80821080156139f3575083828151811061398b5761398b6154b7565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168583815181106139ca576139ca6154b7565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156135d25781600101915061396f565b60606113b7613a1183614712565b6147fb565b600080600080846000015111613ad4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610654565b6020840151805160001a607f8111613af957600060016000945094509450505061447c565b60b78111613d07576000613b0e608083614f34565b905080876000015111613bc9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a401610654565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613c4257507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613cf4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a401610654565b506001955093506000925061447c915050565b60bf8111614055576000613d1c60b783614f34565b905080876000015111613dd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a401610654565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613eb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a401610654565b600184015160088302610100031c60378111613f79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a401610654565b613f83818461549f565b895111614038576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a401610654565b61404383600161549f565b975095506000945061447c9350505050565b60f7811161413657600061406a60c083614f34565b905080876000015111614125576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a401610654565b60019550935084925061447c915050565b600061414360f783614f34565b9050808760000151116141fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a401610654565b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036142dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a401610654565b600184015160088302610100031c603781116143a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a401610654565b6143aa818461549f565b89511161445f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a401610654565b61446a83600161549f565b975095506001945061447c9350505050565b9193909250565b606060008267ffffffffffffffff8111156144a0576144a0614a5f565b6040519080825280601f01601f1916602001820160405280156144ca576020820181803683370190505b509050826000036144dc579050611fea565b60006144e8858761549f565b90506020820160005b858110156145095782810151828201526020016144f1565b85811115614518576000868301525b50919695505050505050565b60606113b7826020015160008460000151614483565b60608182601f0110156145a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610654565b828284011015614615576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610654565b81830184511015614682576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610654565b6060821580156146a15760405191506000825260208201604052614709565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156146da5780518352602092830192016146c2565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015260008251116147dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610654565b50604080518082019091528151815260209182019181019190915290565b6060600080600061480b85613a16565b91945092509050600181600181111561482657614826615568565b146148b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d00000000000000006064820152608401610654565b84516148bf838561549f565b1461494c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e64657200000000000000000000000000006064820152608401610654565b6040805160208082526104208201909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816149655790505090506000845b8751811015614a53576000806149d86040518060400160405280858d600001516149bc9190614f34565b8152602001858d602001516149d1919061549f565b9052613a16565b5091509150604051806040016040528083836149f4919061549f565b8152602001848c60200151614a09919061549f565b815250858581518110614a1e57614a1e6154b7565b6020908102919091010152614a3460018561549f565b9350614a40818361549f565b614a4a908461549f565b92505050614992565b50815295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614ad557614ad5614a5f565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114614b0157600080fd5b919050565b600082601f830112614b1757600080fd5b813567ffffffffffffffff811115614b3157614b31614a5f565b614b6260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614a8e565b818152846020838601011115614b7757600080fd5b816020850160208301376000918101602001919091529392505050565b600060c08284031215614ba657600080fd5b60405160c0810167ffffffffffffffff8282108183111715614bca57614bca614a5f565b8160405282935084358352614be160208601614add565b6020840152614bf260408601614add565b6040840152606085013560608401526080850135608084015260a0850135915080821115614c1f57600080fd5b50614c2c85828601614b06565b60a0830152505092915050565b600080600080600085870360e0811215614c5257600080fd5b863567ffffffffffffffff80821115614c6a57600080fd5b614c768a838b01614b94565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614caf57600080fd5b60408901955060c0890135925080831115614cc957600080fd5b828901925089601f840112614cdd57600080fd5b8235915080821115614cee57600080fd5b508860208260051b8401011115614d0457600080fd5b959894975092955050506020019190565b60005b83811015614d30578181015183820152602001614d18565b83811115614d3f576000848401525b50505050565b60008151808452614d5d816020860160208601614d15565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611fea6020830184614d45565b600060208284031215614db457600080fd5b5035919050565b600060208284031215614dcd57600080fd5b813567ffffffffffffffff811115614de457600080fd5b61227084828501614b94565b80358015158114614b0157600080fd5b600060208284031215614e1257600080fd5b611fea82614df0565b600080600080600060a08688031215614e3357600080fd5b614e3c86614add565b945060208601359350604086013567ffffffffffffffff8082168214614e6157600080fd5b819450614e7060608901614df0565b93506080880135915080821115614e8657600080fd5b50614e9388828901614b06565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614ef4816049850160208701614d15565b919091016049019695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015614f4657614f46614f05565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614f8957614f89614f4b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615614fdd57614fdd614f05565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561501c5761501c614f05565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561505057615050614f05565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561509757615097614f05565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156150d2576150d2614f05565b600087129250878205871284841616156150ee576150ee614f05565b8785058712818416161561510457615104614f05565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0384138115161561514c5761514c614f05565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561518057615180614f05565b50500190565b600067ffffffffffffffff8083168185168083038211156151a9576151a9614f05565b01949350505050565b60006fffffffffffffffffffffffffffffffff808316818516818304811182151516156151e1576151e1614f05565b02949350505050565b6000826151f9576151f9614f4b565b500490565b80516fffffffffffffffffffffffffffffffff81168114614b0157600080fd5b60006060828403121561523057600080fd5b6040516060810181811067ffffffffffffffff8211171561525357615253614a5f565b60405282518152615266602084016151fe565b6020820152615277604084016151fe565b60408201529392505050565b60006080828403121561529557600080fd5b6040516080810181811067ffffffffffffffff821117156152b8576152b8614a5f565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff8084111561530457615304614a5f565b8360051b6020615315818301614a8e565b86815291850191818101903684111561532d57600080fd5b865b84811015615361578035868111156153475760008081fd5b61535336828b01614b06565b84525091830191830161532f565b50979650505050505050565b6000845161537f818460208901614d15565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516153bb816001850160208a01614d15565b600192019182015283516153d6816002840160208801614d15565b0160020195945050505050565b6000602082840312156153f557600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361542d5761542d614f05565b5060010190565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261547f60c0830184614d45565b98975050505050505050565b60008261549a5761549a614f4b565b500690565b600082198211156154b2576154b2614f05565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806154f9576154f9614f4b565b8060ff84160691505092915050565b600060ff821660ff84168082101561552257615522614f05565b90039392505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561556357615563614f05565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a",
}
// OptimismPortalABI is the input ABI used to generate the binding from.
......
......@@ -13,7 +13,7 @@ const OptimismPortalStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contrac
var OptimismPortalStorageLayout = new(solc.StorageLayout)
var OptimismPortalDeployedBin = "0x6080604052600436106101835760003560e01c80638456cb59116100d6578063ca3e99ba1161007f578063d53a822f11610059578063d53a822f146104ec578063e965084c1461050c578063e9e05c421461059857600080fd5b8063ca3e99ba14610421578063cd7c978914610436578063cff0ab961461044b57600080fd5b80638c3152e9116100b05780638c3152e9146103a45780639bf62d82146103c4578063a14238e7146103f157600080fd5b80638456cb5914610379578063867ead131461038e5780638b4c40b0146101a857600080fd5b80635c1f2827116101385780636bb0291e116101125780636bb0291e146103105780636dbffb7814610325578063724c184c1461034557600080fd5b80635c1f28271461029d5780635c975abb146102cf57806364b79208146102f957600080fd5b80633f4ba83a116101695780633f4ba83a146102465780634870496f1461025b57806354fd4d501461027b57600080fd5b80621c2ff6146101af57806313620abd1461020d57600080fd5b366101aa576101a83334620186a06000604051806020016040528060008152506105a6565b005b600080fd5b3480156101bb57600080fd5b506101e37f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561021957600080fd5b50610225633b9aca0081565b6040516fffffffffffffffffffffffffffffffff9091168152602001610204565b34801561025257600080fd5b506101a8610aba565b34801561026757600080fd5b506101a8610276366004614ca1565b610bdd565b34801561028757600080fd5b50610290611243565b6040516102049190614df7565b3480156102a957600080fd5b506102c16fffffffffffffffffffffffffffffffff81565b604051908152602001610204565b3480156102db57600080fd5b506035546102e99060ff1681565b6040519015158152602001610204565b34801561030557600080fd5b506102c1627a120081565b34801561031c57600080fd5b506102c1600481565b34801561033157600080fd5b506102e9610340366004614e0a565b6112e6565b34801561035157600080fd5b506101e37f000000000000000000000000000000000000000000000000000000000000000081565b34801561038557600080fd5b506101a86113bd565b34801561039a57600080fd5b506102c161271081565b3480156103b057600080fd5b506101a86103bf366004614e23565b6114dd565b3480156103d057600080fd5b506032546101e39073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103fd57600080fd5b506102e961040c366004614e0a565b60336020526000908152604090205460ff1681565b34801561042d57600080fd5b506102c1611e60565b34801561044257600080fd5b506102c1600881565b34801561045757600080fd5b506001546104b3906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff9283166020850152911690820152606001610204565b3480156104f857600080fd5b506101a8610507366004614e68565b611e71565b34801561051857600080fd5b5061056a610527366004614e0a565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff9283166020850152911690820152606001610204565b6101a86105a6366004614e83565b8260005a9050831561065d5773ffffffffffffffffffffffffffffffffffffffff87161561065d57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6152088567ffffffffffffffff1610156106f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4f7074696d69736d506f7274616c3a20676173206c696d6974206d757374206360448201527f6f76657220696e737472696e7369632067617320636f737400000000000000006064820152608401610654565b3332811461071a575033731111000000000000000000000000000000001111015b60003488888888604051602001610735959493929190614f08565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516107a59190614df7565b60405180910390a450506001546000906107e5907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f9c565b905080156109195760006107fd6004627a1200614fe2565b6001546108289190700100000000000000000000000000000000900467ffffffffffffffff1661504a565b90506000600861083c6004627a1200614fe2565b61084691906150be565b6001546108669084906fffffffffffffffffffffffffffffffff166150be565b6108709190614fe2565b6001549091506000906108b39061089a9084906fffffffffffffffffffffffffffffffff1661517a565b6127106fffffffffffffffffffffffffffffffff61207a565b905060018411156108da576108d761089a8260086108d2600189614f9c565b612099565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b6001805484919060109061094c908490700100000000000000000000000000000000900467ffffffffffffffff166151ee565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550627a1200600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315610a28576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d697400006064820152608401610654565b600154600090610a54906fffffffffffffffffffffffffffffffff1667ffffffffffffffff861661521a565b6fffffffffffffffffffffffffffffffff1690506000610a7848633b9aca006120ee565b610a829083615252565b905060005a610a919086614f9c565b905080821115610aad57610aad610aa88284614f9c565b612105565b5050505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610b7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e706175736500000000000000000000000000000000000000000000006064820152608401610654565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff1615610c4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610654565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610d09576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e7472616374006064820152608401610654565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610d97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbb9190615286565b519050610dd5610dd0368690038601866152eb565b612133565b8114610e63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f6600000000000000000000000000000000000000000000006064820152608401610654565b6000610e6e8761218f565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610fa05750805160408083015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610f78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9c9190615286565b5114155b61102c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610654565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506110f59101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f01000000000000000000000000000000000000000000000000000000000000006020830152906110eb888a615351565b8a604001356121bf565b611181576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610654565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b606061126e7f00000000000000000000000000000000000000000000000000000000000000006121e3565b6112977f00000000000000000000000000000000000000000000000000000000000000006121e3565b6112c07f00000000000000000000000000000000000000000000000000000000000000006121e3565b6040516020016112d2939291906153d5565b604051602081830303815290604052905090565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018290526000906113b79073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa158015611378573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139c9190615286565b602001516fffffffffffffffffffffffffffffffff16612320565b92915050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611482576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e207061757365000000000000000000000000000000000000000000000000006064820152608401610654565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610bd3565b60355460ff161561154a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610654565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead146115f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e006064820152608401610654565b60006115fe8261218f565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff808216948301859052700100000000000000000000000000000000909104169181019190915292935090036116e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610654565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa158015611754573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611778919061544b565b81602001516fffffffffffffffffffffffffffffffff161015611843576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610654565b61186281602001516fffffffffffffffffffffffffffffffff16612320565b611914576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610654565b60408181015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156119b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119dd9190615286565b8251815191925014611a97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610654565b611ab681602001516fffffffffffffffffffffffffffffffff16612320565b611b68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610654565b60008381526033602052604090205460ff1615611c07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610654565b600083815260336020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556080840151611c5090614e2090615464565b5a1015611cdf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a20696e73756666696369656e742067617360448201527f20746f2066696e616c697a65207769746864726177616c0000000000000000006064820152608401610654565b6020840151603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790556040840151600090611d5190614e205a611d429190614f9c565b87606001518860a001516123c3565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611db690841515815260200190565b60405180910390a280158015611dcc5750326001145b15611e59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610654565b5050505050565b611e6e6004627a1200614fe2565b81565b600054610100900460ff1615808015611e915750600054600160ff909116105b80611eab5750303b158015611eab575060005460ff166001145b611f37576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610654565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611f9557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055603580548315157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909116179055611ff76123dd565b801561205a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600061208f61208985856124c0565b836124d0565b90505b9392505050565b6000670de0b6b3a76400006120da6120b18583614fe2565b6120c390670de0b6b3a764000061504a565b6120d585670de0b6b3a76400006150be565b6124df565b6120e490866150be565b61208f9190614fe2565b6000818310156120fe5781612092565b5090919050565b6000805a90505b825a6121189083614f9c565b101561212e576121278261547c565b915061210c565b505050565b60008160000151826020015183604001518460600151604051602001612172949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a088015193516000976121729790969591016154b4565b6000806121cb86612510565b90506121d981868686612542565b9695505050505050565b60608160000361222657505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115612250578061223a8161547c565b91506122499050600a83615252565b915061222a565b60008167ffffffffffffffff81111561226b5761226b614ac7565b6040519080825280601f01601f191660200182016040528015612295576020820181803683370190505b5090505b8415612318576122aa600183614f9c565b91506122b7600a8661550b565b6122c2906030615464565b60f81b8183815181106122d7576122d761551f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612311600a86615252565b9450612299565b949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa15801561238d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b1919061544b565b6123bb9083615464565b421192915050565b600080600080845160208601878a8af19695505050505050565b600054610100900460ff16612474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610654565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6000818312156120fe5781612092565b60008183126120fe5781612092565b6000612092670de0b6b3a7640000836124f786612572565b61250191906150be565b61250b9190614fe2565b6127b6565b6060818051906020012060405160200161252c91815260200190565b6040516020818303038152906040529050919050565b6000612569846125538786866129f5565b8051602091820120825192909101919091201490565b95945050505050565b60008082136125dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610654565b600060606125ea8461347d565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136127e757506000919050565b680755bf798b4a1bf1e58212612859576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610654565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b60606000845111612a62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610654565b6000612a6d84613553565b90506000612a7a86613642565b9050600084604051602001612a9191815260200190565b60405160208183030381529060405290506000805b84518110156133f4576000858281518110612ac357612ac361551f565b602002602001015190508451831115612b5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610654565b82600003612c175780518051602091820120604051612bac92612b8692910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610654565b612d6e565b805151602011612ccd5780518051602091820120604051612c4192612b8692910190815260200190565b612c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610654565b805184516020808701919091208251919092012014612d6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610654565b612d7a60106001615464565b81602001515103612f5b5784518303612ef3576000612db68260200151601081518110612da957612da961551f565b60200260200101516137dd565b90506000815111612e49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610654565b60018751612e579190614f9c565b8314612ee5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610654565b965061209295505050505050565b6000858481518110612f0757612f0761551f565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110612f3257612f3261551f565b60200260200101519050612f458161393d565b9550612f52600186615464565b945050506133e1565b600281602001515103613359576000612f7382613962565b9050600081600081518110612f8a57612f8a61551f565b016020015160f81c90506000612fa160028361554e565b612fac906002615570565b90506000612fbd848360ff16613986565b90506000612fcb8a89613986565b90506000612fd983836139bc565b90508083511461306b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610654565b60ff851660021480613080575060ff85166003145b156132745780825114613115576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610654565b60006131318860200151600181518110612da957612da961551f565b905060008151116131c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610654565b60018d516131d29190614f9c565b8914613260576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610654565b9c506120929b505050505050505050505050565b60ff85161580613287575060ff85166001145b156132c6576132b387602001516001815181106132a6576132a661551f565b602002602001015161393d565b99506132bf818a615464565b985061334e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610654565b5050505050506133e1565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610654565b50806133ec8161547c565b915050612aa6565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610654565b60008082116134e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610654565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b805160609060008167ffffffffffffffff81111561357357613573614ac7565b6040519080825280602002602001820160405280156135b857816020015b60408051808201909152606080825260208201528152602001906001900390816135915790505b50905060005b8281101561363a5760405180604001604052808683815181106135e3576135e361551f565b602002602001015181526020016136128784815181106136055761360561551f565b6020026020010151613a6b565b8152508282815181106136275761362761551f565b60209081029190910101526001016135be565b509392505050565b80516060906000613654826002615593565b67ffffffffffffffff81111561366c5761366c614ac7565b6040519080825280601f01601f191660200182016040528015613696576020820181803683370190505b5090506000805b838110156137d3578581815181106136b7576136b761551f565b6020910101517fff000000000000000000000000000000000000000000000000000000000000008116925060041c7f0ff00000000000000000000000000000000000000000000000000000000000001683613713836002615593565b815181106137235761372361551f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f0f00000000000000000000000000000000000000000000000000000000000000821683613781836002615593565b61378c906001615464565b8151811061379c5761379c61551f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060010161369d565b5090949350505050565b606060008060006137ed85613a7e565b919450925090506000816001811115613808576138086155d0565b14613895576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d000000000000006064820152608401610654565b61389f8284615464565b85511461392e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e6465720000000000000000000000006064820152608401610654565b612569856020015184846144eb565b6060602082600001511061395957613954826137dd565b6113b7565b6113b78261458c565b60606113b76139818360200151600081518110612da957612da961551f565b613642565b6060825182106139a557506040805160208101909152600081526113b7565b61209283838486516139b79190614f9c565b6145a2565b600080600083518551106139d15783516139d4565b84515b90505b8082108015613a5b57508382815181106139f3576139f361551f565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916858381518110613a3257613a3261551f565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b1561363a578160010191506139d7565b60606113b7613a798361477a565b614863565b600080600080846000015111613b3c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610654565b6020840151805160001a607f8111613b615760006001600094509450945050506144e4565b60b78111613d6f576000613b76608083614f9c565b905080876000015111613c31576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a401610654565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613caa57507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613d5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a401610654565b50600195509350600092506144e4915050565b60bf81116140bd576000613d8460b783614f9c565b905080876000015111613e3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a401610654565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613f1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a401610654565b600184015160088302610100031c60378111613fe1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a401610654565b613feb8184615464565b8951116140a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a401610654565b6140ab836001615464565b97509550600094506144e49350505050565b60f7811161419e5760006140d260c083614f9c565b90508087600001511161418d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a401610654565b6001955093508492506144e4915050565b60006141ab60f783614f9c565b905080876000015111614266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a401610654565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003614344576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a401610654565b600184015160088302610100031c60378111614408576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a401610654565b6144128184615464565b8951116144c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a401610654565b6144d2836001615464565b97509550600194506144e49350505050565b9193909250565b606060008267ffffffffffffffff81111561450857614508614ac7565b6040519080825280601f01601f191660200182016040528015614532576020820181803683370190505b50905082600003614544579050612092565b60006145508587615464565b90506020820160005b85811015614571578281015182820152602001614559565b85811115614580576000868301525b50919695505050505050565b60606113b78260200151600084600001516144eb565b60608182601f011015614611576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610654565b82828401101561467d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610654565b818301845110156146ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610654565b6060821580156147095760405191506000825260208201604052614771565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561474257805183526020928301920161472a565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60408051808201909152600080825260208201526000825111614845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610654565b50604080518082019091528151815260209182019181019190915290565b6060600080600061487385613a7e565b91945092509050600181600181111561488e5761488e6155d0565b1461491b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d00000000000000006064820152608401610654565b84516149278385615464565b146149b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e64657200000000000000000000000000006064820152608401610654565b6040805160208082526104208201909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816149cd5790505090506000845b8751811015614abb57600080614a406040518060400160405280858d60000151614a249190614f9c565b8152602001858d60200151614a399190615464565b9052613a7e565b509150915060405180604001604052808383614a5c9190615464565b8152602001848c60200151614a719190615464565b815250858581518110614a8657614a8661551f565b6020908102919091010152614a9c600185615464565b9350614aa88183615464565b614ab29084615464565b925050506149fa565b50815295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614b3d57614b3d614ac7565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114614b6957600080fd5b919050565b600082601f830112614b7f57600080fd5b813567ffffffffffffffff811115614b9957614b99614ac7565b614bca60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614af6565b818152846020838601011115614bdf57600080fd5b816020850160208301376000918101602001919091529392505050565b600060c08284031215614c0e57600080fd5b60405160c0810167ffffffffffffffff8282108183111715614c3257614c32614ac7565b8160405282935084358352614c4960208601614b45565b6020840152614c5a60408601614b45565b6040840152606085013560608401526080850135608084015260a0850135915080821115614c8757600080fd5b50614c9485828601614b6e565b60a0830152505092915050565b600080600080600085870360e0811215614cba57600080fd5b863567ffffffffffffffff80821115614cd257600080fd5b614cde8a838b01614bfc565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614d1757600080fd5b60408901955060c0890135925080831115614d3157600080fd5b828901925089601f840112614d4557600080fd5b8235915080821115614d5657600080fd5b508860208260051b8401011115614d6c57600080fd5b959894975092955050506020019190565b60005b83811015614d98578181015183820152602001614d80565b83811115614da7576000848401525b50505050565b60008151808452614dc5816020860160208601614d7d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006120926020830184614dad565b600060208284031215614e1c57600080fd5b5035919050565b600060208284031215614e3557600080fd5b813567ffffffffffffffff811115614e4c57600080fd5b61231884828501614bfc565b80358015158114614b6957600080fd5b600060208284031215614e7a57600080fd5b61209282614e58565b600080600080600060a08688031215614e9b57600080fd5b614ea486614b45565b945060208601359350604086013567ffffffffffffffff8082168214614ec957600080fd5b819450614ed860608901614e58565b93506080880135915080821115614eee57600080fd5b50614efb88828901614b6e565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614f5c816049850160208701614d7d565b919091016049019695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015614fae57614fae614f6d565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614ff157614ff1614fb3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561504557615045614f6d565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561508457615084614f6d565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156150b8576150b8614f6d565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156150ff576150ff614f6d565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561513a5761513a614f6d565b6000871292508782058712848416161561515657615156614f6d565b8785058712818416161561516c5761516c614f6d565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156151b4576151b4614f6d565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156151e8576151e8614f6d565b50500190565b600067ffffffffffffffff80831681851680830382111561521157615211614f6d565b01949350505050565b60006fffffffffffffffffffffffffffffffff8083168185168183048111821515161561524957615249614f6d565b02949350505050565b60008261526157615261614fb3565b500490565b80516fffffffffffffffffffffffffffffffff81168114614b6957600080fd5b60006060828403121561529857600080fd5b6040516060810181811067ffffffffffffffff821117156152bb576152bb614ac7565b604052825181526152ce60208401615266565b60208201526152df60408401615266565b60408201529392505050565b6000608082840312156152fd57600080fd5b6040516080810181811067ffffffffffffffff8211171561532057615320614ac7565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff8084111561536c5761536c614ac7565b8360051b602061537d818301614af6565b86815291850191818101903684111561539557600080fd5b865b848110156153c9578035868111156153af5760008081fd5b6153bb36828b01614b6e565b845250918301918301615397565b50979650505050505050565b600084516153e7818460208901614d7d565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551615423816001850160208a01614d7d565b6001920191820152835161543e816002840160208801614d7d565b0160020195945050505050565b60006020828403121561545d57600080fd5b5051919050565b6000821982111561547757615477614f6d565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036154ad576154ad614f6d565b5060010190565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526154ff60c0830184614dad565b98975050505050505050565b60008261551a5761551a614fb3565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff83168061556157615561614fb3565b8060ff84160691505092915050565b600060ff821660ff84168082101561558a5761558a614f6d565b90039392505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156155cb576155cb614f6d565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a"
var OptimismPortalDeployedBin = "0x6080604052600436106101835760003560e01c80638456cb59116100d6578063ca3e99ba1161007f578063d53a822f11610059578063d53a822f146104ec578063e965084c1461050c578063e9e05c421461059857600080fd5b8063ca3e99ba14610421578063cd7c978914610436578063cff0ab961461044b57600080fd5b80638c3152e9116100b05780638c3152e9146103a45780639bf62d82146103c4578063a14238e7146103f157600080fd5b80638456cb5914610379578063867ead131461038e5780638b4c40b0146101a857600080fd5b80635c1f2827116101385780636bb0291e116101125780636bb0291e146103105780636dbffb7814610325578063724c184c1461034557600080fd5b80635c1f28271461029d5780635c975abb146102cf57806364b79208146102f957600080fd5b80633f4ba83a116101695780633f4ba83a146102465780634870496f1461025b57806354fd4d501461027b57600080fd5b80621c2ff6146101af57806313620abd1461020d57600080fd5b366101aa576101a83334620186a06000604051806020016040528060008152506105a6565b005b600080fd5b3480156101bb57600080fd5b506101e37f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561021957600080fd5b50610225633b9aca0081565b6040516fffffffffffffffffffffffffffffffff9091168152602001610204565b34801561025257600080fd5b506101a8610aba565b34801561026757600080fd5b506101a8610276366004614c39565b610bdd565b34801561028757600080fd5b50610290611243565b6040516102049190614d8f565b3480156102a957600080fd5b506102c16fffffffffffffffffffffffffffffffff81565b604051908152602001610204565b3480156102db57600080fd5b506035546102e99060ff1681565b6040519015158152602001610204565b34801561030557600080fd5b506102c1627a120081565b34801561031c57600080fd5b506102c1600481565b34801561033157600080fd5b506102e9610340366004614da2565b6112e6565b34801561035157600080fd5b506101e37f000000000000000000000000000000000000000000000000000000000000000081565b34801561038557600080fd5b506101a86113bd565b34801561039a57600080fd5b506102c161271081565b3480156103b057600080fd5b506101a86103bf366004614dbb565b6114dd565b3480156103d057600080fd5b506032546101e39073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103fd57600080fd5b506102e961040c366004614da2565b60336020526000908152604090205460ff1681565b34801561042d57600080fd5b506102c1611db8565b34801561044257600080fd5b506102c1600881565b34801561045757600080fd5b506001546104b3906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff9283166020850152911690820152606001610204565b3480156104f857600080fd5b506101a8610507366004614e00565b611dc9565b34801561051857600080fd5b5061056a610527366004614da2565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff9283166020850152911690820152606001610204565b6101a86105a6366004614e1b565b8260005a9050831561065d5773ffffffffffffffffffffffffffffffffffffffff87161561065d57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6152088567ffffffffffffffff1610156106f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4f7074696d69736d506f7274616c3a20676173206c696d6974206d757374206360448201527f6f76657220696e737472696e7369632067617320636f737400000000000000006064820152608401610654565b3332811461071a575033731111000000000000000000000000000000001111015b60003488888888604051602001610735959493929190614ea0565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516107a59190614d8f565b60405180910390a450506001546000906107e5907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643614f34565b905080156109195760006107fd6004627a1200614f7a565b6001546108289190700100000000000000000000000000000000900467ffffffffffffffff16614fe2565b90506000600861083c6004627a1200614f7a565b6108469190615056565b6001546108669084906fffffffffffffffffffffffffffffffff16615056565b6108709190614f7a565b6001549091506000906108b39061089a9084906fffffffffffffffffffffffffffffffff16615112565b6127106fffffffffffffffffffffffffffffffff611fd2565b905060018411156108da576108d761089a8260086108d2600189614f34565b611ff1565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b6001805484919060109061094c908490700100000000000000000000000000000000900467ffffffffffffffff16615186565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550627a1200600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315610a28576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d697400006064820152608401610654565b600154600090610a54906fffffffffffffffffffffffffffffffff1667ffffffffffffffff86166151b2565b6fffffffffffffffffffffffffffffffff1690506000610a7848633b9aca00612046565b610a8290836151ea565b905060005a610a919086614f34565b905080821115610aad57610aad610aa88284614f34565b61205d565b5050505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610b7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e706175736500000000000000000000000000000000000000000000006064820152608401610654565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff1615610c4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610654565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610d09576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e7472616374006064820152608401610654565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610d97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbb919061521e565b519050610dd5610dd036869003860186615283565b61208b565b8114610e63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f6600000000000000000000000000000000000000000000006064820152608401610654565b6000610e6e876120e7565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610fa05750805160408083015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610f78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9c919061521e565b5114155b61102c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610654565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506110f59101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f01000000000000000000000000000000000000000000000000000000000000006020830152906110eb888a6152e9565b8a60400135612117565b611181576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610654565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b606061126e7f000000000000000000000000000000000000000000000000000000000000000061213b565b6112977f000000000000000000000000000000000000000000000000000000000000000061213b565b6112c07f000000000000000000000000000000000000000000000000000000000000000061213b565b6040516020016112d29392919061536d565b604051602081830303815290604052905090565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018290526000906113b79073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa158015611378573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139c919061521e565b602001516fffffffffffffffffffffffffffffffff16612278565b92915050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611482576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e207061757365000000000000000000000000000000000000000000000000006064820152608401610654565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610bd3565b60355460ff161561154a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610654565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead146115f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e006064820152608401610654565b60006115fe826120e7565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff808216948301859052700100000000000000000000000000000000909104169181019190915292935090036116e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610654565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa158015611754573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177891906153e3565b81602001516fffffffffffffffffffffffffffffffff161015611843576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610654565b61186281602001516fffffffffffffffffffffffffffffffff16612278565b611914576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610654565b60408181015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156119b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119dd919061521e565b8251815191925014611a97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610654565b611ab681602001516fffffffffffffffffffffffffffffffff16612278565b611b68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610654565b60008381526033602052604090205460ff1615611c07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610654565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a0880151611ca99392919061231b565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611d0e90841515815260200190565b60405180910390a280158015611d245750326001145b15611db1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610654565b5050505050565b611dc66004627a1200614f7a565b81565b600054610100900460ff1615808015611de95750600054600160ff909116105b80611e035750303b158015611e03575060005460ff166001145b611e8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610654565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611eed57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055603580548315157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909116179055611f4f612375565b8015611fb257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000611fe7611fe18585612458565b83612468565b90505b9392505050565b6000670de0b6b3a76400006120326120098583614f7a565b61201b90670de0b6b3a7640000614fe2565b61202d85670de0b6b3a7640000615056565b612477565b61203c9086615056565b611fe79190614f7a565b6000818310156120565781611fea565b5090919050565b6000805a90505b825a6120709083614f34565b10156120865761207f826153fc565b9150612064565b505050565b600081600001518260200151836040015184606001516040516020016120ca949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a088015193516000976120ca979096959101615434565b600080612123866124a8565b9050612131818686866124da565b9695505050505050565b60608160000361217e57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156121a85780612192816153fc565b91506121a19050600a836151ea565b9150612182565b60008167ffffffffffffffff8111156121c3576121c3614a5f565b6040519080825280601f01601f1916602001820160405280156121ed576020820181803683370190505b5090505b841561227057612202600183614f34565b915061220f600a8661548b565b61221a90603061549f565b60f81b81838151811061222f5761222f6154b7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612269600a866151ea565b94506121f1565b949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122e5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061230991906153e3565b612313908361549f565b421192915050565b600080603f60c88601604002045a101561235e576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080845160208601878a5af19695505050505050565b600054610100900460ff1661240c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610654565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6000818312156120565781611fea565b60008183126120565781611fea565b6000611fea670de0b6b3a76400008361248f8661250a565b6124999190615056565b6124a39190614f7a565b61274e565b606081805190602001206040516020016124c491815260200190565b6040516020818303038152906040529050919050565b6000612501846124eb87868661298d565b8051602091820120825192909101919091201490565b95945050505050565b6000808213612575576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610654565b6000606061258284613415565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361277f57506000919050565b680755bf798b4a1bf1e582126127f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610654565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b606060008451116129fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610654565b6000612a05846134eb565b90506000612a12866135da565b9050600084604051602001612a2991815260200190565b60405160208183030381529060405290506000805b845181101561338c576000858281518110612a5b57612a5b6154b7565b602002602001015190508451831115612af6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610654565b82600003612baf5780518051602091820120604051612b4492612b1e92910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b612baa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610654565b612d06565b805151602011612c655780518051602091820120604051612bd992612b1e92910190815260200190565b612baa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610654565b805184516020808701919091208251919092012014612d06576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610654565b612d126010600161549f565b81602001515103612ef35784518303612e8b576000612d4e8260200151601081518110612d4157612d416154b7565b6020026020010151613775565b90506000815111612de1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610654565b60018751612def9190614f34565b8314612e7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610654565b9650611fea95505050505050565b6000858481518110612e9f57612e9f6154b7565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110612eca57612eca6154b7565b60200260200101519050612edd816138d5565b9550612eea60018661549f565b94505050613379565b6002816020015151036132f1576000612f0b826138fa565b9050600081600081518110612f2257612f226154b7565b016020015160f81c90506000612f396002836154e6565b612f44906002615508565b90506000612f55848360ff1661391e565b90506000612f638a8961391e565b90506000612f718383613954565b905080835114613003576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610654565b60ff851660021480613018575060ff85166003145b1561320c57808251146130ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610654565b60006130c98860200151600181518110612d4157612d416154b7565b9050600081511161315c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610654565b60018d5161316a9190614f34565b89146131f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610654565b9c50611fea9b505050505050505050505050565b60ff8516158061321f575060ff85166001145b1561325e5761324b876020015160018151811061323e5761323e6154b7565b60200260200101516138d5565b9950613257818a61549f565b98506132e6565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610654565b505050505050613379565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610654565b5080613384816153fc565b915050612a3e565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610654565b6000808211613480576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610654565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b805160609060008167ffffffffffffffff81111561350b5761350b614a5f565b60405190808252806020026020018201604052801561355057816020015b60408051808201909152606080825260208201528152602001906001900390816135295790505b50905060005b828110156135d257604051806040016040528086838151811061357b5761357b6154b7565b602002602001015181526020016135aa87848151811061359d5761359d6154b7565b6020026020010151613a03565b8152508282815181106135bf576135bf6154b7565b6020908102919091010152600101613556565b509392505050565b805160609060006135ec82600261552b565b67ffffffffffffffff81111561360457613604614a5f565b6040519080825280601f01601f19166020018201604052801561362e576020820181803683370190505b5090506000805b8381101561376b5785818151811061364f5761364f6154b7565b6020910101517fff000000000000000000000000000000000000000000000000000000000000008116925060041c7f0ff000000000000000000000000000000000000000000000000000000000000016836136ab83600261552b565b815181106136bb576136bb6154b7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f0f0000000000000000000000000000000000000000000000000000000000000082168361371983600261552b565b61372490600161549f565b81518110613734576137346154b7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101613635565b5090949350505050565b6060600080600061378585613a16565b9194509250905060008160018111156137a0576137a0615568565b1461382d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d000000000000006064820152608401610654565b613837828461549f565b8551146138c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e6465720000000000000000000000006064820152608401610654565b61250185602001518484614483565b606060208260000151106138f1576138ec82613775565b6113b7565b6113b782614524565b60606113b76139198360200151600081518110612d4157612d416154b7565b6135da565b60608251821061393d57506040805160208101909152600081526113b7565b611fea838384865161394f9190614f34565b61453a565b6000806000835185511061396957835161396c565b84515b90505b80821080156139f3575083828151811061398b5761398b6154b7565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168583815181106139ca576139ca6154b7565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156135d25781600101915061396f565b60606113b7613a1183614712565b6147fb565b600080600080846000015111613ad4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610654565b6020840151805160001a607f8111613af957600060016000945094509450505061447c565b60b78111613d07576000613b0e608083614f34565b905080876000015111613bc9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a401610654565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613c4257507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613cf4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a401610654565b506001955093506000925061447c915050565b60bf8111614055576000613d1c60b783614f34565b905080876000015111613dd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a401610654565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613eb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a401610654565b600184015160088302610100031c60378111613f79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a401610654565b613f83818461549f565b895111614038576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a401610654565b61404383600161549f565b975095506000945061447c9350505050565b60f7811161413657600061406a60c083614f34565b905080876000015111614125576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a401610654565b60019550935084925061447c915050565b600061414360f783614f34565b9050808760000151116141fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a401610654565b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036142dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a401610654565b600184015160088302610100031c603781116143a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a401610654565b6143aa818461549f565b89511161445f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a401610654565b61446a83600161549f565b975095506001945061447c9350505050565b9193909250565b606060008267ffffffffffffffff8111156144a0576144a0614a5f565b6040519080825280601f01601f1916602001820160405280156144ca576020820181803683370190505b509050826000036144dc579050611fea565b60006144e8858761549f565b90506020820160005b858110156145095782810151828201526020016144f1565b85811115614518576000868301525b50919695505050505050565b60606113b7826020015160008460000151614483565b60608182601f0110156145a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610654565b828284011015614615576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610654565b81830184511015614682576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610654565b6060821580156146a15760405191506000825260208201604052614709565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156146da5780518352602092830192016146c2565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015260008251116147dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610654565b50604080518082019091528151815260209182019181019190915290565b6060600080600061480b85613a16565b91945092509050600181600181111561482657614826615568565b146148b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d00000000000000006064820152608401610654565b84516148bf838561549f565b1461494c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e64657200000000000000000000000000006064820152608401610654565b6040805160208082526104208201909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816149655790505090506000845b8751811015614a53576000806149d86040518060400160405280858d600001516149bc9190614f34565b8152602001858d602001516149d1919061549f565b9052613a16565b5091509150604051806040016040528083836149f4919061549f565b8152602001848c60200151614a09919061549f565b815250858581518110614a1e57614a1e6154b7565b6020908102919091010152614a3460018561549f565b9350614a40818361549f565b614a4a908461549f565b92505050614992565b50815295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614ad557614ad5614a5f565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114614b0157600080fd5b919050565b600082601f830112614b1757600080fd5b813567ffffffffffffffff811115614b3157614b31614a5f565b614b6260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614a8e565b818152846020838601011115614b7757600080fd5b816020850160208301376000918101602001919091529392505050565b600060c08284031215614ba657600080fd5b60405160c0810167ffffffffffffffff8282108183111715614bca57614bca614a5f565b8160405282935084358352614be160208601614add565b6020840152614bf260408601614add565b6040840152606085013560608401526080850135608084015260a0850135915080821115614c1f57600080fd5b50614c2c85828601614b06565b60a0830152505092915050565b600080600080600085870360e0811215614c5257600080fd5b863567ffffffffffffffff80821115614c6a57600080fd5b614c768a838b01614b94565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614caf57600080fd5b60408901955060c0890135925080831115614cc957600080fd5b828901925089601f840112614cdd57600080fd5b8235915080821115614cee57600080fd5b508860208260051b8401011115614d0457600080fd5b959894975092955050506020019190565b60005b83811015614d30578181015183820152602001614d18565b83811115614d3f576000848401525b50505050565b60008151808452614d5d816020860160208601614d15565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611fea6020830184614d45565b600060208284031215614db457600080fd5b5035919050565b600060208284031215614dcd57600080fd5b813567ffffffffffffffff811115614de457600080fd5b61227084828501614b94565b80358015158114614b0157600080fd5b600060208284031215614e1257600080fd5b611fea82614df0565b600080600080600060a08688031215614e3357600080fd5b614e3c86614add565b945060208601359350604086013567ffffffffffffffff8082168214614e6157600080fd5b819450614e7060608901614df0565b93506080880135915080821115614e8657600080fd5b50614e9388828901614b06565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614ef4816049850160208701614d15565b919091016049019695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015614f4657614f46614f05565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614f8957614f89614f4b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615614fdd57614fdd614f05565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561501c5761501c614f05565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561505057615050614f05565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561509757615097614f05565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156150d2576150d2614f05565b600087129250878205871284841616156150ee576150ee614f05565b8785058712818416161561510457615104614f05565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0384138115161561514c5761514c614f05565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561518057615180614f05565b50500190565b600067ffffffffffffffff8083168185168083038211156151a9576151a9614f05565b01949350505050565b60006fffffffffffffffffffffffffffffffff808316818516818304811182151516156151e1576151e1614f05565b02949350505050565b6000826151f9576151f9614f4b565b500490565b80516fffffffffffffffffffffffffffffffff81168114614b0157600080fd5b60006060828403121561523057600080fd5b6040516060810181811067ffffffffffffffff8211171561525357615253614a5f565b60405282518152615266602084016151fe565b6020820152615277604084016151fe565b60408201529392505050565b60006080828403121561529557600080fd5b6040516080810181811067ffffffffffffffff821117156152b8576152b8614a5f565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff8084111561530457615304614a5f565b8360051b6020615315818301614a8e565b86815291850191818101903684111561532d57600080fd5b865b84811015615361578035868111156153475760008081fd5b61535336828b01614b06565b84525091830191830161532f565b50979650505050505050565b6000845161537f818460208901614d15565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516153bb816001850160208a01614d15565b600192019182015283516153d6816002840160208801614d15565b0160020195945050505050565b6000602082840312156153f557600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361542d5761542d614f05565b5060010190565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261547f60c0830184614d45565b98975050505050505050565b60008261549a5761549a614f4b565b500690565b600082198211156154b2576154b2614f05565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff8316806154f9576154f9614f4b565b8060ff84160691505092915050565b600060ff821660ff84168082101561552257615522614f05565b90039392505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561556357615563614f05565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(OptimismPortalStorageLayoutJSON), OptimismPortalStorageLayout); err != nil {
......
......@@ -8,6 +8,8 @@ import (
"os"
"strings"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-chain-ops/db"
"github.com/mattn/go-isatty"
......@@ -22,7 +24,6 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/hardhat"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis/migration"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/urfave/cli"
......@@ -46,11 +47,6 @@ func main() {
Usage: "Path to ovm-addresses.json",
Required: true,
},
&cli.StringFlag{
Name: "evm-addresses",
Usage: "Path to evm-addresses.json",
Required: true,
},
&cli.StringFlag{
Name: "ovm-allowances",
Usage: "Path to ovm-allowances.json",
......@@ -62,8 +58,8 @@ func main() {
Required: true,
},
&cli.StringFlag{
Name: "evm-messages",
Usage: "Path to evm-messages.json",
Name: "witness-file",
Usage: "Path to witness file",
Required: true,
},
&cli.StringFlag{
......@@ -118,30 +114,35 @@ func main() {
return err
}
ovmAddresses, err := migration.NewAddresses(ctx.String("ovm-addresses"))
ovmAddresses, err := crossdomain.NewAddresses(ctx.String("ovm-addresses"))
if err != nil {
return err
}
evmAddresess, err := migration.NewAddresses(ctx.String("evm-addresses"))
ovmAllowances, err := crossdomain.NewAllowances(ctx.String("ovm-allowances"))
if err != nil {
return err
}
ovmAllowances, err := migration.NewAllowances(ctx.String("ovm-allowances"))
ovmMessages, err := crossdomain.NewSentMessageFromJSON(ctx.String("ovm-messages"))
if err != nil {
return err
}
ovmMessages, err := migration.NewSentMessage(ctx.String("ovm-messages"))
if err != nil {
return err
}
evmMessages, err := migration.NewSentMessage(ctx.String("evm-messages"))
evmMessages, evmAddresses, err := crossdomain.ReadWitnessData(ctx.String("witness-file"))
if err != nil {
return err
}
migrationData := migration.MigrationData{
log.Info(
"Loaded witness data",
"ovmAddresses", len(ovmAddresses),
"evmAddresses", len(evmAddresses),
"ovmAllowances", len(ovmAllowances),
"ovmMessages", len(ovmMessages),
"evmMessages", len(evmMessages),
)
migrationData := crossdomain.MigrationData{
OvmAddresses: ovmAddresses,
EvmAddresses: evmAddresess,
EvmAddresses: evmAddresses,
OvmAllowances: ovmAllowances,
OvmMessages: ovmMessages,
EvmMessages: evmMessages,
......
......@@ -18,8 +18,6 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis/migration"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
......@@ -768,7 +766,7 @@ func newWithdrawals(ctx *cli.Context, l1ChainID *big.Int) ([]*crossdomain.Legacy
evmMsgs := ctx.String("evm-messages")
log.Debug("Migration data", "ovm-path", ovmMsgs, "evm-messages", evmMsgs)
ovmMessages, err := migration.NewSentMessage(ovmMsgs)
ovmMessages, err := crossdomain.NewSentMessageFromJSON(ovmMsgs)
if err != nil {
return nil, err
}
......@@ -777,20 +775,20 @@ func newWithdrawals(ctx *cli.Context, l1ChainID *big.Int) ([]*crossdomain.Legacy
// committed to in git.
if l1ChainID.Cmp(common.Big1) != 0 {
log.Info("not using ovm messages because its not mainnet")
ovmMessages = []*migration.SentMessage{}
ovmMessages = []*crossdomain.SentMessage{}
}
evmMessages, err := migration.NewSentMessage(evmMsgs)
evmMessages, err := crossdomain.NewSentMessageFromJSON(evmMsgs)
if err != nil {
return nil, err
}
migrationData := migration.MigrationData{
migrationData := crossdomain.MigrationData{
OvmMessages: ovmMessages,
EvmMessages: evmMessages,
}
wds, err := migrationData.ToWithdrawals()
wds, _, err := migrationData.ToWithdrawals()
if err != nil {
return nil, err
}
......
......@@ -11,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
)
var (
......@@ -82,8 +83,7 @@ func MigrateWithdrawal(withdrawal *LegacyWithdrawal, l1CrossDomainMessenger *com
return nil, fmt.Errorf("cannot abi encode relayMessage: %w", err)
}
// Set the outer gas limit. This cannot be zero
gasLimit := uint64(len(data)*16 + 200_000)
gasLimit := MigrateWithdrawalGasLimit(data)
w := NewWithdrawal(
versionedNonce,
......@@ -95,3 +95,25 @@ func MigrateWithdrawal(withdrawal *LegacyWithdrawal, l1CrossDomainMessenger *com
)
return w, nil
}
func MigrateWithdrawalGasLimit(data []byte) uint64 {
// Compute the cost of the calldata
dataCost := uint64(0)
for _, b := range data {
if b == 0 {
dataCost += params.TxDataZeroGas
} else {
dataCost += params.TxDataNonZeroGasEIP2028
}
}
// Set the outer gas limit. This cannot be zero
gasLimit := dataCost + 200_000
// Cap the gas limit to be 25 million to prevent creating withdrawals
// that go over the block gas limit.
if gasLimit > 25_000_000 {
gasLimit = 25_000_000
}
return gasLimit
}
......@@ -2,6 +2,7 @@ package crossdomain_test
import (
"fmt"
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
......@@ -11,6 +12,8 @@ import (
"github.com/stretchr/testify/require"
)
var big25Million = big.NewInt(25_000_000)
func TestMigrateWithdrawal(t *testing.T) {
withdrawals := make([]*crossdomain.LegacyWithdrawal, 0)
......@@ -31,6 +34,57 @@ func TestMigrateWithdrawal(t *testing.T) {
require.Equal(t, legacy.XDomainNonce.Uint64(), withdrawal.Nonce.Uint64())
require.Equal(t, *withdrawal.Sender, predeploys.L2CrossDomainMessengerAddr)
require.Equal(t, *withdrawal.Target, l1CrossDomainMessenger)
// Always equal to or lower than the cap
require.True(t, withdrawal.GasLimit.Cmp(big25Million) <= 0)
})
}
}
// TestMigrateWithdrawalGasLimitMax computes the migrated withdrawal
// gas limit with a very large amount of data. The max value for a migrated
// withdrawal's gas limit is 25 million.
func TestMigrateWithdrawalGasLimitMax(t *testing.T) {
size := 300_000_000 / 16
data := make([]byte, size)
for _, i := range data {
data[i] = 0xff
}
result := crossdomain.MigrateWithdrawalGasLimit(data)
require.Equal(t, result, big25Million.Uint64())
}
// TestMigrateWithdrawalGasLimit tests an assortment of zero and non zero
// bytes when computing the migrated withdrawal's gas limit.
func TestMigrateWithdrawalGasLimit(t *testing.T) {
tests := []struct {
input []byte
output uint64
}{
{
input: []byte{},
output: 200_000,
},
{
input: []byte{0xff},
output: 200_000 + 16,
},
{
input: []byte{0xff, 0x00},
output: 200_000 + 16 + 4,
},
{
input: []byte{0x00},
output: 200_000 + 4,
},
{
input: []byte{0x00, 0x00, 0x00},
output: 200_000 + 4 + 4 + 4,
},
}
for _, test := range tests {
result := crossdomain.MigrateWithdrawalGasLimit(test.input)
require.Equal(t, test.output, result)
}
}
......@@ -5,6 +5,7 @@ import (
"fmt"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/util"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/log"
......@@ -12,28 +13,40 @@ import (
var (
ErrUnknownSlotInMessagePasser = errors.New("unknown slot in legacy message passer")
ErrMissingSlotInWitness = errors.New("missing storage slot in witness data")
ErrMissingSlotInWitness = errors.New("missing storage slot in witness data (see logs for details)")
)
// PreCheckWithdrawals checks that the given list of withdrawals represents all withdrawals made
// in the legacy system and filters out any extra withdrawals not included in the legacy system.
func PreCheckWithdrawals(db *state.StateDB, withdrawals DangerousUnfilteredWithdrawals) (SafeFilteredWithdrawals, error) {
func PreCheckWithdrawals(db *state.StateDB, withdrawals DangerousUnfilteredWithdrawals, invalidMessages []InvalidMessage) (SafeFilteredWithdrawals, error) {
// Convert each withdrawal into a storage slot, and build a map of those slots.
slotsInp := make(map[common.Hash]*LegacyWithdrawal)
validSlotsInp := make(map[common.Hash]*LegacyWithdrawal)
for _, wd := range withdrawals {
slot, err := wd.StorageSlot()
if err != nil {
return nil, fmt.Errorf("cannot check withdrawals: %w", err)
}
slotsInp[slot] = wd
validSlotsInp[slot] = wd
}
// Convert each invalid message into a storage slot, and build a map of those slots.
invalidSlotsInp := make(map[common.Hash]InvalidMessage)
for _, msg := range invalidMessages {
slot, err := msg.StorageSlot()
if err != nil {
return nil, fmt.Errorf("cannot check invalid messages: %w", err)
}
invalidSlotsInp[slot] = msg
}
// Build a mapping of the slots of all messages actually sent in the legacy system.
var count int
var innerErr error
slotsAct := make(map[common.Hash]bool)
progress := util.ProgressLogger(1000, "Iterating legacy messages")
err := db.ForEachStorage(predeploys.LegacyMessagePasserAddr, func(key, value common.Hash) bool {
progress()
// When a message is inserted into the LegacyMessagePasser, it is stored with the value
// of the ABI encoding of "true". Although there should not be any other storage slots, we
// can safely ignore anything that is not "true".
......@@ -59,24 +72,32 @@ func PreCheckWithdrawals(db *state.StateDB, withdrawals DangerousUnfilteredWithd
log.Info("Iterated legacy messages", "count", count)
// Iterate over the list of actual slots and check that we have an input message for each one.
var missing int
for slot := range slotsAct {
_, ok := slotsInp[slot]
if !ok {
return nil, ErrMissingSlotInWitness
_, okValid := validSlotsInp[slot]
_, okInvalid := invalidSlotsInp[slot]
if !okValid && !okInvalid {
log.Error("missing storage slot", "slot", slot.String())
missing++
}
}
if missing > 0 {
log.Error("missing storage slots in witness data", "count", missing)
return nil, ErrMissingSlotInWitness
}
// Iterate over the list of input messages and check that we have a known slot for each one.
// We'll filter out any extra messages that are not in the legacy system.
filtered := make(SafeFilteredWithdrawals, 0)
for slot := range slotsInp {
for slot := range validSlotsInp {
_, ok := slotsAct[slot]
if !ok {
log.Info("filtering out unknown input message", "slot", slot.String())
continue
}
wd := slotsInp[slot]
wd := validSlotsInp[slot]
if wd.MessageSender != predeploys.L2CrossDomainMessengerAddr {
log.Info("filtering out message from sender other than the L2XDM", "sender", wd.MessageSender)
continue
......
......@@ -71,7 +71,7 @@ func TestPreCheckWithdrawals_InvalidSlotInStorage(t *testing.T) {
err = stateDB.Database().TrieDB().Commit(root, true)
require.NoError(t, err)
_, err = PreCheckWithdrawals(stateDB, nil)
_, err = PreCheckWithdrawals(stateDB, nil, nil)
require.ErrorIs(t, err, ErrUnknownSlotInMessagePasser)
}
......@@ -130,5 +130,5 @@ func runPrecheck(t *testing.T, dbWds []*LegacyWithdrawal, witnessWds []*LegacyWi
err = stateDB.Database().TrieDB().Commit(root, true)
require.NoError(t, err)
return PreCheckWithdrawals(stateDB, witnessWds)
return PreCheckWithdrawals(stateDB, witnessWds, nil)
}
MSG|0x4200000000000000000000000000000000000007|cafa81dc000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001a4cbd4ece900000000000000000000000099c9fc46f92e8a1c0dec1b1747d010903e884be1000000000000000000000000420000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000019bd000000000000000000000000000000000000000000000000000000000000000e4a9f9e675000000000000000000000000d533a949740bb3306d119cc777fa900ba034cd520000000000000000000000000994206dfe8de6ec6920ff4d779b0d950605fb53000000000000000000000000e3a44dd2a8c108be56a78635121ec914074da16d000000000000000000000000e3a44dd2a8c108be56a78635121ec914074da16d0000000000000000000000000000000000000000000001b0ac98ab3858d7547800000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
MSG|0x8B1d477410344785ff1DF52500032E6D5f532EE4|cafa81dc000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030420690000000000000000000000000000000000000000000000000000000000
ETH|0x6340d44c5174588B312F545eEC4a42f8a514eF50
\ No newline at end of file
package crossdomain
import (
"fmt"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
// DangerousUnfilteredWithdrawals is a list of raw withdrawal witness
......@@ -30,3 +33,35 @@ type WithdrawalMessage interface {
Hash() (common.Hash, error)
StorageSlot() (common.Hash, error)
}
// InvalidMessage represents a message to the L1 message passer that
// cannot be decoded as a withdrawal. They are defined as a separate
// type in order to completely disambiguate them from any other
// message.
type InvalidMessage SentMessage
func (msg *InvalidMessage) Encode() ([]byte, error) {
out := make([]byte, len(msg.Msg)+20)
copy(out, msg.Msg)
copy(out[len(msg.Msg):], msg.Who.Bytes())
return out, nil
}
func (msg *InvalidMessage) Hash() (common.Hash, error) {
bytes, err := msg.Encode()
if err != nil {
return common.Hash{}, fmt.Errorf("cannot hash: %w", err)
}
return crypto.Keccak256Hash(bytes), nil
}
func (msg *InvalidMessage) StorageSlot() (common.Hash, error) {
hash, err := msg.Hash()
if err != nil {
return common.Hash{}, fmt.Errorf("cannot compute storage slot: %w", err)
}
preimage := make([]byte, 64)
copy(preimage, hash.Bytes())
return crypto.Keccak256Hash(preimage), nil
}
package crossdomain
import (
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
func TestInvalidMessage(t *testing.T) {
tests := []struct {
name string
msg InvalidMessage
slot common.Hash
}{
{
name: "unparseable x-domain message on mainnet",
msg: InvalidMessage{
Who: common.HexToAddress("0x8b1d477410344785ff1df52500032e6d5f532ee4"),
Msg: common.FromHex("0x042069"),
},
slot: common.HexToHash("0x2a49ae6579c3878f10cf87ecdbebc6c4e2b2159ffe2b1af88af6ca9697fc32cb"),
},
{
name: "valid x-domain message on mainnet for validation",
msg: InvalidMessage{
Who: common.HexToAddress("0x4200000000000000000000000000000000000007"),
Msg: common.FromHex("" +
"0xcbd4ece900000000000000000000000099c9fc46f92e8a1c0dec1b1747d01090" +
"3e884be100000000000000000000000042000000000000000000000000000000" +
"0000001000000000000000000000000000000000000000000000000000000000" +
"0000008000000000000000000000000000000000000000000000000000000000" +
"00019be200000000000000000000000000000000000000000000000000000000" +
"000000e4a9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a" +
"2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837c" +
"a1490cca17c31607000000000000000000000000a420b2d1c0841415a695b81e" +
"5b867bcd07dff8c9000000000000000000000000c186fa914353c44b2e33ebe0" +
"5f21846f1048beda000000000000000000000000000000000000000000000000" +
"00000000295d681d000000000000000000000000000000000000000000000000" +
"00000000000000c0000000000000000000000000000000000000000000000000" +
"0000000000000000000000000000000000000000000000000000000000000000" +
"00000000",
),
},
slot: common.HexToHash("0x8f8f6be7a4c5048f46ca41897181d17c10c39365ead5ac27c23d1e8e466d0ed5"),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
// StorageSlot() tests Hash() and Encode() so we don't
// need to test these separately.
slot, err := test.msg.StorageSlot()
require.NoError(t, err)
require.Equal(t, test.slot, slot)
})
}
}
package migration
package crossdomain
import (
"bufio"
"encoding/json"
"fmt"
"os"
"strings"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
)
// SentMessageJSON represents an entry in the JSON file that is created by
// SentMessage represents an entry in the JSON file that is created by
// the `migration-data` package. Each entry represents a call to the
// `LegacyMessagePasser`. The `who` should always be the
// `L2CrossDomainMessenger` and the `msg` should be an abi encoded
......@@ -20,10 +24,10 @@ type SentMessage struct {
Msg hexutil.Bytes `json:"msg"`
}
// NewSentMessageJSON will read a JSON file from disk given a path to the JSON
// NewSentMessageFromJSON will read a JSON file from disk given a path to the JSON
// file. The JSON file this function reads from disk is an output from the
// `migration-data` package.
func NewSentMessage(path string) ([]*SentMessage, error) {
func NewSentMessageFromJSON(path string) ([]*SentMessage, error) {
file, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("cannot find sent message json at %s: %w", path, err)
......@@ -37,15 +41,81 @@ func NewSentMessage(path string) ([]*SentMessage, error) {
return j, nil
}
// ReadWitnessData will read messages and addresses from a raw l2geth state
// dump file.
func ReadWitnessData(path string) ([]*SentMessage, OVMETHAddresses, error) {
f, err := os.Open(path)
if err != nil {
return nil, nil, fmt.Errorf("cannot open witness data file: %w", err)
}
defer f.Close()
scan := bufio.NewScanner(f)
var witnesses []*SentMessage
addresses := make(map[common.Address]bool)
for scan.Scan() {
line := scan.Text()
splits := strings.Split(line, "|")
if len(splits) < 2 {
return nil, nil, fmt.Errorf("invalid line: %s", line)
}
switch splits[0] {
case "MSG":
if len(splits) != 3 {
return nil, nil, fmt.Errorf("invalid line: %s", line)
}
msg := splits[2]
// Make sure that the witness data has a 0x prefix
if !strings.HasPrefix(msg, "0x") {
msg = "0x" + msg
}
abi, err := bindings.LegacyMessagePasserMetaData.GetAbi()
if err != nil {
return nil, nil, fmt.Errorf("failed to get abi: %w", err)
}
msgB := hexutil.MustDecode(msg)
method, err := abi.MethodById(msgB[:4])
if err != nil {
return nil, nil, fmt.Errorf("failed to get method: %w", err)
}
out, err := method.Inputs.Unpack(msgB[4:])
if err != nil {
return nil, nil, fmt.Errorf("failed to unpack: %w", err)
}
cast, ok := out[0].([]byte)
if !ok {
return nil, nil, fmt.Errorf("failed to cast to bytes")
}
witnesses = append(witnesses, &SentMessage{
Who: common.HexToAddress(splits[1]),
Msg: cast,
})
case "ETH":
addresses[common.HexToAddress(splits[1])] = true
default:
return nil, nil, fmt.Errorf("invalid line: %s", line)
}
}
return witnesses, addresses, nil
}
// ToLegacyWithdrawal will convert a SentMessageJSON to a LegacyWithdrawal
// struct. This is useful because the LegacyWithdrawal struct has helper
// functions on it that can compute the withdrawal hash and the storage slot.
func (s *SentMessage) ToLegacyWithdrawal() (*crossdomain.LegacyWithdrawal, error) {
func (s *SentMessage) ToLegacyWithdrawal() (*LegacyWithdrawal, error) {
data := make([]byte, len(s.Who)+len(s.Msg))
copy(data, s.Msg)
copy(data[len(s.Msg):], s.Who[:])
var w crossdomain.LegacyWithdrawal
var w LegacyWithdrawal
if err := w.Decode(data); err != nil {
return nil, err
}
......@@ -117,26 +187,26 @@ type MigrationData struct {
EvmMessages []*SentMessage
}
func (m *MigrationData) ToWithdrawals() (crossdomain.DangerousUnfilteredWithdrawals, error) {
messages := make(crossdomain.DangerousUnfilteredWithdrawals, 0)
func (m *MigrationData) ToWithdrawals() (DangerousUnfilteredWithdrawals, []InvalidMessage, error) {
messages := make(DangerousUnfilteredWithdrawals, 0)
invalidMessages := make([]InvalidMessage, 0)
for _, msg := range m.OvmMessages {
wd, err := msg.ToLegacyWithdrawal()
if err != nil {
return nil, err
return nil, nil, fmt.Errorf("error serializing OVM message: %w", err)
}
messages = append(messages, wd)
if err != nil {
return nil, err
}
}
for _, msg := range m.EvmMessages {
wd, err := msg.ToLegacyWithdrawal()
if err != nil {
return nil, err
log.Warn("Discovered mal-formed withdrawal", "who", msg.Who, "data", msg.Msg)
invalidMessages = append(invalidMessages, InvalidMessage(*msg))
continue
}
messages = append(messages, wd)
}
return messages, nil
return messages, invalidMessages, nil
}
func (m *MigrationData) Addresses() []common.Address {
......
package crossdomain
import (
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
func TestRead(t *testing.T) {
witnesses, addresses, err := ReadWitnessData("testdata/witness.txt")
require.NoError(t, err)
require.Equal(t, []*SentMessage{
{
Who: common.HexToAddress("0x4200000000000000000000000000000000000007"),
Msg: common.FromHex(
"0xcbd4ece900000000000000000000000099c9fc46f92e8a1c0dec1b1747d01090" +
"3e884be100000000000000000000000042000000000000000000000000000000" +
"0000001000000000000000000000000000000000000000000000000000000000" +
"0000008000000000000000000000000000000000000000000000000000000000" +
"00019bd000000000000000000000000000000000000000000000000000000000" +
"000000e4a9f9e675000000000000000000000000d533a949740bb3306d119cc7" +
"77fa900ba034cd520000000000000000000000000994206dfe8de6ec6920ff4d" +
"779b0d950605fb53000000000000000000000000e3a44dd2a8c108be56a78635" +
"121ec914074da16d000000000000000000000000e3a44dd2a8c108be56a78635" +
"121ec914074da16d0000000000000000000000000000000000000000000001b0" +
"ac98ab3858d75478000000000000000000000000000000000000000000000000" +
"00000000000000c0000000000000000000000000000000000000000000000000" +
"0000000000000000000000000000000000000000000000000000000000000000" +
"00000000",
),
},
{
Who: common.HexToAddress("0x8b1d477410344785ff1df52500032e6d5f532ee4"),
Msg: common.FromHex("0x042069"),
},
}, witnesses)
require.Equal(t, OVMETHAddresses{
common.HexToAddress("0x6340d44c5174588B312F545eEC4a42f8a514eF50"): true,
}, addresses)
}
......@@ -8,9 +8,9 @@ import (
"io"
"strings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis/migration"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/ethdb"
......@@ -105,7 +105,7 @@ func IterateAllowanceList(r io.Reader, cb AllowanceCB) error {
func IterateMintEvents(db ethdb.Database, headNum uint64, cb AddressCBWithHead, progressCb func(uint64)) error {
for headNum > 0 {
hash := rawdb.ReadCanonicalHash(db, headNum)
receipts, err := migration.ReadLegacyReceipts(db, hash, headNum)
receipts, err := crossdomain.ReadLegacyReceipts(db, hash, headNum)
if err != nil {
return err
}
......
......@@ -4,9 +4,10 @@ import (
"fmt"
"math/big"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis/migration"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-chain-ops/util"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/log"
......@@ -30,7 +31,7 @@ var (
func MigrateLegacyETH(db *state.StateDB, addresses []common.Address, chainID int, noCheck bool) error {
// Chain params to use for integrity checking.
params := migration.ParamsByChainID[chainID]
params := crossdomain.ParamsByChainID[chainID]
if params == nil {
return fmt.Errorf("no chain params for %d", chainID)
}
......@@ -47,7 +48,7 @@ func MigrateLegacyETH(db *state.StateDB, addresses []common.Address, chainID int
// Migrate the legacy ETH to ETH.
log.Info("Migrating legacy ETH to ETH", "num-accounts", len(addresses))
totalMigrated := new(big.Int)
logAccountProgress := ProgressLogger(1000, "imported accounts")
logAccountProgress := util.ProgressLogger(1000, "imported accounts")
for addr := range deduped {
// No accounts should have a balance in state. If they do, bail.
if db.GetBalance(addr).Sign() > 0 {
......
package ether
import (
"errors"
"fmt"
"math/big"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis/migration"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-chain-ops/util"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/ethdb"
......@@ -17,9 +19,9 @@ import (
// slots in the LegacyERC20ETH contract. We don't have to filter out extra addresses like we do for
// withdrawals because we'll simply carry the balance of a given address to the new system, if the
// account is extra then it won't have any balance and nothing will happen.
func PreCheckBalances(ldb ethdb.Database, db *state.StateDB, addresses []common.Address, allowances []*migration.Allowance, chainID int, noCheck bool) ([]common.Address, error) {
func PreCheckBalances(ldb ethdb.Database, db *state.StateDB, addresses []common.Address, allowances []*crossdomain.Allowance, chainID int, noCheck bool) ([]common.Address, error) {
// Chain params to use for integrity checking.
params := migration.ParamsByChainID[chainID]
params := crossdomain.ParamsByChainID[chainID]
if params == nil {
return nil, fmt.Errorf("no chain params for %d", chainID)
}
......@@ -53,7 +55,10 @@ func PreCheckBalances(ldb ethdb.Database, db *state.StateDB, addresses []common.
// slots that we know we can ignore (totalSupply, name, symbol).
var count int
slotsAct := make(map[common.Hash]common.Hash)
progress := util.ProgressLogger(1000, "Read OVM_ETH storage slot")
err := db.ForEachStorage(predeploys.LegacyERC20ETHAddr, func(key, value common.Hash) bool {
progress()
// We can safely ignore specific slots (totalSupply, name, symbol).
if ignoredSlots[key] {
return true
......@@ -75,13 +80,16 @@ func PreCheckBalances(ldb ethdb.Database, db *state.StateDB, addresses []common.
// keep track of the total balance to be migrated and throw if the total supply exceeds the
// expected supply delta.
totalFound := new(big.Int)
var unknown bool
for slot := range slotsAct {
slotType, ok := slotsInp[slot]
if !ok {
if noCheck {
log.Error("ignoring unknown storage slot in state", "slot", slot)
log.Error("ignoring unknown storage slot in state", "slot", slot.String())
} else {
log.Crit("unknown storage slot in state: %s", slot)
unknown = true
log.Error("unknown storage slot in state", "slot", slot.String())
continue
}
}
......@@ -102,6 +110,9 @@ func PreCheckBalances(ldb ethdb.Database, db *state.StateDB, addresses []common.
}
}
}
if unknown {
return nil, errors.New("unknown storage slots in state (see logs for details)")
}
// Verify the supply delta. Recorded total supply in the LegacyERC20ETH contract may be higher
// than the actual migrated amount because self-destructs will remove ETH supply in a way that
......
......@@ -19,7 +19,6 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis/migration"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
)
......@@ -89,7 +88,7 @@ var (
// PostCheckMigratedDB will check that the migration was performed correctly
func PostCheckMigratedDB(
ldb ethdb.Database,
migrationData migration.MigrationData,
migrationData crossdomain.MigrationData,
l1XDM *common.Address,
l1ChainID uint64,
finalSystemOwner common.Address,
......@@ -468,8 +467,8 @@ func PostCheckL1Block(db vm.StateDB, info *derive.L1BlockInfo) error {
return nil
}
func CheckWithdrawalsAfter(db vm.StateDB, data migration.MigrationData, l1CrossDomainMessenger *common.Address) error {
wds, err := data.ToWithdrawals()
func CheckWithdrawalsAfter(db vm.StateDB, data crossdomain.MigrationData, l1CrossDomainMessenger *common.Address) error {
wds, invalidMessages, err := data.ToWithdrawals()
if err != nil {
return err
}
......@@ -479,6 +478,7 @@ func CheckWithdrawalsAfter(db vm.StateDB, data migration.MigrationData, l1CrossD
// some witness data may references withdrawals that reverted.
oldToNewSlots := make(map[common.Hash]common.Hash)
wdsByOldSlot := make(map[common.Hash]*crossdomain.LegacyWithdrawal)
invalidMessagesByOldSlot := make(map[common.Hash]crossdomain.InvalidMessage)
for _, wd := range wds {
migrated, err := crossdomain.MigrateWithdrawal(wd, l1CrossDomainMessenger)
if err != nil {
......@@ -497,6 +497,15 @@ func CheckWithdrawalsAfter(db vm.StateDB, data migration.MigrationData, l1CrossD
oldToNewSlots[legacySlot] = migratedSlot
wdsByOldSlot[legacySlot] = wd
}
for _, im := range invalidMessages {
invalidSlot, err := im.StorageSlot()
if err != nil {
return fmt.Errorf("cannot compute legacy storage slot: %w", err)
}
invalidMessagesByOldSlot[invalidSlot] = im
}
log.Info("computed withdrawal storage slots", "migrated", len(oldToNewSlots), "invalid", len(invalidMessagesByOldSlot))
// Now, iterate over each legacy withdrawal and check if there is a corresponding
// migrated withdrawal.
......@@ -515,6 +524,17 @@ func CheckWithdrawalsAfter(db vm.StateDB, data migration.MigrationData, l1CrossD
return false
}
// Make sure invalid slots don't get migrated.
_, isInvalidSlot := invalidMessagesByOldSlot[key]
if isInvalidSlot {
value := db.GetState(predeploys.L2ToL1MessagePasserAddr, key)
if value != abiFalse {
innerErr = fmt.Errorf("expected invalid slot not to be migrated, but got %s", value)
return false
}
return true
}
// Grab the migrated slot.
migratedSlot := oldToNewSlots[key]
if migratedSlot == (common.Hash{}) {
......
......@@ -8,7 +8,6 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-chain-ops/ether"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis/migration"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
......@@ -35,7 +34,7 @@ type MigrationResult struct {
}
// MigrateDB will migrate an l2geth legacy Optimism database to a Bedrock database.
func MigrateDB(ldb ethdb.Database, config *DeployConfig, l1Block *types.Block, migrationData *migration.MigrationData, commit, noCheck bool) (*MigrationResult, error) {
func MigrateDB(ldb ethdb.Database, config *DeployConfig, l1Block *types.Block, migrationData *crossdomain.MigrationData, commit, noCheck bool) (*MigrationResult, error) {
// Grab the hash of the tip of the legacy chain.
hash := rawdb.ReadHeadHeaderHash(ldb)
log.Info("Reading chain tip from database", "hash", hash)
......@@ -114,17 +113,19 @@ func MigrateDB(ldb ethdb.Database, config *DeployConfig, l1Block *types.Block, m
// Convert all input messages into legacy messages. Note that this list is not yet filtered and
// may be missing some messages or have some extra messages.
unfilteredWithdrawals, err := migrationData.ToWithdrawals()
unfilteredWithdrawals, invalidMessages, err := migrationData.ToWithdrawals()
if err != nil {
return nil, fmt.Errorf("cannot serialize withdrawals: %w", err)
}
log.Info("Read withdrawals from witness data", "unfiltered", len(unfilteredWithdrawals), "invalid", len(invalidMessages))
// We now need to check that we have all of the withdrawals that we expect to have. An error
// will be thrown if there are any missing messages, and any extra messages will be removed.
var filteredWithdrawals crossdomain.SafeFilteredWithdrawals
if !noCheck {
log.Info("Checking withdrawals...")
filteredWithdrawals, err = crossdomain.PreCheckWithdrawals(db, unfilteredWithdrawals)
filteredWithdrawals, err = crossdomain.PreCheckWithdrawals(db, unfilteredWithdrawals, invalidMessages)
if err != nil {
return nil, fmt.Errorf("withdrawals mismatch: %w", err)
}
......
......@@ -5,8 +5,9 @@ import (
"math/big"
"path/filepath"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis/migration"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/ethclient"
)
......@@ -30,28 +31,28 @@ type Config struct {
func Migrate(cfg *Config) (*genesis.MigrationResult, error) {
deployConfig := cfg.DeployConfig
ovmAddresses, err := migration.NewAddresses(cfg.OVMAddressesPath)
ovmAddresses, err := crossdomain.NewAddresses(cfg.OVMAddressesPath)
if err != nil {
return nil, err
}
evmAddresess, err := migration.NewAddresses(cfg.EVMAddressesPath)
evmAddresess, err := crossdomain.NewAddresses(cfg.EVMAddressesPath)
if err != nil {
return nil, err
}
ovmAllowances, err := migration.NewAllowances(cfg.OVMAllowancesPath)
ovmAllowances, err := crossdomain.NewAllowances(cfg.OVMAllowancesPath)
if err != nil {
return nil, err
}
ovmMessages, err := migration.NewSentMessage(cfg.OVMMessagesPath)
ovmMessages, err := crossdomain.NewSentMessageFromJSON(cfg.OVMMessagesPath)
if err != nil {
return nil, err
}
evmMessages, err := migration.NewSentMessage(cfg.EVMMessagesPath)
evmMessages, err := crossdomain.NewSentMessageFromJSON(cfg.EVMMessagesPath)
if err != nil {
return nil, err
}
migrationData := migration.MigrationData{
migrationData := crossdomain.MigrationData{
OvmAddresses: ovmAddresses,
EvmAddresses: evmAddresess,
OvmAllowances: ovmAllowances,
......
package ether
package util
import (
"github.com/ethereum/go-ethereum/log"
......
......@@ -184,42 +184,68 @@ func (s *L1Replica) L1Client(t Testing, cfg *rollup.Config) *sources.L1Client {
return l1F
}
// ActL1FinalizeNext finalizes the next block, which must be marked as safe before doing so (see ActL1SafeNext).
func (s *L1Replica) ActL1FinalizeNext(t Testing) {
func (s *L1Replica) UnsafeNum() uint64 {
head := s.l1Chain.CurrentBlock()
headNum := uint64(0)
if head != nil {
headNum = head.NumberU64()
}
return headNum
}
func (s *L1Replica) SafeNum() uint64 {
safe := s.l1Chain.CurrentSafeBlock()
safeNum := uint64(0)
if safe != nil {
safeNum = safe.NumberU64()
}
return safeNum
}
func (s *L1Replica) FinalizedNum() uint64 {
finalized := s.l1Chain.CurrentFinalizedBlock()
finalizedNum := uint64(0)
if finalized != nil {
finalizedNum = finalized.NumberU64()
}
if safeNum <= finalizedNum {
return finalizedNum
}
// ActL1Finalize finalizes a later block, which must be marked as safe before doing so (see ActL1SafeNext).
func (s *L1Replica) ActL1Finalize(t Testing, num uint64) {
safeNum := s.SafeNum()
finalizedNum := s.FinalizedNum()
if safeNum < num {
t.InvalidAction("need to move forward safe block before moving finalized block")
return
}
next := s.l1Chain.GetBlockByNumber(finalizedNum + 1)
if next == nil {
t.Fatalf("expected next block after finalized L1 block %d, safe head is ahead", finalizedNum)
newFinalized := s.l1Chain.GetBlockByNumber(num)
if newFinalized == nil {
t.Fatalf("expected block at %d after finalized L1 block %d, safe head is ahead", num, finalizedNum)
}
s.l1Chain.SetFinalized(next)
s.l1Chain.SetFinalized(newFinalized)
}
// ActL1SafeNext marks the next unsafe block as safe.
func (s *L1Replica) ActL1SafeNext(t Testing) {
safe := s.l1Chain.CurrentSafeBlock()
safeNum := uint64(0)
if safe != nil {
safeNum = safe.NumberU64()
}
next := s.l1Chain.GetBlockByNumber(safeNum + 1)
if next == nil {
t.InvalidAction("if head of chain is marked as safe then there's no next block")
// ActL1FinalizeNext finalizes the next block, which must be marked as safe before doing so (see ActL1SafeNext).
func (s *L1Replica) ActL1FinalizeNext(t Testing) {
n := s.FinalizedNum() + 1
s.ActL1Finalize(t, n)
}
// ActL1Safe marks the given unsafe block as safe.
func (s *L1Replica) ActL1Safe(t Testing, num uint64) {
newSafe := s.l1Chain.GetBlockByNumber(num)
if newSafe == nil {
t.InvalidAction("could not find L1 block %d, cannot label it as safe", num)
return
}
s.l1Chain.SetSafe(next)
s.l1Chain.SetSafe(newSafe)
}
// ActL1SafeNext marks the next unsafe block as safe.
func (s *L1Replica) ActL1SafeNext(t Testing) {
n := s.SafeNum() + 1
s.ActL1Safe(t, n)
}
func (s *L1Replica) Close() error {
......
......@@ -196,6 +196,62 @@ func TestL2Finalization(gt *testing.T) {
require.Equal(t, heightToSubmit, sequencer.SyncStatus().FinalizedL2.Number, "unknown/bad finalized L1 blocks are ignored")
}
// TestL2FinalizationWithSparseL1 tests that safe L2 blocks can be finalized even if we do not regularly get a L1 finalization signal
func TestL2FinalizationWithSparseL1(gt *testing.T) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug)
miner, engine, sequencer := setupSequencerTest(t, sd, log)
sequencer.ActL2PipelineFull(t)
miner.ActEmptyBlock(t)
sequencer.ActL1HeadSignal(t)
sequencer.ActBuildToL1Head(t)
startStatus := sequencer.SyncStatus()
require.Less(t, startStatus.SafeL2.Number, startStatus.UnsafeL2.Number, "sequencer has unsafe L2 block")
batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{
MinL1TxSize: 0,
MaxL1TxSize: 128_000,
BatcherKey: dp.Secrets.Batcher,
}, sequencer.RollupClient(), miner.EthClient(), engine.EthClient())
batcher.ActSubmitAll(t)
// include in L1
miner.ActL1StartBlock(12)(t)
miner.ActL1IncludeTx(dp.Addresses.Batcher)(t)
miner.ActL1EndBlock(t)
// Make 2 L1 blocks without batches
miner.ActEmptyBlock(t)
miner.ActEmptyBlock(t)
// See the L1 head, and traverse the pipeline to it
sequencer.ActL1HeadSignal(t)
sequencer.ActL2PipelineFull(t)
updatedStatus := sequencer.SyncStatus()
require.Equal(t, updatedStatus.SafeL2.Number, updatedStatus.UnsafeL2.Number, "unsafe L2 block is now safe")
require.Less(t, updatedStatus.FinalizedL2.Number, updatedStatus.UnsafeL2.Number, "submitted block is not yet finalized")
// Now skip straight to the head with L1 signals (sequencer has traversed the L1 blocks, but they did not have L2 contents)
headL1Num := miner.UnsafeNum()
miner.ActL1Safe(t, headL1Num)
miner.ActL1Finalize(t, headL1Num)
sequencer.ActL1SafeSignal(t)
sequencer.ActL1FinalizedSignal(t)
// Now see if the signals can be processed
sequencer.ActL2PipelineFull(t)
finalStatus := sequencer.SyncStatus()
// Verify the signal was processed, even though we signalled a later L1 block than the one with the batch.
require.Equal(t, finalStatus.FinalizedL2.Number, finalStatus.UnsafeL2.Number, "sequencer submitted its L2 block and it finalized")
}
// TestGarbageBatch tests the behavior of an invalid/malformed output channel frame containing
// valid batches being submitted to the batch inbox. These batches should always be rejected
// and the safe L2 head should remain unaltered.
......
......@@ -4,8 +4,6 @@ import (
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"
......@@ -144,24 +142,19 @@ func TestL2Sequencer_SequencerOnlyReorg(gt *testing.T) {
// so it'll keep the L2 block with the old L1 origin, since no conflict is detected.
sequencer.ActL1HeadSignal(t)
sequencer.ActL2PipelineFull(t)
// TODO: CLI-3405 we can detect the inconsistency of the L1 origin of the unsafe L2 head:
// as verifier, there is no need to wait for sequencer to recognize it.
// Verifier should detect the inconsistency of the L1 origin and reset the pipeline to follow the reorg
newStatus := sequencer.SyncStatus()
require.Equal(t, status.HeadL1.Hash, newStatus.UnsafeL2.L1Origin.Hash, "still have old bad L1 origin")
require.Zero(t, newStatus.UnsafeL2.L1Origin.Number, "back to genesis block with good L1 origin, drop old unsafe L2 chain with bad L1 origins")
require.NotEqual(t, status.HeadL1.Hash, newStatus.HeadL1.Hash, "did see the new L1 head change")
require.Equal(t, newStatus.HeadL1.Hash, newStatus.CurrentL1.Hash, "did sync the new L1 head as verifier")
// the block N+1 cannot build on the old N which still refers to the now orphaned L1 origin
require.Equal(t, status.UnsafeL2.L1Origin.Number, newStatus.HeadL1.Number-1, "seeing N+1 to attempt to build on N")
require.NotEqual(t, status.UnsafeL2.L1Origin.Hash, newStatus.HeadL1.ParentHash, "but N+1 cannot fit on N")
sequencer.ActL1HeadSignal(t)
// sequence more L2 blocks, until we actually need the next L1 origin
sequencer.ActBuildToL1HeadExclUnsafe(t)
// We expect block building to fail when the next L1 block is not consistent with the existing L1 origin
sequencer.ActL2StartBlockCheckErr(t, derive.ErrReset)
// After hitting a reset error, it reset derivation, and drops the old L1 chain
// After hitting a reset error, it resets derivation, and drops the old L1 chain
sequencer.ActL2PipelineFull(t)
require.Zero(t, sequencer.SyncStatus().UnsafeL2.L1Origin.Number, "back to genesis block with good L1 origin, drop old unsafe L2 chain with bad L1 origins")
// Can build new L2 blocks with good L1 origin
sequencer.ActBuildToL1HeadUnsafe(t)
require.Equal(t, newStatus.HeadL1.Hash, sequencer.SyncStatus().UnsafeL2.L1Origin.Hash, "build L2 chain with new correct L1 origins")
......
......@@ -12,6 +12,7 @@ import (
"time"
bss "github.com/ethereum-optimism/optimism/op-batcher/batcher"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/sources"
l2os "github.com/ethereum-optimism/optimism/op-proposer/proposer"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
......@@ -311,7 +312,9 @@ func TestMigration(t *testing.T) {
},
L1EpochPollInterval: 4 * time.Second,
}
rollupNode, err := node.New(ctx, rollupNodeConfig, log.New(), snapLog, "", metrics.NewMetrics(""))
rollupLog := log.New()
rollupNodeConfig.Rollup.LogDescription(rollupLog, chaincfg.L2ChainIDToNetworkName)
rollupNode, err := node.New(ctx, rollupNodeConfig, rollupLog, snapLog, "", metrics.NewMetrics(""))
require.NoError(t, err)
require.NoError(t, rollupNode.Start(ctx))
......
......@@ -8,6 +8,7 @@ import (
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
......@@ -371,6 +372,12 @@ func TestRegolith(t *testing.T) {
tx, _, err := opGeth.L2Client.TransactionByHash(ctx, contractCreateTx.Hash())
require.NoError(t, err)
require.Equal(t, expectedNonce, *tx.EffectiveNonce(), "should report actual tx nonce")
// Should be able to search for logs even though there are deposit transactions in blocks.
logs, err := opGeth.L2Client.FilterLogs(ctx, ethereum.FilterQuery{})
require.NoError(t, err)
require.NotNil(t, logs)
require.Empty(t, logs)
})
t.Run("ReturnUnusedGasToPool_"+test.name, func(t *testing.T) {
......
......@@ -26,6 +26,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/metrics"
rollupNode "github.com/ethereum-optimism/optimism/op-node/node"
......@@ -468,6 +469,8 @@ func (cfg SystemConfig) Start() (*System, error) {
}
}
c.Rollup.LogDescription(cfg.Loggers[name], chaincfg.L2ChainIDToNetworkName)
node, err := rollupNode.New(context.Background(), &c, cfg.Loggers[name], snapLog, "", metrics.NewMetrics(""))
if err != nil {
didErrAfterStart = true
......
......@@ -415,6 +415,7 @@ func TestMixedDepositValidity(t *testing.T) {
// TestMixedWithdrawalValidity makes a number of withdrawal transactions and ensures ones with modified parameters are
// rejected while unmodified ones are accepted. This runs test cases in different systems.
func TestMixedWithdrawalValidity(t *testing.T) {
parallel(t)
// Setup our logger handler
if !verboseGethNodes {
log.Root().SetHandler(log.DiscardHandler())
......@@ -424,7 +425,6 @@ func TestMixedWithdrawalValidity(t *testing.T) {
for i := 0; i <= 8; i++ {
i := i // avoid loop var capture
t.Run(fmt.Sprintf("withdrawal test#%d", i+1), func(t *testing.T) {
parallel(t)
// Create our system configuration, funding all accounts we created for L1/L2, and start it
cfg := DefaultSystemConfig(t)
cfg.DeployConfig.FinalizationPeriodSeconds = 6
......
package fetch
import (
"context"
"encoding/json"
"fmt"
"log"
"math/big"
"os"
"path"
"time"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
)
type TransactionWithMeta struct {
TxIndex uint64 `json:"tx_index"`
InboxAddr common.Address `json:"inbox_address"`
BlockNumber uint64 `json:"block_number"`
BlockHash common.Hash `json:"block_hash"`
ChainId uint64 `json:"chain_id"`
Sender common.Address `json:"sender"`
ValidSender bool `json:"valid_sender"`
Frames []derive.Frame `json:"frames"`
FrameErr string `json:"frame_parse_error"`
ValidFrames bool `json:"valid_data"`
Tx *types.Transaction `json:"tx"`
}
type Config struct {
Start, End uint64
ChainID *big.Int
BatchInbox common.Address
BatchSenders map[common.Address]struct{}
OutDirectory string
}
func Batches(client *ethclient.Client, config Config) (totalValid, totalInvalid int) {
if err := os.MkdirAll(config.OutDirectory, 0750); err != nil {
log.Fatal(err)
}
number := new(big.Int).SetUint64(config.Start)
signer := types.LatestSignerForChainID(config.ChainID)
for i := config.Start; i < config.End; i++ {
valid, invalid := fetchBatchesPerBlock(client, number, signer, config)
totalValid += valid
totalInvalid += invalid
number = number.Add(number, common.Big1)
}
return
}
func fetchBatchesPerBlock(client *ethclient.Client, number *big.Int, signer types.Signer, config Config) (validBatchCount, invalidBatchCount int) {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
block, err := client.BlockByNumber(ctx, number)
if err != nil {
log.Fatal(err)
}
for i, tx := range block.Transactions() {
if tx.To() != nil && *tx.To() == config.BatchInbox {
sender, err := signer.Sender(tx)
if err != nil {
log.Fatal(err)
}
validSender := true
if _, ok := config.BatchSenders[sender]; !ok {
fmt.Printf("Found a transaction (%s) from an invalid sender (%s)\n", tx.Hash().String(), sender.String())
invalidBatchCount += 1
validSender = false
}
validFrames := true
frameError := ""
frames, err := derive.ParseFrames(tx.Data())
if err != nil {
fmt.Printf("Found a transaction (%s) with invalid data: %v\n", tx.Hash().String(), err)
validFrames = false
frameError = err.Error()
}
if validSender && validFrames {
validBatchCount += 1
} else {
invalidBatchCount += 1
}
txm := &TransactionWithMeta{
Tx: tx,
Sender: sender,
ValidSender: validSender,
TxIndex: uint64(i),
BlockNumber: block.NumberU64(),
BlockHash: block.Hash(),
ChainId: config.ChainID.Uint64(),
InboxAddr: config.BatchInbox,
Frames: frames,
FrameErr: frameError,
ValidFrames: validFrames,
}
filename := path.Join(config.OutDirectory, fmt.Sprintf("%s.json", tx.Hash().String()))
file, err := os.Create(filename)
if err != nil {
log.Fatal(err)
}
defer file.Close()
enc := json.NewEncoder(file)
if err := enc.Encode(txm); err != nil {
log.Fatal(err)
}
}
}
return
}
package main
import (
"context"
"fmt"
"log"
"os"
"time"
"github.com/ethereum-optimism/optimism/op-node/cmd/batch_decoder/fetch"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/urfave/cli"
)
func main() {
app := cli.NewApp()
app.Name = "batch-decoder"
app.Usage = "Optimism Batch Decoding Utility"
app.Commands = []cli.Command{
{
Name: "fetch",
Usage: "Fetches batches in the specified range",
Flags: []cli.Flag{
cli.IntFlag{
Name: "start",
Required: true,
Usage: "First block (inclusive) to fetch",
},
cli.IntFlag{
Name: "end",
Required: true,
Usage: "Last block (exclusive) to fetch",
},
cli.StringFlag{
Name: "inbox",
Required: true,
Usage: "Batch Inbox Address",
},
cli.StringFlag{
Name: "sender",
Required: true,
Usage: "Batch Sender Address",
},
cli.StringFlag{
Name: "out",
Value: "/tmp/batch_decoder/transactions_cache",
Usage: "Cache directory for the found transactions",
},
cli.StringFlag{
Name: "l1",
Required: true,
Usage: "L1 RPC URL",
EnvVar: "L1_RPC",
},
},
Action: func(cliCtx *cli.Context) error {
client, err := ethclient.Dial(cliCtx.String("l1"))
if err != nil {
log.Fatal(err)
}
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
chainID, err := client.ChainID(ctx)
if err != nil {
log.Fatal(err)
}
config := fetch.Config{
Start: uint64(cliCtx.Int("start")),
End: uint64(cliCtx.Int("end")),
ChainID: chainID,
BatchSenders: map[common.Address]struct{}{
common.HexToAddress(cliCtx.String("sender")): struct{}{},
},
BatchInbox: common.HexToAddress(cliCtx.String("inbox")),
OutDirectory: cliCtx.String("out"),
}
totalValid, totalInvalid := fetch.Batches(client, config)
fmt.Printf("Fetched batches in range [%v,%v). Found %v valid & %v invalid batches\n", config.Start, config.End, totalValid, totalInvalid)
fmt.Printf("Fetch Config: Chain ID: %v. Inbox Address: %v. Valid Senders: %v.\n", config.ChainID, config.BatchInbox, config.BatchSenders)
fmt.Printf("Wrote transactions with batches to %v\n", config.OutDirectory)
return nil
},
},
}
if err := app.Run(os.Args); err != nil {
log.Fatal(err)
}
}
......@@ -8,6 +8,7 @@ import (
"strconv"
"syscall"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/cmd/doc"
"github.com/urfave/cli"
......@@ -22,6 +23,7 @@ import (
"github.com/ethereum-optimism/optimism/op-node/metrics"
"github.com/ethereum-optimism/optimism/op-node/node"
"github.com/ethereum-optimism/optimism/op-node/version"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
)
......@@ -48,12 +50,7 @@ var VersionWithMeta = func() string {
func main() {
// Set up logger with a default INFO level in case we fail to parse flags,
// otherwise the final critical log won't show what the parsing error was.
log.Root().SetHandler(
log.LvlFilterHandler(
log.LvlInfo,
log.StreamHandler(os.Stdout, log.TerminalFormat(true)),
),
)
oplog.SetupDefaults()
app := cli.NewApp()
app.Version = VersionWithMeta
......@@ -85,12 +82,12 @@ func main() {
func RollupNodeMain(ctx *cli.Context) error {
log.Info("Initializing Rollup Node")
logCfg, err := opnode.NewLogConfig(ctx)
if err != nil {
logCfg := oplog.ReadCLIConfig(ctx)
if err := logCfg.Check(); err != nil {
log.Error("Unable to create the log config", "error", err)
return err
}
log := logCfg.NewLogger()
log := oplog.NewLogger(logCfg)
m := metrics.NewMetrics("default")
cfg, err := opnode.NewConfig(ctx, log)
......@@ -104,6 +101,13 @@ func RollupNodeMain(ctx *cli.Context) error {
return err
}
// Only pretty-print the banner if it is a terminal log. Other log it as key-value pairs.
if logCfg.Format == "terminal" {
log.Info("rollup config:\n" + cfg.Rollup.Description(chaincfg.L2ChainIDToNetworkName))
} else {
cfg.Rollup.LogDescription(log, chaincfg.L2ChainIDToNetworkName)
}
n, err := node.New(context.Background(), cfg, log, snapshotLog, VersionWithMeta, m)
if err != nil {
log.Error("Unable to create the rollup node", "error", err)
......
package node
import (
"fmt"
"os"
"strings"
"golang.org/x/term"
"github.com/ethereum/go-ethereum/log"
)
type LogConfig struct {
Level string // Log level: trace, debug, info, warn, error, crit. Capitals are accepted too.
Color bool // Color the log output. Defaults to true if terminal is detected.
Format string // Format the log output. Supported formats: 'text', 'json'
}
func DefaultLogConfig() LogConfig {
return LogConfig{
Level: "info",
Format: "text",
Color: term.IsTerminal(int(os.Stdout.Fd())),
}
}
// Check verifes that the LogConfig is valid. Calls to `NewLogger` may fail if this
// returns an error.
func (cfg *LogConfig) Check() error {
switch cfg.Format {
case "json", "json-pretty", "terminal", "text":
default:
return fmt.Errorf("unrecognized log format: %s", cfg.Format)
}
level := strings.ToLower(cfg.Level) // ignore case
_, err := log.LvlFromString(level)
if err != nil {
return fmt.Errorf("unrecognized log level: %w", err)
}
return nil
}
// NewLogger creates a logger based on the supplied configuration
func (cfg *LogConfig) NewLogger() log.Logger {
handler := log.StreamHandler(os.Stdout, format(cfg.Format, cfg.Color))
handler = log.SyncHandler(handler)
handler = log.LvlFilterHandler(level(cfg.Level), handler)
logger := log.New()
logger.SetHandler(handler)
return logger
}
// format turns a string and color into a structured Format object
func format(lf string, color bool) log.Format {
switch lf {
case "json":
return log.JSONFormat()
case "json-pretty":
return log.JSONFormatEx(true, true)
case "text", "terminal":
return log.TerminalFormat(color)
default:
panic("Failed to create `log.Format` from options")
}
}
// level parses the level string into an appropriate object
func level(s string) log.Lvl {
s = strings.ToLower(s) // ignore case
l, err := log.LvlFromString(s)
if err != nil {
panic(fmt.Sprintf("Could not parse log level: %v", err))
}
return l
}
......@@ -13,7 +13,6 @@ import (
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/client"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/metrics"
......@@ -62,8 +61,6 @@ func New(ctx context.Context, cfg *Config, log log.Logger, snapshotLog log.Logge
// not a context leak, gossipsub is closed with a context.
n.resourcesCtx, n.resourcesClose = context.WithCancel(context.Background())
log.Info("rollup config:\n" + cfg.Rollup.Description(chaincfg.L2ChainIDToNetworkName))
err := n.init(ctx, cfg, snapshotLog)
if err != nil {
log.Error("Error initializing the rollup node", "err", err)
......
......@@ -208,13 +208,6 @@ func (eq *EngineQueue) SafeL2Head() eth.L2BlockRef {
return eq.safeHead
}
func (eq *EngineQueue) LastL2Time() uint64 {
if len(eq.safeAttributes) == 0 {
return eq.safeHead.Time
}
return uint64(eq.safeAttributes[len(eq.safeAttributes)-1].Timestamp)
}
func (eq *EngineQueue) Step(ctx context.Context) error {
if eq.needForkchoiceUpdate {
return eq.tryUpdateEngine(ctx)
......@@ -224,7 +217,13 @@ func (eq *EngineQueue) Step(ctx context.Context) error {
}
outOfData := false
if len(eq.safeAttributes) == 0 {
eq.origin = eq.prev.Origin()
newOrigin := eq.prev.Origin()
// Check if the L2 unsafe head origin is consistent with the new origin
if err := eq.verifyNewL1Origin(ctx, newOrigin); err != nil {
return err
}
eq.origin = newOrigin
eq.postProcessSafeL2() // make sure we track the last L2 safe head for every new L1 block
if next, err := eq.prev.NextAttributes(ctx, eq.safeHead); err == io.EOF {
outOfData = true
} else if err != nil {
......@@ -245,6 +244,38 @@ func (eq *EngineQueue) Step(ctx context.Context) error {
}
}
// verifyNewL1Origin checks that the L2 unsafe head still has a L1 origin that is on the canonical chain.
// If the unsafe head origin is after the new L1 origin it is assumed to still be canonical.
// The check is only required when moving to a new L1 origin.
func (eq *EngineQueue) verifyNewL1Origin(ctx context.Context, newOrigin eth.L1BlockRef) error {
if newOrigin == eq.origin {
return nil
}
unsafeOrigin := eq.unsafeHead.L1Origin
if newOrigin.Number == unsafeOrigin.Number && newOrigin.ID() != unsafeOrigin {
return NewResetError(fmt.Errorf("l1 origin was inconsistent with l2 unsafe head origin, need reset to resolve: l1 origin: %v; unsafe origin: %v",
newOrigin.ID(), unsafeOrigin))
}
// Avoid requesting an older block by checking against the parent hash
if newOrigin.Number == unsafeOrigin.Number+1 && newOrigin.ParentHash != unsafeOrigin.Hash {
return NewResetError(fmt.Errorf("l2 unsafe head origin is no longer canonical, need reset to resolve: canonical hash: %v; unsafe origin hash: %v",
newOrigin.ParentHash, unsafeOrigin.Hash))
}
if newOrigin.Number > unsafeOrigin.Number+1 {
// If unsafe origin is further behind new origin, check it's still on the canonical chain.
canonical, err := eq.l1Fetcher.L1BlockRefByNumber(ctx, unsafeOrigin.Number)
if err != nil {
return NewTemporaryError(fmt.Errorf("failed to fetch canonical L1 block at slot: %v; err: %w", unsafeOrigin.Number, err))
}
if canonical.ID() != unsafeOrigin {
eq.log.Error("Resetting due to origin mismatch")
return NewResetError(fmt.Errorf("l2 unsafe head origin is no longer canonical, need reset to resolve: canonical: %v; unsafe origin: %v",
canonical, unsafeOrigin))
}
}
return nil
}
// tryFinalizeL2 traverses the past L1 blocks, checks if any has been finalized,
// and then marks the latest fully derived L2 block from this as finalized,
// or defaults to the current finalized L2 block.
......@@ -279,9 +310,15 @@ func (eq *EngineQueue) postProcessSafeL2() {
L2Block: eq.safeHead,
L1Block: eq.origin.ID(),
})
last := &eq.finalityData[len(eq.finalityData)-1]
eq.log.Debug("extended finality-data", "last_l1", last.L1Block, "last_l2", last.L2Block)
} else {
// if it's a now L2 block that was derived from the same latest L1 block, then just update the entry
eq.finalityData[len(eq.finalityData)-1].L2Block = eq.safeHead
// if it's a new L2 block that was derived from the same latest L1 block, then just update the entry
last := &eq.finalityData[len(eq.finalityData)-1]
if last.L2Block != eq.safeHead { // avoid logging if there are no changes
last.L2Block = eq.safeHead
eq.log.Debug("updated finality-data", "last_l1", last.L1Block, "last_l2", last.L2Block)
}
}
}
......
......@@ -265,3 +265,575 @@ func TestEngineQueue_Finalize(t *testing.T) {
l1F.AssertExpectations(t)
eng.AssertExpectations(t)
}
func TestEngineQueue_ResetWhenUnsafeOriginNotCanonical(t *testing.T) {
logger := testlog.Logger(t, log.LvlInfo)
rng := rand.New(rand.NewSource(1234))
l1Time := uint64(2)
refA := testutils.RandomBlockRef(rng)
refB := eth.L1BlockRef{
Hash: testutils.RandomHash(rng),
Number: refA.Number + 1,
ParentHash: refA.Hash,
Time: refA.Time + l1Time,
}
refC := eth.L1BlockRef{
Hash: testutils.RandomHash(rng),
Number: refB.Number + 1,
ParentHash: refB.Hash,
Time: refB.Time + l1Time,
}
refD := eth.L1BlockRef{
Hash: testutils.RandomHash(rng),
Number: refC.Number + 1,
ParentHash: refC.Hash,
Time: refC.Time + l1Time,
}
refE := eth.L1BlockRef{
Hash: testutils.RandomHash(rng),
Number: refD.Number + 1,
ParentHash: refD.Hash,
Time: refD.Time + l1Time,
}
refF := eth.L1BlockRef{
Hash: testutils.RandomHash(rng),
Number: refE.Number + 1,
ParentHash: refE.Hash,
Time: refE.Time + l1Time,
}
refA0 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: 0,
ParentHash: common.Hash{},
Time: refA.Time,
L1Origin: refA.ID(),
SequenceNumber: 0,
}
cfg := &rollup.Config{
Genesis: rollup.Genesis{
L1: refA.ID(),
L2: refA0.ID(),
L2Time: refA0.Time,
},
BlockTime: 1,
SeqWindowSize: 2,
}
refA1 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refA0.Number + 1,
ParentHash: refA0.Hash,
Time: refA0.Time + cfg.BlockTime,
L1Origin: refA.ID(),
SequenceNumber: 1,
}
refB0 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refA1.Number + 1,
ParentHash: refA1.Hash,
Time: refA1.Time + cfg.BlockTime,
L1Origin: refB.ID(),
SequenceNumber: 0,
}
refB1 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refB0.Number + 1,
ParentHash: refB0.Hash,
Time: refB0.Time + cfg.BlockTime,
L1Origin: refB.ID(),
SequenceNumber: 1,
}
refC0 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refB1.Number + 1,
ParentHash: refB1.Hash,
Time: refB1.Time + cfg.BlockTime,
L1Origin: refC.ID(),
SequenceNumber: 0,
}
refC1 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refC0.Number + 1,
ParentHash: refC0.Hash,
Time: refC0.Time + cfg.BlockTime,
L1Origin: refC.ID(),
SequenceNumber: 1,
}
refD0 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refC1.Number + 1,
ParentHash: refC1.Hash,
Time: refC1.Time + cfg.BlockTime,
L1Origin: refD.ID(),
SequenceNumber: 0,
}
refD1 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refD0.Number + 1,
ParentHash: refD0.Hash,
Time: refD0.Time + cfg.BlockTime,
L1Origin: refD.ID(),
SequenceNumber: 1,
}
refE0 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refD1.Number + 1,
ParentHash: refD1.Hash,
Time: refD1.Time + cfg.BlockTime,
L1Origin: refE.ID(),
SequenceNumber: 0,
}
refE1 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refE0.Number + 1,
ParentHash: refE0.Hash,
Time: refE0.Time + cfg.BlockTime,
L1Origin: refE.ID(),
SequenceNumber: 1,
}
refF0 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refE1.Number + 1,
ParentHash: refE1.Hash,
Time: refE1.Time + cfg.BlockTime,
L1Origin: refF.ID(),
SequenceNumber: 0,
}
refF1 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refF0.Number + 1,
ParentHash: refF0.Hash,
Time: refF0.Time + cfg.BlockTime,
L1Origin: refF.ID(),
SequenceNumber: 1,
}
t.Log("refA", refA.Hash)
t.Log("refB", refB.Hash)
t.Log("refC", refC.Hash)
t.Log("refD", refD.Hash)
t.Log("refE", refE.Hash)
t.Log("refF", refF.Hash)
t.Log("refA0", refA0.Hash)
t.Log("refA1", refA1.Hash)
t.Log("refB0", refB0.Hash)
t.Log("refB1", refB1.Hash)
t.Log("refC0", refC0.Hash)
t.Log("refC1", refC1.Hash)
t.Log("refD0", refD0.Hash)
t.Log("refD1", refD1.Hash)
t.Log("refE0", refE0.Hash)
t.Log("refE1", refE1.Hash)
t.Log("refF0", refF0.Hash)
t.Log("refF1", refF1.Hash)
metrics := &testutils.TestDerivationMetrics{}
eng := &testutils.MockEngine{}
// we find the common point to initialize to by comparing the L1 origins in the L2 chain with the L1 chain
l1F := &testutils.MockL1Source{}
eng.ExpectL2BlockRefByLabel(eth.Finalized, refA1, nil)
eng.ExpectL2BlockRefByLabel(eth.Safe, refE0, nil)
eng.ExpectL2BlockRefByLabel(eth.Unsafe, refF1, nil)
// unsafe
l1F.ExpectL1BlockRefByNumber(refF.Number, refF, nil)
eng.ExpectL2BlockRefByHash(refF1.ParentHash, refF0, nil)
eng.ExpectL2BlockRefByHash(refF0.ParentHash, refE1, nil)
// meet previous safe, counts 1/2
l1F.ExpectL1BlockRefByNumber(refE.Number, refE, nil)
eng.ExpectL2BlockRefByHash(refE1.ParentHash, refE0, nil)
eng.ExpectL2BlockRefByHash(refE0.ParentHash, refD1, nil)
// now full seq window, inclusive
l1F.ExpectL1BlockRefByNumber(refD.Number, refD, nil)
eng.ExpectL2BlockRefByHash(refD1.ParentHash, refD0, nil)
eng.ExpectL2BlockRefByHash(refD0.ParentHash, refC1, nil)
// now one more L1 origin
l1F.ExpectL1BlockRefByNumber(refC.Number, refC, nil)
eng.ExpectL2BlockRefByHash(refC1.ParentHash, refC0, nil)
// parent of that origin will be considered safe
eng.ExpectL2BlockRefByHash(refC0.ParentHash, refB1, nil)
// and we fetch the L1 origin of that as starting point for engine queue
l1F.ExpectL1BlockRefByHash(refB.Hash, refB, nil)
l1F.ExpectL1BlockRefByHash(refB.Hash, refB, nil)
// and mock a L1 config for the last L2 block that references the L1 starting point
eng.ExpectSystemConfigByL2Hash(refB1.Hash, eth.SystemConfig{
BatcherAddr: common.Address{42},
Overhead: [32]byte{123},
Scalar: [32]byte{42},
GasLimit: 20_000_000,
}, nil)
prev := &fakeAttributesQueue{origin: refE}
eq := NewEngineQueue(logger, cfg, eng, metrics, prev, l1F)
require.ErrorIs(t, eq.Reset(context.Background(), eth.L1BlockRef{}, eth.SystemConfig{}), 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.Origin(), "Expecting to be set back derivation L1 progress to B")
require.Equal(t, refA1, eq.Finalized(), "A1 is recognized as finalized before we run any steps")
// First step after reset will do a fork choice update
require.True(t, eq.needForkchoiceUpdate)
eng.ExpectForkchoiceUpdate(&eth.ForkchoiceState{
HeadBlockHash: eq.unsafeHead.Hash,
SafeBlockHash: eq.safeHead.Hash,
FinalizedBlockHash: eq.finalized.Hash,
}, nil, &eth.ForkchoiceUpdatedResult{PayloadStatus: eth.PayloadStatusV1{Status: eth.ExecutionValid}}, nil)
err := eq.Step(context.Background())
require.NoError(t, err)
require.Equal(t, refF.ID(), eq.unsafeHead.L1Origin, "should have refF as unsafe head origin")
// L1 chain reorgs so new origin is at same slot as refF but on a different fork
prev.origin = eth.L1BlockRef{
Hash: testutils.RandomHash(rng),
Number: refF.Number,
ParentHash: refE.Hash,
Time: refF.Time,
}
eq.UnsafeL2Head()
err = eq.Step(context.Background())
require.ErrorIs(t, err, ErrReset, "should reset pipeline due to mismatched origin")
l1F.AssertExpectations(t)
eng.AssertExpectations(t)
}
func TestVerifyNewL1Origin(t *testing.T) {
logger := testlog.Logger(t, log.LvlInfo)
rng := rand.New(rand.NewSource(1234))
l1Time := uint64(2)
refA := testutils.RandomBlockRef(rng)
refB := eth.L1BlockRef{
Hash: testutils.RandomHash(rng),
Number: refA.Number + 1,
ParentHash: refA.Hash,
Time: refA.Time + l1Time,
}
refC := eth.L1BlockRef{
Hash: testutils.RandomHash(rng),
Number: refB.Number + 1,
ParentHash: refB.Hash,
Time: refB.Time + l1Time,
}
refD := eth.L1BlockRef{
Hash: testutils.RandomHash(rng),
Number: refC.Number + 1,
ParentHash: refC.Hash,
Time: refC.Time + l1Time,
}
refE := eth.L1BlockRef{
Hash: testutils.RandomHash(rng),
Number: refD.Number + 1,
ParentHash: refD.Hash,
Time: refD.Time + l1Time,
}
refF := eth.L1BlockRef{
Hash: testutils.RandomHash(rng),
Number: refE.Number + 1,
ParentHash: refE.Hash,
Time: refE.Time + l1Time,
}
refG := eth.L1BlockRef{
Hash: testutils.RandomHash(rng),
Number: refF.Number + 1,
ParentHash: refF.Hash,
Time: refF.Time + l1Time,
}
refH := eth.L1BlockRef{
Hash: testutils.RandomHash(rng),
Number: refG.Number + 1,
ParentHash: refG.Hash,
Time: refG.Time + l1Time,
}
refA0 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: 0,
ParentHash: common.Hash{},
Time: refA.Time,
L1Origin: refA.ID(),
SequenceNumber: 0,
}
cfg := &rollup.Config{
Genesis: rollup.Genesis{
L1: refA.ID(),
L2: refA0.ID(),
L2Time: refA0.Time,
},
BlockTime: 1,
SeqWindowSize: 2,
}
refA1 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refA0.Number + 1,
ParentHash: refA0.Hash,
Time: refA0.Time + cfg.BlockTime,
L1Origin: refA.ID(),
SequenceNumber: 1,
}
refB0 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refA1.Number + 1,
ParentHash: refA1.Hash,
Time: refA1.Time + cfg.BlockTime,
L1Origin: refB.ID(),
SequenceNumber: 0,
}
refB1 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refB0.Number + 1,
ParentHash: refB0.Hash,
Time: refB0.Time + cfg.BlockTime,
L1Origin: refB.ID(),
SequenceNumber: 1,
}
refC0 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refB1.Number + 1,
ParentHash: refB1.Hash,
Time: refB1.Time + cfg.BlockTime,
L1Origin: refC.ID(),
SequenceNumber: 0,
}
refC1 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refC0.Number + 1,
ParentHash: refC0.Hash,
Time: refC0.Time + cfg.BlockTime,
L1Origin: refC.ID(),
SequenceNumber: 1,
}
refD0 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refC1.Number + 1,
ParentHash: refC1.Hash,
Time: refC1.Time + cfg.BlockTime,
L1Origin: refD.ID(),
SequenceNumber: 0,
}
refD1 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refD0.Number + 1,
ParentHash: refD0.Hash,
Time: refD0.Time + cfg.BlockTime,
L1Origin: refD.ID(),
SequenceNumber: 1,
}
refE0 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refD1.Number + 1,
ParentHash: refD1.Hash,
Time: refD1.Time + cfg.BlockTime,
L1Origin: refE.ID(),
SequenceNumber: 0,
}
refE1 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refE0.Number + 1,
ParentHash: refE0.Hash,
Time: refE0.Time + cfg.BlockTime,
L1Origin: refE.ID(),
SequenceNumber: 1,
}
refF0 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refE1.Number + 1,
ParentHash: refE1.Hash,
Time: refE1.Time + cfg.BlockTime,
L1Origin: refF.ID(),
SequenceNumber: 0,
}
refF1 := eth.L2BlockRef{
Hash: testutils.RandomHash(rng),
Number: refF0.Number + 1,
ParentHash: refF0.Hash,
Time: refF0.Time + cfg.BlockTime,
L1Origin: refF.ID(),
SequenceNumber: 1,
}
t.Log("refA", refA.Hash)
t.Log("refB", refB.Hash)
t.Log("refC", refC.Hash)
t.Log("refD", refD.Hash)
t.Log("refE", refE.Hash)
t.Log("refF", refF.Hash)
t.Log("refG", refG.Hash)
t.Log("refH", refH.Hash)
t.Log("refA0", refA0.Hash)
t.Log("refA1", refA1.Hash)
t.Log("refB0", refB0.Hash)
t.Log("refB1", refB1.Hash)
t.Log("refC0", refC0.Hash)
t.Log("refC1", refC1.Hash)
t.Log("refD0", refD0.Hash)
t.Log("refD1", refD1.Hash)
t.Log("refE0", refE0.Hash)
t.Log("refE1", refE1.Hash)
t.Log("refF0", refF0.Hash)
t.Log("refF1", refF1.Hash)
metrics := &testutils.TestDerivationMetrics{}
tests := []struct {
name string
newOrigin eth.L1BlockRef
expectReset bool
expectedFetchBlocks map[uint64]eth.L1BlockRef
}{
{
name: "L1OriginBeforeUnsafeOrigin",
newOrigin: refD,
expectReset: false,
},
{
name: "Matching",
newOrigin: refF,
expectReset: false,
},
{
name: "BlockNumberEqualDifferentHash",
newOrigin: eth.L1BlockRef{
Hash: testutils.RandomHash(rng),
Number: refF.Number,
ParentHash: refE.Hash,
Time: refF.Time,
},
expectReset: true,
},
{
name: "UnsafeIsParent",
newOrigin: refG,
expectReset: false,
},
{
name: "UnsafeIsParentNumberDifferentHash",
newOrigin: eth.L1BlockRef{
Hash: testutils.RandomHash(rng),
Number: refG.Number,
ParentHash: testutils.RandomHash(rng),
Time: refG.Time,
},
expectReset: true,
},
{
name: "UnsafeIsOlderCanonical",
newOrigin: refH,
expectReset: false,
expectedFetchBlocks: map[uint64]eth.L1BlockRef{
refF.Number: refF,
},
},
{
name: "UnsafeIsOlderNonCanonical",
newOrigin: eth.L1BlockRef{
Hash: testutils.RandomHash(rng),
Number: refH.Number,
ParentHash: testutils.RandomHash(rng),
Time: refH.Time,
},
expectReset: true,
expectedFetchBlocks: map[uint64]eth.L1BlockRef{
// Second look up gets a different block in F's block number due to a reorg
refF.Number: {
Hash: testutils.RandomHash(rng),
Number: refF.Number,
ParentHash: refE.Hash,
Time: refF.Time,
},
},
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
eng := &testutils.MockEngine{}
// we find the common point to initialize to by comparing the L1 origins in the L2 chain with the L1 chain
l1F := &testutils.MockL1Source{}
eng.ExpectL2BlockRefByLabel(eth.Finalized, refA1, nil)
eng.ExpectL2BlockRefByLabel(eth.Safe, refE0, nil)
eng.ExpectL2BlockRefByLabel(eth.Unsafe, refF1, nil)
// unsafe
l1F.ExpectL1BlockRefByNumber(refF.Number, refF, nil)
eng.ExpectL2BlockRefByHash(refF1.ParentHash, refF0, nil)
eng.ExpectL2BlockRefByHash(refF0.ParentHash, refE1, nil)
for blockNum, block := range test.expectedFetchBlocks {
l1F.ExpectL1BlockRefByNumber(blockNum, block, nil)
}
// meet previous safe, counts 1/2
l1F.ExpectL1BlockRefByNumber(refE.Number, refE, nil)
eng.ExpectL2BlockRefByHash(refE1.ParentHash, refE0, nil)
eng.ExpectL2BlockRefByHash(refE0.ParentHash, refD1, nil)
// now full seq window, inclusive
l1F.ExpectL1BlockRefByNumber(refD.Number, refD, nil)
eng.ExpectL2BlockRefByHash(refD1.ParentHash, refD0, nil)
eng.ExpectL2BlockRefByHash(refD0.ParentHash, refC1, nil)
// now one more L1 origin
l1F.ExpectL1BlockRefByNumber(refC.Number, refC, nil)
eng.ExpectL2BlockRefByHash(refC1.ParentHash, refC0, nil)
// parent of that origin will be considered safe
eng.ExpectL2BlockRefByHash(refC0.ParentHash, refB1, nil)
// and we fetch the L1 origin of that as starting point for engine queue
l1F.ExpectL1BlockRefByHash(refB.Hash, refB, nil)
l1F.ExpectL1BlockRefByHash(refB.Hash, refB, nil)
// and mock a L1 config for the last L2 block that references the L1 starting point
eng.ExpectSystemConfigByL2Hash(refB1.Hash, eth.SystemConfig{
BatcherAddr: common.Address{42},
Overhead: [32]byte{123},
Scalar: [32]byte{42},
GasLimit: 20_000_000,
}, nil)
prev := &fakeAttributesQueue{origin: refE}
eq := NewEngineQueue(logger, cfg, eng, metrics, prev, l1F)
require.ErrorIs(t, eq.Reset(context.Background(), eth.L1BlockRef{}, eth.SystemConfig{}), 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.Origin(), "Expecting to be set back derivation L1 progress to B")
require.Equal(t, refA1, eq.Finalized(), "A1 is recognized as finalized before we run any steps")
// First step after reset will do a fork choice update
require.True(t, eq.needForkchoiceUpdate)
eng.ExpectForkchoiceUpdate(&eth.ForkchoiceState{
HeadBlockHash: eq.unsafeHead.Hash,
SafeBlockHash: eq.safeHead.Hash,
FinalizedBlockHash: eq.finalized.Hash,
}, nil, &eth.ForkchoiceUpdatedResult{PayloadStatus: eth.PayloadStatusV1{Status: eth.ExecutionValid}}, nil)
err := eq.Step(context.Background())
require.NoError(t, err)
require.Equal(t, refF.ID(), eq.unsafeHead.L1Origin, "should have refF as unsafe head origin")
// L1 chain reorgs so new origin is at same slot as refF but on a different fork
prev.origin = test.newOrigin
eq.UnsafeL2Head()
err = eq.Step(context.Background())
if test.expectReset {
require.ErrorIs(t, err, ErrReset, "should reset pipeline due to mismatched origin")
} else {
require.ErrorIs(t, err, io.EOF, "should not reset pipeline")
}
l1F.AssertExpectations(t)
eng.AssertExpectations(t)
})
}
}
......@@ -24,10 +24,10 @@ const MaxFrameLen = 1_000_000
// is_last = bool
type Frame struct {
ID ChannelID
FrameNumber uint16
Data []byte
IsLast bool
ID ChannelID `json:"id"`
FrameNumber uint16 `json:"frame_number"`
Data []byte `json:"data"`
IsLast bool `'json:"is_last"`
}
// MarshalBinary writes the frame to `w`.
......
package derive
import (
"encoding/hex"
"errors"
"fmt"
)
......@@ -44,3 +45,19 @@ func (id ChannelID) String() string {
func (id ChannelID) TerminalString() string {
return fmt.Sprintf("%x..%x", id[:3], id[13:])
}
func (id ChannelID) MarshalText() ([]byte, error) {
return []byte(id.String()), nil
}
func (id *ChannelID) UnmarshalText(text []byte) error {
h, err := hex.DecodeString(string(text))
if err != nil {
return err
}
if len(h) != ChannelIDLength {
return errors.New("invalid length")
}
copy(id[:], h)
return nil
}
......@@ -9,6 +9,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum-optimism/optimism/op-node/eth"
......@@ -271,6 +272,28 @@ func (c *Config) Description(l2Chains map[string]string) string {
return banner
}
// Description outputs a banner describing the important parts of rollup configuration in a log format.
// Optionally provide a mapping of L2 chain IDs to network names to label the L2 chain with if not unknown.
// The config should be config.Check()-ed before creating a description.
func (c *Config) LogDescription(log log.Logger, l2Chains map[string]string) {
// Find and report the network the user is running
networkL2 := ""
if l2Chains != nil {
networkL2 = l2Chains[c.L2ChainID.String()]
}
if networkL2 == "" {
networkL2 = "unknown L2"
}
networkL1 := params.NetworkNames[c.L1ChainID.String()]
if networkL1 == "" {
networkL1 = "unknown L1"
}
log.Info("Rollup Config", "l2_chain_id", c.L2ChainID, "l2_network", networkL2, "l1_chain_id", c.L1ChainID,
"l1_network", networkL1, "l2_start_time", c.Genesis.L2Time, "l2_block_hash", c.Genesis.L2.Hash.String(),
"l2_block_number", c.Genesis.L2.Number, "l1_block_hash", c.Genesis.L1.Hash.String(),
"l1_block_number", c.Genesis.L1.Number, "regolith_time", fmtForkTimeOrUnset(c.RegolithTime))
}
func fmtForkTimeOrUnset(v *uint64) string {
if v == nil {
return "(not configured)"
......
......@@ -168,21 +168,6 @@ func NewRollupConfig(ctx *cli.Context) (*rollup.Config, error) {
return &rollupConfig, nil
}
// NewLogConfig creates a log config from the provided flags or environment variables.
func NewLogConfig(ctx *cli.Context) (node.LogConfig, error) {
cfg := node.DefaultLogConfig() // Done to set color based on terminal type
cfg.Level = ctx.GlobalString(flags.LogLevelFlag.Name)
cfg.Format = ctx.GlobalString(flags.LogFormatFlag.Name)
if ctx.IsSet(flags.LogColorFlag.Name) {
cfg.Color = ctx.GlobalBool(flags.LogColorFlag.Name)
}
if err := cfg.Check(); err != nil {
return cfg, err
}
return cfg, nil
}
func NewSnapshotLogger(ctx *cli.Context) (log.Logger, error) {
snapshotFile := ctx.GlobalString(flags.SnapshotLog.Name)
handler := log.DiscardHandler()
......
......@@ -92,7 +92,7 @@ func Main(version string, cliCtx *cli.Context) error {
}
rpcCfg := cfg.RPCConfig
server := oprpc.NewServer(rpcCfg.ListenAddr, rpcCfg.ListenPort, version)
server := oprpc.NewServer(rpcCfg.ListenAddr, rpcCfg.ListenPort, version, oprpc.WithLogger(l))
if err := server.Start(); err != nil {
cancel()
return fmt.Errorf("error starting RPC server: %w", err)
......
......@@ -28,13 +28,13 @@ func CLIFlags(envPrefix string) []cli.Flag {
},
cli.StringFlag{
Name: FormatFlagName,
Usage: "Format the log output. Supported formats: 'text', 'json'",
Usage: "Format the log output. Supported formats: 'text', 'terminal', 'logfmt', 'json', 'json-pretty',",
Value: "text",
EnvVar: opservice.PrefixEnvVar(envPrefix, "LOG_FORMAT"),
},
cli.BoolFlag{
Name: ColorFlagName,
Usage: "Color the log output",
Usage: "Color the log output if in terminal mode",
EnvVar: opservice.PrefixEnvVar(envPrefix, "LOG_COLOR"),
},
}
......@@ -43,12 +43,12 @@ func CLIFlags(envPrefix string) []cli.Flag {
type CLIConfig struct {
Level string // Log level: trace, debug, info, warn, error, crit. Capitals are accepted too.
Color bool // Color the log output. Defaults to true if terminal is detected.
Format string // Format the log output. Supported formats: 'text', 'json'
Format string // Format the log output. Supported formats: 'text', 'terminal', 'logfmt', 'json', 'json-pretty'
}
func (cfg CLIConfig) Check() error {
switch cfg.Format {
case "json", "json-pretty", "terminal", "text":
case "json", "json-pretty", "terminal", "text", "logfmt":
default:
return fmt.Errorf("unrecognized log format: %s", cfg.Format)
}
......@@ -65,6 +65,9 @@ func NewLogger(cfg CLIConfig) log.Logger {
handler := log.StreamHandler(os.Stdout, Format(cfg.Format, cfg.Color))
handler = log.SyncHandler(handler)
handler = log.LvlFilterHandler(Level(cfg.Level), handler)
// Set the root handle to what we have configured. Some components like go-ethereum's RPC
// server use log.Root() instead of being able to pass in a log.
log.Root().SetHandler(handler)
logger := log.New()
logger.SetHandler(handler)
return logger
......@@ -82,7 +85,9 @@ func ReadLocalCLIConfig(ctx *cli.Context) CLIConfig {
cfg := DefaultCLIConfig()
cfg.Level = ctx.String(LevelFlagName)
cfg.Format = ctx.String(FormatFlagName)
if ctx.IsSet(ColorFlagName) {
cfg.Color = ctx.Bool(ColorFlagName)
}
return cfg
}
......@@ -90,7 +95,9 @@ func ReadCLIConfig(ctx *cli.Context) CLIConfig {
cfg := DefaultCLIConfig()
cfg.Level = ctx.GlobalString(LevelFlagName)
cfg.Format = ctx.GlobalString(FormatFlagName)
if ctx.IsSet(ColorFlagName) {
cfg.Color = ctx.GlobalBool(ColorFlagName)
}
return cfg
}
......@@ -101,8 +108,16 @@ func Format(lf string, color bool) log.Format {
return log.JSONFormat()
case "json-pretty":
return log.JSONFormatEx(true, true)
case "text", "terminal":
case "text":
if term.IsTerminal(int(os.Stdout.Fd())) {
return log.TerminalFormat(color)
} else {
return log.LogfmtFormat()
}
case "terminal":
return log.TerminalFormat(color)
case "logfmt":
return log.LogfmtFormat()
default:
panic("Failed to create `log.Format` from options")
}
......
......@@ -10,7 +10,7 @@ func SetupDefaults() {
log.Root().SetHandler(
log.LvlFilterHandler(
log.LvlInfo,
log.StreamHandler(os.Stdout, log.TerminalFormat(true)),
log.StreamHandler(os.Stdout, log.LogfmtFormat()),
),
)
}
......@@ -17,6 +17,7 @@ import (
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
......@@ -316,6 +317,7 @@ func StoragePatch(patch io.Reader, address common.Address) HeadFn {
}
type OvmOwnersConfig struct {
Network string `json:"network"`
Owner common.Address `json:"owner"`
Sequencer common.Address `json:"sequencer"`
Proposer common.Address `json:"proposer"`
......@@ -323,17 +325,42 @@ type OvmOwnersConfig struct {
func OvmOwners(conf *OvmOwnersConfig) HeadFn {
return func(headState *state.StateDB) error {
var addressManager common.Address // Lib_AddressManager
var l1SBProxy common.Address // Proxy__OVM_L1StandardBridge
var l1XDMProxy common.Address // Proxy__OVM_L1CrossDomainMessenger
var l1ERC721BridgeProxy common.Address
switch conf.Network {
case "mainnet":
addressManager = common.HexToAddress("0xdE1FCfB0851916CA5101820A69b13a4E276bd81F")
l1SBProxy = common.HexToAddress("0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1")
l1XDMProxy = common.HexToAddress("0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1")
l1ERC721BridgeProxy = common.HexToAddress("0x5a7749f83b81B301cAb5f48EB8516B986DAef23D")
case "goerli":
addressManager = common.HexToAddress("0xa6f73589243a6A7a9023b1Fa0651b1d89c177111")
l1SBProxy = common.HexToAddress("0x636Af16bf2f682dD3109e60102b8E1A089FedAa8")
l1XDMProxy = common.HexToAddress("0x5086d1eEF304eb5284A0f6720f79403b4e9bE294")
l1ERC721BridgeProxy = common.HexToAddress("0x8DD330DdE8D9898d43b4dc840Da27A07dF91b3c9")
default:
return fmt.Errorf("unknown network: %q", conf.Network)
}
// See Proxy.sol OWNER_KEY: https://eips.ethereum.org/EIPS/eip-1967#admin-address
ownerSlot := common.HexToHash("0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103")
// Address manager owner
headState.SetState(common.HexToAddress("0xa6f73589243a6A7a9023b1Fa0651b1d89c177111"), common.Hash{}, conf.Owner.Hash())
// Ownable, first storage slot
headState.SetState(addressManager, common.Hash{}, conf.Owner.Hash())
// L1SB proxy owner
headState.SetState(common.HexToAddress("0x636Af16bf2f682dD3109e60102b8E1A089FedAa8"), common.HexToHash("0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103"), conf.Owner.Hash())
headState.SetState(l1SBProxy, ownerSlot, conf.Owner.Hash())
// L1XDM owner
headState.SetState(common.HexToAddress("0x5086d1eEF304eb5284A0f6720f79403b4e9bE294"), common.Hash{31: 0x33}, conf.Owner.Hash())
// 0x33 = 51. L1CrossDomainMessenger is L1CrossDomainMessenger (0) Lib_AddressResolver (1) OwnableUpgradeable (1, but covered by gap) + ContextUpgradeable (special gap of 50) and then _owner
headState.SetState(l1XDMProxy, common.Hash{31: 0x33}, conf.Owner.Hash())
// L1 ERC721 bridge owner
headState.SetState(common.HexToAddress("0x8DD330DdE8D9898d43b4dc840Da27A07dF91b3c9"), common.HexToHash("0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103"), conf.Owner.Hash())
headState.SetState(l1ERC721BridgeProxy, ownerSlot, conf.Owner.Hash())
// Legacy sequencer/proposer addresses
headState.SetState(common.HexToAddress("0xa6f73589243a6A7a9023b1Fa0651b1d89c177111"), common.HexToHash("0x2e0dfce60e9e27f035ce28f63c1bdd77cff6b13d8909da4d81d623ff9123fbdc"), conf.Sequencer.Hash())
headState.SetState(common.HexToAddress("0xa6f73589243a6A7a9023b1Fa0651b1d89c177111"), common.HexToHash("0x9776dbdebd0d5eedaea450b21da9901ecd5254e5136a3a9b7b0ecd532734d5b5"), conf.Proposer.Hash())
// See AddressManager.sol "addresses" mapping(bytes32 => address), at slot position 1
addressesSlot := common.BigToHash(big.NewInt(1))
headState.SetState(addressManager, crypto.Keccak256Hash(crypto.Keccak256([]byte("OVM_Sequencer")), addressesSlot.Bytes()), conf.Sequencer.Hash())
headState.SetState(addressManager, crypto.Keccak256Hash(crypto.Keccak256([]byte("OVM_Proposer")), addressesSlot.Bytes()), conf.Proposer.Hash())
// Fund sequencer and proposer with 100 ETH
headState.SetBalance(conf.Sequencer, HundredETH)
headState.SetBalance(conf.Proposer, HundredETH)
......
FROM ethereumoptimism/op-geth:optimism
FROM us-docker.pkg.dev/oplabs-tools-artifacts/images/op-geth:optimism
RUN apk add --no-cache jq
......
......@@ -100,7 +100,6 @@ services:
OP_PROPOSER_RESUBMISSION_TIMEOUT: 30s
OP_PROPOSER_MNEMONIC: test test test test test test test test test test test junk
OP_PROPOSER_L2_OUTPUT_HD_PATH: "m/44'/60'/0'/0/1"
OP_PROPOSER_LOG_TERMINAL: "true"
OP_PROPOSER_L2OO_ADDRESS: "${L2OO_ADDRESS}"
OP_PROPOSER_PPROF_ENABLED: "true"
OP_PROPOSER_METRICS_ENABLED: "true"
......@@ -134,7 +133,6 @@ services:
OP_BATCHER_RESUBMISSION_TIMEOUT: 30s
OP_BATCHER_MNEMONIC: test test test test test test test test test test test junk
OP_BATCHER_SEQUENCER_HD_PATH: "m/44'/60'/0'/0/2"
OP_BATCHER_LOG_TERMINAL: "true"
OP_BATCHER_PPROF_ENABLED: "true"
OP_BATCHER_METRICS_ENABLED: "true"
OP_BATCHER_RPC_ENABLE_ADMIN: "true"
......
......@@ -14,10 +14,10 @@ npm install @eth-optimism/atst --global
npx atst <command> [options]
```
## Commands
### Commands
read read an attestation
write write an attestation
- `read` read an attestation
- `write` write an attestation
For more info, run any command with the `--help` flag:
......@@ -26,55 +26,46 @@ npx atst read --help
npx atst write --help
```
## Options:
### General options
-h, --help Display this message
-v, --version Display version number
- `-h`, `--help` Display help message
- `-v`, `--version` Display version number
## Usage:
```bash
npx atst <command> [options]
```
Commands:
read read an attestation
write write an attestation
For more info, run any command with the `--help` flag:
```bash
npx atst read --help
npx atst write --help
```
### Read
`--creator <string> Address of the creator of the attestation`
`--about <string> Address of the subject of the attestation`
`--key <string> Key of the attestation either as string or hex number`
`--data-type [string] Zod validator for the DataType type string | bytes | number | bool | address (default: string)`
`--rpc-url [url] Rpc url to use (default: https://mainnet.optimism.io)`
`--contract [address] Contract address to read from (default: 0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77)`
`-h, --help Display this message`
- `--creator <address>` Address of the creator of the attestation
- `--about <address>` Address of the subject of the attestation
- `--key <string>` Key of the attestation either as string or hex number
- `[--data-type <string>]` The DataType type `string` | `bytes` | `number` | `bool` | `address` (default: `string`)
- `[--rpc-url <url>]` Rpc url to use (default: `https://mainnet.optimism.io`)
- `[--contract <address>]` Contract address to read from (default: `0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77`)
- `-h`, `--help` Display help message
Example:
```bash
npx atst read --key "optimist.base-uri" --about 0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5 --creator 0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3
npx atst read --key "optimist.base-uri" --about 0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5 \
--creator 0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3
```
### write
### Write
- `--private-key <string>` Private key of the creator of the attestation
- `[--data-type <string>]` The DataType type `string` | `bytes` | `number` | `bool` | `address` (default: `string`)
- `--about <address>` Address of the subject of the attestation
- `--key <address>` Key of the attestation either as string or hex number
- `--value <string>` undefined
- `[--rpc-url <url>]` Rpc url to use (default: `https://mainnet.optimism.io`)
- `[--contract <address>]` Contract address to read from (default: 0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77)
- `-h`, `--help` Display this message
`--private-key <string> Address of the creator of the attestation`
`--data-type [string] Zod validator for the DataType type string | bytes | number | bool | address (default: string)`
`--about <string> Address of the subject of the attestation`
`--key <string> Key of the attestation either as string or hex number`
`--value <string> undefined`
`--rpc-url [url] Rpc url to use (default: https://mainnet.optimism.io)`
`--contract [address] Contract address to read from (default: 0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77) -h, --help Display this message`
Example:
```bash
atst write --key "optimist.base-uri" --about 0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5 --value "my attestation" --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --rpc-url http://localhost:8545
atst/0.0.0
atst write --key "optimist.base-uri" \
--about 0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5 \
--value "my attestation" \
--private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
--rpc-url http://localhost:8545
```
......@@ -2,11 +2,26 @@
Typescript sdk for interacting with the ATST based on [@wagmi/core](https://wagmi.sh/core/getting-started)
TODO add a table of contents like [zod](https://github.com/colinhacks/zod/blob/master/README.md)
## Table of content
- [Installation](#installation)
- [Basic usage](#basic-usage)
- [Setup](#setup)
- [Reading an attestation](#reading-an-attestation)
- [Reading multiple attestation](#reading-multiple-attestations)
- [Writing an attestation](#writing-an-attestation)
- [API](#api)
- [High level API](#high-level-api)
- [Low level API](#low-level-api)
- [React API](#react-api)
- [Tutorial](#tutorial)
## Installation
Install atst and it's peer dependencies.
Install atst and its peer dependencies.
npm
......@@ -26,212 +41,223 @@ yarn
yarn add @eth-optimism/atst @wagmi/core ethers@5.7.0
```
**Note** as ethers v6 is not yet stable we only support ethers v5 at this time
**Note:** As ethers v6 is not yet stable we only support ethers v5 at this time
## Basic usage
Note: all functions are fully tested. The tests are a great example to see usage examples.
### Setup
### Basic Setup
atst uses `@wagmi/core` under the hood.
[See their documentation for more information](https://wagmi.sh/core/getting-started).
ATST uses `@wagmi/core` under the hood. See their documentation for more information.
```javascript
import ethers from "ethers"
const wagmiCore = await import("@wagmi/core")
const wagmiAlchemy = await import("@wagmi/core/providers/alchemy")
const wagmiChains = await import("@wagmi/core/chains")
```typescript
import { connect, createClient } from '@wagmi/core'
import { providers, Wallet } from 'ethers'
const provider = new providers.JsonRpcProvider({
url: parsedOptions.rpcUrl,
headers: {
'User-Agent': '@eth-optimism/atst',
},
})
const { chains, provider, webSocketProvider } = wagmiCore.configureChains(
[wagmiChains.optimismGoerli],
[wagmiAlchemy.alchemyProvider({ apiKey: process.env.ALCHEMY_API_KEY })],
)
createClient({
wagmiCore.createClient({
provider,
webSocketProvider
})
```
### Reading an attestation
To read an attestation use `readString`, `readAddress`, `readNumber`, `readBool`
Use `readAttestationString` with `bytes` passed in for the types parameter to read raw bytes
### Reading an attestation
Here is an example of reading an attestation used by the optimist nft
```typescript
import { readAttestationString } from '@eth-optimism/atst'
```javascript
import { readAttestation } from '@eth-optimism/atst'
const creator = '0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3'
const about = '0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5'
const key = 'optimist.base-uri'
const str = await readAttestationString(creator, about, key)
console.log(attestation) // https://assets.optimism.io/4a609661-6774-441f-9fdb-453fdbb89931-bucket/optimist-nft/attributes
console.log(attestation)
// https://assets.optimism.io/4a609661-6774-441f-9fdb-453fdbb89931-bucket/optimist-nft/attributes
```
### Reading multiple Attestations
### Reading multiple attestations
If reading more than one attestation you can use readAttestations to read them with multicall
If reading more than one attestation you can use [`readAttestations`](#readattestations) to read them with [multicall](https://www.npmjs.com/package/ethereum-multicall).
### Writing an attestation
To write to an attestation you must [connect](https://wagmi.sh/core/connectors/metaMask) your wagmi client if not already connected. If using Node.js use the [mock connector](https://wagmi.sh/core/connectors/mock)
To write to an attestation you must [connect](https://wagmi.sh/core/connectors/metaMask) your wagmi client if not already connected.
If using Node.js use the [mock connector](https://wagmi.sh/core/connectors/mock).
```typescript
import { prepareWriteAttestation, writeAttestation } from '@eth-optimism/sdk'
import { prepareWriteAttestation, writeAttestation } from '@eth-optimism/atst'
const preparedTx = await prepareWriteAttestation(about, key, 'hello world')
console.log(preparedTx.gasLimit)
await writeAttestation(preparedTx)
```
## API
### ATTESTATION_STATION_ADDRESS
The deterministic deployment address for the attestation station currently deployed with create2 on Optimism and Optimism Goerli `0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77`
### High level API
These functions are the easiest way to interact with the AttestationStation contract.
For a more detailed explanation, [see the tutorial](https://github.com/ethereum-optimism/optimism-tutorial/tree/main/ecosystem/attestation-station/using-sdk).
#### `getEvents`
Use `getEvents` to get attestation events using a provider and filters.
```typescript
import { ATTESTATION_STATION_ADDRESS } from '@eth-optimism/atst'
const events = await getEvents({
creator,
about,
key,
value,
provider: new ethers.providers.JsonRpcProvider('http://localhost:8545'),
fromBlockOrBlockhash,
toBlock,
})
```
### abi
Set `key`, `about`, `creator`, or `value` to `null` to not filter that value.
The abi of the attestation station
#### `prepareWriteAttestation`
[Prepares](https://wagmi.sh/core/actions/prepareWriteContract) an attestation to be written.
This function creates the transaction data, estimates the gas cost, etc.
```typescript
import { abi } from '@eth-optimism/atst'
const preparedTx = await prepareWriteAttestation(about, key, 'hello world')
console.log(preparedTx.gasFee)
```
### readAttestation
**Return Value:** A prepared transaction, ready for [`writeAttestation`](#writeattestation).
#### `readAttestation`
[Reads](https://wagmi.sh/core/actions/readContract) and parses an attestation based on it's data type.
[Reads](https://wagmi.sh/core/actions/readContract) and parses an attestation based on its data type.
```typescript
const attestation = await readAttestation(
/**
* Address: The creator of the attestation
*/
creator,
/**
* Address: The about topic of the attestation
*/
about,
/**
* string: The key of the attestation
*/
key,
/**
* 'string' | 'bytes' | 'number' | 'bool' | 'address'
* The data type of the attestation
* @defaults defaults to 'string'
*/
dataType,
/**
* Address: the contract address of the attestation station
* @defaults defaults to the create2 address
*/
contractAddress
creator, // Address: The creator of the attestation
about, // Address: The about topic of the attestation
key, // string: The key of the attestation
dataType, // Optional, the data type of the attestation, 'string' | 'bytes' | 'number' | 'bool' | 'address'
contractAddress // Optional address: the contract address of the attestation station
)
```
`Return Value` The data returned from invoking the contract method.
**Return Value:** The value attested by the `creator` on the `about` address concerning the `key`, when interpreted as the `dataType`.
If there is no such attestation the result is zero, `false`, or an empty string.
### readAttestations
#### `readAttestations`
Similar to read attestation but reads multiple attestations at once. Pass in a variadic amount of attestations to read.
Similar to `readAttestation` but reads multiple attestations at once.
Pass in a variadic amount of attestations to read.
The parameters are all the same structure type, the one shown below.
```typescript
const attestation = await readAttestations({
/**
* Address: The creator of the attestation
*/
creator,
/**
* Address: The about topic of the attestation
*/
about,
/**
* string: The key of the attestation
*/
key,
/**
* 'string' | 'bytes' | 'number' | 'bool' | 'address'
* The data type of the attestation
* @defaults defaults to 'string'
*/
dataType,
/**
* Address: the contract address of the attestation station
* @defaults defaults to the create2 address
*/
contractAddress,
})
const attestationList = await readAttestations({
creator: <creator address>,
about: <about address>,
key: <attestation key (string)>,
[dataType: <data type - 'string' | 'bytes' | 'number' | 'bool' | 'address'>,]
[contractAddress: <contract address, if not the default>]
}, {...}, {...})
```
### Parsing bytes
**Return Value:** A list of values attested by the `creator` on the `about` address concerning the `key`, when interpreted as the `dataType`.
These utilities for parsing bytes are provided:
`parseAddress`
`parseNumber`
`parseBool`
`parseString`
#### `writeAttestation`
Note: `readAttestation` and `readAttestations` already parse the bytes so this is only necessary if reading attestations directly from chain instead of through this utility
[Writes the prepared tx](https://wagmi.sh/core/actions/writeContract).
```typescript
const attestation = parseAttestationBytes(
/**
* HexString: The raw bytes returned from reading an attestation
*/
bytes,
/**
* 'string' | 'bytes' | 'number' | 'bool' | 'address'
* The data type of the attestation
* @defaults defaults to 'string'
*/
dataType
)
const preparedTx = await prepareWriteAttestation(about, key, 'hello world')
await writeAttestation(preparedTx)
```
### Low level API
These definitions allow you to communicate with AttestationStation, but are not as easy to use as the high level API.
#### `ATTESTATION_STATION_ADDRESS`
The deployment address for the attestation station currently deployed with create2 on Optimism and Optimism Goerli `0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77`.
```typescript
import { ATTESTATION_STATION_ADDRESS } from '@eth-optimism/atst'
```
### attestation keys
#### `abi`
Attestation keys are limited to 32 bytes. To support keys longer than 32 bytes, you can use the `createKey` function
The abi of the attestation station contract
```typescript
import { abi } from '@eth-optimism/atst'
```
#### `createKey`
`createKey` hashes keys longer than 31 bytes, because the atst key size is limited to 32 bytes.
```typescript
const key = await createKey(
about,
key,
'i.am.a.key.much.longer.than.32.bytes.long'
)
await writeAttestation(preparedTx)
```
createKey will keep the key as is if it is shorter than 32 bytes and otherwise run it through kekkak256
createKey will keep the key as is if it is shorter than 32 bytes and otherwise run it through keccak256.
### prepareWriteAttestation
[Prepares](https://wagmi.sh/core/actions/prepareWriteContract) an attestation to be written.
#### `parseAddress`
```typescript
const preparedTx = await prepareWriteAttestation(about, key, 'hello world')
console.log(preparedTx.gasFee)
```
Turn bytes into an address.
### stringifyAttestationBytes
**Note:** `readAttestation` and `readAttestations` already do this for you.
This is only needed if talking to the contracts directly, or through a different library.
Stringifys an attestation into raw bytes.
#### `parseBool`
Turn bytes into a boolean value.
**Note:** `readAttestation` and `readAttestations` already do this for you.
This is only needed if talking to the contracts directly, or through a different library.
#### `parseNumber`
Note: `writeAttestation` already does this for you so this is only needed if using a library other than the attestation station
Turn bytes into a number.
**Note:** `readAttestation` and `readAttestations` already do this for you.
This is only needed if talking to the contracts directly, or through a different library.
#### `parseString`
Turn bytes into a string.
**Note:** `readAttestation` and `readAttestations` already do this for you.
This is only needed if talking to the contracts directly, or through a different library.
#### `stringifyAttestationBytes`
Stringifys an attestation into raw bytes.
```typescript
const stringAttestatoin = stringifyAttestationBytes('hello world')
const stringAttestation = stringifyAttestationBytes('hello world')
const numberAttestation = stringifyAttestationBytes(500)
const hexAttestation = stringifyAttestationBytes('0x1')
const bigNumberAttestation = stringifyAttestationBytes(
......@@ -239,33 +265,24 @@ const bigNumberAttestation = stringifyAttestationBytes(
)
```
### writeAttestation
**Note:** `writeAttestation` already does this for you so this is only needed if using a library other than the attestation station.
[Writes the prepared tx](https://wagmi.sh/core/actions/writeContract)
### React API
```typescript
const preparedTx = await prepareWriteAttestation(about, key, 'hello world')
await writeAttestation(preparedTx)
```
For react hooks we recomend using the [wagmi cli](https://wagmi.sh/cli/getting-started) with the [etherscan plugin](https://wagmi.sh/cli/plugins/etherscan) and [react plugin](https://wagmi.sh/cli/plugins/react) to automatically generate react hooks around the attestation station.
### getEvents
Use `createKey` and `createValue` to convert your raw keys and values into bytes that can be used in the attestation station contract calls.
Use `parseString`, `parseBool`, `parseAddress` and `parseNumber` to convert values returned by attestation station to their correct data type.
To getEvents use getEvents with a provider and any filters to filter the event
For convenience we also [export the hooks](../src/react.ts) here:
- `useAttestationStationAttestation` - Reads attestations with useContractRead
- `useAttestationStationVersion` - Reads attestation version
- `useAttestationStationAttest` - Wraps useContractWrite with attestation station abi calling attest
- `usePrepareAttestationStationAttest` - Wraps usePrepare with attestation station abi calling attest
- `useAttestationStationAttestationCreatedEvent` - Wraps useContractEvents for Created events
```typescript
const events = await getEvents({
creator,
about,
key,
value,
provider: new ethers.providers.JsonRpcProvider('http://localhost:8545'),
fromBlockOrBlockhash,
toBlock,
})
```
Set key, about, creator, or value to `null` to not include that filter
## Tutorial
For a tutorial on using the attestation station in general, see out tutorial as well as other Optimism related tutorials in our [optimism-tutorial](https://github.com/ethereum-optimism/optimism-tutorial/tree/main/ecosystem/attestation-station#key-values) repo
For a tutorial on using the attestation station in general, see out tutorial as well as other Optimism related tutorials in our [optimism-tutorial](https://github.com/ethereum-optimism/optimism-tutorial/tree/main/ecosystem/attestation-station#key-values) repo.
......@@ -2,10 +2,24 @@
"name": "@eth-optimism/atst",
"version": "0.1.0",
"type": "module",
"main": "dist/index.js",
"main": "dist/index.cjs",
"types": "src/index.ts",
"module": "dist/index.cjs",
"module": "dist/index.js",
"license": "MIT",
"exports": {
".": {
"types": "./src/index.ts",
"default": "./dist/index.js",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"./react": {
"types": "./src/react.ts",
"default": "./dist/react.js",
"import": "./dist/react.js",
"require": "./dist/react.cjs"
}
},
"bin": {
"atst": "./dist/cli.js"
},
......
......@@ -28,5 +28,3 @@ export type { AttestationCreatedEvent } from './types/AttestationCreatedEvent'
export type { AttestationReadParams } from './types/AttestationReadParams'
export type { DataTypeOption } from './types/DataTypeOption'
export type { WagmiBytes } from './types/WagmiBytes'
// react
export * from './react'
......@@ -76,6 +76,35 @@ describe(getEvents.name, () => {
"transactionHash": "0x61f59bd4dfe54272d9369effe3ae57a0ef2584161fcf2bbd55f5596002e759bd",
"transactionIndex": 1,
},
{
"address": "0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77",
"args": [
"0xBCf86Fd70a0183433763ab0c14E7a760194f3a9F",
"0x00000000000000000000000000000000000060A7",
"0x616e696d616c6661726d2e7363686f6f6c2e617474656e646564000000000000",
"0x01",
],
"blockHash": "0x4870baaac6d7195952dc25e5dc0109ea324f819f8152d2889c7b4ad64040a9bf",
"blockNumber": 6278428,
"data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000",
"decode": [Function],
"event": "AttestationCreated",
"eventSignature": "AttestationCreated(address,address,bytes32,bytes)",
"getBlock": [Function],
"getTransaction": [Function],
"getTransactionReceipt": [Function],
"logIndex": 0,
"removeListener": [Function],
"removed": false,
"topics": [
"0x28710dfecab43d1e29e02aa56b2e1e610c0bae19135c9cf7a83a1adb6df96d85",
"0x000000000000000000000000bcf86fd70a0183433763ab0c14e7a760194f3a9f",
"0x00000000000000000000000000000000000000000000000000000000000060a7",
"0x616e696d616c6661726d2e7363686f6f6c2e617474656e646564000000000000",
],
"transactionHash": "0x4e836b74c51a370375efa374297524d9b0f6eacdd699c30556680ae7dc9a14ea",
"transactionIndex": 1,
},
]
`)
})
......
import { ethers } from 'ethers'
import { Address } from 'wagmi'
import type { Address } from '@wagmi/core'
import { ATTESTATION_STATION_ADDRESS } from '../constants/attestationStationAddress'
import { abi } from '../lib/abi'
......
......@@ -43,7 +43,7 @@ describe(prepareWriteAttestation.name, () => {
expect(result.address).toMatchInlineSnapshot(
'"0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77"'
)
expect(result.chainId).toMatchInlineSnapshot('10')
expect(result.chainId).toMatchInlineSnapshot('undefined')
expect(result.functionName).toMatchInlineSnapshot('"attest"')
expect(result.mode).toMatchInlineSnapshot('"prepared"')
expect(result.request.gasLimit).toMatchInlineSnapshot(`
......@@ -54,18 +54,16 @@ describe(prepareWriteAttestation.name, () => {
`)
})
it('should throw an error if key is longer than 32 bytes', async () => {
it('should work for key longer than 32 bytes', async () => {
const dataType = 'string'
await expect(
readAttestation(
expect(
await readAttestation(
creator,
about,
'this is a key that is way longer than 32 bytes so this key should throw an error matching the inline snapshot',
dataType
)
).rejects.toThrowErrorMatchingInlineSnapshot(
'"Key is longer than the max length of 32 for attestation keys"'
)
).toMatchInlineSnapshot('""')
})
})
import { Address, prepareWriteContract } from '@wagmi/core'
import { formatBytes32String } from 'ethers/lib/utils.js'
import { ATTESTATION_STATION_ADDRESS } from '../constants/attestationStationAddress'
import { WagmiBytes } from '../types/WagmiBytes'
import { abi } from './abi'
import { createKey } from './createKey'
import { createValue } from './createValue'
export const prepareWriteAttestation = async (
......@@ -13,15 +13,7 @@ export const prepareWriteAttestation = async (
chainId: number | undefined = undefined,
contractAddress: Address = ATTESTATION_STATION_ADDRESS
) => {
let formattedKey: WagmiBytes
try {
formattedKey = formatBytes32String(key) as WagmiBytes
} catch (e) {
console.error(e)
throw new Error(
`key is longer than 32 bytes: ${key}. Try using a shorter key or using 'encodeRawKey' to encode the key into 32 bytes first`
)
}
const formattedKey = createKey(key) as WagmiBytes
return prepareWriteContract({
address: contractAddress,
abi,
......
......@@ -49,7 +49,7 @@ describe(prepareWriteAttestations.name, () => {
expect(result.address).toMatchInlineSnapshot(
'"0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77"'
)
expect(result.chainId).toMatchInlineSnapshot('10')
expect(result.chainId).toMatchInlineSnapshot('undefined')
expect(result.functionName).toMatchInlineSnapshot('"attest"')
expect(result.mode).toMatchInlineSnapshot('"prepared"')
expect(result.request.gasLimit).toMatchInlineSnapshot(`
......@@ -60,18 +60,16 @@ describe(prepareWriteAttestations.name, () => {
`)
})
it('should throw an error if key is longer than 32 bytes', async () => {
it('should work if key is longer than 32 bytes', async () => {
const dataType = 'string'
await expect(
readAttestation(
expect(
await readAttestation(
creator,
about,
'this is a key that is way longer than 32 bytes so this key should throw an error matching the inline snapshot',
dataType
)
).rejects.toThrowErrorMatchingInlineSnapshot(
'"Key is longer than the max length of 32 for attestation keys"'
)
).toMatchInlineSnapshot('""')
})
})
......@@ -26,16 +26,14 @@ describe(readAttestation.name, () => {
)
})
it('should throw an error if key is longer than 32 bytes', async () => {
await expect(
readAttestation(
it('should work if key is longer than 32 bytes', async () => {
expect(
await readAttestation(
creator,
about,
'this is a key that is way longer than 32 bytes so this key should throw an error matching the inline snapshot',
dataType
)
).rejects.toThrowErrorMatchingInlineSnapshot(
'"Key is longer than the max length of 32 for attestation keys"'
)
).toMatchInlineSnapshot('""')
})
})
import { readContracts } from '@wagmi/core'
import { formatBytes32String } from 'ethers/lib/utils.js'
import { ATTESTATION_STATION_ADDRESS } from '../constants/attestationStationAddress'
import type { AttestationReadParams } from '../types/AttestationReadParams'
import { DEFAULT_DATA_TYPE } from '../types/DataTypeOption'
import type { WagmiBytes } from '../types/WagmiBytes'
import { abi } from './abi'
import { createKey } from './createKey'
import { parseAttestationBytes } from './parseAttestationBytes'
/**
......@@ -39,16 +39,11 @@ export const readAttestations = async (
key,
contractAddress = ATTESTATION_STATION_ADDRESS,
} = attestation
if (key.length > 32) {
throw new Error(
'Key is longer than the max length of 32 for attestation keys'
)
}
return {
address: contractAddress,
abi,
functionName: 'attestations',
args: [creator, about, formatBytes32String(key) as WagmiBytes],
args: [creator, about, createKey(key) as WagmiBytes],
} as const
})
......
import { BigNumber } from 'ethers'
import { Address } from 'wagmi'
import type { Address } from '@wagmi/core'
import { DataTypeOption } from './DataTypeOption'
import { WagmiBytes } from './WagmiBytes'
......
......@@ -10,7 +10,7 @@ export default defineConfig({
*
* @see https://tsup.egoist.dev/#building-cli-app
*/
entry: ['src/index.ts', 'src/cli.ts'],
entry: ['src/index.ts', 'src/cli.ts', 'src/react.ts'],
outDir: 'dist',
target: 'es2021',
// will create a .js file for commonjs and a .cjs file for esm
......
Bytes_slice_Test:test_slice_acrossMultipleWords_works() (gas: 9423)
Bytes_slice_Test:test_slice_acrossWords_works() (gas: 1418)
Bytes_slice_Test:test_slice_fromNonZeroIdx_works() (gas: 17154)
Bytes_slice_Test:test_slice_fromZeroIdx_works() (gas: 20694)
Bytes_slice_Test:test_slice_acrossMultipleWords_works() (gas: 9413)
Bytes_slice_Test:test_slice_acrossWords_works() (gas: 1430)
Bytes_slice_Test:test_slice_fromNonZeroIdx_works() (gas: 17240)
Bytes_slice_Test:test_slice_fromZeroIdx_works() (gas: 20826)
Bytes_toNibbles_Test:test_toNibbles_expectedResult128Bytes_works() (gas: 129874)
Bytes_toNibbles_Test:test_toNibbles_expectedResult5Bytes_works() (gas: 6132)
Bytes_toNibbles_Test:test_toNibbles_zeroLengthInput_works() (gas: 944)
......@@ -174,16 +174,18 @@ L2OutputOracleUpgradeable_Test:test_initValuesOnProxy_succeeds() (gas: 26208)
L2OutputOracleUpgradeable_Test:test_initializeImpl_alreadyInitialized_reverts() (gas: 15149)
L2OutputOracleUpgradeable_Test:test_initializeProxy_alreadyInitialized_reverts() (gas: 20175)
L2OutputOracleUpgradeable_Test:test_upgrading_succeeds() (gas: 180481)
L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 387833)
L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 388064)
L2StandardBridge_BridgeERC20_Test:test_bridgeERC20_succeeds() (gas: 383536)
L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 389773)
L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 390006)
L2StandardBridge_BridgeERC20_Test:test_bridgeERC20_succeeds() (gas: 385280)
L2StandardBridge_BridgeERC20_Test:test_bridgeLegacyERC20_succeeds() (gas: 393552)
L2StandardBridge_BridgeERC20_Test:test_withdrawLegacyERC20_succeeds() (gas: 393878)
L2StandardBridge_BridgeERC20_Test:test_withdraw_notEOA_reverts() (gas: 251758)
L2StandardBridge_BridgeERC20_Test:test_withdraw_withdrawingERC20_succeeds() (gas: 383722)
L2StandardBridge_BridgeERC20_Test:test_withdraw_withdrawingERC20_succeeds() (gas: 385508)
L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 23843)
L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 23982)
L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 23870)
L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingERC20_succeeds() (gas: 91013)
L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingETH_succeeds() (gas: 89889)
L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingERC20_succeeds() (gas: 93824)
L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingETH_succeeds() (gas: 92700)
L2StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 43155)
L2StandardBridge_Test:test_initialize_succeeds() (gas: 24292)
L2StandardBridge_Test:test_receive_succeeds() (gas: 174011)
......@@ -264,13 +266,13 @@ OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutp
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() (gas: 207520)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() (gas: 41753)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() (gas: 199464)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 203388)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 206360)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() (gas: 180229)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReentrancy_reverts() (gas: 244483)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReplay_reverts() (gas: 245634)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReentrancy_reverts() (gas: 244377)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReplay_reverts() (gas: 245528)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_paused_reverts() (gas: 53555)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() (gas: 235047)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails_fails() (gas: 8797746687696163866)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() (gas: 234941)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails_fails() (gas: 8797746687696163864)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() (gas: 197042)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() (gas: 85690)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() (gas: 137350)
......@@ -403,6 +405,8 @@ ResourceMetering_Test:test_meter_updateTenEmptyBlocks_succeeds() (gas: 21161)
ResourceMetering_Test:test_meter_updateTwoEmptyBlocks_succeeds() (gas: 21117)
ResourceMetering_Test:test_meter_useMax_succeeds() (gas: 8017416)
ResourceMetering_Test:test_meter_useMoreThanMax_reverts() (gas: 16045)
SafeCall_call_Test:test_callWithMinGas_noLeakageHigh_succeeds() (gas: 2075873614)
SafeCall_call_Test:test_callWithMinGas_noLeakageLow_succeeds() (gas: 753665282)
Semver_Test:test_behindProxy_succeeds() (gas: 506748)
Semver_Test:test_version_succeeds() (gas: 9418)
SequencerFeeVault_Test:test_constructor_succeeds() (gas: 5526)
......@@ -410,6 +414,8 @@ SequencerFeeVault_Test:test_minWithdrawalAmount_succeeds() (gas: 5442)
SequencerFeeVault_Test:test_receive_succeeds() (gas: 17373)
SequencerFeeVault_Test:test_withdraw_notEnough_reverts() (gas: 9331)
SequencerFeeVault_Test:test_withdraw_succeeds() (gas: 163228)
StandardBridge_Stateless_Test:test_isCorrectTokenPair_succeeds() (gas: 49936)
StandardBridge_Stateless_Test:test_isOptimismMintableERC20_succeeds() (gas: 33072)
SystemConfig_Initialize_TestFail:test_initialize_lowGasLimit_reverts() (gas: 62012)
SystemConfig_Setters_TestFail:test_setBatcherHash_notOwner_reverts() (gas: 10612)
SystemConfig_Setters_TestFail:test_setGasConfig_notOwner_reverts() (gas: 10555)
......
......@@ -195,6 +195,11 @@ After the initial Bedrock upgrade, contracts MUST use the following versioning s
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.
### Dependencies
Where basic functionality is already supported by an existing contract in the OpenZeppelin library,
we should default to using the Upgradeable version of that contract.
### Tests
Tests are written using Foundry.
......@@ -207,7 +212,7 @@ These guidelines are also encoded in a script which can be run with:
ts-node scripts/forge-test-names.ts
```
*Note: This is a work in progress, not all test files are compliant with these guidelines.*
_Note: This is a work in progress, not all test files are compliant with these guidelines._
#### Organizing Principles
......
......@@ -43,11 +43,6 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
*/
uint64 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;
/**
* @notice Additional gas reserved for clean up after finalizing a transaction withdrawal.
*/
uint256 internal constant FINALIZE_GAS_BUFFER = 20_000;
/**
* @notice Address of the L2OutputOracle.
*/
......@@ -363,26 +358,19 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
// Mark the withdrawal as finalized so it can't be replayed.
finalizedWithdrawals[withdrawalHash] = true;
// We want to maintain the property that the amount of gas supplied to the call to the
// target contract is at least the gas limit specified by the user. We can do this by
// enforcing that, at this point in time, we still have gaslimit + buffer gas available.
require(
gasleft() >= _tx.gasLimit + FINALIZE_GAS_BUFFER,
"OptimismPortal: insufficient gas to finalize withdrawal"
);
// Set the l2Sender so contracts know who triggered this withdrawal on L2.
l2Sender = _tx.sender;
// Trigger the call to the target contract. We use SafeCall because we don't
// care about the returndata and we don't want target contracts to be able to force this
// call to run out of gas via a returndata bomb.
bool success = SafeCall.call(
_tx.target,
gasleft() - FINALIZE_GAS_BUFFER,
_tx.value,
_tx.data
);
// Trigger the call to the target contract. We use a custom low level method
// SafeCall.callWithMinGas to ensure two key properties
// 1. Target contracts cannot force this call to run out of gas by returning a very large
// amount of data (and this is OK because we don't care about the returndata here).
// 2. The amount of gas provided to the call to the target contract is at least the gas
// limit specified by the user. If there is not enough gas in the callframe to
// accomplish this, `callWithMinGas` will revert.
// Additionally, if there is not enough gas remaining to complete the execution after the
// call returns, this function will revert.
bool success = SafeCall.callWithMinGas(_tx.target, _tx.gasLimit, _tx.value, _tx.data);
// Reset the l2Sender back to the default value.
l2Sender = Constants.DEFAULT_L2_SENDER;
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { ILegacyMintableERC20 } from "../universal/OptimismMintableERC20.sol";
/**
* @title LegacyMintableERC20
* @notice The legacy implementation of the OptimismMintableERC20. This
* contract is deprecated and should no longer be used.
*/
contract LegacyMintableERC20 is ILegacyMintableERC20, ERC20 {
/**
* @notice Emitted when the token is minted by the bridge.
*/
event Mint(address indexed _account, uint256 _amount);
/**
* @notice Emitted when a token is burned by the bridge.
*/
event Burn(address indexed _account, uint256 _amount);
/**
* @notice The token on the remote domain.
*/
address public l1Token;
/**
* @notice The local bridge.
*/
address public l2Bridge;
/**
* @param _l2Bridge Address of the L2 standard bridge.
* @param _l1Token Address of the corresponding L1 token.
* @param _name ERC20 name.
* @param _symbol ERC20 symbol.
*/
constructor(
address _l2Bridge,
address _l1Token,
string memory _name,
string memory _symbol
) ERC20(_name, _symbol) {
l1Token = _l1Token;
l2Bridge = _l2Bridge;
}
/**
* @notice Modifier that requires the contract was called by the bridge.
*/
modifier onlyL2Bridge() {
require(msg.sender == l2Bridge, "Only L2 Bridge can mint and burn");
_;
}
/**
* @notice EIP165 implementation.
*/
function supportsInterface(bytes4 _interfaceId) public pure returns (bool) {
bytes4 firstSupportedInterface = bytes4(keccak256("supportsInterface(bytes4)")); // ERC165
bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^
ILegacyMintableERC20.mint.selector ^
ILegacyMintableERC20.burn.selector;
return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;
}
/**
* @notice Only the bridge can mint tokens.
* @param _to The account receiving tokens.
* @param _amount The amount of tokens to receive.
*/
function mint(address _to, uint256 _amount) public virtual onlyL2Bridge {
_mint(_to, _amount);
emit Mint(_to, _amount);
}
/**
* @notice Only the bridge can burn tokens.
* @param _from The account having tokens burnt.
* @param _amount The amount of tokens being burnt.
*/
function burn(address _from, uint256 _amount) public virtual onlyL2Bridge {
_burn(_from, _amount);
emit Burn(_from, _amount);
}
}
......@@ -26,7 +26,7 @@ library SafeCall {
_gas, // gas
_target, // recipient
_value, // ether value
add(_calldata, 0x20), // inloc
add(_calldata, 32), // inloc
mload(_calldata), // inlen
0, // outloc
0 // outlen
......@@ -34,4 +34,71 @@ library SafeCall {
}
return _success;
}
/**
* @notice Perform a low level call without copying any returndata. This function
* will revert if the call cannot be performed with the specified minimum
* gas.
*
* @param _target Address to call
* @param _minGas The minimum amount of gas that may be passed to the call
* @param _value Amount of value to pass to the call
* @param _calldata Calldata to pass to the call
*/
function callWithMinGas(
address _target,
uint256 _minGas,
uint256 _value,
bytes memory _calldata
) internal returns (bool) {
bool _success;
assembly {
// Assertion: gasleft() >= ((_minGas + 200) * 64) / 63
//
// Because EIP-150 ensures that, a maximum of 63/64ths of the remaining gas in the call
// frame may be passed to a subcontext, we need to ensure that the gas will not be
// truncated to hold this function's invariant: "If a call is performed by
// `callWithMinGas`, it must receive at least the specified minimum gas limit." In
// addition, exactly 51 gas is consumed between the below `GAS` opcode and the `CALL`
// opcode, so it is factored in with some extra room for error.
if lt(gas(), div(mul(64, add(_minGas, 200)), 63)) {
// Store the "Error(string)" selector in scratch space.
mstore(0, 0x08c379a0)
// Store the pointer to the string length in scratch space.
mstore(32, 32)
// Store the string.
//
// SAFETY:
// - We pad the beginning of the string with two zero bytes as well as the
// length (24) to ensure that we override the free memory pointer at offset
// 0x40. This is necessary because the free memory pointer is likely to
// be greater than 1 byte when this function is called, but it is incredibly
// unlikely that it will be greater than 3 bytes. As for the data within
// 0x60, it is ensured that it is 0 due to 0x60 being the zero offset.
// - It's fine to clobber the free memory pointer, we're reverting.
mstore(88, 0x0000185361666543616c6c3a204e6f7420656e6f75676820676173)
// Revert with 'Error("SafeCall: Not enough gas")'
revert(28, 100)
}
// The call will be supplied at least (((_minGas + 200) * 64) / 63) - 49 gas due to the
// above assertion. This ensures that, in all circumstances, the call will
// receive at least the minimum amount of gas specified.
// We can prove this property by solving the inequalities:
// ((((_minGas + 200) * 64) / 63) - 49) >= _minGas
// ((((_minGas + 200) * 64) / 63) - 51) * (63 / 64) >= _minGas
// Both inequalities hold true for all possible values of `_minGas`.
_success := call(
gas(), // gas
_target, // recipient
_value, // ether value
add(_calldata, 32), // inloc
mload(_calldata), // inlen
0x00, // outloc
0x00 // outlen
)
}
return _success;
}
}
......@@ -122,6 +122,58 @@ contract Bytes_slice_Test is Test {
vm.expectRevert("slice_overflow");
Bytes.slice(_input, _start, _length);
}
/**
* @notice Tests that the `slice` function correctly updates the free memory pointer depending
* on the length of the slice.
*/
function testFuzz_slice_memorySafety_succeeds(
bytes memory _input,
uint256 _start,
uint256 _length
) public {
// The start should never be more than the length of the input bytes array - 1
vm.assume(_start < _input.length);
// The length should never be more than the length of the input bytes array - the starting
// slice index.
vm.assume(_length <= _input.length - _start);
// Grab the free memory pointer before the slice operation
uint256 initPtr;
assembly {
initPtr := mload(0x40)
}
// Slice the input bytes array from `_start` to `_start + _length`
bytes memory slice = Bytes.slice(_input, _start, _length);
// Grab the free memory pointer after the slice operation
uint256 finalPtr;
assembly {
finalPtr := mload(0x40)
}
// The free memory pointer should have been updated properly
if (_length == 0) {
// If the slice length is zero, only 32 bytes of memory should have been allocated.
assertEq(finalPtr, initPtr + 0x20);
} else {
// If the slice length is greater than zero, the memory allocated should be the
// length of the slice rounded up to the next 32 byte word + 32 bytes for the
// length of the byte array.
//
// Note that we use a slightly less efficient, but equivalent method of rounding
// up `_length` to the next multiple of 32 than is used in the `slice` function.
// This is to diff test the method used in `slice`.
assertEq(finalPtr, initPtr + 0x20 + (((_length + 0x1F) >> 5) << 5));
// Sanity check for equivalence of the rounding methods.
assertEq(((_length + 0x1F) >> 5) << 5, (_length + 0x1F) & ~uint256(0x1F));
}
// The slice length should be equal to `_length`
assertEq(slice.length, _length);
}
}
contract Bytes_toNibbles_Test is Test {
......
......@@ -27,6 +27,7 @@ import { AddressManager } from "../legacy/AddressManager.sol";
import { L1ChugSplashProxy } from "../legacy/L1ChugSplashProxy.sol";
import { IL1ChugSplashDeployer } from "../legacy/L1ChugSplashProxy.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { LegacyMintableERC20 } from "../legacy/LegacyMintableERC20.sol";
contract CommonTest is Test {
address alice = address(128);
......@@ -276,6 +277,7 @@ contract Bridge_Initializer is Messenger_Initializer {
ERC20 L1Token;
ERC20 BadL1Token;
OptimismMintableERC20 L2Token;
LegacyMintableERC20 LegacyL2Token;
ERC20 NativeL2Token;
ERC20 BadL2Token;
OptimismMintableERC20 RemoteL1Token;
......@@ -398,6 +400,14 @@ contract Bridge_Initializer is Messenger_Initializer {
L1Token = new ERC20("Native L1 Token", "L1T");
LegacyL2Token = new LegacyMintableERC20({
_l2Bridge: address(L2Bridge),
_l1Token: address(L1Token),
_name: string.concat("LegacyL2-", L1Token.name()),
_symbol: string.concat("LegacyL2-", L1Token.symbol())
});
vm.label(address(LegacyL2Token), "LegacyMintableERC20");
// Deploy the L2 ERC20 now
L2Token = OptimismMintableERC20(
L2TokenFactory.createStandardL2Token(
......
......@@ -155,15 +155,15 @@ contract L2StandardBridge_Test is Bridge_Initializer {
contract PreBridgeERC20 is Bridge_Initializer {
// withdraw and BridgeERC20 should behave the same when transferring ERC20 tokens
// so they should share the same setup and expectEmit calls
function _preBridgeERC20(bool isLegacy) internal {
function _preBridgeERC20(bool _isLegacy, address _l2Token) internal {
// Alice has 100 L2Token
deal(address(L2Token), alice, 100, true);
assertEq(L2Token.balanceOf(alice), 100);
deal(_l2Token, alice, 100, true);
assertEq(ERC20(_l2Token).balanceOf(alice), 100);
uint256 nonce = L2Messenger.messageNonce();
bytes memory message = abi.encodeWithSelector(
StandardBridge.finalizeBridgeERC20.selector,
address(L1Token),
address(L2Token),
_l2Token,
alice,
alice,
100,
......@@ -190,23 +190,17 @@ contract PreBridgeERC20 is Bridge_Initializer {
})
);
if (isLegacy) {
if (_isLegacy) {
vm.expectCall(
address(L2Bridge),
abi.encodeWithSelector(
L2Bridge.withdraw.selector,
address(L2Token),
100,
1000,
hex""
)
abi.encodeWithSelector(L2Bridge.withdraw.selector, _l2Token, 100, 1000, hex"")
);
} else {
vm.expectCall(
address(L2Bridge),
abi.encodeWithSelector(
L2Bridge.bridgeERC20.selector,
address(L2Token),
_l2Token,
address(L1Token),
100,
1000,
......@@ -237,15 +231,15 @@ contract PreBridgeERC20 is Bridge_Initializer {
// The L2Bridge should burn the tokens
vm.expectCall(
address(L2Token),
_l2Token,
abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)
);
vm.expectEmit(true, true, true, true);
emit WithdrawalInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex"");
emit WithdrawalInitiated(address(L1Token), _l2Token, alice, alice, 100, hex"");
vm.expectEmit(true, true, true, true);
emit ERC20BridgeInitiated(address(L2Token), address(L1Token), alice, alice, 100, hex"");
emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, alice, 100, hex"");
vm.expectEmit(true, true, true, true);
emit MessagePassed(
......@@ -276,7 +270,7 @@ contract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 {
// - emits WithdrawalInitiated
// - calls Withdrawer.initiateWithdrawal
function test_withdraw_withdrawingERC20_succeeds() external {
_preBridgeERC20({ isLegacy: true });
_preBridgeERC20({ _isLegacy: true, _l2Token: address(L2Token) });
L2Bridge.withdraw(address(L2Token), 100, 1000, hex"");
assertEq(L2Token.balanceOf(alice), 0);
......@@ -287,12 +281,26 @@ contract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 {
// - emits WithdrawalInitiated
// - calls Withdrawer.initiateWithdrawal
function test_bridgeERC20_succeeds() external {
_preBridgeERC20({ isLegacy: false });
_preBridgeERC20({ _isLegacy: false, _l2Token: address(L2Token) });
L2Bridge.bridgeERC20(address(L2Token), address(L1Token), 100, 1000, hex"");
assertEq(L2Token.balanceOf(alice), 0);
}
function test_withdrawLegacyERC20_succeeds() external {
_preBridgeERC20({ _isLegacy: true, _l2Token: address(LegacyL2Token) });
L2Bridge.withdraw(address(LegacyL2Token), 100, 1000, hex"");
assertEq(L2Token.balanceOf(alice), 0);
}
function test_bridgeLegacyERC20_succeeds() external {
_preBridgeERC20({ _isLegacy: false, _l2Token: address(LegacyL2Token) });
L2Bridge.bridgeERC20(address(LegacyL2Token), address(L1Token), 100, 1000, hex"");
assertEq(L2Token.balanceOf(alice), 0);
}
function test_withdraw_notEOA_reverts() external {
// This contract has 100 L2Token
deal(address(L2Token), address(this), 100, true);
......@@ -305,14 +313,14 @@ contract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 {
contract PreBridgeERC20To is Bridge_Initializer {
// withdrawTo and BridgeERC20To should behave the same when transferring ERC20 tokens
// so they should share the same setup and expectEmit calls
function _preBridgeERC20To(bool isLegacy) internal {
deal(address(L2Token), alice, 100, true);
assertEq(L2Token.balanceOf(alice), 100);
function _preBridgeERC20To(bool _isLegacy, address _l2Token) internal {
deal(_l2Token, alice, 100, true);
assertEq(ERC20(L2Token).balanceOf(alice), 100);
uint256 nonce = L2Messenger.messageNonce();
bytes memory message = abi.encodeWithSelector(
StandardBridge.finalizeBridgeERC20.selector,
address(L1Token),
address(L2Token),
_l2Token,
alice,
bob,
100,
......@@ -340,10 +348,10 @@ contract PreBridgeERC20To is Bridge_Initializer {
);
vm.expectEmit(true, true, true, true, address(L2Bridge));
emit WithdrawalInitiated(address(L1Token), address(L2Token), alice, bob, 100, hex"");
emit WithdrawalInitiated(address(L1Token), _l2Token, alice, bob, 100, hex"");
vm.expectEmit(true, true, true, true, address(L2Bridge));
emit ERC20BridgeInitiated(address(L2Token), address(L1Token), alice, bob, 100, hex"");
emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, bob, 100, hex"");
vm.expectEmit(true, true, true, true, address(messagePasser));
emit MessagePassed(
......@@ -364,12 +372,12 @@ contract PreBridgeERC20To is Bridge_Initializer {
vm.expectEmit(true, true, true, true, address(L2Messenger));
emit SentMessageExtension1(address(L2Bridge), 0);
if (isLegacy) {
if (_isLegacy) {
vm.expectCall(
address(L2Bridge),
abi.encodeWithSelector(
L2Bridge.withdrawTo.selector,
address(L2Token),
_l2Token,
bob,
100,
1000,
......@@ -381,7 +389,7 @@ contract PreBridgeERC20To is Bridge_Initializer {
address(L2Bridge),
abi.encodeWithSelector(
L2Bridge.bridgeERC20To.selector,
address(L2Token),
_l2Token,
address(L1Token),
bob,
100,
......@@ -427,7 +435,7 @@ contract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To {
// - emits WithdrawalInitiated w/ correct recipient
// - calls Withdrawer.initiateWithdrawal
function test_withdrawTo_withdrawingERC20_succeeds() external {
_preBridgeERC20To({ isLegacy: true });
_preBridgeERC20To({ _isLegacy: true, _l2Token: address(L2Token) });
L2Bridge.withdrawTo(address(L2Token), bob, 100, 1000, hex"");
assertEq(L2Token.balanceOf(alice), 0);
......@@ -438,7 +446,7 @@ contract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To {
// - emits WithdrawalInitiated w/ correct recipient
// - calls Withdrawer.initiateWithdrawal
function test_bridgeERC20To_succeeds() external {
_preBridgeERC20To({ isLegacy: false });
_preBridgeERC20To({ _isLegacy: false, _l2Token: address(L2Token) });
L2Bridge.bridgeERC20To(address(L2Token), address(L1Token), bob, 100, 1000, hex"");
assertEq(L2Token.balanceOf(alice), 0);
}
......
......@@ -905,7 +905,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
);
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectRevert("OptimismPortal: insufficient gas to finalize withdrawal");
vm.expectRevert("SafeCall: Not enough gas");
op.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx);
}
......
......@@ -14,8 +14,8 @@ contract SafeCall_call_Test is CommonTest {
) external {
vm.assume(from.balance == 0);
vm.assume(to.balance == 0);
// no precompiles
vm.assume(uint160(to) > 10);
// no precompiles (mainnet)
assumeNoPrecompiles(to, 1);
// don't call the vm
vm.assume(to != address(vm));
vm.assume(from != address(vm));
......@@ -23,20 +23,140 @@ contract SafeCall_call_Test is CommonTest {
vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67));
// don't call the create2 deployer
vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));
// don't send funds to self
vm.assume(from != to);
assertEq(from.balance, 0, "from balance is 0");
vm.deal(from, value);
assertEq(from.balance, value, "from balance not dealt");
vm.expectCall(to, value, data);
uint256[2] memory balancesBefore = [from.balance, to.balance];
vm.expectCall(to, value, data);
vm.prank(from);
bool success = SafeCall.call(to, gas, value, data);
assertEq(success, true, "call not successful");
assertEq(to.balance, value, "to balance received");
assertEq(from.balance, 0, "from balance not drained");
assertTrue(success, "call not successful");
if (from == to) {
assertEq(from.balance, balancesBefore[0], "Self-send did not change balance");
} else {
assertEq(from.balance, balancesBefore[0] - value, "from balance not drained");
assertEq(to.balance, balancesBefore[1] + value, "to balance received");
}
}
function testFuzz_callWithMinGas_hasEnough_succeeds(
address from,
address to,
uint64 minGas,
uint64 value,
bytes memory data
) external {
vm.assume(from.balance == 0);
vm.assume(to.balance == 0);
// no precompiles (mainnet)
assumeNoPrecompiles(to, 1);
// don't call the vm
vm.assume(to != address(vm));
vm.assume(from != address(vm));
// don't call the console
vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67));
// don't call the create2 deployer
vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C));
assertEq(from.balance, 0, "from balance is 0");
vm.deal(from, value);
assertEq(from.balance, value, "from balance not dealt");
// Bound minGas to [0, l1_block_gas_limit]
minGas = uint64(bound(minGas, 0, 30_000_000));
uint256[2] memory balancesBefore = [from.balance, to.balance];
vm.expectCallMinGas(to, value, minGas, data);
vm.prank(from);
bool success = SafeCall.callWithMinGas(to, minGas, value, data);
assertTrue(success, "call not successful");
if (from == to) {
assertEq(from.balance, balancesBefore[0], "Self-send did not change balance");
} else {
assertEq(from.balance, balancesBefore[0] - value, "from balance not drained");
assertEq(to.balance, balancesBefore[1] + value, "to balance received");
}
}
function test_callWithMinGas_noLeakageLow_succeeds() external {
SimpleSafeCaller caller = new SimpleSafeCaller();
for (uint64 i = 5000; i < 50_000; i++) {
uint256 snapshot = vm.snapshot();
// 26,071 is the exact amount of gas required to make the safe call
// successfully.
if (i < 26_071) {
assertFalse(caller.makeSafeCall(i, 25_000));
} else {
vm.expectCallMinGas(
address(caller),
0,
25_000,
abi.encodeWithSelector(caller.setA.selector, 1)
);
assertTrue(caller.makeSafeCall(i, 25_000));
}
assertTrue(vm.revertTo(snapshot));
}
}
function test_callWithMinGas_noLeakageHigh_succeeds() external {
SimpleSafeCaller caller = new SimpleSafeCaller();
for (uint64 i = 15_200_000; i < 15_300_000; i++) {
uint256 snapshot = vm.snapshot();
// 15,238,769 is the exact amount of gas required to make the safe call
// successfully.
if (i < 15_238_769) {
assertFalse(caller.makeSafeCall(i, 15_000_000));
} else {
vm.expectCallMinGas(
address(caller),
0,
15_000_000,
abi.encodeWithSelector(caller.setA.selector, 1)
);
assertTrue(caller.makeSafeCall(i, 15_000_000));
}
assertTrue(vm.revertTo(snapshot));
}
}
}
contract SimpleSafeCaller {
uint256 public a;
function makeSafeCall(uint64 gas, uint64 minGas) external returns (bool) {
return
SafeCall.call(
address(this),
gas,
0,
abi.encodeWithSelector(this.makeSafeCallMinGas.selector, minGas)
);
}
function makeSafeCallMinGas(uint64 minGas) external returns (bool) {
return
SafeCall.callWithMinGas(
address(this),
minGas,
0,
abi.encodeWithSelector(this.setA.selector, 1)
);
}
function setA(uint256 _a) external {
a = _a;
}
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { StandardBridge } from "../universal/StandardBridge.sol";
import { CommonTest } from "./CommonTest.t.sol";
import {
OptimismMintableERC20,
ILegacyMintableERC20
} from "../universal/OptimismMintableERC20.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
/**
* @title StandardBridgeTester
* @notice Simple wrapper around the StandardBridge contract that exposes
* internal functions so they can be more easily tested directly.
*/
contract StandardBridgeTester is StandardBridge {
constructor(address payable _messenger, address payable _otherBridge)
StandardBridge(_messenger, _otherBridge)
{}
function isOptimismMintableERC20(address _token) external view returns (bool) {
return _isOptimismMintableERC20(_token);
}
function isCorrectTokenPair(address _mintableToken, address _otherToken)
external
view
returns (bool)
{
return _isCorrectTokenPair(_mintableToken, _otherToken);
}
receive() external payable override {}
}
/**
* @title LegacyMintable
* @notice Simple implementation of the legacy OptimismMintableERC20.
*/
contract LegacyMintable is ERC20, ILegacyMintableERC20 {
constructor(string memory _name, string memory _ticker) ERC20(_name, _ticker) {}
function l1Token() external view returns (address) {
return address(0);
}
function mint(address _to, uint256 _amount) external pure {}
function burn(address _from, uint256 _amount) external pure {}
/**
* @notice Implements ERC165. This implementation should not be changed as
* it is how the actual legacy optimism mintable token does the
* check. Allows for testing against code that is has been deployed,
* assuming different compiler version is no problem.
*/
function supportsInterface(bytes4 _interfaceId) external view returns (bool) {
bytes4 firstSupportedInterface = bytes4(keccak256("supportsInterface(bytes4)")); // ERC165
bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^
ILegacyMintableERC20.mint.selector ^
ILegacyMintableERC20.burn.selector;
return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;
}
}
/**
* @title StandardBridge_Stateless_Test
* @notice Tests internal functions that require no existing state or contract
* interactions with the messenger.
*/
contract StandardBridge_Stateless_Test is CommonTest {
StandardBridgeTester internal bridge;
OptimismMintableERC20 internal mintable;
ERC20 internal erc20;
LegacyMintable internal legacy;
function setUp() public override {
super.setUp();
bridge = new StandardBridgeTester({
_messenger: payable(address(0)),
_otherBridge: payable(address(0))
});
mintable = new OptimismMintableERC20({
_bridge: address(0),
_remoteToken: address(0),
_name: "Stonks",
_symbol: "STONK"
});
erc20 = new ERC20("Altcoin", "ALT");
legacy = new LegacyMintable("Legacy", "LEG");
}
/**
* @notice Test coverage for identifying OptimismMintableERC20 tokens.
* This function should return true for both modern and legacy
* OptimismMintableERC20 tokens and false for any accounts that
* do not implement the interface.
*/
function test_isOptimismMintableERC20_succeeds() external {
// Both the modern and legacy mintable tokens should return true
assertTrue(bridge.isOptimismMintableERC20(address(mintable)));
assertTrue(bridge.isOptimismMintableERC20(address(legacy)));
// A regular ERC20 should return false
assertFalse(bridge.isOptimismMintableERC20(address(erc20)));
// Non existent contracts should return false and not revert
assertEq(address(0x20).code.length, 0);
assertFalse(bridge.isOptimismMintableERC20(address(0x20)));
}
/**
* @notice Test coverage of isCorrectTokenPair under different types of
* tokens.
*/
function test_isCorrectTokenPair_succeeds() external {
// Modern + known to be correct remote token
assertTrue(bridge.isCorrectTokenPair(address(mintable), mintable.remoteToken()));
// Modern + known to be correct l1Token (legacy interface)
assertTrue(bridge.isCorrectTokenPair(address(mintable), mintable.l1Token()));
// Modern + known to be incorrect remote token
assertTrue(mintable.remoteToken() != address(0x20));
assertFalse(bridge.isCorrectTokenPair(address(mintable), address(0x20)));
// Legacy + known to be correct l1Token
assertTrue(bridge.isCorrectTokenPair(address(legacy), legacy.l1Token()));
// Legacy + known to be incorrect l1Token
assertTrue(legacy.l1Token() != address(0x20));
assertFalse(bridge.isCorrectTokenPair(address(legacy), address(0x20)));
// A token that doesn't support either modern or legacy interface
// will revert
vm.expectRevert();
bridge.isCorrectTokenPair(address(erc20), address(1));
}
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol";
import { StdUtils } from "forge-std/StdUtils.sol";
import { Vm } from "forge-std/Vm.sol";
import { SafeCall } from "../../libraries/SafeCall.sol";
contract SafeCall_Succeeds_Invariants is Test {
SafeCaller_Actor actor;
function setUp() public {
// Create a new safe caller actor.
actor = new SafeCaller_Actor(vm, false);
// Set the caller to this contract
targetSender(address(this));
// Target the safe caller actor.
targetContract(address(actor));
}
/**
* @custom:invariant If `callWithMinGas` performs a call, then it must always
* provide at least the specified minimum gas limit to the subcontext.
*
* If the check for remaining gas in `SafeCall.callWithMinGas` passes, the
* subcontext of the call below it must be provided at least `minGas` gas.
*/
function invariant_callWithMinGas_alwaysForwardsMinGas_succeeds() public {
assertEq(actor.numCalls(), 0, "no failed calls allowed");
}
function performSafeCallMinGas(uint64 minGas) external {
SafeCall.callWithMinGas(address(0), minGas, 0, hex"");
}
}
contract SafeCall_Fails_Invariants is Test {
SafeCaller_Actor actor;
function setUp() public {
// Create a new safe caller actor.
actor = new SafeCaller_Actor(vm, true);
// Set the caller to this contract
targetSender(address(this));
// Target the safe caller actor.
targetContract(address(actor));
}
/**
* @custom:invariant `callWithMinGas` reverts if there is not enough gas to pass
* to the subcontext.
*
* If there is not enough gas in the callframe to ensure that `callWithMinGas`
* can provide the specified minimum gas limit to the subcontext of the call,
* then `callWithMinGas` must revert.
*/
function invariant_callWithMinGas_neverForwardsMinGas_reverts() public {
assertEq(actor.numCalls(), 0, "no successful calls allowed");
}
function performSafeCallMinGas(uint64 minGas) external {
SafeCall.callWithMinGas(address(0), minGas, 0, hex"");
}
}
contract SafeCaller_Actor is StdUtils {
bool internal immutable FAILS;
Vm internal vm;
uint256 public numCalls;
constructor(Vm _vm, bool _fails) {
vm = _vm;
FAILS = _fails;
}
function performSafeCallMinGas(uint64 gas, uint64 minGas) external {
if (FAILS) {
// Bound the minimum gas amount to [2500, type(uint48).max]
minGas = uint64(bound(minGas, 2500, type(uint48).max));
// Bound the gas passed to [minGas, (((minGas + 200) * 64) / 63)]
gas = uint64(bound(gas, minGas, (((minGas + 200) * 64) / 63)));
} else {
// Bound the minimum gas amount to [2500, type(uint48).max]
minGas = uint64(bound(minGas, 2500, type(uint48).max));
// Bound the gas passed to [(((minGas + 200) * 64) / 63) + 500, type(uint64).max]
gas = uint64(bound(gas, (((minGas + 200) * 64) / 63) + 500, type(uint64).max));
}
vm.expectCallMinGas(address(0x00), 0, minGas, hex"");
bool success = SafeCall.call(
msg.sender,
gas,
0,
abi.encodeWithSelector(0x2ae57a41, minGas)
);
if (success && FAILS) numCalls++;
if (!FAILS && !success) numCalls++;
}
}
......@@ -10,7 +10,7 @@ import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol
* OptimismMintableERC20.
*/
interface IOptimismMintableERC20 is IERC165 {
function remoteToken() external returns (address);
function remoteToken() external view returns (address);
function bridge() external returns (address);
......@@ -26,7 +26,7 @@ interface IOptimismMintableERC20 is IERC165 {
* on the OptimismMintableERC20 contract for backwards compatibility.
*/
interface ILegacyMintableERC20 is IERC165 {
function l1Token() external returns (address);
function l1Token() external view returns (address);
function mint(address _to, uint256 _amount) external;
......
......@@ -458,6 +458,8 @@ abstract contract StandardBridge {
/**
* @notice Checks if the "other token" is the correct pair token for the OptimismMintableERC20.
* Calls can be saved in the future by combining this logic with
* `_isOptimismMintableERC20`.
*
* @param _mintableToken OptimismMintableERC20 to check against.
* @param _otherToken Pair token to check.
......@@ -469,7 +471,13 @@ abstract contract StandardBridge {
view
returns (bool)
{
return _otherToken == OptimismMintableERC20(_mintableToken).l1Token();
if (
ERC165Checker.supportsInterface(_mintableToken, type(ILegacyMintableERC20).interfaceId)
) {
return _otherToken == ILegacyMintableERC20(_mintableToken).l1Token();
} else {
return _otherToken == IOptimismMintableERC20(_mintableToken).remoteToken();
}
}
/** @notice Emits the ETHBridgeInitiated event and if necessary the appropriate legacy event
......
......@@ -33,5 +33,6 @@
"eip1559Denominator": 8,
"eip1559Elasticity": 2,
"l1GenesisBlockTimestamp": "0x638a4554",
"l1StartingBlockTag": "earliest"
"l1StartingBlockTag": "earliest",
"l2GenesisRegolithTimeOffset": "0x0"
}
......@@ -23,7 +23,6 @@ const deployFn: DeployFunction = async (hre) => {
SystemDictator,
ProxyAdmin,
AddressManager,
L1CrossDomainMessenger,
L1StandardBridgeProxy,
L1StandardBridgeProxyWithSigner,
L1ERC721BridgeProxy,
......@@ -43,11 +42,6 @@ const deployFn: DeployFunction = async (hre) => {
name: 'Lib_AddressManager',
signerOrProvider: deployer,
},
{
name: 'Proxy__OVM_L1CrossDomainMessenger',
iface: 'L1CrossDomainMessenger',
signerOrProvider: deployer,
},
{
name: 'Proxy__OVM_L1StandardBridge',
},
......@@ -118,41 +112,6 @@ const deployFn: DeployFunction = async (hre) => {
console.log(`AddressManager already owned by the SystemDictator`)
}
// Transfer ownership of the L1CrossDomainMessenger to SystemDictator.
if (
needsProxyTransfer &&
(await AddressManager.getAddress('OVM_L1CrossDomainMessenger')) !==
ethers.constants.AddressZero &&
(await L1CrossDomainMessenger.owner()) !== SystemDictator.address
) {
if (isLiveDeployer) {
console.log(`Setting L1CrossDomainMessenger owner to MSD`)
await L1CrossDomainMessenger.transferOwnership(SystemDictator.address)
} else {
const tx =
await L1CrossDomainMessenger.populateTransaction.transferOwnership(
SystemDictator.address
)
console.log(`Please transfer L1CrossDomainMessenger owner to MSD`)
console.log(`L1XDM address: ${L1CrossDomainMessenger.address}`)
console.log(`MSD address: ${SystemDictator.address}`)
console.log(`JSON:`)
console.log(jsonifyTransaction(tx))
}
// Wait for the ownership transfer to complete.
await awaitCondition(
async () => {
const owner = await L1CrossDomainMessenger.owner()
return owner === SystemDictator.address
},
30000,
1000
)
} else {
console.log(`L1CrossDomainMessenger already owned by MSD`)
}
// Transfer ownership of the L1StandardBridge (proxy) to SystemDictator.
if (
needsProxyTransfer &&
......
......@@ -14,6 +14,7 @@ This directory contains documentation for all defined invariant tests within `co
- [L2OutputOracle](./L2OutputOracle.md)
- [OptimismPortal](./OptimismPortal.md)
- [ResourceMetering](./ResourceMetering.md)
- [SafeCall](./SafeCall.md)
- [SystemConfig](./SystemConfig.md)
<!-- END autoTOC -->
......
# `SafeCall` Invariants
## If `callWithMinGas` performs a call, then it must always provide at least the specified minimum gas limit to the subcontext.
**Test:** [`SafeCall.t.sol#L30`](../contracts/test/invariants/SafeCall.t.sol#L30)
If the check for remaining gas in `SafeCall.callWithMinGas` passes, the subcontext of the call below it must be provided at least `minGas` gas.
## `callWithMinGas` reverts if there is not enough gas to pass to the subcontext.
**Test:** [`SafeCall.t.sol#L61`](../contracts/test/invariants/SafeCall.t.sol#L61)
If there is not enough gas in the callframe to ensure that `callWithMinGas` can provide the specified minimum gas limit to the subcontext of the call, then `callWithMinGas` must revert.
......@@ -54,10 +54,16 @@ export const deploy = async ({
waitConfirmations: hre.deployConfig.numDeployConfirmations,
})
console.log(`Deployed ${name} at ${result.address}`)
// Only wait for the transaction if it was recently deployed in case the
// result was deployed a long time ago and was pruned from the backend.
await hre.ethers.provider.waitForTransaction(result.transactionHash)
}
// Always wait for the transaction to be mined, just in case.
await hre.ethers.provider.waitForTransaction(result.transactionHash)
// Check to make sure there is code
const code = await hre.ethers.provider.getCode(result.address)
if (code === '0x') {
throw new Error(`no code for ${result.address}`)
}
// Create the contract object to return.
const created = asAdvancedContract({
......
# TeleportrDeposit
> TeleportrDeposit Shout out to 0xclem for providing the inspiration for this contract: https://github.com/0xclem/teleportr/blob/main/contracts/BridgeDeposit.sol
## Methods
### maxBalance
```solidity
function maxBalance() external view returns (uint256)
```
The maximum balance the contract can hold after a receive.
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | uint256 | undefined
### maxDepositAmount
```solidity
function maxDepositAmount() external view returns (uint256)
```
The maximum amount that be deposited in a receive.
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | uint256 | undefined
### minDepositAmount
```solidity
function minDepositAmount() external view returns (uint256)
```
The minimum amount that be deposited in a receive.
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | uint256 | undefined
### owner
```solidity
function owner() external view returns (address)
```
*Returns the address of the current owner.*
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined
### renounceOwnership
```solidity
function renounceOwnership() external nonpayable
```
*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.*
### setMaxAmount
```solidity
function setMaxAmount(uint256 _maxDepositAmount) external nonpayable
```
Sets the maximum amount that can be deposited in a receive.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _maxDepositAmount | uint256 | The new maximum deposit amount.
### setMaxBalance
```solidity
function setMaxBalance(uint256 _maxBalance) external nonpayable
```
Sets the maximum balance the contract can hold after a receive.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _maxBalance | uint256 | The new maximum contract balance.
### setMinAmount
```solidity
function setMinAmount(uint256 _minDepositAmount) external nonpayable
```
Sets the minimum amount that can be deposited in a receive.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _minDepositAmount | uint256 | The new minimum deposit amount.
### totalDeposits
```solidity
function totalDeposits() external view returns (uint256)
```
The total number of successful deposits received.
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | uint256 | undefined
### transferOwnership
```solidity
function transferOwnership(address newOwner) external nonpayable
```
*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| newOwner | address | undefined
### withdrawBalance
```solidity
function withdrawBalance() external nonpayable
```
Sends the contract&#39;s current balance to the owner.
## Events
### BalanceWithdrawn
```solidity
event BalanceWithdrawn(address indexed owner, uint256 balance)
```
Emitted any time the balance is withdrawn by the owner.
#### Parameters
| Name | Type | Description |
|---|---|---|
| owner `indexed` | address | The current owner and recipient of the funds. |
| balance | uint256 | The current contract balance paid to the owner. |
### EtherReceived
```solidity
event EtherReceived(uint256 indexed depositId, address indexed emitter, uint256 indexed amount)
```
Emitted any time a successful deposit is received.
#### Parameters
| Name | Type | Description |
|---|---|---|
| depositId `indexed` | uint256 | A unique sequencer number identifying the deposit. |
| emitter `indexed` | address | The sending address of the payer. |
| amount `indexed` | uint256 | The amount deposited by the payer. |
### MaxBalanceSet
```solidity
event MaxBalanceSet(uint256 previousBalance, uint256 newBalance)
```
Emitted any time the contract maximum balance is set.
#### Parameters
| Name | Type | Description |
|---|---|---|
| previousBalance | uint256 | The previous maximum contract balance. |
| newBalance | uint256 | The new maximum contract balance. |
### MaxDepositAmountSet
```solidity
event MaxDepositAmountSet(uint256 previousAmount, uint256 newAmount)
```
Emitted any time the maximum deposit amount is set.
#### Parameters
| Name | Type | Description |
|---|---|---|
| previousAmount | uint256 | The previous maximum deposit amount. |
| newAmount | uint256 | The new maximum deposit amount. |
### MinDepositAmountSet
```solidity
event MinDepositAmountSet(uint256 previousAmount, uint256 newAmount)
```
Emitted any time the minimum deposit amount is set.
#### Parameters
| Name | Type | Description |
|---|---|---|
| previousAmount | uint256 | The previous minimum deposit amount. |
| newAmount | uint256 | The new minimum deposit amount. |
### OwnershipTransferred
```solidity
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner)
```
#### Parameters
| Name | Type | Description |
|---|---|---|
| previousOwner `indexed` | address | undefined |
| newOwner `indexed` | address | undefined |
# TeleportrDisburser
> TeleportrDisburser
## Methods
### disburse
```solidity
function disburse(uint256 _nextDepositId, TeleportrDisburser.Disbursement[] _disbursements) external payable
```
Accepts a list of Disbursements and forwards the amount paid to the contract to each recipient. The method reverts if there are zero disbursements, the total amount to forward differs from the amount sent in the transaction, or the _nextDepositId is unexpected. Failed disbursements will not cause the method to revert, but will instead be held by the contract and availabe for the owner to withdraw.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _nextDepositId | uint256 | The depositId of the first Dispursement.
| _disbursements | TeleportrDisburser.Disbursement[] | A list of Disbursements to process.
### owner
```solidity
function owner() external view returns (address)
```
*Returns the address of the current owner.*
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined
### renounceOwnership
```solidity
function renounceOwnership() external nonpayable
```
*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.*
### totalDisbursements
```solidity
function totalDisbursements() external view returns (uint256)
```
The total number of disbursements processed.
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | uint256 | undefined
### transferOwnership
```solidity
function transferOwnership(address newOwner) external nonpayable
```
*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| newOwner | address | undefined
### withdrawBalance
```solidity
function withdrawBalance() external nonpayable
```
Sends the contract&#39;s current balance to the owner.
## Events
### BalanceWithdrawn
```solidity
event BalanceWithdrawn(address indexed owner, uint256 balance)
```
Emitted any time the balance is withdrawn by the owner.
#### Parameters
| Name | Type | Description |
|---|---|---|
| owner `indexed` | address | The current owner and recipient of the funds. |
| balance | uint256 | The current contract balance paid to the owner. |
### DisbursementFailed
```solidity
event DisbursementFailed(uint256 indexed depositId, address indexed to, uint256 amount)
```
Emitted any time a disbursement fails to send.
#### Parameters
| Name | Type | Description |
|---|---|---|
| depositId `indexed` | uint256 | The unique sequence number identifying the deposit. |
| to `indexed` | address | The intended recipient of the disbursement. |
| amount | uint256 | The amount intended to be sent to the recipient. |
### DisbursementSuccess
```solidity
event DisbursementSuccess(uint256 indexed depositId, address indexed to, uint256 amount)
```
Emitted any time a disbursement is successfuly sent.
#### Parameters
| Name | Type | Description |
|---|---|---|
| depositId `indexed` | uint256 | The unique sequence number identifying the deposit. |
| to `indexed` | address | The recipient of the disbursement. |
| amount | uint256 | The amount sent to the recipient. |
### OwnershipTransferred
```solidity
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner)
```
#### Parameters
| Name | Type | Description |
|---|---|---|
| previousOwner `indexed` | address | undefined |
| newOwner `indexed` | address | undefined |
......@@ -124,7 +124,7 @@ export class FaultDetector extends BaseServiceV2<Options, Metrics, State> {
this.state.oo = {
contract: oo,
filter: oo.filters.OutputProposed(),
getTotalElements: async () => oo.latestOutputIndex(),
getTotalElements: async () => oo.nextOutputIndex(),
getEventIndex: (args) => args.l2OutputIndex,
}
} else {
......
......@@ -18,12 +18,10 @@ import {
sleep,
remove0x,
toHexString,
fromHexString,
toRpcHexString,
hashCrossDomainMessage,
encodeCrossDomainMessageV0,
encodeCrossDomainMessageV1,
L2OutputOracleParameters,
BedrockOutputData,
BedrockCrossChainMessageProof,
decodeVersionedNonce,
......@@ -67,6 +65,7 @@ import {
makeMerkleTreeProof,
makeStateTrieProof,
hashLowLevelMessage,
migratedWithdrawalGasLimit,
DEPOSIT_CONFIRMATION_BLOCKS,
CHAIN_BLOCK_TIMES,
} from './utils'
......@@ -352,12 +351,12 @@ export class CrossChainMessenger {
}
}
const minGasLimit = fromHexString(resolved.message).length * 16 + 200_000
const minGasLimit = migratedWithdrawalGasLimit(resolved.message)
return {
...resolved,
value,
minGasLimit: BigNumber.from(minGasLimit),
minGasLimit,
messageNonce: encodeVersionedNonce(
BigNumber.from(1),
resolved.messageNonce
......
import { hashWithdrawal } from '@eth-optimism/core-utils'
import { hashWithdrawal, calldataCost } from '@eth-optimism/core-utils'
import { BigNumber } from 'ethers'
import { LowLevelMessage } from '../interfaces'
......@@ -18,3 +19,16 @@ export const hashLowLevelMessage = (message: LowLevelMessage): string => {
message.message
)
}
/**
* Compute the min gas limit for a migrated withdrawal.
*/
export const migratedWithdrawalGasLimit = (data: string): BigNumber => {
// Compute the gas limit and cap at 25 million
const dataCost = calldataCost(data)
let minGasLimit = dataCost.add(200_000)
if (minGasLimit.gt(25_000_000)) {
minGasLimit = BigNumber.from(25_000_000)
}
return minGasLimit
}
import { BigNumber } from 'ethers'
import { expect } from '../setup'
import { migratedWithdrawalGasLimit } from '../../src/utils/message-utils'
describe('Message Utils', () => {
describe('migratedWithdrawalGasLimit', () => {
it('should have a max of 25 million', () => {
const data = '0x' + 'ff'.repeat(15_000_000)
const result = migratedWithdrawalGasLimit(data)
expect(result).to.eq(BigNumber.from(25_000_000))
})
it('should work for mixes of zeros and ones', () => {
const tests = [
{ input: '0x', result: BigNumber.from(200_000) },
{ input: '0xff', result: BigNumber.from(200_000 + 16) },
{ input: '0xff00', result: BigNumber.from(200_000 + 16 + 4) },
{ input: '0x00', result: BigNumber.from(200_000 + 4) },
{ input: '0x000000', result: BigNumber.from(200_000 + 4 + 4 + 4) },
]
for (const test of tests) {
const result = migratedWithdrawalGasLimit(test.input)
expect(result).to.eq(test.result)
}
})
})
})
......@@ -605,7 +605,7 @@ The safe L2 head is the highest [safe L2 block][safe-l2-block] that a [rollup no
[unsafe-l2-block]: glossary.md#unsafe-l2-block
An unsafe L2 block is an L2 block that a [rollup node][rollup-node] knows about, but which was not derived from the L1
chian. In sequencer mode, this will be a block sequenced by the sequencer itself. In validator mode, this will be a
chain. In sequencer mode, this will be a block sequenced by the sequencer itself. In validator mode, this will be a
block acquired from the sequencer via [unsafe sync][unsafe-sync].
## Unsafe L2 Head
......
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